Skip to content

[v1.x] Buffer per-request StreamableHTTP streams; store priming event before dispatch#2948

Open
maxisbey wants to merge 1 commit into
v1.xfrom
backport/v1x-streamable-http-hol
Open

[v1.x] Buffer per-request StreamableHTTP streams; store priming event before dispatch#2948
maxisbey wants to merge 1 commit into
v1.xfrom
backport/v1x-streamable-http-hol

Conversation

@maxisbey

Copy link
Copy Markdown
Contributor

Backport of #2934.

Buffers the per-request _request_streams[EventMessage] channels (REQUEST_STREAM_BUFFER_SIZE = 16) so the serial message_router can deposit a response and move on instead of head-of-line blocking the session on a lazily-started sse_writer; and stores the priming event before the request is dispatched so its event-store position precedes anything message_router can store for that stream by data dependency.

v1.x adaptations vs main

  • _run_sse_writer checks event_message.message.root (v1.x's JSONRPCMessage is a RootModel).
  • _mint_priming_event keeps v1.x's protocol_version < "2025-11-25" string compare (no is_version_at_least on this branch).
  • The two end-to-end tests added on main live in tests/interaction/transports/ which doesn't exist on v1.x; instead, the three _maybe_send_priming_event unit tests are rewritten against _mint_priming_event to keep the no-store / old-pv / retry-field branches covered.
  • _run_sse_writer carries a # pragma: no cover matching the closure it replaces (v1.x's coverage of that path is subprocess-only and the branch has no strict-no-cover).

Motivation and Context

Fixes #1764.

How Has This Been Tested?

  • New tests/server/test_streamable_http_router.py (HOL test + priming-failure test, with JSONRPCMessage(...) wrapping for the RootModel).
  • tests/shared/test_streamable_http.py priming unit tests rewritten for _mint_priming_event.
  • Full v1.x suite at 100%.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

AI Disclaimer

… before dispatch

Backport of #2934.

Gives the per-request _request_streams[EventMessage] sites a small bounded
buffer (REQUEST_STREAM_BUFFER_SIZE = 16) so the serial message_router can
deposit a response and move on instead of head-of-line blocking the session
on a lazily-started sse_writer.

Replaces _maybe_send_priming_event with _mint_priming_event (stores + returns
the wire dict) and extracts the inline sse_writer closure to _run_sse_writer.
The POST handler now mints priming before any per-request state is registered
and before the request is dispatched, so the priming row precedes anything
message_router can store for that stream by data dependency.

Adds a finally to replay_sender; uses a generic 500 body in the outer except.

Fixes #1764.
@maxisbey maxisbey marked this pull request as ready for review June 22, 2026 16:43
Comment thread src/mcp/server/streamable_http.py
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.

2 participants