Require protocol_version to be a string#2763
Merged
Merged
Conversation
The MCP schema defines protocolVersion as a plain string. The int variant only existed for compatibility with pre-release protocol negotiation (before 2024-10-07 date-based versioning), which sent protocolVersion: 1. Integer versions can never successfully negotiate against the supported version list, so accepting them only changed the failure mode. This matches the TypeScript SDK, which made the same change in November 2024.
Kludex
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
InitializeRequestParams.protocol_versionandInitializeResult.protocol_versionwere typedstr | int; this narrows both tostr, and drops a now-redundantstr(...)coercion in the streamable HTTP client transport.Motivation and Context
The spec schema defines
protocolVersionas a plainstring. Theintvariant dates back to the pre-release protocol, where the handshake used the literal integer1— when versioning moved to date strings in 2024-10-07, the union was kept so old peers wouldn't fail validation. The TypeScript SDK removed its equivalent (z.string().or(z.number().int())→z.string()) in November 2024 (modelcontextprotocol/typescript-sdk@0bf7e66); the Python SDK never followed.The
intarm is dead in practice: an integer version can never matchSUPPORTED_PROTOCOL_VERSIONS(alist[str]), so on the server it always fell into the version-mismatch fallback, and on the client it always raisedRuntimeError. Accepting integers only changed the failure mode for peers that haven't been able to negotiate since 2024.How Has This Been Tested?
Full test suite passes locally with 100% coverage (
./scripts/test). No tests exercised integer versions.Breaking Changes
Peers that send an integer
protocolVersionnow get a validation error instead of a version-mismatch response; they could not complete negotiation before either. Type annotations referencing the union (str | int) on these fields will need updating.Types of changes
Checklist
Additional context
The field's pre-history in this repo:
protocolVersion: Literal[1]→str | intin 2d55eab ("Update types for protocol version 2024-10-07").