Align with spec #3002: optional clientInfo, serverInfo in result _meta#3143
Draft
maxisbey wants to merge 5 commits into
Draft
Align with spec #3002: optional clientInfo, serverInfo in result _meta#3143maxisbey wants to merge 5 commits into
maxisbey wants to merge 5 commits into
Conversation
Spec PR #3002 (merged upstream 07-16) made io.modelcontextprotocol/clientInfo optional on request _meta, removed the top-level serverInfo field from DiscoverResult, and introduced ResultMetaObject: every result's _meta now carries an optional io.modelcontextprotocol/serverInfo Implementation. ResultMetaObject joins OPEN_CLASSES: the spec defines it as an open key-value bag (all MetaObject key rules apply), so it must keep extra="allow" or the serialize sieve would silently drop custom result _meta keys.
…3002) Spec PR #3002 made io.modelcontextprotocol/clientInfo optional (SHOULD-include): the required per-request envelope is now the protocolVersion + clientCapabilities pair. - classify_inbound_request rung 1 demands the pair and reads absent clientInfo as None; a missing required key rejects -32602 with a message naming the key(s), per basic/index.mdx. - Era evidence on the stdio dual-era loop is now presence of the reserved protocolVersion _meta key alone: the io.modelcontextprotocol/ prefix is spec-reserved, so legacy traffic never mints it, and a half-built envelope (version without capabilities) routes modern to get the classifier's named rejection instead of the legacy path's generic one. Failed classification still locks no era. - The regenerated surface types (previous commit) already carry the optional clientInfo on RequestMetaObject. - Connection records client_capabilities as its own fact so capability checks (check_capability, sampling tools validation, extension and apps gates) work for pair-only requests; the client_params setter keeps the two in lockstep on the handshake path. ServerSession exposes client_capabilities and all capability consumers read it. - The Mcp-Param schema-resolving tools/list walk omits the clientInfo key from its synthetic envelope when the caller sent none.
…(spec #3002) The 2026-07-28 draft removed the serverInfo body field from DiscoverResult: servers now report identity by stamping io.modelcontextprotocol/serverInfo into every result's _meta (new ResultMetaObject type), and clients treat it as optional, display-only metadata. Server side: - DiscoverResult loses server_info (monolith and generated surface); the default discover handler no longer passes identity. - Every 2026-era result is stamped at the runner's single exit point, after the middleware chain, so custom methods, empty results, and middleware short-circuits are covered by construction. Stamping builds a shallow copy rather than mutating a dict the handler may retain, a handler-authored value wins, and the dumped stamp is cached per server. Notifications, error responses, and handshake-era results are never stamped. - Opt-out per the spec's 'unless specifically configured not to do so': Server(include_server_info=False), also exposed on MCPServer. Client side: - ClientSession.server_info reads the discover result's _meta stamp, parsed once at adopt time; absent or malformed reads as None (the spec forbids acting on the value, so a bad stamp must not fail the connection). The wire surface keeps the field untyped for the same reason, via a shape-driven transform in the generator that stays lenient for future result-meta definitions. - Client.server_info is now Implementation | None. This also fixes a live interop break: servers that already shipped the new shape omit the body field, which previously failed our discover validation and silently downgraded auto mode to the legacy handshake. Tests: the interaction matrix runs with stamping off (the stamp would bake the commit-dependent package version into every snapshot); stamping has dedicated unit and wire-level coverage in tests/server/, and the tests that exercise identity assert the new _meta form.
Migration guide gets a grouped section for the spec #3002 reshape (field removal, stamping default and opt-out, Optional server_info, pair-only requests and the client_capabilities accessor). Whats-new, protocol-versions, client, session-groups, media, testing, and low-level pages updated to the new shapes.
The last published referee (0.2.0-alpha.9) still enforces the pre-#3002 shape, so implementing the reshape at the old pin fails three checks. Conformance main@da56f663 includes #403 (checks flipped to the final revision) and #406 (per-check expected-failures granularity); the sha256- verified tarball pin mechanism is unchanged. All server scenarios pass with zero baseline entries. The bump window adds client auth scenarios for features the OAuth client does not implement (DPoP per SEP-1932, and the jwt-bearer grant); those are baselined per-check so their passing checks stay live. Riding the same window: requiredCapabilities error data moves from the old array shape to the schema's object shape (referee #376), and the everything-server capability gate reads client_capabilities so it works for clients that omit the now-optional clientInfo.
Contributor
📚 Documentation preview
|
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.
Aligns the SDK with spec #3002 (merged 2026-07-16), the 2026-07-28 draft's identity reshape. Reference implementations: go#1097, ts#2513 (shipped in
2.0.0-beta.5).What the spec changed
_metakeyio.modelcontextprotocol/clientInfois now optional (SHOULD-include); the required pair isprotocolVersion+clientCapabilities, and the-32602/HTTP 400 MUST-reject applies only to those.DiscoverResultno longer has a top-levelserverInfofield. Servers SHOULD stampio.modelcontextprotocol/serverInfointo every result's_metainstead (newResultMetaObjecttype), "unless specifically configured not to do so".What this PR does
Types: re-vendors the draft schema at spec commit
71e30695and regenerates the surface models. The newResultMetaObjectjoins the generator's open-classes list (the spec defines it as an open key-value bag; without this the serialize sieve would drop custom result_metakeys).Server: accepts requests that omit
clientInfo(rejecting a missing required key with-32602naming the key); recordsclient_capabilitiesas its own connection fact so capability checks work for pair-only requests (ServerSession.client_capabilitiesis the new preferred accessor); era evidence on the stdio dual-era loop is now the reservedprotocolVersionkey alone. StampsserverInfointo every 2026-era result's_metaat the runner's single exit point, after the middleware chain, so coverage holds by construction (custom methods, empty results, and middleware short-circuits included; notifications, error responses, and handshake-era results never stamped). A handler-authored value wins.Client: reads server identity from the discover result's
_metastamp;Client.server_info/ClientSession.server_infoare nowImplementation | None. This also fixes a live interop break: typescript-sdk2.0.0-beta.5already omits the bodyserverInfo, which made our auto-mode probe treat a spec-conformant discover reply as unparseable and silently fall back to the legacy handshake.Conformance: bumps the pinned referee to conformance
da56f663(includes conformance#403, the post-#3002 checks, and #406, per-check baselines). All server legs pass with zero skip entries. The bump window adds new client auth scenarios (DPoP per SEP-1932, and a jwt-bearer grant check) for features the OAuth client does not implement; those are baselined per-check. TherequiredCapabilitiesfixtures move from the old array shape to the schema's object shape, and the everything-server capability gate now readsclient_capabilitiesso it works for pair-only clients.Decisions to review
Client.server_infoisImplementation | None. Identity is optional wire metadata now; an anonymous server (or a pinned connection withoutprior_discover=) reads asNone, where it previously was a placeholderImplementation(name="", version=""). Documented in the migration guide.serverInfodisplay-only (clients SHOULD NOT act on it), so a malformed value must never reject an otherwise-valid response. The wire surface keeps the field opaque (schema patch) and the typed, lenient parse happens at the read edge. typescript-sdk does the same with a schema-level catch."clientInfo": nullis accepted as absent. go rejects an explicit null with-32602; this SDK treats it like a missing key. The field is optional and display-only, so we lean tolerant; flagging it in case reviewers prefer strictness.{}becomes{"_meta": {...}}on the 2026 wire). The spec says every result; go's empty-result carve-out is an artifact of its internal types, not spec semantics. Note: a client that rejects unknown keys on empty results (rust's rmcp does) already breaks onresultType, so this adds no new incompatibility.Server(include_server_info=False), also onMCPServer), consumed at the single stamping site. No per-request knobs. Neither go nor ts shipped the opt-out the spec language anticipates; this PR does.tests/server/and is exercised on the real wire by the conformance suite.Testing
clientInforequests, malformed-envelope rejections, discover shape, stamp presence/opt-out, legacy handshake untouched, and auto-mode negotiation against both an identifying and an anonymous server.AI Disclaimer