MCP server: One MCP server.

Bernstein

@sipyourdrink-ltdMCP server · External

Verifies Bernstein run receipts and hash chains; lists the shipped presets and adapters. Read-only.

v0.2.0Apache-2.0TypeScript
Freeno charge per call

One address for any MCP client. No sign-in needed on this server.

bernstein-mcp
From the README

What it does

10 read1 other

Grouped by tool name. At most: only reads or looks up information.

What it costs

Free

Odel charges nothing per call. The publisher may charge for its own service.

Tools

11 · grouped by tool name · checked 24 Oct 2026

Read · 10Look things up

  • verify_receipt
  • explain_receipt
  • verify_chain
  • verify_trace_record
  • verify_agent_manifest
  • verify_delegation_chain
  • explain_trace_mapping
  • list_presets
  • get_preset
  • list_adapters

Other · 1Neither hinted nor named

  • server_info
Try it in the Inspector
README4 min read

bernstein-mcp

bernstein-mcp

Stateless, read-only MCP endpoint at https://mcp.bernstein.run that verifies bernstein run receipts and hash chains. No account, no key, nothing stored, nothing fetched.

claude mcp add --transport http bernstein https://mcp.bernstein.run/mcp

What it does

ToolResult
verify_receiptrecomputes every chain a run receipt embeds, rebuilds the signed subject, checks the Ed25519 signature; verdict + one line per check, plus the verdict as a signed statement (below)
explain_receiptthe same verification, narrated: what the run recorded, where it diverges, what the result does and does not prove
verify_chainwalks journal rows, lineage entries or audit events on their own (pass the file text for byte-exact rows); names the first broken link
verify_trace_recordTRACE v0.2 conformance checks on one Trust Record, stateless, no account: vendored schema, profile rules, the embedded signature with the key in cnf.jwk (EdDSA, ES256, ES384); record_sha256 is the RFC 8785 digest a child hop links to
verify_delegation_chainwalks a set of Trust Records from the leaf to the root and classifies the chain (verified, provenance-invalid, authorization-invalid, unverifiable) with the same codes as the delegation-link corpus
verify_agent_manifeststateless check of a signed agent manifest (v0.2 COSE envelope): vendored schema, profile, canonicalization, embedded signature (Ed25519, P-256, P-384); optional trust record cross-check via references[]; verdicts valid / invalid / unverifiable
explain_trace_mappinghow a bernstein run maps onto a TRACE v0.2 Trust Record, claim by claim; pass a receipt to fill in what its journal answers
list_presets / get_presetthe compliance presets this release ships
list_adaptersthe agent adapters bundled with this release
server_infoversion and limits

Same walk as bernstein verify-receipt, reachable from any MCP client or the paste form at /verify. A verdict's page address is the receipt's own digest.

Trust model

ProvesDoes not prove
the embedded rows are exactly the rows that were signedthat the embedded key belongs to who you think (trust-on-first-use; pin the operator's published key yourself)
nothing was edited, reordered, dropped or appended after signingaudit-range HMAC values (keyed by the producing install; their linkage and content hash are still checked)

Pass the receipt file's contents as a string: an already parsed object cannot tell 1 from 1.0, and the reference hashes the original spelling.

Signed verdicts

Every verdict comes back as a DSSE envelope (signed_verdict) signed with this deployment's Ed25519 key: the payload is a JCS-canonical statement naming the receipt by digest, the verdict, every check, and an appraisal block in the EAR status vocabulary (affirming / contraindicated / none). Keep it next to the receipt; anyone can re-check it offline against the public key at /.well-known/bernstein-mcp/keys.json (kid = RFC 7638 thumbprint). The signature covers the DSSE PAE of application/vnd.bernstein.verdict+json, the same construction the receipt itself uses. It attests that this verifier reached this verdict for these bytes at this time — nothing about the receipt's producer.

Session receipts

bernstein-attest turns a Claude Code or Codex CLI session into a signed run receipt that this server verifies.

bash
npx bernstein-attest init          # registers hooks for both agents (user scope); --claude-code / --codex / --project to narrow
bernstein-attest link              # verify link + one Markdown line for a PR description
bernstein-attest verify .bernstein/receipts/<session>.json

Codex runs project hooks only after they are trusted once with /hooks in an interactive session; codex exec skips untrusted hooks without printing anything. With --project, Claude Code hooks go to .claude/settings.local.json and Codex hooks to .codex/hooks.json; both name the bundle under your home directory, so keep .codex/hooks.json out of version control.

Recorded per tool call: tool name, hashes of its input and output, success flag, repo-relative path for files the call wrote (hash only for paths outside the project), the program name of a shell command (first token, path stripped, at most 32 characters). Not recorded: prompts, model output, command text, file contents, absolute paths. The receipt is sealed at the end of every turn that recorded something new, and every 2 000 rows; the file lives in .bernstein/receipts/ and can be committed with the change it describes. Because later turns reseal the same file, run npx bernstein-attest link right before committing it so the link you paste names the current bytes.

Limits

Request body1 MiB
Rows per chain2 000 (larger receipts: verify locally)
Rate60 requests/min per address on POST /mcp and POST /verify
Loggingone JSON line per request: route, method, status, JSON-RPC method, tool, verdict, producer family, MCP client name/version, country, colo. Never the address, a header, the body or the receipt

Correctness

vectors/ holds eight golden vectors generated by the Python reference (scripts/gen_vectors.py against the pinned bernstein source). The TypeScript verifier must reproduce each vector's verdict, every check, the binding bytes and the receipt digest byte for byte (test/vectors.test.ts). vectors/session/ holds three frozen session receipts written by bernstein-attest (scripts/gen-session-vectors.mjs).

Development

bash
npm install
npm test          # no-fetch guard + vitest
npm run typecheck
npm run dev       # wrangler dev

src/ may not call fetch, eval or new Function; CI fails otherwise. Deploying: see DEPLOY.md. Licence: Apache-2.0.