Conformance Coverage

Per-SEP coverage matrix and open gaps for mcpkit.

MCP Conformance

mcpkit’s posture against the MCP conformance suite and the per-SEP traceability manifest. Refreshed before each tagged release; CI keeps the rendering in sync on PRs.

This file has two parts:

  • Overview (hand-edited, preserved across regenerations) — what the report covers, what it does not cover, and how to read it.
  • Generated block below the begin-marker — rebuilt from npx @modelcontextprotocol/conformance tier-check --output json + src/seps/traceability.json. Do not hand-edit; changes are overwritten by scripts/refresh-conformance.sh.

How to read this

  • Conformance Summary counts wire-level scenarios from the upstream conformance suite running against cmd/testserver. Aggregate pass/total at the scenario level + check-level pass/fail totals.
  • SEP Coverage is sourced from upstream’s traceability manifest, which maps each SEP to its declared requirements. A row’s Status says whether upstream has emitted a check ID for every declared requirement — not whether mcpkit passes them. Scenario-level pass/fail per SEP lives in conformance/UPSTREAM_AUDIT.md, which grades mcpkit against every scenario upstream currently ships.
  • Open Gaps lists failing scenarios + traceability rows with no emitted check. Tracking links and one-line context come from conformance/known-gaps.yaml.

Every report on this site grades an mcpkit server. For the inverse — the mcpkit client graded by an independent third-party gauntlet on the integrated stateless draft wire (2026-07-28) — see conformance/EXTERNAL_CHECKER.md, regenerated via just testconf-external-checker.

What this report is not

The renderer drops the tier-check checks that depend on live GitHub state (labels, triage SLA, P0 resolution, stable release, policy signals, spec tracking). Those are useful tier-1 signals but they change daily independent of code, which would break the CI staleness gate. To see the full tier-check scorecard for a point-in-time tier judgement, run npx @modelcontextprotocol/conformance tier-check --repo panyam/mcpkit --output markdown directly.

Regenerate locally

bash scripts/refresh-conformance.sh

Needs Node.js 22+ and a clone of modelcontextprotocol/conformance at ../conf-upstream-main (override with MCPCONFORMANCE_BASE_PATH=...). Output is deterministic — re-running on unchanged input produces a byte-identical file.


Conformance Summary

Surface Scenarios pass/total Checks pass/fail
Server 31/31 73/0
Client 21/21 581/0

mcpkit-local Conformance Suites

These suites exercise SEP-specific behavior beyond what upstream’s tier-check covers. Each is wired into just testall as a separate stage and may show as PASS, FAIL, INFO (informational, not gating), or SKIP. INFO typically means “work in flight” — see the Tracking column. The Source column links to the branch the scenarios live on; per-suite env vars and default checkout paths are listed below the tables.

Upstream-scenario suites

Scenarios owned and maintained in modelcontextprotocol/conformance; mcpkit supplies only the fixture under test.

Suite Covers Stage Status Source Tracking
testconf-scope-challenge SEP-2350 server-side scope challenges - INFO1 modelcontextprotocol/conformance@pull/481/head conformance 481
testconf-tasks-v2 SEP-2663 Tasks v2 8d PASS2 modelcontextprotocol/conformance@main —
testconf-mrtr SEP-2322 MRTR 8e PASS3 modelcontextprotocol/conformance@main —
testconf-client Client core + auth (full suite) - PASS4 modelcontextprotocol/conformance@main —
testconf-stateless SEP-2575 Stateless wire - PASS5 modelcontextprotocol/conformance@main —
testconf-skills SEP-2640 Skills 8h PASS6 modelcontextprotocol/conformance@main —

mcpkit-authored suites

Scenarios authored by this project, typically in the panyam/mcpconformance fork while the SEP they cover is still in flight upstream. They assert what the spec says, not what mcpkit does, but they have not been through upstream review.

Suite Covers Stage Status Source Tracking
testconf-file-inputs SEP-2356 File inputs (withdrawn upstream) 8f PASS panyam/mcpconformance@pending mcpkit 827
testconf-auth-server MCP authz 2025-11-25 8g PASS panyam/mcpconformance@pending —
testconf-events SEP-3415 Events (draft) 8i INFO7 panyam/mcpconformance@feat/events-conformance-suite mcpkit 1374
testconf-events-client SEP-3415 Events, client scenarios (draft) 8j INFO8 panyam/mcpconformance@feat/events-client-conformance mcpkit 1500
testconf-agents Agent discovery, agents-wg#22 (merged 2026-10-20, placeholder sep-9998) 8k INFO9 panyam/mcpconformance@feat/agents-conformance-suite mcpkit 1673

1 17 pass / 0 fail / 0 warn / 0 skip as of 2026-09-03 against ccb0744 (hand-recorded from the target’s own summary line, so re-run testconf-scope-challenge before trusting it). Tracks an unmerged upstream PR, so a red run means the fixture contract moved rather than mcpkit regressing. Retarget to upstream main and flip to a hard gate once 481 lands. Drives examples/auth/conformance-scope-challenge over opaque tokens with no authorization server; the real-IdP counterpart is testconf-auth-server.
2 44 pass / 0 fail / 1 skip across all 10 upstream tasks-* scenarios, against examples/tasks-v2 at upstream a983ba9. Until 2026-09-07 this target set TASKS_SERVER_URL / TASKS_SERVER_CMD and ran upstream’s all-scenarios.test.ts, which reads neither var and spawns its own everything-server.ts, so it graded the TypeScript reference server and never touched mcpkit. Now CLI-driven per scenario, gated on zero FAILURE.
3 36 pass / 0 fail / 1 warn across all 14 upstream input-required-result-* scenarios, against cmd/testserver at upstream a983ba9. The fixture is cmd/testserver, not examples/mrtr: the scenarios call test_input_required_result_* tools that only cmd/testserver/conformance_input_required.go registers. Same dead-env-var history as testconf-tasks-v2 (MRTR_SERVER_URL / MRTR_SERVER_CMD were read by nothing upstream). Upstream’s negative-mrtr suite still runs after the gate; it spawns its own broken fixture and grades the harness, not mcpkit.
4 Same scenario set tier-check’s –client-cmd runs. Expected failures (extension + draft + backcompat categories, none tier-scored) live in conformance/baseline.yml.
5 30/30 as of upstream 0.2.0-alpha.9 (#376 fixed the former array-vs-object requiredCapabilities test).
6 45 pass / 0 fail / 0 warn across the three upstream server scenarios (enumeration 32, manifest 6, directory 7), against examples/skills at upstream 7169291. Retargeted from the panyam/mcpconformance fork branch chore/sep-2640-yaml once PR 330 merged to upstream main; the scenario names did not change, so the move was a path swap. Gating since the retarget — it was INFO only because the fork branch was mid-WG-iteration. Upstream also registers five client-side skills scenarios (sep-2640-client-no-prefetch, sep-2640-client-verify-{digest,size,frontmatter}) that this target does not run.
7 130 pass / 0 fail / 11 warn across five scenarios, measured 2026-11-08 against examples/events/kitchen-sink at 1664 with the fork at 76fef32 (hand-recorded from the runner’s own summaries, so re-run before trusting it): events-discovery 14/14, events-poll 33/33, events-push 28/28, events-webhook 30/30, events-webhook-delivery 25/25. The webhook-id-per-message row came in with the re-pin to b08e4f9d and was red until 1664, which stopped sending the eventId as webhook-id. The three Mcp-Name rows (missing, mismatch, list exempt) came in with the re-pin to 2ec39b9c and were red until 1570. Since 1529 the cross-tenant row unsubscribes by key, the 410 row also grades that the subscription survives, and lastError is graded off a refresh after the 413 probe; since 1505 discovery grades list-changed-notification over subscriptions/listen, driving the catalog control; since 1417 push grades stream-mode-unsupported on digest.ready, a poll-only type; since 1465 push grades the four removal and schema-change rows through the catalog control’s remove, retype and extend. kitchen-sink passes all of them. The fixture is spawned with –conformance-events, which registers thirteen diagnostic controls the scenarios drive, including a restart that rebuilds the server over the same subscription store and one that permits the harness’s loopback receiver past the callback guards after the SSRF rows are graded; without them rows describe conditions a harness cannot provoke and report untestable, which upstream’s policy renders red. See examples/CONVENTIONS.md § Conformance fixtures. Proposed upstream as a draft in modelcontextprotocol/conformance 521 and tracked on the fork branch until it lands. Check IDs are sep-3415-*: MCP Events is SEP-3415, a draft in modelcontextprotocol/modelcontextprotocol. Every row quotes SEP-3415 at b08e4f9d with a per-row section url (1502, 1567, 1664). INFO because the SEP is still a draft and its text can move. Every graded row is green since 1570; subscribe-auth-required and subscribe-refresh-replaces-secret, which no harness can grade over the wire, are excluded upstream. Thirteen divergences found in total, all closed (1379, 1381, 1416, 1432, 1433, 1434, and endpoint verification in 1444). Set tracked in 1425.
8 Four client scenarios graded against the Go events client SDK through experimental/ext/events/clients/go/cmd/conformance-client, measured 2026-10-20 at 1570 with the fork at 095a156, on both lifecycles: events-client-poll 10/10 on 2026-07-28 (list_changed over subscriptions/listen since 1505, Mcp-Name set and Base64-encoded since 1570) and 7/7 on 2025-11-25 (the listen opt-in and Mcp-Name rows do not apply there), events-client-push 3/3 (dead-stream reconnect since 1503), events-client-webhook 3/3, events-client-no-extension 1/1. The harness plays the events server and grades what the client sends. The driver only calls what the SDK offers, so a red row is an SDK gap. Proposed upstream as a draft in modelcontextprotocol/conformance 541, stacked on 521. Re-measured 2026-10-14 after the rows were re-quoted against SEP-3415 (1502), and 2026-11-08 with the fork at c8625de after the re-pin to b08e4f9d (1664), both with the same results. The receiver’s per-subscription eventId dedup that b08e4f9d adds is excluded, since what reaches the application is not observable over the wire. INFO for the same reason as testconf-events: the SEP is still a draft. make conf-events-setup creates this checkout as a worktree of the server one.
9 Two scenarios, measured 2026-11-08 against examples/agents/discovery –conformance-agents: sep-9998-agents-discovery 28/28 and sep-9998-agents-list-changed 4/4. Rows quote agents-wg#22 at its merge commit 137d88bd, checked by script. The text is identical to head 9b16840e, which the rows quoted until 1673. The yaml declares 49 rows, 31 graded and 18 excluded (host obligations, rules needing two authorization contexts, and step-up, a MAY needing a credential the harness can raise). Breaking the fixture turns the matching rows red: a visible hidden agent fails two discovery rows, an unsent list_changed fails one list-changed row, a wrong agent_not_found reason fails one, and an omitted ttlMs fails two, since the draft CacheableResult requires it. The fixture flag serves anonymously, pages one agent at a time, adds an agent naming a missing tool, and registers agents_conformance_fixture and agents_conformance_add_agent (see examples/CONVENTIONS.md § Conformance fixtures). Check IDs carry the sep-9998 placeholder because the proposal lives in the Agents IG repository and has no spec PR number yet. INFO for that reason. Runs with –force, since the extension is not on the spec timeline. Proposed upstream as modelcontextprotocol/conformance 556. The -32021 refusal of an undeclared client (1673) has no row yet, because the proposal text does not state it.

Setup — clone the right worktree per suite

Each suite’s Makefile target reads MCPCONFORMANCE_*_PATH to find its scenario worktree. Defaults assume sibling clones of the source repo at the relative path shown. Override per-invocation when the worktree lives elsewhere.

Suite Env var Default path Clone command
testconf-scope-challenge MCPCONFORMANCE_SCOPE_CHALLENGE_PATH ../conf-481 git clone -b pull/481/head https://github.com/modelcontextprotocol/conformance.git ../conf-481
testconf-tasks-v2 MCPCONFORMANCE_TASKS_V2_PATH ../conf-upstream-main git clone -b main https://github.com/modelcontextprotocol/conformance.git ../conf-upstream-main
testconf-mrtr MCPCONFORMANCE_MRTR_PATH ../conf-upstream-main git clone -b main https://github.com/modelcontextprotocol/conformance.git ../conf-upstream-main
testconf-file-inputs MCPCONFORMANCE_FILE_INPUTS_PATH ../conf-pending git clone -b pending https://github.com/panyam/mcpconformance.git ../conf-pending
testconf-auth-server MCPCONFORMANCE_AUTH_PATH ../conf-pending git clone -b pending https://github.com/panyam/mcpconformance.git ../conf-pending
testconf-client MCPCONFORMANCE_CLIENT_PATH ../conf-upstream-main git clone -b main https://github.com/modelcontextprotocol/conformance.git ../conf-upstream-main
testconf-stateless MCPCONFORMANCE_STATELESS_PATH ../conf-upstream-main git clone -b main https://github.com/modelcontextprotocol/conformance.git ../conf-upstream-main
testconf-skills MCPCONFORMANCE_SKILLS_PATH ../conf-upstream-main git clone -b main https://github.com/modelcontextprotocol/conformance.git ../conf-upstream-main
testconf-events MCPCONFORMANCE_EVENTS_PATH ../conf-events git clone -b feat/events-conformance-suite https://github.com/panyam/mcpconformance.git ../conf-events
testconf-events-client MCPCONFORMANCE_EVENTS_CLIENT_PATH ../conf-events-client git clone -b feat/events-client-conformance https://github.com/panyam/mcpconformance.git ../conf-events-client
testconf-agents MCPCONFORMANCE_AGENTS_PATH ../conf-agents git clone -b feat/agents-conformance-suite https://github.com/panyam/mcpconformance.git ../conf-agents

SEP Coverage

These are requirement counts, not test results. Each row counts the normative requirements extracted from that SEP’s text, and whether upstream has a check ID mapped to each one. A SEP with 1 tested requirement may be covered by dozens of assertions, or by one; the numbers here say nothing about how many checks ran or whether mcpkit passed them. For pass/fail see conformance/UPSTREAM_AUDIT.md, and for the mcpkit-local suites see the table above.

SEP Reqs Tested Excluded Untested Status
SEP-837 5 1 4 0 pass
SEP-2106 5 1 4 0 pass
SEP-2164 3 2 1 0 pass
SEP-2207 4 1 3 0 pass
SEP-2243 24 18 4 2 partial
SEP-2260 12 0 12 0 untested
SEP-2322 33 17 16 0 pass
SEP-2350 3 1 2 0 pass
SEP-2352 6 3 3 0 pass
SEP-2468 9 6 3 0 pass
SEP-2549 20 7 13 0 pass
SEP-2575 35 22 13 0 pass

Reqs is the total (tested + excluded + untested). Numeric cells link to per-SEP detail below; hover/long-press surfaces a one-line summary. Excluded means upstream decided a requirement is not harness-observable and recorded why, so it is a deliberate gap rather than an oversight; the reasons are in the per-SEP detail. Status tracks “does upstream have a check ID for this requirement”, not “does mcpkit pass it”, because Scenario→SEP attribution is not exposed in tier-check JSON today.

SEP Detail

Per-SEP breakdown of upstream traceability — what is exercised, what is intentionally excluded, and what is declared but not yet exercised. Useful for auditing whether each exclusion still makes sense as upstream evolves. Check IDs link to their definition in the upstream SEP YAML.

SEP-837

Tested (1)

Excluded (4)

Requirement Upstream reason
Native applications (desktop applications, mobile apps, CLI tools, and locally-hosted web applications accessed via localhost) SHOULD use application_type: “native”. harness cannot determine the client-under-test application class (native vs web) out-of-band; only presence and value validity are wire-observable
Web applications (remote browser-based applications served from a non-local host) SHOULD use application_type: “web”. harness cannot determine the client-under-test application class (native vs web) out-of-band; only presence and value validity are wire-observable
MCP clients MUST be prepared to handle registration failures due to redirect URI constraints when authorization servers implement OIDC. robustness requirement with no defined wire-level success criterion
When a registration request is rejected, clients SHOULD surface a meaningful error to the user or developer. UI/DX behavior, not protocol-observable

Untested (0)

None.

SEP-2106

Tested (1)

Excluded (4)

Requirement Upstream reason
SDK maintainers SHOULD: Document the migration in SDK release notes; Where ergonomic, provide typed helpers (e.g. generics over a tool’s outputSchema) so consumers do not need to write narrowing guards by hand Migration/deprecation guidance for SDK maintainers; about SDK source code, not protocol-observable wire behavior
JSON Schema validation already handles type checking, value constraints, and required field validation, and implementations MUST continue to validate all inputs and outputs against declared schemas Restates pre-existing schema-validation behavior and is too broad to attribute to a specific observable SEP-2106 check; input/output validation overlaps existing tool scenarios
An opt-in mode that fetches non-local $refs SHOULD enforce an allowlist of hosts (or at minimum reject loopback, link-local, and private network addresses), apply timeouts and size limits, and log dereferenced URIs Applies only when the non-default opt-in network-$ref fetch mode is enabled; not observable in default conformance runs
Implementations SHOULD apply reasonable bounds — for example, a maximum schema depth, a cap on the total number of subschemas, or a per-validation time budget — to prevent a malicious tool definition from acting as a CPU DoS vector against the validator Internal validator resource limits (max schema depth, subschema cap, per-validation time budget); a defensive measure not observable on the wire

Untested (0)

None.

SEP-2164

Tested (2)

Excluded (1)

Requirement Upstream reason
clients SHOULD also accept -32002 as a resource not found error Client-side error handling is implementation-defined; not protocol-observable

Untested (0)

None.

SEP-2207

Tested (1)

Excluded (3)

Requirement Upstream reason
MCP Servers (Protected Resources) SHOULD NOT include offline_access in WWW-Authenticate scope or Protected Resource Metadata scopes_supported, as refresh tokens are not a resource requirement The server suite does not yet exercise the SDK server as an OAuth protected resource (no Protected Resource Metadata or WWW-Authenticate probing); revisit once server-side authorization scenarios exist (https://github.com/modelcontextprotocol/conformance/issues/116)
MCP Clients that desire refresh tokens MUST keep refresh tokens confidential in transit and storage as specified in OAuth 2.1 Section 4.3 Confidentiality of refresh tokens in storage is client-internal state, and in-transit (TLS) confidentiality is not exercised by the harness over localhost HTTP; not protocol-observable
MCP Clients that desire refresh tokens MUST NOT assume refresh tokens will be issued; the AS retains discretion A client “assuming” refresh tokens will be issued is mental-state; only manifests as general authorization-flow completion, which other checks already cover; not directly protocol-observable

Untested (0)

None.

SEP-2243

Tested (18)

Excluded (4)

Requirement Upstream reason
Clients SHOULD log a warning when rejecting a tool definition due to invalid x-mcp-header, including the tool name and the reason. Log output is not wire-observable.
Server developers SHOULD NOT mark sensitive parameters (such as passwords, API keys, tokens, or PII) with x-mcp-header. Design guidance to humans; not protocol-observable.
Intermediaries MUST return an appropriate HTTP error status for validation failures. Intermediary requirement; conformance harness tests clients and servers, not intermediaries.
Intermediate servers that do not recognize an Mcp-Param-{Name} header MUST forward it and otherwise ignore it. Intermediary requirement; conformance harness tests clients and servers, not intermediaries.

Untested (2)

SEP-2260

Tested (0)

None.

Excluded (12)

Requirement Upstream reason
roots/list, sampling/createMessage, and elicitation/create requests MUST NOT be sent on standalone streams. No longer needed this behavior is enabled by default SEP-2322 MRTR.
Clients MUST return standard JSON-RPC errors for common failure cases: Server sends an elicitation/create request with no associated client-to-server request: -32602 (Invalid params) No longer needed this behavior is enabled by default SEP-2322 MRTR.
Clients SHOULD return standard JSON-RPC errors for common failure cases: Server sends a roots/list request with no associated client-to-server request: -32602 (Invalid params) No longer needed this behavior is enabled by default SEP-2322 MRTR.
Clients SHOULD return errors for common failure cases: Sampling request not associated with a client-to-server request: -32602 (Invalid params) No longer needed this behavior is enabled by default SEP-2322 MRTR.
These messages MUST relate to the originating client request. Semantic association (“relate to”) is not protocol-observable. The harness cannot determine whether a server request conceptually relates to the client request without understanding application logic.
Implementations SHOULD prefer transport-level SSE keepalive mechanisms for idle-connection maintenance. Implementation preference for keepalive mechanism choice; not observable on the wire.
Servers MUST send server-to-client requests (such as roots/list, sampling/createMessage, or elicitation/create) only in association with an originating client request (e.g., during tools/call, resources/read, or prompts/get processing). No longer needed this behavior is enabled by default SEP-2322 MRTR.
Standalone server-initiated requests of these types on independent communication streams (unrelated to any client request) are not supported and MUST NOT be implemented. No longer needed this behavior is enabled by default SEP-2322 MRTR.
Servers MUST send sampling/createMessage requests only in association with an originating client request (e.g., during tools/call, resources/read, or prompts/get processing). No longer needed this behavior is enabled by default SEP-2322 MRTR.
Standalone server-initiated sampling on independent communication streams (unrelated to any client request) is not supported and MUST NOT be implemented. No longer needed this behavior is enabled by default SEP-2322 MRTR.
Servers MUST send server-to-client requests (such as roots/list, sampling/createMessage, or elicitation/create) only in association with an originating client request (e.g., during tools/call, resources/read, or prompts/get processing). No longer needed this behavior is enabled by default SEP-2322 MRTR.
Standalone server-initiated requests of these types on independent communication streams (unrelated to any client request) are not supported and MUST NOT be implemented. No longer needed this behavior is enabled by default SEP-2322 MRTR.

Untested (0)

None.

SEP-2322

Tested (17)

Excluded (16)

Requirement Upstream reason
inputRequests keys are server assigned identifiers and MUST be unique within the scope of the request. inputRequests is a JSON object; duplicate keys are collapsed by JSON parsing before the harness can observe them, so key uniqueness is not testable at the protocol level
Servers MUST send server-to-client requests (such as roots/list, sampling/createMessage, or elicitation/create) using the MRTR pattern. Architectural migration statement; tested indirectly through all MRTR scenarios
servers MUST treat requestState as an attacker-controlled input Internal security posture; not observable at protocol level
servers MUST protect its integrity (e.g. HMAC or AEAD) Internal implementation choice about encryption/signing; not observable at protocol level
servers SHOULD include the authenticated principal, a short expiry (TTL), and an identifier for the originating request inside the integrity-protected requestState payload and verify each on receipt Internal requestState format; not observable at protocol level
Servers for which a given requestState must be consumed at most once MUST enforce that invariant server-side Internal enforcement policy; conformance harness cannot determine which servers require single-use semantics
Servers MUST NOT assume that clients will fulfill the inputRequests or retry the original request Server-internal robustness assumption; not observable at protocol level
Servers MUST validate request state as described in the server requirements above. Duplicates integrity-protection requirements above; internal security detail
Servers MUST include an inputRequests field in the tasks/result response when the task is in status input_required. Tasks moved to an extension as of SEP-2663; no longer part of core conformance
inputRequests keys are server assigned identifiers and MUST be unique within the scope of a Task. Tasks moved to an extension as of SEP-2663; no longer part of core conformance
When tasks/get shows status input_required, clients MUST call tasks/result to get the inputRequests and optional requestState. Tasks moved to an extension as of SEP-2663; no longer part of core conformance
Clients SHOULD construct the results of those requests and call tasks/input_response with the inputResponses & requestState (if present). Tasks moved to an extension as of SEP-2663; no longer part of core conformance
Receivers MUST reject tasks/input_response requests for tasks that are not in input_required status with error code -32602 (Invalid params). Tasks moved to an extension as of SEP-2663; no longer part of core conformance
When a receiver receives a tasks/result request for a task in working status, it MUST block the response until the task reaches a terminal status or input_required status. Tasks moved to an extension as of SEP-2663; no longer part of core conformance
When a receiver receives a tasks/result request for a task in input_required status, it MUST return an InputRequiredResult containing the inputRequests that the requestor must fulfill. Tasks moved to an extension as of SEP-2663; no longer part of core conformance
After sending tasks/input_response, the requestor SHOULD resume polling via tasks/get. Tasks moved to an extension as of SEP-2663; no longer part of core conformance

Untested (0)

None.

SEP-2350

Tested (1)

Excluded (2)

Requirement Upstream reason
Regardless of the approach chosen, servers SHOULD include all scopes required for the current operation in a single challenge. “All scopes required for the current operation” has no harness-observable ground truth; the challenge is the only place the server declares its requirements. Detecting the negative (incremental challenging) would need server-side auth scenarios that do not exist yet and would test the example app’s scope config rather than SDK behavior; the spec also permits dynamic per-request scope determination, so a second challenge is not conclusively non-conformant.
When responding with insufficient scope errors, servers SHOULD include the scopes needed to satisfy the current operation in the scope parameter, consistent with RFC 6750 Section 3.1. reword of pre-existing requirement (request->operation, +RFC6750 cite); no normative delta; harness already emits scope= in WWW-Authenticate

Untested (0)

None.

SEP-2352

Tested (3)

Excluded (3)

Requirement Upstream reason
Clients MUST maintain separate registration state (client credentials, tokens) per authorization server. internal storage requirement; not directly observable on the wire
Clients that use pre-registered credentials, or persist client credentials obtained via Dynamic Client Registration, MUST associate those credentials with the specific authorization server that issued them, keyed by the authorization server issuer identifier. internal state-keying requirement; not protocol-observable
If the authorization server indicated by protected resource metadata no longer matches the one the credentials were registered with, clients SHOULD surface an error rather than silently attempting to use mismatched credentials. UI behavior; the negative half (do not send mismatched credentials) is covered by sep-2352-no-reuse-on-as-change

Untested (0)

None.

SEP-2468

Tested (6)

Excluded (3)

Requirement Upstream reason
MCP authorization servers SHOULD include the iss parameter in authorization responses, including error responses, as defined in RFC9207 Section 2. Targets the authorization server under test; observing iss in an authorization response requires driving an Authorization Code Grant against the AS, which the authorization-server suite does not implement yet (it only probes the metadata endpoint). (https://github.com/modelcontextprotocol/conformance/issues/208)
Authorization servers that include the iss parameter MUST advertise this by setting authorization_response_iss_parameter_supported to true in their metadata (RFC9207 Section 2.3). Conditional on the AS actually including iss in an authorization response, which requires driving an Authorization Code Grant against the AS under test; the authorization-server suite does not implement that yet. (https://github.com/modelcontextprotocol/conformance/issues/208)
This validation applies equally to error responses - on mismatch the client MUST NOT act on or display error, error_description, or error_uri. display is UI-facing; act-on has no protocol-observable signal beyond the existing reject-on-mismatch checks

Untested (0)

None.

SEP-2549

Tested (7)

Excluded (13)

Requirement Upstream reason
If ttlMs is 0, the response SHOULD be considered immediately stale. Client-side caching behavior; not observable at the protocol level
If ttlMs is positive, the client SHOULD consider the result fresh for that many milliseconds after receiving the response. Client-side caching behavior; not observable at the protocol level
If ttlMs is absent, clients SHOULD assume a default of 0 (immediately stale) and rely on their own caching heuristics or notifications. Client-side caching behavior; not observable at the protocol level
If ttlMs is negative, clients SHOULD ignore it and treat it as 0. Client-side caching behavior; not observable at the protocol level
Once the TTL expires, the response is stale and the client SHOULD re-fetch on next access. Client-side caching behavior; not observable at the protocol level
Clients SHOULD NOT treat TTL as a polling interval that triggers automatic background refetches. Client-side caching behavior; not observable at the protocol level
Implementations that do choose to poll MUST apply jitter and backoff. Client-side polling behavior; not observable at the protocol level
Cached responses MAY be reused for the same authorization context. Caches MUST NOT be shared across authorization contexts (e.g. a different access token requires a different cache). Client/cache-side behavior; not observable at the protocol level
When a cached page expires, the client SHOULD re-fetch that page using its cursor. Client-side caching behavior; not observable at the protocol level
Clients that require a consistent snapshot of the full list SHOULD re-fetch from the beginning (without a cursor). Client-side caching behavior; not observable at the protocol level
If a cursor becomes invalid (e.g., the server returns an error for a previously valid cursor), the client SHOULD discard all cached pages and re-fetch from the beginning. Client-side caching behavior; not observable at the protocol level
Servers MUST be aware that responses with a “public” cacheScope may be shared between callers even if the Result is coming from an authenticated endpoint. Server-side awareness requirement; implementation guidance not testable via protocol messages
Server implementors MUST apply appropriate per-primitive access controls, and MUST NOT rely on cacheScope alone to prevent unauthorized access to primitives. Server-side access control; implementation guidance not testable via protocol messages

Untested (0)

None.

SEP-2575

Tested (22)

Excluded (13)

Requirement Upstream reason
A server MUST NOT treat connection or process identity as a proxy for conversation or session continuity. / Servers MUST NOT rely on prior requests over the same connection to establish context (e.g., capabilities, protocol version, client identity). internal server state, not directly wire-observable; the observable consequence (rejecting requests with incomplete _meta rather than falling back to remembered state) is covered by sep-2575-request-meta-invalid-* — see https://github.com/modelcontextprotocol/conformance/issues/296
Servers MUST NOT require that a client reuse the same connection to perform related operations. not observable from a black-box harness; every harness request already arrives on an independent connection — see https://github.com/modelcontextprotocol/conformance/issues/296
Closing the SSE response stream MUST be treated by the server as cancellation of that request. “treated as cancellation” is internal server state; once the stream is closed there is no channel left on which to observe the effect — see https://github.com/modelcontextprotocol/conformance/issues/296
The server SHOULD stop work on the cancelled request as soon as practical and MUST NOT send any further messages for it [HTTP]. “stop work as soon as practical” is unobservable from a black-box harness, and “no further messages” cannot be verified once the response stream is closed — see https://github.com/modelcontextprotocol/conformance/issues/296
State that needs to span multiple requests (e.g., long-running tasks, application-level handles) MUST be referenced by an explicit identifier the client passes on each request. architectural guidance, observable only via subscriptionId/task-id rows already listed
To distinguish notifications belonging to different concurrent subscriptions, clients MUST correlate notifications using the io.modelcontextprotocol/subscriptionId field carried in _meta. client-internal demux; not observable on the wire from the harness
The client SHOULD check the acknowledged filter against what it requested and handle any unsupported types gracefully. internal comparison; “gracefully” has no wire-observable definition
Because there is no per-request status code to drive fallback, a client that supports both eras SHOULD probe with server/discover first [stdio backward compatibility]. stdio client harness not implemented — see https://github.com/modelcontextprotocol/conformance/issues/258
To cancel an in-flight request [on stdio], the client MUST send a notifications/cancelled notification referencing the request ID. stdio client harness not implemented — see https://github.com/modelcontextprotocol/conformance/issues/258
Servers SHOULD stop work on a cancelled request as soon as practical and MUST NOT send any further messages for it [stdio]. stdio client harness not implemented — see https://github.com/modelcontextprotocol/conformance/issues/258
If the server process exits unexpectedly, the client SHOULD restart it. stdio client harness not implemented — see https://github.com/modelcontextprotocol/conformance/issues/258
If the server returns UnsupportedProtocolVersionError, [the stdio client] SHOULD retry using one of the advertised supportedVersions rather than falling back to initialize. stdio client harness not implemented — see https://github.com/modelcontextprotocol/conformance/issues/258
On stdio, if the connection is terminated and then re-established, the client MUST re-send subscriptions/listen to re-establish its subscriptions. stdio client harness not implemented — see https://github.com/modelcontextprotocol/conformance/issues/258

Untested (0)

None.

Open Gaps

Declared requirements with no emitted check

SEP Check ID Tracking
SEP-2243 sep-2243-server-not-expect-null https://github.com/panyam/mcpkit/issues/1111 — Untested upstream until conformance PR 325 merges. Covered locally by the TestWireParity 1111 row (optional omitted / optional null).
SEP-2243 sep-2243-server-reject-missing-required https://github.com/panyam/mcpkit/issues/1111 — Untested upstream until conformance PR 325 merges. Covered locally by the TestWireParity 1111 row (required omitted → 400 + -32020).