change(mcp): serve protocol revision 2026-07-28, dual-era with initialize - #133
Draft
jdevalk wants to merge 3 commits into
Draft
change(mcp): serve protocol revision 2026-07-28, dual-era with initialize#133jdevalk wants to merge 3 commits into
jdevalk wants to merge 3 commits into
Conversation
…lize Revision 2026-07-28 removes the initialize handshake: every request now declares its own version in params._meta, mirrored into HTTP headers. This Worker was already stateless, so the shape costs nothing structurally. - server/discover (mandatory in the new revision) - per-request validation: MCP-Protocol-Version / Mcp-Method / Mcp-Name must match the body, including the =?base64?…?= sentinel decode - HeaderMismatch (-32020), UnsupportedProtocolVersionError (-32022), unknown method as HTTP 404 + -32601 - initialize keeps legacy semantics and can no longer answer 2026-07-28 - usage logging reads clientInfo from _meta, so the client-mix column in /admin/stats keeps filling as clients migrate off initialize Legacy clients are untouched: validation only applies to requests carrying the modern _meta version key. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same PR as the Worker change, per the ship-it-before-you-spec-it rule. - 2026-07-28 removed initialize: per-request version in _meta, mirrored into MCP-Protocol-Version; no sessions, no standalone GET stream - new "Supporting both eras" section — legacy clients cannot fall forward, so a dual-era server is the courteous option, with the two traps named (never answer initialize with 2026-07-28; never impose the new header validation on a legacy request) - cite the versioning and Streamable HTTP pages of the new revision, replacing the 2025-11-25 tools deep link Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Deploying specification-website with
|
| Latest commit: |
8104822
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://7ffa34cb.specification-website.pages.dev |
| Branch Preview URL: | https://change-mcp-2026-07-28.specification-website.pages.dev |
…ke window Two corrections after checking the deprecated-features registry. 1. server/discover no longer advertises `logging`. It is Deprecated as of 2026-07-28 (SEP-2577, earliest removal 2027-07-28) and new implementations SHOULD NOT adopt it — advertising it in a discovery call written today would be adopting it. Legacy `initialize` still declares it for clients that may already expect it. 2. Legacy `initialize` responses now carry Deprecation, Sunset (2027-07-28) and a rel="deprecation" link. Note what this is not: MCP does NOT deprecate the handshake. 2025-11-25 is Final, not withdrawn, and the registry does not list it — revisions do not sunset. The window is our policy, so the page says so and warns against attributing such dates to an upstream standard that never set them. Scoped to the initialize response, not the endpoint: /mcp is not being retired, only our willingness to answer the handshake on it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
What changed
MCP's
2026-07-28revision removes theinitializehandshake. Every request now declares its own protocol version inparams._meta, mirrored into HTTP headers; sessions, the standaloneGETstream and resumable streams are gone. This PR moves the Worker and the spec page together, per the ship-it-before-you-spec-it rule.Worker (
mcp/src/index.ts)server/discover— mandatory in the new revision.MCP-Protocol-Version,Mcp-MethodandMcp-Namemust match the body, including decoding the=?base64?…?=sentinel before comparison.HeaderMismatch(-32020),UnsupportedProtocolVersionError(-32022) carrying{supported, requested}, unknown method as HTTP404+-32601.initializekeeps legacy semantics and can no longer answer2026-07-28— a handshake must not promise a revision that has no handshake.clientInfofrom_meta. Without this the client-mix column in/admin/statswould have silently gone blank as clients migrate offinitialize.Discovery + skill — server card at
2026-07-28with asupportedProtocolVersionslist;SKILL.mdre-signed.Spec page (
mcp-and-tool-discovery) — describes the handshake-free model, adds a Supporting both eras section, cites the new revision's versioning and Streamable HTTP pages. Changelog entry included (changed).Design decision worth reviewing
server/discoveradvertises only2026-07-28, not the legacy versions, even though the server answers those too. The_metaversion key does not exist before this revision, so a request carrying it can only mean2026-07-28; listing2025-11-25there would invite a client to send it as per-request metadata, which that revision does not define. Legacy versions stay reachable the only way they are defined to be — throughinitialize. The spec's own example does show a legacy version in the list, so this is a deliberate divergence and easy to reverse if you disagree.Verification
No test harness exists under
mcp/, so I bundled the Worker with esbuild and drove the realfetchhandler in-process. 27 assertions, all passing — not a reimplementation, the shipped code path:Two bugs came out of writing it, both fixed here: notifications were being header-validated (the revision explicitly leaves notification header rules undefined, so conforming clients would have been rejected), and rejected requests were logged with a null response instead of the error.
I did not wire this harness into the repo — it needs an esbuild devDependency and a CI job, which felt like scope creep on a protocol change. Happy to land it separately; a protocol handler with no tests is the obvious place for one.
npm run build,tsc --noEmit, Prettier and the SKILL.md digest check all pass.Timing caveat
modelcontextprotocol.io/specification/versioningstill says "the current protocol version is 2025-11-25" in prose while every link on that page resolves to/specification/2026-07-28/…and its Negotiation section describes the new mechanism. The revision is real and rolling out, but the canonical page has not finished catching up. Everything here is backward compatible, so shipping early costs nothing — but that is worth knowing before merge.🤖 Generated with Claude Code