import os import sys import json import argparse from typing import Dict, Any, List from fastapi import FastAPI, HTTPException from pydantic import BaseModel import uvicorn # Add project root to path PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) if PROJECT_ROOT not in sys.path: sys.path.append(PROJECT_ROOT) from mcp_server.registry import ToolRegistry from mcp_server.discovery import scan_local_tools from reasoning.tools.qulab import QuLabBridge app = FastAPI(title="ECH0-PRIME MCP Server") class ToolCallRequest(BaseModel): tool: str args: Dict[str, Any] @app.get("/health") async def health(): return {"status": "ok"} @app.get("/tools") async def list_tools(): return ToolRegistry.get_schemas() @app.post("/tools/call") async def call_tool(request: ToolCallRequest): result = ToolRegistry.call_tool(request.tool, request.args) if result and isinstance(result, str) and result.startswith("Error:"): raise HTTPException(status_code=400, detail=result) return {"output": result} @app.post("/shutdown") async def shutdown(): print("๐Ÿ›‘ Shutdown requested...") os._exit(0) # Standard way to kill uvicorn from an endpoint in simple setups def main(): parser = argparse.ArgumentParser(description="Start ECH0-PRIME MCP Server") parser.add_argument("--config", type=str, help="Path to server list config") parser.add_argument("--port", type=int, default=8000, help="Port to run on") args = parser.parse_args() print("๐Ÿš€ Initializing ECH0-PRIME Tool Registry...") # 1. Scan for tools in standard locations tool_dirs = [ os.path.join(PROJECT_ROOT, "reasoning", "tools"), os.path.join(PROJECT_ROOT, "core"), os.path.join(PROJECT_ROOT, "ech0_governance") ] for d in tool_dirs: if os.path.exists(d): print(f"๐Ÿ” Scanning {d} for tools...") scan_local_tools(d) # 2. Specifically initialize QuLabBridge which registers methods manually print("๐Ÿงช Connecting QuLabBridge...") _qulab = QuLabBridge() # 3. Load config if provided if args.config and os.path.exists(args.config): with open(args.config, 'r') as f: config = json.load(f) print(f"๐Ÿ“œ Loaded server config from {args.config}") # Here we could initialize remote tools or other MCP servers listed in the config print(f"โœจ MCP Server ready! Serving {len(ToolRegistry.get_schemas())} tools.") uvicorn.run(app, host="0.0.0.0", port=args.port) if __name__ == "__main__": main()