Sentinel Conformance report · MCP 2026-07-28 · sentinel

A Go MCP broker & the Python harness that grades it

Grades any MCP server against the spec, clause by clause, and says plainly what it cannot see.

On 28 July 2026 the Model Context Protocol became stateless: sessions, the initialize handshake and server-initiated requests were removed, and server/discover became mandatory. Sentinel is a harness that scans any endpoint over the wire and grades it rule by rule, each with the clause it comes from. It also lists the deprecated features the server still uses and when each can be removed. The broker is a Go server built natively on the new revision, and it is graded by that same harness.

Everything below is rendered from JSON that sentinel wrote, scanned . Nothing is typed in by hand. How it was generated.

Open the report Source on GitHub

The same 52-rule catalog, three servers, both directions

A gate that can only pass proves nothing. CI scans an unmigrated server that must fail, and two correct ones that must pass. The exit code is part of the contract: 0 means the target passed, 1 means the target failed the gate, and 2 means the scanner itself broke.

Loading scan output…

Report viewer

Each row is one finding from a real scan. Open a row to see what was observed, what to change, and the specification clause it is graded against.

    Five MUSTs a scan cannot settle, and does not pretend to

    Some requirements are invisible from the client side. Sentinel reports them as Indeterminate, never as passes. It excludes them from the gate and reprints them on every scan, so a green build can never be read as covering them. The same five appear, with the same wording, on all three scans above.

      Deprecated-feature inventory, against the removal clock

      sentinel deprecations probes for each deprecated feature and records how it knows: observed on the wire, or advertised in server/discover. This inventory never fails a gate. A deprecated feature that still works is a migration to plan, not a defect.

      Sizing the migration from the same evidence

      sentinel migrate maps failing rules onto the revision's breaking changes. Changes the wire cannot reveal are listed as not checkable from here rather than marked done. The hours are the harness's planning estimates, not measurements.

      A rule ID never changes meaning

      A report from six months ago names rules by ID and nothing else, so redefining a rule would silently rewrite what that report said. When a rule turns out to be wrong it is deprecated, and a successor is published under a new ID. Retired rules are skipped by default and never deleted. Re-running with --include-deprecated-rules reproduces an old report.

      All three corrections in 0.2.0 went the same way: sentinel had been demanding more than the specification does. Reasons are quoted from the README. Outcomes are from a replay scan of the unmigrated fixture.

      Two products, one wire between them

      The harness never imports server internals and runs against any endpoint URL. Its probe is a deliberately literal client, with no MCP SDK. An SDK that helpfully adds Mcp-Method would make the rule that requires Mcp-Method untestable.

      harness/ · Python

      sentinel

      1. probehand-built JSON-RPC over HTTP, no SDK
      2. catalog52 live rules: MUST · SHOULD · SENTINEL/ beyond-spec, each with a citation or a rationale
      3. gradePASS · FAIL · INDETERMINATE · N/A, then the gate
      4. reporttext · JSON · SARIF for GitHub code scanning

      any endpoint URL

      broker Go · 2026-07-28 native

      • Envoy routes and authorizes on Mcp-Method/Mcp-Name, with no body-parsing filter
      • Stateless: cross-call state is a principal-bound handle, re-verified on every use
      • MRTR with exactly-once effects: a duplicate retry replays the recorded result
      • Exact-audience tokens; hash-chained, append-only audit log in Postgres

      oracle fixtures Python

      • non-conformant: tags each seeded violation in its own source
      • conformant: a minimal correct server. Any FAIL against it is a false positive
      Broker claims are summarized from the README. The rule count is the length of the scan reports on this page.

      Run it yourself

      Requires Go 1.23+, Python 3.12, uv ≥ 0.5 and Docker. No model API key is needed anywhere. The broker serves tools and never calls a model.

      The whole stack

      make up             # postgres + broker + envoy + smokescreen + otel-collector
      make check          # golangci-lint, go test -race, ruff, mypy, pytest
      make scan-broker    # grade the broker against its own harness
      make scan-fixture   # grade an unmigrated server; expected to exit 1
      make demo           # the nine-step demo

      Scanning your own server

      uv run sentinel scan --endpoint https://your-server.example/mcp --gate must \
        --token "$TOKEN" --format sarif --out scan.sarif
      uv run sentinel deprecations --endpoint https://your-server.example/mcp

      Regenerating this page's data

      bash site/data/regenerate.sh 2026-09-29

      The script header lists the prerequisites: the broker, both fixtures, and a dev token from broker mint-token.

      Commands quoted from the repository README.