feat(core): per-revision spec reference types and the 2026-07-28 wire contract surface#2252
feat(core): per-revision spec reference types and the 2026-07-28 wire contract surface#2252felixweinberger wants to merge 3 commits into
Conversation
…26-07-28) Replace the single generated spec.types.ts with one reference file per protocol revision: - spec.types.2025-11-25.ts: the released 2025-11-25 schema, pinned at spec commit 357adac4 and frozen. - spec.types.2026-07-28.ts: the upcoming 2026-07-28 revision, pinned at spec commit 9d700ed6. Until that revision is published, its schema is fetched from the spec repository's draft directory. fetch-spec-types.ts takes the revision (and an optional commit SHA) and writes spec.types.<revision>.ts; with no arguments it refreshes both. The type comparison test splits accordingly: spec.types.2025-11-25.test.ts compares the SDK against the frozen release, and spec.types.2026-07-28.test.ts pins the 2026-07-28 protocol version and the new -32003/-32004 error code constants, tracking the not-yet-implemented surface in MISSING_SDK_TYPES_2026_07_28 with completeness checks that force honest burn-down.
Add the 2026-07-28 wire shapes needed for per-request, sessionless
operation (SEP-2575 / SEP-2567), plus a SEP-2322 forward-compatibility
guard. Types and constants only — no dispatch, negotiation, or
transport behavior yet:
- Reserved `_meta` envelope key constants (protocolVersion, clientInfo,
clientCapabilities, logLevel) plus RequestMetaEnvelopeSchema modeling
the complete envelope; the logLevel key carries the spec's SEP-2577
deprecation tag. The base request schemas stay lenient so the same
wire schemas parse requests from earlier protocol revisions; envelope
requiredness is enforced at dispatch when that lands.
- server/discover request and result schemas and types.
- ProtocolErrorCode.UnsupportedProtocolVersion (-32004) with a typed
UnsupportedProtocolVersionError carrying the spec's
{ supported, requested } error data, materialized by
ProtocolError.fromError, and
ProtocolErrorCode.MissingRequiredClientCapability (-32003).
- An optional resultType passthrough on the base result schema (absent
means "complete"), so results from 2026-07-28 servers parse without
per-result modeling (SEP-2322).
The 2026-07-28 type-comparison allowlist burns RequestMetaObject — now
genuinely modeled, with the mutual-assignability check doubling as a
pin on the meta-key strings — and re-annotates the remaining deferred
groups with the work that will burn them. The frozen 2025-11-25
key-parity checks tolerate exactly the new resultType key via a
dedicated assertion helper so every other key stays strictly checked.
🦋 Changeset detectedLatest commit: f123c81 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
There was a problem hiding this comment.
I didn't find any bugs — the new shapes are pinned against the upstream schema by the comparison tests and the spot checks hold up — but this PR adds substantial new public API surface (the io.modelcontextprotocol/* meta-key constants, UnsupportedProtocolVersionError, the -32003/-32004 codes, RequestMetaEnvelopeSchema, server/discover schemas, and the resultType passthrough) anchored to a draft spec revision, so it needs maintainer judgment on the design rather than just a correctness check.
Extended reasoning...
Overview
This PR (1) splits the single generated spec reference file into per-revision files (spec.types.2025-11-25.ts frozen, spec.types.2026-07-28.ts pinned to the spec repo's draft directory) with corresponding comparison tests, and (2) adds the first slice of the 2026-07-28 wire contract: reserved _meta key constants, RequestMetaEnvelopeSchema, DiscoverRequest/ResultSchema, the -32003/-32004 error codes, an UnsupportedProtocolVersionError class wired into ProtocolError.fromError, and an optional resultType passthrough on ResultSchema. Supporting changes touch the fetch script, the nightly update workflow, prettier/eslint ignores, the codemod schema map, and the public export barrel.
Security risks
None identified. The changes are types, Zod schemas, constants, and an error class — no transport, auth, or request-handling behavior changes. The new schemas are additive and the base wire schemas deliberately stay lenient, so existing parsing behavior is unchanged (the only behavioral nuance is that resultType, when present, must now be a string, which matches the spec).
Level of scrutiny
High, but on design rather than correctness. The repo's review conventions put the burden of proof on additions to the public API, and this PR exports several new symbols (four *_META_KEY constants, two error codes, an error class, two schemas plus RequestMetaEnvelopeSchema, and new types) for a protocol revision that has not shipped — pinned to the spec repo's draft directory. Whether the SDK should commit to this surface now, whether these names/shapes are the right contract for the parallel implementation branches, and whether a changeset is needed (the changeset bot flagged none) are maintainer calls I can't make.
Other factors
The verification story is strong: the new spec.types.2026-07-28.test.ts carries a completeness-checked allowlist that forces real assignability checks as types get implemented, the 2025-11-25 comparison still runs against the frozen released schema, and the new runtime tests cover the envelope, discover shapes, error materialization, and malformed-data fallbacks. I checked that the old spec.types.ts references are fully migrated (workflow, prettierignore, eslint config, tests) and found no leftovers, that ProtocolError.fromError only materializes the typed error when data.supported/data.requested validate, and that EmptyResultSchema (strict) still behaves as intended with the new resultType key. No bugs were reported by the bug-hunting pass either; the deferral is purely about the design/API decisions and the missing changeset.
There was a problem hiding this comment.
No bugs found, but this PR adds substantial new public API surface (meta-key constants, UnsupportedProtocolVersionError, -32003/-32004 codes, RequestMetaEnvelopeSchema, server/discover shapes, the resultType passthrough) modeled on the still-draft 2026-07-28 revision, plus a restructure of the spec-reference-type/test infrastructure — those are design-level decisions a maintainer should sign off on.
Extended reasoning...
Overview
The PR replaces the single generated spec.types.ts with per-revision frozen reference files (spec.types.2025-11-25.ts and spec.types.2026-07-28.ts), splits the spec-comparison tests accordingly (the 2026 test carries a completeness-checked allowlist of not-yet-modeled types), and ships the first slice of the 2026-07-28 wire contract: io.modelcontextprotocol/* request-meta key constants, RequestMetaEnvelopeSchema, server/discover request/result schemas, the -32003/-32004 error codes, a typed UnsupportedProtocolVersionError, and an optional resultType passthrough on ResultSchema. It also touches the nightly spec-types workflow, the fetch script, lint/prettier ignores, the codemod schema map, and public exports.
Security risks
None identified. The changes are types, constants, Zod schema definitions, and test/tooling infrastructure — no auth, transport, or request-handling behavior changes. The new schemas are additive and the existing wire schemas deliberately stay lenient, so no spec-valid payloads from earlier revisions are newly rejected.
Level of scrutiny
High at the design level rather than the bug level. The PR expands the public API of @modelcontextprotocol/core based on the spec repo's draft schema (pinned to a draft-directory commit), and the per-revision reference-file + allowlist structure will shape how all subsequent 2026-07-28 work lands. Per the repo's review conventions, every new export needs intentional sign-off, and design justification is the first review question — that is a maintainer call, not something to shadow-approve. Mechanically the implementation looks consistent: the *_META_KEY constants match the schema's reserved keys, the new error codes match the spec constants, ResultSchema keeps resultType optional (absent ⇒ "complete") so older-revision results still parse, and ProtocolError.fromError validates the -32004 data shape before constructing the typed error.
Other factors
The bug-hunting system found no bugs, and the PR carries meaningful test coverage: split spec-comparison tests with bidirectional assignability checks, key-parity assertions, runtime tests for the new schemas, and error-class tests including malformed-data fallbacks. The changeset text matches the implementation. Remaining open questions are judgment calls (e.g. shipping draft-revision constants/exports in a patch release, whether the nightly workflow should now track only the 2026-07-28 file, naming/placement of RequestMetaEnvelopeSchema), which reinforces deferring to a human reviewer.
Foundation for the 2026-07-28 revision, in two commits:
spec.types.tswith one frozen reference file per revision:spec.types.2025-11-25.ts(released schema, pinned) andspec.types.2026-07-28.ts(pinned to the spec repo's draft directory, which already declaresLATEST_PROTOCOL_VERSION = "2026-07-28"; the fetch-script mapping drops onceschema/2026-07-28/exists upstream). The comparison tests split accordingly: the 2025 test asserts the SDK against the released schema; the 2026 test carries an explicit, completeness-checked allowlist of not-yet-modeled types that must shrink as the revision is implemented.io.modelcontextprotocol/*request-meta key constants, a strictRequestMetaEnvelopeSchema(wire schemas stay lenient so one schema parses both revisions),server/discoverrequest/result shapes, the typed-32004error carryingdata.{supported, requested}, the-32003code constant, and a forward-compatibleresultTypepassthrough on the base result. Types only — no behavior changes.Tracking: #2184, #2185
Motivation and Context
Every 2026-07-28 feature needs these shapes; extracting them as a standalone PR lets implementation work proceed in parallel branches against a shared, reviewed contract.
How Has This Been Tested?
check:all,lint:all, core test suite (463 tests) — the spec comparison tests are themselves the primary verification: every shape is type-checked against the pinned upstream schema in both directions.Breaking Changes
None — additive types and constants only.
Types of changes
Checklist