
Ed25519 signed receipts + Cedar policies for AI agents. Finance mandate gate (Legate), proof packs, 3 IETF Internet-Drafts. npx protect-mcp
Fail-closed Cedar policy gate plus signed receipts for AI agent tool calls.
protect-mcp is a gate that sits in front of an AI agent's tool calls. It evaluates
each call against a Cedar policy (the same language
AWS uses for IAM), blocks what breaks the rules before it runs, and signs an
offline-verifiable Ed25519 receipt of every decision. It runs locally, sends no
telemetry of your decisions anywhere, and is MIT licensed.
would_deny: true, so a failure is never silent.serve --enforce and doctor run a startup
self-test and refuse to arm the gate unless they can show that a known-forbidden
action is actually denied. A gate that cannot prove it denies does not start.@veritasacta/verify.
No vendor trust required: the math does not care who runs it.# 1. Generate an Ed25519 keypair, config template, and sample policy.
npx protect-mcp init
# 2. Wrap any MCP server in shadow mode. Nothing is blocked yet; calls are logged.
npx protect-mcp wrap -- node your-mcp-server.js
# 3. Inspect the local-only dashboard: tool inventory, risk, approvals, receipts.
npx protect-mcp dashboard --open
# 4. Draft a reviewable policy from observed calls.
npx protect-mcp recommend --write
# 5. When reviewed, restart the wrapper in enforce mode with that policy.
npx protect-mcp --policy protect-mcp.recommended.json --enforce -- node your-mcp-server.js
For Claude Desktop, run a dry-run config patch first, then apply it:
npx protect-mcp wrap --claude-desktop
npx protect-mcp wrap --claude-desktop --write
npx protect-mcp dashboard --open
The dashboard binds to 127.0.0.1, reads only local log/receipt files, and does
not upload anything. Use npx protect-mcp connect only if you explicitly want a
hosted ScopeBlind dashboard.
If you would rather call the gate as tools than wire the Claude Code hooks, run it as an MCP server:
npx protect-mcp mcp
It speaks MCP over stdio and exposes four read-only tools, the whole loop:
evaluate_action: decide a proposed tool call against an inline Cedar policy, fail-closed (any policy error is DENY). Returns { allowed, decision, reason, policy_digest }.sign_decision: turn a decision into an Ed25519 signed receipt (a denial signs a gateway_restraint, an allow a decision_receipt). Returns the receipt and its public key; generates an ephemeral key if you do not supply one.verify_receipt: verify a signed receipt offline against a public key. Returns { valid, error, type, kid, issuer }.self_test: prove it, no inputs. A known-forbidden action is denied, then a signed receipt round-trips and a tampered copy fails.Point any MCP host at it, for example Claude Desktop:
{
"mcpServers": {
"protect-mcp": { "command": "npx", "args": ["-y", "protect-mcp", "mcp"] }
}
}
Receipts are byte-compatible with the ones the gate signs at runtime, so a
receipt minted here verifies with @veritasacta/verify
and the browser verifier just the same.
protect-mcp dashboard is the operator view for moving from visibility to
enforcement:
Require approval,
Block, or Observe. Restart the wrapper after reviewing changes.For live desktop fallback approvals, start the dashboard with the local gateway approval endpoint and nonce printed by the wrapper:
npx protect-mcp dashboard --open \
--approval-endpoint http://127.0.0.1:9876 \
--approval-nonce "$PROTECT_MCP_APPROVAL_NONCE"
Approve forwards to the live local gateway when those flags are present.
Deny, Edit, and Take over are recorded locally as approval-resolution
records; use them as the operator instruction and rerun the tool when needed.
Local self-signed receipts stay free and offline-verifiable. The paid boundary is independent evidence that ScopeBlind saw a receipt digest at a time, under an org identity, without receiving the raw prompt, tool payload, output, private key, or raw receipt.
# Create or refresh a local org identity and public-key directory.
npx protect-mcp registry init --org "Meridian Global Macro" --billing-account acct_meridian
# Local preview: writes a digest registry and shareable static verifier page.
npx protect-mcp registry anchor
# Hosted mode: uploads receipt digests only for independent anchoring.
SCOPEBLIND_TOKEN=... npx protect-mcp registry anchor \
--hosted \
--endpoint https://api.scopeblind.com \
--verifier-base https://scopeblind.com
The local preview is deliberately labeled local-preview-not-independent.
Hosted mode anchors only receipt hashes, request ids, org public keys, and
billing metadata. It does not upload raw receipts or sensitive context.
protect-mcp killer-demo generates a complete three-minute sales/demo pack:
npx protect-mcp killer-demo --dir ./scopeblind-demo
It creates mock filesystem, GitHub, email, and PMS activity; shows risky calls in shadow mode; applies a policy pack; requires approval for a sensitive PMS booking; executes through the gateway; writes a signed receipt; proves the original receipt verifies; proves a tampered receipt fails; and creates a selective disclosure package that hides sensitive context while showing the minimum proof.
Open the generated DEMO-RUNBOOK.md first. Then run the printed dashboard
command to walk a customer through the exact sequence.
Commitment-mode receipts can carry a committed_fields_root instead of exposing
every field in cleartext. Later, the holder can disclose selected fields only:
npx protect-mcp verify-disclosure \
--receipt ./receipts/selective-disclosure.receipt.json \
--disclosure ./receipts/selective-disclosure.tool-only.json