|
|
""" |
|
|
FleetMind MCP Server with Authentication Proxy |
|
|
Launches both the FastMCP server and the authentication proxy. |
|
|
|
|
|
This script: |
|
|
1. Starts FastMCP server on port 7861 (internal) |
|
|
2. Starts authentication proxy on port 7860 (public) |
|
|
3. Handles graceful shutdown of both processes |
|
|
|
|
|
Usage: |
|
|
python start_with_proxy.py |
|
|
""" |
|
|
|
|
|
import subprocess |
|
|
import sys |
|
|
import time |
|
|
import signal |
|
|
import os |
|
|
from pathlib import Path |
|
|
|
|
|
|
|
|
fastmcp_process = None |
|
|
proxy_process = None |
|
|
|
|
|
|
|
|
def signal_handler(sig, frame): |
|
|
"""Handle Ctrl+C gracefully""" |
|
|
print("\n\nShutting down FleetMind MCP Server...") |
|
|
|
|
|
if proxy_process: |
|
|
print(" -> Stopping proxy...") |
|
|
proxy_process.terminate() |
|
|
try: |
|
|
proxy_process.wait(timeout=5) |
|
|
except subprocess.TimeoutExpired: |
|
|
proxy_process.kill() |
|
|
|
|
|
if fastmcp_process: |
|
|
print(" -> Stopping FastMCP server...") |
|
|
fastmcp_process.terminate() |
|
|
try: |
|
|
fastmcp_process.wait(timeout=5) |
|
|
except subprocess.TimeoutExpired: |
|
|
fastmcp_process.kill() |
|
|
|
|
|
print("[OK] FleetMind MCP Server stopped.") |
|
|
sys.exit(0) |
|
|
|
|
|
|
|
|
def main(): |
|
|
global fastmcp_process, proxy_process |
|
|
|
|
|
|
|
|
signal.signal(signal.SIGINT, signal_handler) |
|
|
signal.signal(signal.SIGTERM, signal_handler) |
|
|
|
|
|
print("\n" + "=" * 70) |
|
|
print("FleetMind MCP Server with Multi-Tenant Authentication") |
|
|
print("=" * 70) |
|
|
print("Starting components:") |
|
|
print(" 1. FastMCP Server (port 7861) - Internal") |
|
|
print(" 2. Auth Proxy (port 7860) - Public") |
|
|
print("=" * 70 + "\n") |
|
|
|
|
|
|
|
|
python_exe = sys.executable |
|
|
|
|
|
|
|
|
print("[1/2] Starting FastMCP server on port 7861...") |
|
|
try: |
|
|
|
|
|
fastmcp_process = subprocess.Popen( |
|
|
[python_exe, "app.py"] |
|
|
) |
|
|
print("[OK] FastMCP server starting (output below)...") |
|
|
except Exception as e: |
|
|
print(f"[ERROR] Failed to start FastMCP server: {e}") |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
print(" Waiting for FastMCP to initialize...") |
|
|
time.sleep(3) |
|
|
|
|
|
|
|
|
if fastmcp_process.poll() is not None: |
|
|
print("[ERROR] FastMCP server failed to start") |
|
|
print(" Check the error messages above") |
|
|
sys.exit(1) |
|
|
|
|
|
print("[OK] FastMCP server running") |
|
|
|
|
|
|
|
|
print("\n[2/2] Starting authentication proxy on port 7860...") |
|
|
try: |
|
|
|
|
|
proxy_process = subprocess.Popen( |
|
|
[python_exe, "proxy.py"] |
|
|
) |
|
|
print("[OK] Auth proxy starting (output below)...") |
|
|
except Exception as e: |
|
|
print(f"[ERROR] Failed to start proxy: {e}") |
|
|
if fastmcp_process: |
|
|
fastmcp_process.terminate() |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
time.sleep(2) |
|
|
|
|
|
|
|
|
if proxy_process.poll() is not None: |
|
|
print("[ERROR] Proxy failed to start") |
|
|
if fastmcp_process: |
|
|
fastmcp_process.terminate() |
|
|
sys.exit(1) |
|
|
|
|
|
print("[OK] Auth proxy running") |
|
|
|
|
|
print("\n" + "=" * 70) |
|
|
print("[OK] FleetMind MCP Server is READY!") |
|
|
print("=" * 70) |
|
|
print(f"Connect to: http://localhost:7860/sse") |
|
|
print(f"Claude Desktop config:") |
|
|
print(f' "args": ["mcp-remote", "http://localhost:7860/sse?api_key=YOUR_KEY"]') |
|
|
print("=" * 70) |
|
|
print("\n[AUTH] Multi-tenant authentication is ENABLED") |
|
|
print(" Each connection's API key will be captured automatically\n") |
|
|
print("Press Ctrl+C to stop...\n") |
|
|
|
|
|
|
|
|
try: |
|
|
while True: |
|
|
|
|
|
if fastmcp_process.poll() is not None: |
|
|
print("[ERROR] FastMCP server stopped unexpectedly") |
|
|
if proxy_process: |
|
|
proxy_process.terminate() |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
if proxy_process.poll() is not None: |
|
|
print("[ERROR] Proxy stopped unexpectedly") |
|
|
if fastmcp_process: |
|
|
fastmcp_process.terminate() |
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
|
|
|
time.sleep(1) |
|
|
|
|
|
except KeyboardInterrupt: |
|
|
signal_handler(signal.SIGINT, None) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
if not Path("app.py").exists(): |
|
|
print("[ERROR] app.py not found") |
|
|
sys.exit(1) |
|
|
|
|
|
if not Path("proxy.py").exists(): |
|
|
print("[ERROR] proxy.py not found") |
|
|
sys.exit(1) |
|
|
|
|
|
main() |
|
|
|