fix: correct server-stateless error-code expectations against the draft spec
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.requestedshape. - 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.