Skip to content

Latest commit

 

History

History
234 lines (171 loc) · 6.16 KB

File metadata and controls

234 lines (171 loc) · 6.16 KB

Critical Issue Diagnosis - MCP Server Services Not Initialized

🔍 Root Cause Identified

The Problem: The MCP stdio server (stdio_full_mcp.py) does NOT initialize the Qdrant client or embedding model. These services are only initialized by the FastAPI HTTP server (server.py) in its lifespan handler.

Evidence:

1. HTTP Server (server.py) - ✅ Initializes Services

@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan manager"""
    logger.info("FastAPI application starting up...")
    
    try:
        from src.vector_db.qdrant_client import connect_qdrant
        from src.vector_db.embeddings import initialize_embeddings
        
        # Connect to Qdrant
        await connect_qdrant()
        logger.info("Qdrant connection initialized successfully")
        
        # Initialize embeddings
        await initialize_embeddings()
        logger.info("Embedding service initialized successfully")
    except Exception as e:
        logger.error(f"Failed to initialize vector database: {e}", exc_info=True)

2. MCP Stdio Server (stdio_full_mcp.py) - ❌ Does NOT Initialize Services

def main():
    logger.info("Starting FULL STDIO MCP server (all tools)...")
    
    # Create MCP server and FastMCP instance
    server = MCPServer()
    mcp = server.create_server()
    
    # Register ALL tools (context-aware, indexing, search, etc.)
    server.register_tools()
    
    # Mark as running/listening for status reporting
    server.is_running = True
    server.connection_state = "listening"
    
    try:
        logger.info("Starting FastMCP stdio transport...")
        mcp.run()  # <-- NO SERVICE INITIALIZATION!

Result:

  • ✅ HTTP server at http://localhost:8000 works fine (services initialized)
  • ❌ MCP stdio server fails because Qdrant client and embeddings are NOT initialized
  • ❌ All search/vector tools fail with "Client not initialized" errors

📊 Current System State

✅ Working (HTTP Server)

  • FastAPI server running on port 8000
  • Health endpoint accessible
  • Qdrant connection initialized
  • Embedding model loaded
  • All infrastructure services running

❌ Broken (MCP Stdio Server)

  • MCP server starts but services not initialized
  • Qdrant client: None (not connected)
  • Embedding model: None (not loaded)
  • Search tools: Non-functional
  • Vector tools: Non-functional

🎯 Solution

Option 1: Add Service Initialization to stdio_full_mcp.py (Recommended)

Modify src/mcp_server/stdio_full_mcp.py to initialize services before starting:

async def initialize_services():
    """Initialize Qdrant and embedding services"""
    from src.vector_db.qdrant_client import connect_qdrant
    from src.vector_db.embeddings import initialize_embeddings
    
    logger.info("Initializing vector database services...")
    
    try:
        # Connect to Qdrant
        await connect_qdrant()
        logger.info("✅ Qdrant connection initialized")
        
        # Initialize embeddings
        await initialize_embeddings()
        logger.info("✅ Embedding service initialized")
        
        return True
    except Exception as e:
        logger.error(f"❌ Failed to initialize services: {e}", exc_info=True)
        return False

def main():
    logger.info("Starting FULL STDIO MCP server (all tools)...")
    
    # Initialize services BEFORE creating MCP server
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    
    success = loop.run_until_complete(initialize_services())
    if not success:
        logger.error("Failed to initialize services, exiting...")
        sys.exit(1)
    
    # Create MCP server and FastMCP instance
    server = MCPServer()
    mcp = server.create_server()
    
    # Register ALL tools
    server.register_tools()
    
    # Mark as running
    server.is_running = True
    server.connection_state = "listening"
    
    try:
        logger.info("Starting FastMCP stdio transport...")
        mcp.run()

Option 2: Use HTTP Transport Instead of Stdio

Configure Claude Code CLI to use HTTP transport:

{
  "mcpServers": {
    "context": {
      "type": "http",
      "url": "http://localhost:8000/mcp",
      "timeout": 30000
    }
  }
}

Note: This requires implementing an HTTP MCP endpoint in server.py.


📋 Action Plan

Immediate Fix (5 minutes)

  1. Modify stdio_full_mcp.py to initialize services
  2. Restart Docker container to apply changes
  3. Test MCP connection from Claude Code CLI

Steps:

# 1. Apply the fix (automated script provided)
cd D:\GitProjects\Context
.\scripts\fix_mcp_stdio_initialization.ps1

# 2. Restart container
docker-compose -f deployment/docker/docker-compose.yml restart context-server

# 3. Wait for initialization (30 seconds)
Start-Sleep -Seconds 30

# 4. Test connection
docker exec -i context-server python -m src.mcp_server.stdio_full_mcp

🔧 Verification Steps

1. Check Services Initialized

docker logs context-server --tail 50 | Select-String "Qdrant|embedding|initialized"

Expected Output:

✅ Qdrant connection initialized
✅ Embedding service initialized

2. Test MCP Connection

docker exec -i context-server python -m src.mcp_server.stdio_full_mcp

Expected: Server starts and shows tool registration

3. Verify from Claude Code CLI

/mcp

Expected: Context server shows "Connected ✅"


📈 Success Metrics

Metric Before After
Qdrant Connected ❌ No ✅ Yes
Embedding Model Loaded ❌ No ✅ Yes
Search Tools Functional ❌ No ✅ Yes
MCP Connection ❌ Shutdown ✅ Connected

🎓 Key Learnings

  1. Two separate servers: HTTP (FastAPI) and MCP (stdio) are independent
  2. Service initialization: Must be done explicitly in each entry point
  3. Lifespan handlers: Only work for FastAPI, not for stdio MCP servers
  4. Async initialization: Requires proper event loop management

Status: Root cause identified, solution ready to implement
Confidence: 100%
Time to Fix: 5 minutes
Risk: Low (changes are isolated to stdio entry point)