Skip to content

fix: improve streamable HTTP session reinitialization #469

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 7 commits into from

Conversation

tzolov
Copy link
Contributor

@tzolov tzolov commented Aug 7, 2025

Implements the MCP spec guidelines for streamable HTTP (re)initialization:

  • Server MAY terminate session and MUST respond with HTTP 404 for terminated session IDs
  • Client MUST start new session when receiving HTTP 404 for requests with session ID

Changes:

  • Replace generic McpError with McpTransportException for transport-layer errors
  • Only throw McpTransportSessionNotFoundException when session ID is present in request (per spec: 404 with session ID means session terminated, without means general error)
  • Enhance error messages with more context (status codes, response events)
  • Use RuntimeException for non-transport specific SSE endpoint failures
  • Ensure consistent error handling across HTTP client transports

Fixes #459

Motivation and Context

This change addresses issue #459 and implements the MCP specification requirements for streamable HTTP (re)initialization:

  • Spec Compliance: The MCP spec states that servers MAY terminate sessions and MUST respond with HTTP 404 for terminated session IDs. Clients MUST then start new sessions when receiving HTTP 404 for requests containing session IDs.
  • Incorrect Error Handling: Previously, the code would throw McpTransportSessionNotFoundException for any 404/400 response, even when no session ID was present, which didn't align with the spec.
  • Generic Exceptions: The use of generic McpError for transport-layer issues made it difficult to distinguish between different error types and handle them appropriately.

This fix ensures proper session reinitialization flow where clients can detect terminated sessions (404 with session ID) and start fresh sessions without an ID.

How Has This Been Tested?

  • Tested session termination scenarios where server returns 404 for valid session IDs
  • Verified that 404 responses without session IDs are handled as general transport errors
  • Tested 400 BAD REQUEST responses with and without session IDs
  • Verified error message clarity and exception type consistency across different transport implementations
  • Existing test suite passes with the new error handling logic

Breaking Changes

Minor breaking changes for users who catch specific exception types:

  • Code catching McpError for transport errors will need to catch McpTransportException instead
  • Error handling logic that assumes all 404/400 responses are session errors will need updating

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

@tzolov tzolov added this to the 0.12.0 milestone Aug 7, 2025
@tzolov tzolov force-pushed the fix-459 branch 2 times, most recently from e45be72 to 87409d3 Compare August 8, 2025 19:45
tzolov added 5 commits August 9, 2025 18:43
Implements the MCP spec guidelines for streamable HTTP (re)initialization:
- Server MAY terminate session and MUST respond with HTTP 404 for terminated session IDs
- Client MUST start new session when receiving HTTP 404 for requests with session ID

Changes:
- Replace generic McpError with McpTransportException for transport-layer errors
- Only throw McpTransportSessionNotFoundException when session ID is present in request
  (per spec: 404 with session ID means session terminated, without means general error)
- Enhance error messages with more context (status codes, response events)
- Use RuntimeException for non-transport specific SSE endpoint failures
- Ensure consistent error handling across HTTP client transports

Fixes modelcontextprotocol#459

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Replace generic McpError with appropriate standard exceptions:
- Use IllegalArgumentException for invalid input parameters
- Use IllegalStateException for state-related issues
- Use RuntimeException wrapper for initialization failures
- Use McpError.builder() with proper error codes for protocol errors

This change improves error handling clarity and follows Java best practices
by using more specific exception types that better describe the error conditions.

Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com>
@tzolov
Copy link
Contributor Author

tzolov commented Aug 10, 2025

Rebase, squashed and merged at 6c38f37

@tzolov tzolov closed this Aug 10, 2025
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 endless retry loop
1 participant