Skip to content

Review fixes for SEP-2575 client conformance scenario#1

Closed
pcarleton wants to merge 14 commits into
anubhav756:feat/stateless-client-testsfrom
modelcontextprotocol:paulc/sep-2575-client-review-fixes
Closed

Review fixes for SEP-2575 client conformance scenario#1
pcarleton wants to merge 14 commits into
anubhav756:feat/stateless-client-testsfrom
modelcontextprotocol:paulc/sep-2575-client-review-fixes

Conversation

@pcarleton
Copy link
Copy Markdown

Stacked on modelcontextprotocol#270 — one commit per finding from the review. Merging this into your branch will pull all of them into modelcontextprotocol#270.

commit change
ecfacd6 drop client-consistent-version — spec lets clients vary protocolVersion per request
36b1c59 drop client-cancels-by-notification (stdio-only), client-cancels-by-closing-stream (server-side req), client-calls-discover (MAY)
2a9b731 run header/_meta checks on every POST incl. server/discover; split header presence vs match; fix example discover call
eca9f86 rename check IDs to sep-2575-* to match the traceability YAML; fill specReferences URLs
159c026 specVersionssource: { introducedIn } (rebase prep for modelcontextprotocol#265)
620f3a3 rename scenario statelessrequest-metadata
1bf10b2 add src/seps/sep-2575.yaml (carries modelcontextprotocol#273; stdio rows excluded → modelcontextprotocol#258)

After this, --scenario request-metadata runs green against everything-client (6/6) and the 3 negative tests pass. Still uncovered (follow-up welcome): sep-2575-client-declares-{elicitation,roots,sampling}-capability and sep-2575-client-retry-supported-version.

Note: 159c026 targets the post-modelcontextprotocol#265 Scenario interface, so a rebase onto current main is needed before modelcontextprotocol#270's CI will type-check.

anubhav756 and others added 14 commits May 12, 2026 20:38
SEP-2575 makes each request self-contained: "Servers MUST NOT rely on prior
requests over the same connection to establish context (e.g., capabilities,
protocol version, client identity)." Nothing forbids a client from sending a
different protocolVersion on a subsequent request, so this check would FAIL a
spec-compliant client. Removes the check, the flippingVersionClient negative
test, and the redundant second tools/list call in the example.
- client-calls-discover: spec says clients "MAY call it" — MAY-level
  behavior gets no check row. Handler still responds so a client that
  does call discover proceeds normally.
- client-cancels-by-notification: spec scopes notifications/cancelled to
  stdio. For Streamable HTTP it states "No notifications/cancelled message
  is required or expected." Unreachable from a compliant HTTP client.
- client-cancels-by-closing-stream: the normative sentence is "Closing the
  SSE response stream MUST be treated by the server as cancellation" — a
  server obligation (sep-2575-http-server-disconnect-is-cancel in #271),
  not a client one. The req-on-close handler also fires on any disconnect,
  so it could only ever emit SUCCESS.

Removes the long_running_task plumbing and example flow that existed only
to exercise these.
Spec: "Every POST request to the MCP endpoint MUST include an
MCP-Protocol-Version header" and "Every client request MUST include …
_meta". Both are unconditional, but the previous code:
- guarded the header check behind `if (currentVersion)` (so a request with
  no _meta got no header check), and
- ran the _meta check after the server/discover early-return (so the
  example discover call, which sent neither header nor _meta, passed).

Now both checks fire on every POST including server/discover, and the
header requirement is split into the two distinct spec sentences:
- client-sends-version-header (presence)
- client-version-header-matches-meta (header == _meta.protocolVersion)

Adds a mismatchedHeaderClient negative test for the new check and fixes
the example to send header + _meta on discover.
Aligns with the traceability YAML in #273 so the coverage tooling can
match check rows automatically. Also pins the badClient negative test to
both slugs it now fails (it sends neither header nor _meta).
#265 replaced specVersions: SpecVersion[] with source: ScenarioSource on
the Scenario interface. This branch predates that, so it would not
type-check after merging main.
Post-SEP-2575 there is no stateful mode to contrast with, so "stateless"
describes the SEP rather than what this scenario checks. The checks here
are the per-request _meta and MCP-Protocol-Version header obligations,
which the spec groups under "Request Metadata".
Carries the requirement-traceability YAML from #273 so the scenario PR is
self-contained. The 6 stdio-transport rows are moved to excluded: with a
pointer to #258 (stdio client harness tracking issue) — the conformance
client harness is HTTP-only today, so these are not reachable until #258
lands. The 3 prior excluded: rows from #273 are kept as-is.
@anubhav756
Copy link
Copy Markdown
Owner

Thanks for the PR!

Updated modelcontextprotocol#270 with these changes and others highlighted.

Let me know your thoughts! :)

@anubhav756 anubhav756 closed this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants