mcp: carry the SEP-2575 _meta envelope on notifications/cancelled - #1213
Closed
yhxlele wants to merge 1 commit into
Closed
mcp: carry the SEP-2575 _meta envelope on notifications/cancelled#1213yhxlele wants to merge 1 commit into
yhxlele wants to merge 1 commit into
Conversation
Contributor
Author
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.
Fixes #1212.
The two cancellation-notify sites (
cancelCalland the async-notify branch ofcall, both inmcp/transport.go) buildCancelledParamsdirectly, so they are the only client sends on a2026-07-28session that omit the SEP-2575 per-request_metaenvelope. A conformant server rejects the notification with-32602 "missing or invalid _meta field \"io.modelcontextprotocol/protocolVersion\""over HTTP 400, and because that rejection responds to a notification its error body has noid, socheckResponsecannot classify it as a per-call rejection (#1118) and permanently fails the connection. Net effect:ClientSession.Unsubscribe— or canceling any in-flight call — poisons the whole stateless session (see #1212 for the wire trace).This change computes the envelope once per send in
handleSend(cancellationMeta, nil for server sessions and pre-2026 protocols, reusinginjectRequestMetaso the envelope stays identical to every other send) and threads it throughcall/callSubscriptionsListeninto the two notify sites. With it, the cancellation is accepted (202) and the session stays usable.Tests:
TestSubscriptionsListen_CancellationCarriesMetadrives a real stateless server through both triggers (Unsubscribe of a listen subscription, cancellation of an in-flight tool call) and asserts at the wire that eachnotifications/cancelledcarries the_metaprotocol version and is answered 202, then that the session still servestools/list. On main it fails withmissing _meta "io.modelcontextprotocol/protocolVersion",got HTTP 400, want 202, andslow tool never started — session unusable after Unsubscribe; with this change it passes.go test ./...andgo vet ./...are clean.