Skip to content

Conversation

@wukai9203
Copy link

Problem

GET requests to /mcp endpoint hang indefinitely when using streamable_http_app().

Related issue in FastMCP: jlowin/fastmcp#532

Root Cause

The _handle_get_request method's standalone_sse_writer function doesn't send a priming event before entering the message loop, unlike the POST handler which calls _maybe_send_priming_event() at line 592.

This causes the SSE writer to block waiting for messages that may never arrive, making the GET request appear to hang.

Solution

Send an event immediately after establishing the SSE connection in standalone_sse_writer():

  1. With event_store and protocol >= 2025-11-25: Send proper priming event via _maybe_send_priming_event() (for SSE resumability support)
  2. Without event_store or older protocol: Send a simple {"event": "open", "data": ""} event to confirm connection is established

Additional fixes:

  • Add anyio.ClosedResourceError handling for clean shutdown when close_standalone_sse_stream() is called
  • Store SSE writer reference so close_standalone_sse_stream() can properly close it

Testing

  • Added test case test_get_request_receives_priming_event_with_event_store to verify the fix
  • Manually tested with curl and verified GET requests return immediately:
    # Before fix: hangs indefinitely
    # After fix: returns "event: open\ndata: \n\n" immediately
    curl -N http://localhost:8003/mcp \
      -H "Accept: text/event-stream" \
      -H "mcp-session-id: <session_id>"

Checklist

  • Code follows project style guidelines
  • Tests added for the fix
  • Manually tested the fix with FastMCP integration

The GET request handler in streamable_http.py was missing the priming
event that the POST handler sends. This caused GET requests to /mcp
endpoint to hang indefinitely while waiting for messages.

Fix:
- Send a priming event immediately after establishing the SSE connection
  in standalone_sse_writer()
- When event_store is configured and protocol >= 2025-11-25, use the
  proper priming event with resumability support
- Otherwise, send a simple "open" event to confirm connection is
  established
- Add anyio.ClosedResourceError handling for clean shutdown
- Store SSE writer reference for close_standalone_sse_stream() to work

Related: jlowin/fastmcp#532
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant