fix(server): stop replay cleanly when streamable HTTP replay stream c…#1681
Open
meirk-brd wants to merge 1 commit intomodelcontextprotocol:mainfrom
Open
Conversation
|
@modelcontextprotocol/client
@modelcontextprotocol/server
@modelcontextprotocol/express
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This fixes streamable HTTP event replay when a client disconnects in the middle of a replayed SSE response.
The shared
WebStandardStreamableHTTPServerTransportnow treats a closed replay stream as a normal abort condition: it stops replay immediately, closes the controller safely, and avoids leaving a stale replay entry in_streamMapping.A regression test was added at the shared transport layer to cover the exact failure mode.
Motivation and Context
When a client reconnects with
Last-Event-ID, the server replays missed events throughreplayEvents().Before this change, if the replay stream closed mid-replay, the transport could continue attempting to write to a closed stream and then surface replay failures downstream. That forced consumers (like me ;) ) to add local monkey patches around the SDK transport.
This change fixes the issue where it originates, in the shared streamable HTTP server transport, so downstream projects do not need replay-disconnect workarounds.
How Has This Been Tested?
Tested locally in the @modelcontextprotocol/server package with:
pnpm --filter @modelcontextprotocol/server checkpnpm --filter @modelcontextprotocol/server test -- test/server/streamableHttp.test.tsScenarios covered:
Breaking Changes
None.
This is an internal bug fix in the shared streamable HTTP server transport. There are no public API or configuration changes.
Types of changes
Checklist
Additional context
This intentionally fixes the issue in the shared
WebStandardStreamableHTTPServerTransportinstead of patching downstream wrappers. TheNodeStreamableHTTPServerTransportdoes not require code changes because it delegates to this shared implementation.The EventStore contract was left unchanged. The fix works by making replay writes fail fast and cleanly once the replay response stream has already been closed.