Skip to content

feat: Implement Stateless MCP (SEP-2575) support#73

Open
stenalpjolly wants to merge 3 commits into
googleapis:mainfrom
stenalpjolly:stenalpjolly_issue-35-stateless-mcp
Open

feat: Implement Stateless MCP (SEP-2575) support#73
stenalpjolly wants to merge 3 commits into
googleapis:mainfrom
stenalpjolly:stenalpjolly_issue-35-stateless-mcp

Conversation

@stenalpjolly

Copy link
Copy Markdown
Contributor

Summary

Implement Stateless MCP (SEP-2575) support in the Java SDK. This includes bypassing connection handshake initialization for version 2026-06-18, embedding namespace-prefixed protocol metadata inside _meta on all outgoing tool requests, setting the MCP-Protocol-Version HTTP request header, and implementing dynamic client-side fallback/retry version negotiation when target servers return version mismatch errors (-32004 or -32001).

Expectation & Implementation

  • New Protocol Version: Registered stateless protocol version 2026-06-18 in ProtocolVersion.
  • JSON-RPC Model Extension: Added _meta map to CallToolParams to support inline protocol metadata.
  • Stateless HTTP Transport Subclass: Created HttpMcpTransportV20260618 which inherits from BaseMcpTransport. It overrides modifyRequestParams to inject reverse-DNS prefixed _meta keys (io.modelcontextprotocol/protocolVersion, etc.), sets the MCP-Protocol-Version header, and overrides ensureInitialized to bypass stateful handshake checks.
  • Base Transport Hook: Added modifyRequestParams request lifecycle hook in BaseMcpTransport.
  • Dynamic Version Switching: Implemented switchVersion(ProtocolVersion) in HttpMcpTransport to reconstruct delegate transports.
  • Exception Mapping: Caught JSON-RPC error codes -32004 (Unsupported protocol version) and -32001 (Method not found) during response deserialization, parsed server-supported versions, and threw a custom McpProtocolNegotiationException.
  • Client Fallback Retry: Wrapped client requests in executeWithFallback in McpToolboxClientImpl which catches McpProtocolNegotiationException, selects the highest mutually supported version, invokes switchVersion on the transport, and retries the request exactly once.

Test cases

  • Created HttpMcpTransportStatelessTest to verify:
    • Bypassing initialize handshake for 2026-06-18 transport.
    • Embedding correct metadata in request _meta and MCP-Protocol-Version header.
    • Throwing McpProtocolNegotiationException with compatible version lists.
    • Client-level automatic retry and version switching fallback.
  • Enhanced HttpMcpTransportTest to cover all error states (non-200, missing session ID, version mismatches) across all stateful transport versions.
  • Added comprehensive enum and close check coverage.

Acceptance criteria

  • All compilation, unit tests, formatting (using google-java-format), checkstyle, and Jacoco coverage checks (>98%) pass.

Breaking changes

  • No public API breaking changes. The client wrapper handles version fallbacks transparently.

stenalpjolly and others added 2 commits June 25, 2026 16:52
- Register stateless protocol version 2026-06-18
- Add _meta parameters for inline protocol negotiation metadata
- Support MCP-Protocol-Version HTTP header
- Bypass connection handshakes in HttpMcpTransportV20260618
- Implement dynamic client-side fallback/retry protocol negotiation

TAG=agy
CONV=2e1a2106-f882-4b08-92df-a27ba37c6fae
@stenalpjolly stenalpjolly requested a review from a team as a code owner June 26, 2026 18:03
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.

1 participant