Skip to content

Handle streamable POSTs to properly support new streamable transport protocol spec #91

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

stallent
Copy link
Contributor

@stallent stallent commented Apr 26, 2025

The streamable http transport spec handles SSE a bit different than the original sse transport spec. In the original spec, POSTs returned their responses as sse messages on the GET stream. Now the POSTs themselves can sse streams so the GET becomes primarily for notifications (or resuming a POST that experienced a broken connection, but thats a separate can of worms that has not been properly addressed yet).

Motivation and Context

The current HTTPClientTransport does not support streams coming back from POSTs and it must to work with latest spec servers.

How Has This Been Tested?

We have 3 sandbox servers set up with latest server sdk from anthropic. Each configured differently to exercise expected variations.

// streaming response + session management
https://hgai-sandbox.aks.stage.mercury.io/streamable/mcp

// JSON response + session management
https://hgai-sandbox.aks.stage.mercury.io/streamable/json/mcp

// JSON response with no session management
https://hgai-sandbox.aks.stage.mercury.io/streamable/stateless/mcp

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

Additional context

Supporting true resumability will require some additional work that was beyond the scope of this initial PR

@stallent
Copy link
Contributor Author

stallent commented Apr 27, 2025

@mattt trying to follow from my phone while offline today so may have missed it, but while you are in there I believe we are suppose to wait until after we are initialized before starting up the GET. Wasn’t a clean way to do that since the transport itself isn’t aware. If you haven’t done that and can think of a good way, that would let us avoid the error on initial GET (that works on retry because it then has the session id)

@mattt
Copy link
Contributor

mattt commented May 6, 2025

@stallent Thank you for digging into the details of how the MCP specifies streamable HTTP transport. I opened another PR (#96) which incorporates these changes while replacing our ad hoc SSE implementation to a more robust package. Please take a look and let me know if you see anything here that's missing in #96 ✌️

@mattt mattt closed this May 6, 2025
mattt added a commit that referenced this pull request May 6, 2025
- Add a signaling mechanism to ensure the SSE streaming task waits for the initial session ID to be set before attempting the GET connection.
- Use a TaskGroup to race between session ID signal and a 10-second timeout, logging the outcome.
- Trigger the signal when a session ID is received for the first time from any response.
- Add detailed logging for all code paths to aid debugging and clarify connection timing.
- Clean up signal resources on disconnect to prevent leaks.

This addresses the initialization timing issue where the SSE GET could be attempted before the session was established, as discussed in MCP PR #91.
mattt added a commit that referenced this pull request May 6, 2025
- Add a signaling mechanism to ensure the SSE streaming task waits for the initial session ID to be set before attempting the GET connection.
- Use a TaskGroup to race between session ID signal and a 10-second timeout, logging the outcome.
- Trigger the signal when a session ID is received for the first time from any response.
- Add detailed logging for all code paths to aid debugging and clarify connection timing.
- Clean up signal resources on disconnect to prevent leaks.

This addresses the initialization timing issue where the SSE GET could be attempted before the session was established, as discussed in MCP PR #91.
mattt added a commit that referenced this pull request May 6, 2025
* Delay SSE GET connection until after session ID is established

- Add a signaling mechanism to ensure the SSE streaming task waits for the initial session ID to be set before attempting the GET connection.
- Use a TaskGroup to race between session ID signal and a 10-second timeout, logging the outcome.
- Trigger the signal when a session ID is received for the first time from any response.
- Add detailed logging for all code paths to aid debugging and clarify connection timing.
- Clean up signal resources on disconnect to prevent leaks.

This addresses the initialization timing issue where the SSE GET could be attempted before the session was established, as discussed in MCP PR #91.

* Update tests for SSE timing

* Use configurable timeout for acquiring session ID

* Remove Actor protocol conformance for HTTPClientTransport

* Configure shorter session ID timeout for tests

* Add documentation comments to HTTPClientTransport

* Rename sessionIDWaitTimeout to sseInitializationTimeout
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