Skip to content

Conversation

@kxbnb
Copy link

@kxbnb kxbnb commented Jan 23, 2026

Summary

Fixes #1811

When an SSE stream closes without having received any events with IDs, the client silently returns without notifying the session layer. This leaves call_tool() hanging indefinitely.

Changes

  • Added else branch in _handle_sse_response to handle the case where last_event_id is None
  • When we can't reconnect (no event ID), we now send a JSONRPCError with CONNECTION_CLOSED code back to the session
  • The session receives the error and call_tool() properly raises McpError instead of hanging

Root Cause

The issue occurs when:

  1. Client sends a tool call request
  2. Server returns HTTP 200 with SSE stream
  3. SSE read timeout fires before any events with IDs are received
  4. Client closes the HTTP connection
  5. The _handle_sse_response function exits silently (no last_event_id to reconnect with)
  6. Session layer never gets notified → client hangs forever

Validation

  • uv run pyright passes with 0 errors
  • All 758 tests pass

Closes #1811

Fixes modelcontextprotocol#1811

When an SSE stream closes without having received any events with IDs,
the client would silently return without notifying the session layer.
This left `call_tool()` hanging indefinitely since the session never
received a response or error.

Now when the stream closes without a `last_event_id` (meaning we can't
reconnect), we send a JSONRPCError with CONNECTION_CLOSED code back
to the session so the request properly fails instead of hanging.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.

client's read_stream_writer open after SSE disconnection hanging .receive()

1 participant