About bernstein-mcp
bernstein-mcp is a stateless, read-only MCP endpoint for checking bernstein run receipts, hash chains, Trust Records, and signed agent manifests. It returns verification checks and signed verdicts without storing or fetching data.
Key features
- 01Verify receipts and hash chains
- 02Check TRACE Trust Records
- 03Validate signed agent manifests
- 04Explain receipt and TRACE mappings
- 05List presets and bundled adapters
- 06Return signed verification verdicts
Use cases
- 01Check a run receipt before relying on it
- 02Locate the first broken link in a chain
- 03Assess a delegation chain
- 04Keep a signed verdict with a receipt
MCP support
Exposes read-only verification, explanation, and listing tools to MCP clients over the endpoint at https://mcp.bernstein.run/mcp.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://mcp.bernstein.run/mcpclaude mcp add --transport http sipyourdrink-ltd-bernstein https://mcp.bernstein.run/mcp{"mcpServers":{"sipyourdrink-ltd-bernstein":{"type":"http","url":"https://mcp.bernstein.run/mcp"}}}Open in Cursor{"servers":{"sipyourdrink-ltd-bernstein":{"type":"http","url":"https://mcp.bernstein.run/mcp"}}}Open in VS Code{"mcpServers":{"sipyourdrink-ltd-bernstein":{"type":"http","url":"https://mcp.bernstein.run/mcp"}}}{"mcpServers":{"sipyourdrink-ltd-bernstein":{"serverUrl":"https://mcp.bernstein.run/mcp"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
Tools
11This tool takes no parameters.
Details
From the project README
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
| Tool | Result |
|---|---|
verify_receipt | recomputes 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_receipt | the same verification, narrated: what the run recorded, where it diverges, what the result does and does not prove |
verify_chain | walks 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_record | TRACE 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_chain | walks 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_manifest | stateless 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_mapping | how 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_preset | the compliance presets this release ships |
list_adapters | the agent adapters bundled with this release |
server_info | version 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
| Proves | Does not prove |
|---|---|
| the embedded rows are exactly the rows that were signed | that 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 signing | audit-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.
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 body | 1 MiB |
| Rows per chain | 2 000 (larger receipts: verify locally) |
| Rate | 60 requests/min per address on POST /mcp and POST /verify |
| Logging | one 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
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.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.