Skip to content

MCP 2026-07-28 conformance

edi-mcp targets the 2026-07-28 revision of the Model Context Protocol, the stateless core1, on the Python mcp SDK 2.x (2.3.0 today) through its low-level Server API2. server.py is the only module coupled to the SDK; the tool registry is SDK-agnostic.

What the server does

Requirement edi-mcp
No initialize handshake, no sessions Streamable HTTP runs with stateless_http=True: no Mcp-Session-Id, any instance answers any request. stdio also accepts the legacy handshake.
server/discover Answered by the SDK with the supported versions, capabilities (tools, resources) and the server instructions.
Per-request _meta envelope io.modelcontextprotocol/clientCapabilities decides whether a tool may ask a follow-up question (MRTR elicitation).
Cacheable results tools/list 5 min, resources/list and resources/templates/list 1 h, server/discover 5 min, resources/read 24 h for static guides and 1 h for derived content; cacheScope is always public because nothing depends on the caller.
resultType complete on every result; input_required only for an MRTR follow-up.
structuredContent and outputSchema Every tool declares an outputSchema; results carry structuredContent and the same JSON as text. Failures set isError with structuredContent.error (see error codes).
JSON Schema 2020-12 Every inputSchema and outputSchema declares the dialect. Pydantic's generated title keys are dropped from both, and descriptions from output schemas (the tool reference keeps them).
Tool annotations All four hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) and a title on every tool.
Tool _meta io.edi-mcp/surface, io.edi-mcp/requiresKey, io.edi-mcp/endpoints, and io.edi-mcp/stdioOnly on stdio-only tools.
Result _meta The SDK's io.modelcontextprotocol/serverInfo plus io.edi-mcp/upstream: upstream request count, cache hits, the backend used and how the call authenticated (never the credential).
Deterministic tools/list Sorted by name and fixed per deployment (transport and whether downloads are enabled); its serialized size has a conformance bound.
Header routing Mcp-Method / Mcp-Name must match the body; protocol-version mismatches are -32020 and unsupported versions -32022 (see Transports).

MRTR and requestState

The server supports multi round-trip requests: a tool can return an InputRequiredResult with an elicitation form, and the client resumes by calling the tool again with inputResponses and the requestState continuation. The continuation is compact base64url JSON of at most 16 KiB, never contains a key, token or authorization decision, and is rejected when malformed, issued for another tool, or older than an hour. Elicitation is used only when the client declares support. No released tool asks a question yet; the mechanism is covered by the conformance tests.

Deliberately left out

edi-mcp uses none of the features the 2026-07-28 revision deprecates or that a stateless server cannot honour: no legacy SSE transport, no sessions, no roots/list, no sampling/createMessage and no logging/setLevel. A CI job greps the source for them and fails if any appear.

Measured size

With the eight tools registered today, tools/list is about 37 KB of compact JSON on both transports. The conformance bound is 60,000 bytes and will be re-measured once every planned tool has landed.

Conformance tests

tests/test_spec_conformance_2026_07_28.py and tests/transport/ run as their own CI job: schema dialect and validity, annotations and _meta, sorted and stable tools/list within its size bound, aliases accepted and unknown arguments rejected, cache hints on lists and reads, server/discover, stateless requests in both eras, result _meta, header routing, protocol-version errors, host allow-lists, resources over HTTP, an MRTR round trip with a tampered continuation, a stateless session manager, and a real stdio subprocess speaking both protocol eras.