Skip to content

cancellation.mdx and subscriptions.mdx disagree on how a server ends a subscriptions/listen stream #3348

Description

@AmirK-S

What's broken?

The spec is ambiguous or self-contradictory

Where in the spec or docs?

A server **MUST** send `notifications/cancelled`
referencing a `subscriptions/listen` request ID when it tears down that subscription
stream (see [Subscriptions][subscriptions]). Servers **MUST NOT** send
`notifications/cancelled` for any other purpose.

What should happen?

The two pages should agree with each other, with the schema and with the SDKs. subscriptions/listen has a declared result type and both SDKs send it, so cancellation.mdx is the page to align: state that cancellation notifications travel from client to server only, that a server does not send notifications/cancelled, and point to Graceful Closure for server-initiated teardown. That means replacing lines 11 to 14 and removing the bullet at lines 71 to 72, in both the 2026-07-28 and draft copies, as #3171 did for subscriptions.mdx. The stdio sentence at schema/draft/schema.ts line 637 and the generated schema.json can be updated in the same change. Happy to open the PR.

What actually happens?

Two pages of the 2026-07-28 revision describe the same event, a server tearing down a subscriptions/listen stream, with different messages and different normative levels, and neither refers to the other. Links pinned to e76e9c57.

cancellation.mdx#L11-L14: "A server MUST send notifications/cancelled referencing a subscriptions/listen request ID when it tears down that subscription stream". Repeated at #L71-L72: "Server-sent cancellation notifications MUST reference a subscriptions/listen request".

subscriptions.mdx#L122-L124, with Graceful Closure at #L128-L136: the server "SHOULD send a successful subscriptions/listen response to signal a graceful end [...], then close the stream".

The same divergence is present in docs/specification/draft/.

How they drifted: #2863 introduced a server-sent notifications/cancelled bounded to stdio; #2889 (merged 2026-06-17) mirrored that wording into cancellation.mdx in commit be09b82e, and a review suggestion then dropped "on stdio" in commit 8792e0b1; #2953 replaced the mechanism in subscriptions.mdx with the subscriptions/listen result in commit 2ffc3fa2, without touching cancellation.mdx.

schema.ts#L637 still describes the server sending this notification "On stdio" only, so the unqualified MUST has no counterpart in the schema, while SubscriptionsListenResult is a declared type with a required _meta.

Both SDKs follow subscriptions.mdx: typescript-sdk packages/server/src/server/listenRouter.ts lines 171 to 187 and 412 to 429 (5119ee7f), and python-sdk src/mcp/server/subscriptions.py lines 188, 241 and 243 to 254 (7bb486a1) send the result and no server-side notifications/cancelled, on either transport.

Anything else?

I searched open and closed issues and PRs and found no earlier report of this.

AI disclosure, per AI_POLICY.md: this issue was researched and drafted primarily with Claude Code, under my direction and reviewed by me; my replies here may be AI-assisted as well.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions