Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The cross-SDK matrix

Each Tier 1 SDK the matrix covers — TypeScript, Python, Go and Rust — ships a conformance server: the server its maintainers run the official suite against. TypeScript has two lines and so two rows: v1 (@modelcontextprotocol/sdk, the maintenance line, which implements the specification up to 2025-11-25) and v2 (@modelcontextprotocol/server and its companions, which also serves 2026-07-28). This page records each of those servers, at each revision it serves, while an official SDK client drives it, and judges every recording with this project’s validator. Nothing of this project’s speaks MCP in these sessions; the recorder and the judge are the only parts of it involved.

The table below is generated by cargo xtask sdk-matrix from the golden reports committed under corpus/, and cargo xtask gates fails when it drifts from them. A scheduled job re-records every session with the pinned SDKs each week and fails if the results differ from the committed ones, so a row here is what the pinned release does today rather than what it did once. How each session is recorded, with the exact commands, is Recording an SDK’s server.

SDKPinned releaseRevisionVerdictpassfailwarnnot observedWire schemaEvidence
TypeScript v1@modelcontextprotocol/sdk 1.32.12025-11-25pass-with-warnings390162pass (18 messages)report · trace
TypeScript v1@modelcontextprotocol/sdk 1.32.12026-07-28not served——————
TypeScript v2@modelcontextprotocol/server 2.3.12025-11-25pass430059pass (18 messages)report · trace
TypeScript v2@modelcontextprotocol/server 2.3.12026-07-28pass7200109pass (14 messages)report · trace
Pythonmcp 2.3.02025-11-25pass390063pass (17 messages)report · trace
Pythonmcp 2.3.02026-07-28pass6500116pass (14 messages)report · trace
Gogo-sdk v1.8.02025-11-25pass430059pass (17 messages)report · trace
Gogo-sdk v1.8.02026-07-28fail784198pass (14 messages)report · trace
Rustrmcp 3.7.02025-11-25pass420060pass (17 messages)report · trace
Rustrmcp 3.7.02026-07-28pass-with-warnings7301107pass (14 messages)report · trace

At 2025-11-25 every server is driven by the same TypeScript SDK (v1) client (ts-client.mjs). At 2026-07-28 every server is driven by the same Python SDK client (py-client.py).

Findings. Every failing or warning row of a committed report, with the first of its findings as the validator words it; the report link holds the rest.

  • TypeScript v1, 2025-11-25 — BASE-086 (SHOULD, warn, 8 findings): the server sent tool “test_tool_with_logging”’s inputSchema declaring $schema “http://json-schema.org/draft-07/schema#”; JSON Schema 2020-12 (https://json-schema.org/draft/2020-12/schema) is the recommended dialect
  • Go, 2026-07-28 — BASE-034 (MUST NOT, fail, 1 finding): server asked for elicitation/create, which needs the elicitation capability, but the request’s clientCapabilities did not declare it
  • Go, 2026-07-28 — TRAN-068 (SHOULD, warn, 6 findings): SSE response does not carry X-Accel-Buffering: no
  • Go, 2026-07-28 — MRTR-012 (MUST NOT, fail, 1 finding): server asked for elicitation/create, which needs the elicitation capability, but the request’s clientCapabilities did not declare it
  • Go, 2026-07-28 — MRTR-013 (MUST NOT, fail, 1 finding): server asked for elicitation/create, which needs the elicitation capability, but the request’s clientCapabilities did not declare it
  • Go, 2026-07-28 — ELIC-059 (MUST NOT, fail, 1 finding): inputRequests[user_context] (elicitation/create) asks for form mode, but the request’s clientCapabilities does not declare elicitation at all
  • Rust, 2026-07-28 — BASE-037 (SHOULD, warn, 5 findings): result answering tools/list carries no io.modelcontextprotocol/serverInfo in its _meta; servers should include it in every result unless specifically configured not to

Reading a row

Each row is one recorded session. Verdict and the four counts are the report’s, with the same meaning as in Reading a report: not observed counts the clauses the session carried nothing to judge, so a short session is not mistaken for a conforming one. Wire schema is every message checked against the revision’s published JSON Schema. Not served means the server does not implement that revision — the client asked, and the server answered with an older one — so there is no session to judge.

Every server at a revision is driven by the same client running the same script, so the difference between two rows of one revision is the server’s. The script is small — list, call, read, get — so these sessions evidence the common surface. Compare like with like: a row with more passes did not necessarily conform better; it may only have been asked more.

Findings are reported, not hidden

A failing row is a finding against that SDK’s pinned release, stated with the clause it breaks and a link to the report and the recording it came from. Each was read against the recording before being published — a check can only be as honest as the capture it reads, and the corpus’s own history has findings that turned out to be the tool’s, not the implementation’s (the trace corpus). A finding you believe is wrong is a bug to file with its requirement ID; the dispute process says how each is triaged.