Skip to main content
Glama
NOTIFICATION_ROUTING_BUG.md4.61 kB
# Notification Routing Bug - Root Cause Found ## TL;DR **Notifications ARE being sent, but to the WRONG SESSION!** Claude Code is listening on the StreamableHTTP session, but notifications are routed to an SSE session. This is a session mismatch bug. ## The Evidence ### 1. Two Different Sessions Created From logs at `11:09:07`: ``` 2025-10-23 11:09:07,468 - mcp.server.sse - DEBUG - Created new session with ID: a9a08e1e-ba01-474b-9c87-5c2bf387008b 2025-10-23 11:09:07,469 - mcp.server.streamable_http_manager - INFO - Created new transport with session ID: fa53bae066fa4e8eab220462a6f2463a ``` **Two separate sessions:** - SSE session: `a9a08e1e-ba01-474b-9c87-5c2bf387008b` - StreamableHTTP session: `fa53bae066fa4e8eab220462a6f2463a` ### 2. Tool Call Came Through StreamableHTTP ``` 2025-10-23 11:09:33,302 - fastapi_mcp.server - DEBUG - Extracted HTTP request info from context: POST /mcp-streamable ``` Claude Code sent the tool call to `/mcp-streamable`. ### 3. Notifications Sent to SSE Session ``` 2025-10-23 11:09:33,304 - sse_starlette.sse - DEBUG - chunk: b'event: message\r\ndata: {"method":"notifications/message",... ``` All notifications are being sent as SSE chunks, which go to the SSE session. ### 4. Request Context Returns Wrong Session From `stata_mcp_server.py:3009`: ```python session = getattr(ctx, "session", None) ... await session.send_log_message(...) # This sends to SSE session! ``` When the tool executes, `mcp.server.request_context.session` returns the **SSE session** (`a9a08e1e...`), not the **StreamableHTTP session** (`fa53bae0...`). ## The Root Cause **We created a separate `StreamableHTTPSessionManager` that's isolated from fastapi-mcp's session management.** From `stata_mcp_server.py:2843`: ```python # Create the MCP HTTP session manager (from official SDK) http_session_manager = StreamableHTTPSessionManager( app=mcp.server, event_store=None, json_response=False, # ✓ Enable SSE streaming stateless=False, ) ``` This creates a **parallel** session management system. When requests come through `/mcp-streamable`: 1. ✅ They're handled by `http_session_manager` (StreamableHTTP session `fa53bae0...`) 2. ❌ But `mcp.server.request_context` still points to the SSE session (`a9a08e1e...`) 3. ❌ Notifications go to the SSE session, not the StreamableHTTP session 4. ❌ Claude Code is listening on StreamableHTTP, never receives notifications ## The Flow Diagram ``` Claude Code | | POST /mcp-streamable (tool call) v StreamableHTTPSessionManager session: fa53bae066fa4e8eab220462a6f2463a | v Tool Execution mcp.server.request_context.session -> a9a08e1e-ba01-474b-9c87-5c2bf387008b (WRONG!) | v Notifications sent to SSE session | v SSE Transport (a9a08e1e-ba01-474b-9c87-5c2bf387008b) | v ❌ Claude Code never receives (listening on fa53bae0...) ``` ## Why Our Test Client Worked Our `test_mcp_streamable_client.py` **DID** receive notifications because it: 1. Made a POST request to `/mcp-streamable` 2. Established a separate GET connection for SSE listening 3. The SDK client handles both connections and merges the streams But Claude Code expects notifications to come through the SAME StreamableHTTP POST connection. ## The Fix We need to use **fastapi-mcp's built-in HTTP transport** instead of creating a separate StreamableHTTPSessionManager. According to fastapi-mcp docs: ```python # Instead of manually creating StreamableHTTPSessionManager # Use fastapi-mcp's built-in method: mcp.mount_http() ``` This will ensure: 1. Only ONE session is created per connection 2. Request context points to the correct session 3. Notifications are routed to the same connection that made the request ## Alternative Fix If we must use a custom StreamableHTTPSessionManager, we need to: 1. **Update the request context** when requests come through `/mcp-streamable` 2. Ensure `mcp.server.request_context.session` points to the StreamableHTTP session, not SSE ## Verification Command To see the session mismatch: ```bash grep -E "Created new|session ID|POST /mcp-streamable" \ /Users/hanlulong/.vscode/extensions/deepecon.stata-mcp-0.3.4/logs/stata_mcp_server.log | \ grep -A 5 -B 5 "11:09:07" ``` ## Conclusion **This IS a server-side bug!** The notifications are being sent to the wrong session. Claude Code cannot see them because it's listening on a different session than where notifications are being sent. **Action Required:** Fix the session routing so notifications go to the StreamableHTTP session when requests come through `/mcp-streamable`.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hanlulong/stata-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server