Skip to content

Align draft schema with spec docs (subscriptionId, HeaderMismatch, notification directions)#2889

Merged
pja-ant merged 6 commits into
mainfrom
fix/draft-schema-consistency
Jun 17, 2026
Merged

Align draft schema with spec docs (subscriptionId, HeaderMismatch, notification directions)#2889
pja-ant merged 6 commits into
mainfrom
fix/draft-schema-consistency

Conversation

@pja-ant

@pja-ant pja-ant commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

What this does

Fixes a set of inconsistencies between schema/draft/schema.ts (the source of truth) and the draft specification prose, found during a pre-release consistency review.

Why now

The draft is heading to release; each of these is a place where an implementer reading the schema and one reading the prose would build incompatible behavior.

Changes

  • Declare the reserved io.modelcontextprotocol/subscriptionId _meta key in a new NotificationMetaObject type, and specify the derivation rule (decimal string of a numeric JSON-RPC ID, verbatim for a string ID). Previously the key existed only in prose and one example, and the docs showed numeric id 1 acknowledged as string "1" with no conversion rule — a strict comparison silently drops all subscription notifications on stdio.
  • Fix the three *ListChangedNotification doc comments that still said notifications "may be issued by servers without any previous subscription", contradicting the opt-in subscriptions model (servers MUST NOT send unrequested types).
  • Add HEADER_MISMATCH = -32001 and a HeaderMismatchError interface. The transport requires servers to emit this code, but the schema had no definition, so generated SDKs could not recognize it.
  • Align the cacheScope: "private" doc comment with caching.mdx's authorization-context model (the two previously described different cache-sharing rules — a security boundary).
  • Make CancelledNotificationParams.requestId required (the optionality was a leftover from removed task cancellation, and an id-less cancellation has no defined meaning).
  • Give ListRootsRequest minimal params instead of RequestParams, which forced servers to fabricate client-identifying _meta on a server-initiated input request.
  • Remove ProgressNotification from ClientNotification (clients no longer receive requests, so they have nothing to report progress on). CancelledNotification stays in ServerNotification but is now scoped: servers send it solely to terminate a subscriptions/listen stream on stdio, matching the teardown rule from (chore): sep-to-spec consistency pass #2863. cancellation.mdx and progress.mdx are rewritten to match the directional model.

Verification

npm run generate:schema artifacts committed; npm run prep and npm run check pass clean.

pja-ant added 2 commits June 7, 2026 13:57
- Declare the reserved io.modelcontextprotocol/subscriptionId _meta key
  via a new NotificationMetaObject type, including the rule for deriving
  the value from the subscriptions/listen request's JSON-RPC ID
- Rewrite the three list_changed notification doc comments to reflect
  the opt-in subscriptions model instead of unsolicited delivery
- Add the HEADER_MISMATCH (-32001) error code and HeaderMismatchError
  type required by the Streamable HTTP transport's header validation
- Update cacheScope JSDoc to the authorization-context caching model
  used by the caching utility doc
- Make CancelledNotificationParams.requestId required
- Describe cancellation as client-initiated, with one server-side use:
  on stdio a server sends notifications/cancelled solely to terminate a
  subscriptions/listen stream
- Give ListRootsRequest a minimal params shape instead of RequestParams,
  matching other server-initiated input requests
- Remove ProgressNotification from ClientNotification: only clients
  issue requests, so only servers report progress

Regenerated schema.json and schema.mdx.
- Cancellation: describe cancellation as client-to-server, with the
  server-side exception for subscriptions/listen stream teardown on
  stdio
- Progress: describe progress notifications as server-to-client only,
  and use Client/Server in the sequence diagram
- Subscriptions: state how io.modelcontextprotocol/subscriptionId is
  derived from the subscriptions/listen request's JSON-RPC ID (decimal
  string for numeric IDs, verbatim for string IDs)
@mintlify

mintlify Bot commented Jun 7, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
mcp-staging 🟢 Ready View Preview Jun 7, 2026, 1:04 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@mintlify

mintlify Bot commented Jun 7, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
mcp 🟢 Ready View Preview Jun 7, 2026, 1:04 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@pja-ant pja-ant marked this pull request as ready for review June 7, 2026 13:08
@pja-ant pja-ant requested a review from a team as a code owner June 7, 2026 13:08
@localden localden added spec rc-high-priority Related to an upcoming specification release and needs to be addressed with a high priority. labels Jun 8, 2026
Comment thread docs/specification/draft/basic/patterns/cancellation.mdx Outdated
Comment thread docs/specification/draft/basic/patterns/cancellation.mdx Outdated
Comment thread schema/draft/schema.ts Outdated
* request that opened the stream: the decimal string representation of the
* ID if it is a number, or the ID verbatim if it is a string.
*/
"io.modelcontextprotocol/subscriptionId"?: string;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this optional shouldn't it be required?

Suggested change
"io.modelcontextprotocol/subscriptionId"?: string;
"io.modelcontextprotocol/subscriptionId": string;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all notifications need this (e.g. a progress notification on a regular tool call).

Comment thread schema/draft/schema.ts
… and error example

- Make the server-to-client direction of the stdio cancellation exception
  explicit in cancellation.mdx
- Document why io.modelcontextprotocol/subscriptionId is optional on
  NotificationMetaObject (the type covers all notifications, not just
  subscription-stream deliveries)
- Add a HeaderMismatchError example so -32001 renders in the schema
  Error section
Comment thread docs/specification/draft/basic/patterns/cancellation.mdx Outdated
Comment thread docs/specification/draft/basic/patterns/cancellation.mdx Outdated
- The request cannot be cancelled
1. The sender of the cancellation notification **SHOULD** ignore any response to the
request that arrives afterward
1. The client **SHOULD** ignore any response to the cancelled request that arrives

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a MUST?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe, but things like "afterwards" are always tricky in distributed systems - e.g. sending cancellation at the same time that a response starts its handler.

@CaitieM20 CaitieM20 Jun 17, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 to @pja-ant comment. it also may be application dependent. For instance if it cancels a request but it completes anyway then the client may want to take some compensating action.

Comment thread docs/specification/draft/basic/patterns/progress.mdx Outdated
Comment thread docs/specification/draft/basic/patterns/subscriptions.mdx Outdated
Co-authored-by: David Soria Parra <167242713+dsp-ant@users.noreply.github.com>
pja-ant added 2 commits June 9, 2026 18:16
The _meta value is now typed as RequestId (string | number) instead of
string, so no numeric-to-string conversion rule is needed. Update the
subscriptions and resources doc examples to show a numeric ID passed
through unchanged, and fix a verb agreement typo in cancellation.mdx.
@pja-ant pja-ant merged commit 38639c0 into main Jun 17, 2026
9 checks passed
@pja-ant pja-ant deleted the fix/draft-schema-consistency branch June 17, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rc-high-priority Related to an upcoming specification release and needs to be addressed with a high priority. spec

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants