myrmidon / python /src /mcp_server /mcp_server.py
tek Atrust
chore(deploy): build monolithic server for Hugging Face
d5ef46f
Raw
History Blame Contribute Delete
7.3 kB
"""
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
# Add the project root to Python path for imports
sys.path.insert(0, str(Path(__file__).resolve().parent.parent.parent))
# Import Core Infrastructure (Phase 4.6.20 Slimming)
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 environment variables from the project root .env file by searching upwards
load_dotenv(find_dotenv(), override=True)
# Configure logging
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)
# Load instructions from external markdown file (Phase 5.4.1 Slimming)
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}")
# Initialize the main FastMCP server with physical instruction alignment
try:
logger.info("πŸ—οΈ MCP SERVER INITIALIZATION:")
logger.info(" Server Name: archon-mcp-server")
mcp = FastMCP(
"archon-mcp-server",
instructions=MCP_INSTRUCTIONS, # Correct way to pass 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 routing (Discovery, RPC Bridge, Sessions)
register_custom_routes(mcp)
# Import and register modules
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")
# PHYSICAL PERSISTENCE (Phase 4.6.19)
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}")
# Register all modules
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()