| """ |
| MCP Server for Archon (Microservices Version) |
| |
| This is the MCP server that uses HTTP calls to other services |
| instead of importing heavy dependencies directly. This significantly reduces |
| the container size from 1.66GB to ~150MB. |
| |
| Modules: |
| - RAG Module: RAG queries, search, and source management via HTTP |
| - Project Module: Task and project management via HTTP |
| - Health & Session: Local operations |
| |
| Note: Crawling and document upload operations are handled directly by the |
| API service and frontend, not through MCP tools. |
| """ |
|
|
| import json |
| import logging |
| import os |
| import sys |
| import traceback |
| from pathlib import Path |
|
|
| from dotenv import find_dotenv, load_dotenv |
| from mcp.server.fastmcp import FastMCP |
|
|
| |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent)) |
|
|
| |
| from src.mcp_server.core import ( |
| get_tool_schema, |
| lifespan, |
| ) |
| from src.mcp_server.router import register_custom_routes |
| from src.server.config.logfire_config import setup_logfire |
|
|
| |
| load_dotenv(find_dotenv(), override=True) |
|
|
| |
| logging.basicConfig( |
| level=logging.INFO, |
| format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", |
| handlers=[logging.StreamHandler(sys.stdout)], |
| ) |
| logger = logging.getLogger(__name__) |
|
|
| server_host = "0.0.0.0" |
| mcp_port = os.getenv("ARCHON_MCP_PORT", "8051") |
| server_port = int(mcp_port) |
|
|
| |
| instructions_path = Path(__file__).parent / "mcp_instructions.md" |
| MCP_INSTRUCTIONS = "" |
| try: |
| if instructions_path.exists(): |
| MCP_INSTRUCTIONS = instructions_path.read_text(encoding="utf-8") |
| logger.info("β Loaded MCP instructions from mcp_instructions.md") |
| else: |
| logger.warning(f"β οΈ Instructions file not found at {instructions_path}") |
| except Exception as e: |
| logger.error(f"Failed to load MCP instructions: {e}") |
|
|
|
|
| |
| try: |
| logger.info("ποΈ MCP SERVER INITIALIZATION:") |
| logger.info(" Server Name: archon-mcp-server") |
|
|
| mcp = FastMCP( |
| "archon-mcp-server", |
| instructions=MCP_INSTRUCTIONS, |
| lifespan=lifespan, |
| host=server_host, |
| port=server_port, |
| ) |
| logger.info("β FastMCP server instance created successfully") |
|
|
| except Exception as e: |
| logger.error(f"β Failed to create FastMCP server: {e}") |
| logger.error(traceback.format_exc()) |
| raise |
|
|
| |
| register_custom_routes(mcp) |
|
|
|
|
| |
| def register_modules(): |
| """Register all MCP tool modules.""" |
| logger.info("π§ Registering MCP tool modules...") |
| modules_registered = 0 |
|
|
| try: |
| from src.mcp_server.features.infra_tools import register_infra_tools |
|
|
| register_infra_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Infrastructure tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register infra tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.rag import register_rag_tools |
|
|
| register_rag_tools(mcp) |
| modules_registered += 1 |
| logger.info("β RAG module registered (HTTP-based)") |
| except Exception as e: |
| logger.error(f"β Error registering RAG module: {e}") |
|
|
| try: |
| from src.mcp_server.features.projects import register_project_tools |
|
|
| register_project_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Project tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register project tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.tasks import register_task_tools |
|
|
| register_task_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Task tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register task tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.feature_tools import register_feature_tools |
|
|
| register_feature_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Feature tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register feature tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.developer import register_developer_tools |
|
|
| register_developer_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Developer tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register developer tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.marketing import register_marketing_tools |
|
|
| register_marketing_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Marketing tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register marketing tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.design import register_design_tools |
|
|
| register_design_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Design tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register design tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.documents import register_document_tools |
|
|
| register_document_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Document tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register document tools: {e}") |
|
|
| try: |
| from src.mcp_server.features.documents import register_version_tools |
|
|
| register_version_tools(mcp) |
| modules_registered += 1 |
| logger.info("β Version tools registered") |
| except Exception as e: |
| logger.error(f"β Failed to register version tools: {e}") |
|
|
| logger.info(f"π¦ Total modules registered: {modules_registered}") |
| if modules_registered == 0: |
| raise RuntimeError("No MCP modules available") |
|
|
| |
| try: |
| tools = mcp._tool_manager.list_tools() |
| formatted = [ |
| { |
| "type": "function", |
| "function": {"name": t.name, "description": t.description or "", "parameters": get_tool_schema(t)}, |
| } |
| for t in tools |
| ] |
| with open("/tmp/mcp_tools.json", "w") as f: |
| json.dump(formatted, f) |
| logger.info(f"β
PHYSICAL TOOLS PERSISTED: {len(formatted)} tools saved to /tmp/mcp_tools.json") |
| except Exception as e: |
| logger.error(f"Failed to persist physical tools: {e}") |
|
|
|
|
| |
| try: |
| register_modules() |
| except Exception as e: |
| logger.error(f"π₯ Critical error during module registration: {e}") |
| raise |
|
|
|
|
| def main(): |
| """Main entry point for the MCP server.""" |
| try: |
| setup_logfire(service_name="archon-mcp-server") |
| logger.info("π Starting Archon MCP Server") |
| logger.info(f" URL: http://{server_host}:{server_port}/mcp") |
| mcp.run(transport="streamable-http") |
| except Exception as e: |
| logger.error(f"π₯ Fatal error in main: {e}") |
| sys.exit(1) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|