Skip to content

fix: drain terminal streamable HTTP responses#2725

Open
he-yufeng wants to merge 1 commit into
modelcontextprotocol:mainfrom
he-yufeng:fix/drain-sse-response-on-completion
Open

fix: drain terminal streamable HTTP responses#2725
he-yufeng wants to merge 1 commit into
modelcontextprotocol:mainfrom
he-yufeng:fix/drain-sse-response-on-completion

Conversation

@he-yufeng
Copy link
Copy Markdown

Summary

  • stop closing terminal Streamable HTTP SSE responses immediately after the matching JSON-RPC response
  • keep draining the POST, GET resumption, and standalone GET SSE streams to EOF so HTTP keepalive connections stay reusable
  • add regression coverage for both normal response handling and reconnection after a terminal event

Fixes #2707.

To verify

  • uv run pytest tests/shared/test_streamable_http.py -q
  • uv run ruff check src/mcp/client/streamable_http.py tests/shared/test_streamable_http.py
  • uv run pyright src/mcp/client/streamable_http.py tests/shared/test_streamable_http.py
  • git diff --check

@he-yufeng he-yufeng force-pushed the fix/drain-sse-response-on-completion branch 3 times, most recently from e89af5b to a043f86 Compare May 30, 2026 03:16
@he-yufeng he-yufeng force-pushed the fix/drain-sse-response-on-completion branch from a043f86 to 93a88fa Compare June 6, 2026 21:57
@he-yufeng
Copy link
Copy Markdown
Author

Rebased this branch on current main and force-pushed 93a88fa.

The conflict was in tests/shared/test_streamable_http.py because upstream added newer priming-event coverage around the same area. I kept the upstream test shape and re-applied this PR's drain-after-terminal-event coverage before it.

Validated locally:

  • uv run --frozen pytest tests/shared/test_streamable_http.py::test_handle_sse_response_drains_after_terminal_event tests/shared/test_streamable_http.py::test_reconnection_drains_after_terminal_event tests/shared/test_streamable_http.py::test_streamable_http_client_session_termination tests/shared/test_streamable_http.py::test_streamable_http_client_session_termination_204 tests/interaction/transports/test_hosting_resume.py -q (10 passed)
  • uv run --frozen ruff check src/mcp/client/streamable_http.py tests/shared/test_streamable_http.py tests/interaction/transports/test_hosting_resume.py
  • uv run --frozen ruff format --check src/mcp/client/streamable_http.py tests/shared/test_streamable_http.py tests/interaction/transports/test_hosting_resume.py
  • uv run --frozen pyright src/mcp/client/streamable_http.py tests/shared/test_streamable_http.py tests/interaction/transports/test_hosting_resume.py (0 errors)
  • python -m py_compile src\mcp\client\streamable_http.py tests\shared\test_streamable_http.py tests\interaction\transports\test_hosting_resume.py
  • git diff --check --cached before completing the rebase

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.

streamable_http: early response.aclose() poisons keepalive connection, causes ~260ms latency on every subsequent tool call

1 participant