Skip to content

Name supported protocol versions when rejecting legacy initialize - #1209

Open
Emryswu wants to merge 1 commit into
modelcontextprotocol:mainfrom
Emryswu:fix/1195-initialize-supported-versions
Open

Emryswu wants to merge 1 commit into
modelcontextprotocol:mainfrom
Emryswu:fix/1195-initialize-supported-versions

Conversation

@Emryswu

@Emryswu Emryswu commented Oct 21, 2026

Copy link
Copy Markdown

Fixes #1195

Motivation and Context

The 2026-07-28 spec says a server that supports only modern versions SHOULD name the protocol versions it supports in any error it returns to an initialize request, on any transport (Versioning: Backward Compatibility). Today a legacy client never learns them:

  • stdio: -32602 "params._meta is required"
  • HTTP: 400 / -32020 "Missing required header: Mcp-Method"

This change recognizes initialize in McpServer#dispatch before the _meta checks, and HttpServletMcpTransport#validateHeaders lets it through so both transports share the same rejection path.

The error keeps -32602 and reuses the existing UnsupportedProtocolVersionData:

{
  "code": -32602,
  "message": "Unsupported protocol version: 2025-11-25. Supported versions: 2026-07-28",
  "data": { "supported": ["2026-07-28"], "requested": "2025-11-25" }
}

This is the same shape earlier spec revisions used for a failed version negotiation, so legacy clients can read data.supported, and the message still names the versions for clients that only surface the message. requested is taken from params.protocolVersion and is null when it is missing or not a string. The list comes from the builder's supportedVersions, nothing is hard-coded.

How Has This Been Tested?

  • StdioMcpTransportTests#legacyInitializeErrorNamesSupportedVersions: legacy initialize with custom supported versions; asserts code, message, data.supported and data.requested.
  • StdioMcpTransportTests#legacyInitializeWithoutRequestedVersionStillNamesSupportedVersions (parameterized): no params, empty params, non-string protocolVersion; asserts data.requested is null and no exception.
  • HttpServletMcpTransportIntegrationTests#legacyInitializeWithoutMethodHeaderErrorNamesSupportedVersions: end to end over Tomcat without Mcp-Method; asserts 400 and the same error body.

The new stdio and HTTP tests fail on main and pass with this change.

./mvnw -pl mcp-core test
./mvnw -pl mcp-test -am test -Dtest=HttpServletMcpTransportIntegrationTests -Dsurefire.failIfNoSpecifiedTests=false
./mvnw -pl mcp-test -am -Pjackson2 test -Dtest=HttpServletMcpTransportIntegrationTests -Dsurefire.failIfNoSpecifiedTests=false

mcp-core: 604 tests, 0 failures. HttpServletMcpTransportIntegrationTests: 24 tests, 0 failures on both Jackson 3 and Jackson 2.

Breaking Changes

None. Only the error returned to a legacy initialize changes; it was already rejected.

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

The error code stays -32602 rather than UNSUPPORTED_PROTOCOL_VERSION (-32022), since that is the code legacy clients expect for this case; the spec leaves the code implementation-defined. Happy to switch if you prefer -32022.

  • AI-assisted; reviewed by a human who is accountable for it

@Emryswu
Emryswu force-pushed the fix/1195-initialize-supported-versions branch from 0290d53 to ba0cc74 Compare October 21, 2026 08:31

This branch has not been deployed

No deployments
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.

Name the supported protocol versions when rejecting a legacy initialize

1 participant