Skip to content

fix: correct server-stateless error-code expectations against the draft spec#336

Draft
felixweinberger wants to merge 1 commit into
mainfrom
fweinberger/fix-stateless-error-table
Draft

fix: correct server-stateless error-code expectations against the draft spec#336
felixweinberger wants to merge 1 commit into
mainfrom
fweinberger/fix-stateless-error-table

Conversation

@felixweinberger

Copy link
Copy Markdown
Collaborator

Three checks in server-stateless expect error codes the draft spec contradicts, so a spec-correct server can't pass the scenario. This fixes the expectations to match the spec text, updates the mock server and the everything-server fixture to the same behavior, and tightens the header-mismatch probe so it actually tests what its requirement sentence says.

Motivation and Context

1+2. Missing _meta / missing _meta.protocolVersion expected -32602, spec says -32001.

The probes send a valid MCP-Protocol-Version header with a body that has no value to mirror it. That's a header validation failure, not generic invalid params. The transports spec is explicit (streamable-http, error codes):

When rejecting a request due to header validation failure, servers MUST return HTTP status 400 Bad Request and MUST include a JSON-RPC error response using the following error code:

| -32001 | HeaderMismatch | The HTTP headers do not match the corresponding values in the request body, or required headers are missing/malformed. |

and the validation failure conditions include "A header value does not match the corresponding request body value" — a body with no value can't match. clientInfo/clientCapabilities have no corresponding header, so those two cells correctly stay -32602.

3. A body carrying protocolVersion: 'v999.0.0' expected -32001, spec says -32004.

The probe's requested version isn't implemented by anyone, and versioning is unambiguous about that case:

If the server does not implement the requested version (whether the version is unknown to the server, or is a known version the server has chosen not to support), it MUST respond with an UnsupportedProtocolVersionError listing the versions it does support

UnsupportedProtocolVersionError is -32004 with data: { supported, requested } (see the schema type). Expecting a bare -32001 here also denies the client the supported list it needs to renegotiate. The check is re-tagged sep-2575-http-server-unsupported-version-400-body since it exercises the unsupported-version requirement (body channel), not the mismatch requirement.

The mismatch requirement keeps a real probe. sep-2575-http-server-header-mismatch-400 now sends two different implemented per-request-metadata versions on header vs body — the only construction where the mismatch rule applies without colliding with the unsupported-version rule. Exactly one such version exists today, so the check reports SKIPPED until a second one ships; before this change it was passing/failing on a probe that actually exercised a different requirement.

Fixture fixes that fall out of this: the everything-server returned its -32602 with HTTP 200 (every rejection here must be 400), and applied draft per-request validation to 2025-era traffic — the spec notes header–body validation only applies to versions that require it. Both fixed, and the mock server now uses the same precedence (mirror-missing → -32001, other _meta fields → -32602, unimplemented version on either channel → -32004, mismatch of two implemented versions → -32001).

How Has This Been Tested?

  • Full suite: 273/273 passing, including new mock-server cells for each corrected code and the data.supported/data.requested shape.
  • The scenario self-tests (all-scenarios.test.ts) run against the updated fixture and pass; the dns-rebinding scenario surfaced the fixture's 200-on-error bug during this work (its "accepted" probe was previously matching an HTTP 200 error response).

Breaking Changes

None for spec-correct servers. Servers that were passing these three cells by emitting the old codes will now fail them — that's the correction.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

All spec links pin the schema/prose revision the suite's own src/spec-types/SOURCE vendors (0168c57f), so the cited text is exactly what the runner's types are generated from. src/seps/sep-2575.yaml gains the -body check id under the unsupported-version requirement; the requirement sentences themselves are unchanged.

…ft spec

- missing _meta / missing protocolVersion: expect -32001 HeaderMismatch
  instead of -32602 (the transports spec routes header-mirror failures,
  including a missing body counterpart, to -32001 with HTTP 400);
  clientInfo/clientCapabilities cells stay -32602
- a body carrying an unimplemented protocolVersion now expects
  UnsupportedProtocolVersionError (-32004 with data.supported/requested)
  per the versioning spec; re-tagged as
  sep-2575-http-server-unsupported-version-400-body
- sep-2575-http-server-header-mismatch-400 becomes a real mismatch probe
  between two implemented per-request-metadata versions and reports
  SKIPPED while only one such version exists
- mock server and everything-server fixture updated to the same
  precedence; the fixture also returned -32602 with HTTP 200 and applied
  draft validation to 2025-era traffic, both fixed
@pkg-pr-new

pkg-pr-new Bot commented Jun 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

npx https://pkg.pr.new/@modelcontextprotocol/conformance@336

commit: d868653

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.

1 participant