Skip to main content

Module declared

Module declared 

Source
Expand description

What protocol revision a session says it is, read from the session itself.

A registry judges one revision. Point the validator at a recording of a different one and every clause the two revisions disagree about becomes a finding — confidently, with a verbatim spec quote, against an implementation that violated nothing. A conforming 2026-07-28 stateless session judged against 2025-11-25 fails LIFE-001 for not opening with initialize, which 2026-07-28 removes (SEP-2575), and BASE-003 for reusing request ids, which 2026-07-28 permits.

The trace is not silent about this. Every revision states its own version on the wire, and a recording carries it:

  • the initialize result’s protocolVersion — the negotiated revision, and the authority where there is one;
  • the initialize request’s protocolVersion — what the client proposed, which is evidence even when no server answered;
  • a request’s _meta io.modelcontextprotocol/protocolVersion — how 2026-07-28 carries it, per request, having no handshake;
  • the MCP-Protocol-Version HTTP header.

So the validator can tell the difference between this session broke the rules and these are not the rules this session was playing by, and Report::revision_mismatch says which.

The rule is deliberately quiet, in three ways.

A mismatch is reported only when the session declared at least one revision and none of them is the registry’s. A session that proposes one revision and negotiates another has touched both, so judging it against either is a question worth asking and draws no note.

A session that declares nothing at all — a message-level capture of a handshake that never happened — gets no note either: there is nothing to disagree with, and inventing a warning from an absence is the vacuous reasoning this validator refuses everywhere else.

And a version is only a declaration if the session actually ran under it. Two filters enforce that. A request the other end answered with a JSON-RPC error states nothing — it named a version and was told no — so a probe asking for 1900-01-01 and drawing -32022, or a legacy initialize drawing -32601 from a server that no longer has one, are sessions of no revision at all rather than of the one they asked for; the clauses that judge those refusals (TRAN-074, VERS-008) are the ones with something to say. And only revisions this build ships a registry for count, because the note exists to send a reader to a registry that exists: re-run with --revision X is worthless advice when there is no X to run against.

Functions§

declared_revisions
Every protocol revision the session states about itself, ascending.
mismatch
The revisions a session declared, when it declared some and the registry’s is not among them. None means there is nothing to warn about.
mismatch_any
mismatch for a run judging several revisions at once: the note fires only when none of them is one the session declared.