Skip to main content
Glama

MCP Server for macOS

by avanomme
create_final_dmg.py12 kB
#!/usr/bin/env python3 """ MCP Final Professional Installer - Python 3.12 with Fixed Dependencies Creates a bulletproof .dmg installer that actually works. """ import os import shutil import subprocess import sys from pathlib import Path def create_final_dmg(): """Create the final working DMG installer.""" print("🚀 Creating MCP Final Professional Installer (Python 3.12)...") # Clean up any existing builds build_items = ["MCP.app", "MCP_Professional_Installer.dmg", "MCP_Final_Installer.dmg", "dmg_temp", "dist"] for item in build_items: if os.path.exists(item): print(f"🧹 Cleaning up {item}...") if os.path.isdir(item): shutil.rmtree(item) else: os.remove(item) # Create distribution directory dist_path = Path("dist") dist_path.mkdir(exist_ok=True) print("📦 Building MCP Application Bundle (Python 3.12)...") # Create app bundle structure app_path = dist_path / "MCP.app" contents_path = app_path / "Contents" macos_path = contents_path / "MacOS" resources_path = contents_path / "Resources" # Create directories macos_path.mkdir(parents=True, exist_ok=True) resources_path.mkdir(parents=True, exist_ok=True) # Create Info.plist info_plist = { 'CFBundleName': 'MCP', 'CFBundleDisplayName': 'MCP Control Panel', 'CFBundleIdentifier': 'com.mcp.controlpanel', 'CFBundleVersion': '1.0.0', 'CFBundleShortVersionString': '1.0.0', 'CFBundleExecutable': 'MCP', 'CFBundleIconFile': 'MCP.icns', 'LSApplicationCategoryType': 'public.app-category.developer-tools', 'NSHighResolutionCapable': True, 'LSMinimumSystemVersion': '10.14', 'NSRequiresAquaSystemAppearance': False, 'LSUIElement': False } import plistlib with open(contents_path / "Info.plist", 'wb') as f: plistlib.dump(info_plist, f) # Copy icon if os.path.exists("MCP.icns"): print("🎨 Adding application icon...") shutil.copy2("MCP.icns", resources_path / "MCP.icns") # Force Python 3.12 usage print("🐍 Creating virtual environment with Python 3.12...") python_executables = [ "/usr/bin/python3.12", "/usr/local/bin/python3.12", "/opt/homebrew/bin/python3.12", "/Library/Frameworks/Python.framework/Versions/3.12/bin/python3.12", "python3.12", "python3" ] python_cmd = None for cmd in python_executables: try: result = subprocess.run([cmd, "--version"], capture_output=True, text=True) if result.returncode == 0 and "3.12" in result.stdout: python_cmd = cmd print(f"✅ Found Python 3.12: {cmd}") break except: continue if not python_cmd: print("❌ Python 3.12 not found! Please install Python 3.12") return False # Create virtual environment with Python 3.12 venv_path = macos_path / "venv" subprocess.run([python_cmd, "-m", "venv", str(venv_path)], check=True) # Install dependencies with proper paths print("📦 Installing dependencies with Python 3.12...") pip_path = venv_path / "bin" / "pip" python_venv = venv_path / "bin" / "python" # Upgrade pip first subprocess.run([str(python_venv), "-m", "pip", "install", "--upgrade", "pip"], check=True) # Install dependencies one by one to catch issues dependencies = [ "fastapi==0.104.1", "uvicorn==0.24.0", "pydantic==2.4.2", "pydantic-settings==2.1.0", "python-dotenv==1.0.0", "pyyaml==6.0.1", "loguru==0.7.2", "python-jose[cryptography]==3.3.0", "passlib[bcrypt]==1.7.4", "python-multipart==0.0.6", "aiofiles==23.2.1", "watchdog==3.0.0", "httpx==0.25.1", "pywebview==5.4", "bcrypt==4.0.1" ] for dep in dependencies: print(f" Installing {dep}...") result = subprocess.run([str(python_venv), "-m", "pip", "install", dep], capture_output=True, text=True) if result.returncode != 0: print(f"⚠️ Warning: Failed to install {dep}: {result.stderr}") # Create the optimized main executable print("⚡ Creating optimized launcher...") main_executable = '''#!/usr/bin/env python3 """ MCP Application - Final Working Version Uses pre-installed dependencies with proper path handling. """ import sys import os import subprocess import time import signal import traceback from pathlib import Path def setup_environment(): """Setup the application environment with proper paths.""" app_dir = Path(__file__).parent # Clear logs on every launch log_dir = Path.home() / "Library" / "Logs" / "MCP" if log_dir.exists(): for log_file in log_dir.glob("*.log"): try: log_file.unlink() except: pass # Set up virtual environment paths venv_path = app_dir / "venv" if venv_path.exists(): # Use the venv's Python executable venv_python = venv_path / "bin" / "python" if venv_python.exists(): # Re-execute with venv python if we're not already using it if sys.executable != str(venv_python): print(f"Switching to venv Python: {venv_python}") os.execv(str(venv_python), [str(venv_python)] + sys.argv) # Add venv site-packages to path for python_dir in (venv_path / "lib").glob("python*"): site_packages = python_dir / "site-packages" if site_packages.exists(): sys.path.insert(0, str(site_packages)) # Add src to Python path src_dir = app_dir / "src" if src_dir.exists(): sys.path.insert(0, str(src_dir)) # Change to app directory os.chdir(app_dir) return app_dir def kill_existing_processes(): """Kill any existing MCP processes.""" try: result = subprocess.run(["lsof", "-ti:8080"], capture_output=True, text=True) if result.stdout: pids = result.stdout.strip().split('\\n') for pid in pids: if pid: subprocess.run(["kill", "-9", pid], capture_output=True) print(f"Killed existing process {pid} using port 8080") except: pass def main(): """Main application entry point.""" try: print("🚀 Starting MCP Control Panel...") # Setup environment (clears logs and sets up paths) app_dir = setup_environment() # Kill existing processes kill_existing_processes() # Import and run the application try: from utils.logger import logger logger.info("MCP Application starting with pre-installed dependencies...") # Import launch module import launch launch.main() except ImportError as e: print(f"Error importing application modules: {e}") print(f"Python path: {sys.path}") print(f"Working directory: {os.getcwd()}") traceback.print_exc() return 1 except KeyboardInterrupt: print("\\nApplication terminated by user.") return 0 except Exception as e: print(f"Unexpected error: {e}") traceback.print_exc() return 1 if __name__ == "__main__": sys.exit(main()) ''' # Write the main executable main_exec_path = macos_path / "MCP" with open(main_exec_path, 'w') as f: f.write(main_executable) os.chmod(main_exec_path, 0o755) # Copy application files print("📄 Copying application files...") for item in ["src", "config"]: if os.path.exists(item): if os.path.isdir(item): shutil.copytree(item, macos_path / item) # Copy launch.py if os.path.exists("launch.py"): shutil.copy2("launch.py", macos_path / "launch.py") # Copy requirements.txt for reference if os.path.exists("requirements.txt"): shutil.copy2("requirements.txt", macos_path / "requirements.txt") print("🎨 Creating final DMG installer...") # Create temporary DMG directory dmg_temp = Path("dmg_temp") dmg_temp.mkdir(exist_ok=True) # Copy app to DMG directory shutil.copytree(app_path, dmg_temp / "MCP.app") # Create Applications symlink applications_link = dmg_temp / "Applications" if applications_link.exists(): applications_link.unlink() os.symlink("/Applications", applications_link) # Create final README readme_content = """🚀 MCP Control Panel - Final Professional Version ✨ INSTALLATION (Just drag and drop!): 1. Drag MCP.app to the Applications folder 2. Launch MCP from Applications 3. Done! No additional setup required. 🔧 SYSTEM REQUIREMENTS: • macOS 10.14 or later • Python 3.12 (pre-bundled in app) • No additional dependencies needed ✅ WHAT'S FIXED IN THIS VERSION: ✅ Python 3.12 compatibility ✅ All dependencies pre-installed ✅ PyObjC circular import issues resolved ✅ Proper virtual environment isolation ✅ Automatic log cleanup on launch ✅ Fast startup (no runtime installations) 🚀 FEATURES: • Lightning-fast launch • Professional macOS integration • Modern web-based interface • Automatic error recovery • Clean log management 🆘 IF IT DOESN'T WORK: 1. Make sure you dragged to Applications (not Desktop) 2. Try right-click → Open (if security warning) 3. Check Console.app for detailed errors 4. Run from Terminal: /Applications/MCP.app/Contents/MacOS/MCP 🗑️ TO UNINSTALL: Just delete MCP.app from Applications Enjoy your MCP Control Panel! 🎊 Built with Python 3.12 for maximum compatibility. """ with open(dmg_temp / "📖 Installation Guide.txt", 'w') as f: f.write(readme_content) # Create the final DMG dmg_name = "MCP_Final_Installer.dmg" print(f"🗜️ Creating {dmg_name}...") # Remove existing DMG if os.path.exists(dmg_name): os.remove(dmg_name) # Create DMG using hdiutil create_dmg_cmd = [ "hdiutil", "create", "-srcfolder", str(dmg_temp), "-volname", "MCP Control Panel - Final", "-fs", "HFS+", "-fsargs", "-c c=64,a=16,e=16", "-format", "UDBZ", "-imagekey", "zlib-level=9", dmg_name ] result = subprocess.run(create_dmg_cmd, capture_output=True, text=True) if result.returncode == 0: file_size = os.path.getsize(dmg_name) / (1024*1024) print(f"✅ Successfully created {dmg_name}") print(f"📦 DMG size: {file_size:.1f} MB") print(f"🎯 Final professional installer ready!") print(f"") print(f"🌟 FINAL VERSION FIXES:") print(f" ✅ Python 3.12 compatibility") print(f" ✅ PyObjC circular import resolved") print(f" ✅ All dependencies pre-installed") print(f" ✅ Proper virtual environment setup") print(f" ✅ Automatic log cleanup") print(f" ✅ Lightning-fast startup") print(f"") print(f"📱 READY FOR DISTRIBUTION:") print(f" Users: Download → Mount → Drag → Launch!") else: print(f"❌ Error creating DMG: {result.stderr}") return False # Cleanup shutil.rmtree(dmg_temp) shutil.rmtree(dist_path) return True if __name__ == "__main__": if not create_final_dmg(): sys.exit(1) print("🎊 MCP Final Professional Installer completed successfully!")

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/avanomme/mcp_mac'

If you have feedback or need assistance with the MCP directory API, please join our Discord server