The trace format
A trace is JSON Lines: one event per line. Each event carries a
capture-assigned seq (the only ordering authority — never inferred later), a
direction (client-to-server / server-to-client), a transport, and a
kind:
messageevents hold the JSON-RPC payload verbatim;httpevents record the conformance-relevant headers, a response’s status, and a client request’smethod— Streamable HTTP binds different obligations toPOST,GET, andDELETE, so a clause addressed to one of them is judged only where the recording says which it was; andlifecycleevents mark transport open/close.
The full schema, including the redaction rules that keep credential-bearing
headers out of a trace by construction, is in
02-architecture.md
and 05-security-model.md.
One worked example
The example below is embedded verbatim from the
README, where
a test (readme_examples.rs) pins it to the validator’s real output — so what
you read here cannot drift from what the tool actually produces. It is a session
that reuses a request ID, and the verdict that catches it:
{"seq":0,"direction":"client-to-server","transport":"stdio","kind":"message","payload":{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"my-host","version":"1.0.0"}}}}
{"seq":1,"direction":"server-to-client","transport":"stdio","kind":"message","payload":{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{}},"serverInfo":{"name":"my-server","version":"1.0.0"}}}}
{"seq":2,"direction":"client-to-server","transport":"stdio","kind":"message","payload":{"jsonrpc":"2.0","method":"notifications/initialized"}}
{"seq":3,"direction":"client-to-server","transport":"stdio","kind":"message","payload":{"jsonrpc":"2.0","id":1,"method":"tools/list"}}
and the validator answers with the violated clause, verbatim from the spec via the registry, addressed to the offending event:
FAIL BASE-003 (MUST NOT)
seq 3: request "tools/list" reuses id 1, already used by the same party at seq 0
totals: 17 pass, 1 fail, 0 warn, 87 excluded, 0 unsupported, 6 not applicable, 31 not observed
verdict: fail
The totals line distinguishes the verdict’s components, and two of them are
not passes. The not-applicable rows are capability-gated requirements this
session never negotiated (the resources and prompts clauses); the
not-observed rows are clauses whose subject matter never appeared at all —
nothing was paginated, no binary content was sent, no error was returned. A
four-line session earns 17 passes, not a hundred. See
Architecture for why that distinction is load-bearing.