MCP Proxy
The MCP Proxy is a transparent stdin/stdout proxy that sits between an MCP client (Claude Desktop, Claude Code, etc.) and any MCP server. It intercepts every tool call, classifies and scores it, applies proxy-layer policy rules, redacts sensitive data, and signs and stores an Ed25519 receipt locally. When agent-receipts-daemon is configured via --socket, it also forwards events to the daemon for an independently signed and stored chain — without modifying the server or client.
Repository: mcp-proxy/
Features
Section titled “Features”- Risk scoring — scores every tool call 0-100 based on operation type, sensitive keywords, and patterns
- Operation classification — classifies calls as read, write, delete, or execute by tool name
- Action taxonomy — classifies tool calls using configurable taxonomy mappings; GitHub and Atlassian MCP servers are covered by bundled taxonomies out of the box
- MCP prefix stripping — automatically strips
mcp__<server>__prefixes so receipts and classification use clean tool names - Policy rules (proxy layer) — YAML rules engine with four actions: pass, flag, pause (approval required), and block
- Approval workflows (proxy layer) — HTTP endpoints for async approval of paused operations
- Cryptographic receipts — Ed25519-signed W3C Verifiable Credentials, hash-chained per session; events are also forwarded to
agent-receipts-daemonwhen--socketis configured - Issuer identity — receipts identify the AI agent, model, and operator via CLI flags
- Intent tracking — groups related tool calls by temporal proximity
- Data redaction — JSON-aware and pattern-based redaction of secrets before storage
- Encryption at rest — optional AES-256-GCM encryption of audit data
- Audit CLI — list, inspect, verify, export, and query receipts from the command line
How it works
Section titled “How it works”MCP Client (Claude Desktop / Claude Code) | v mcp-proxy (stdin/stdout) | - classify operation | - score risk | - evaluate policy rules | - redact sensitive data (local storage) | - sign receipt (Ed25519) → local SQLite | - forward event (--socket) ─────────────> agent-receipts-daemon v - sign independently MCP Server (any) - append to daemon chainThe proxy reads JSON-RPC messages on stdin, processes tools/call requests, forwards them to the wrapped server, and returns the response. Each tool call produces a locally signed Agent Receipt. When --socket points to a running agent-receipts-daemon, events are also forwarded for an independently signed chain.
Quick start
Section titled “Quick start”# Install (Homebrew, macOS/Linux)brew install agent-receipts/tap/mcp-proxy# …or from source: go install github.com/agent-receipts/ar/mcp-proxy/cmd/mcp-proxy@latest
# Wrap any MCP server (example: the filesystem server via npx)mcp-proxy npx -y @modelcontextprotocol/server-filesystem ~/Documents
# With configuration (example: GitHub's official MCP server — brew install github-mcp-server)# -key sets the local signing key (omit for an ephemeral key).# Daemon forwarding is a separate path configured via --socket — see Daemon Setup.mcp-proxy \ -name github \ -key private.pem \ -rules rules.yaml \ -taxonomy taxonomy.json \ github-mcp-server stdioTo enable the approval workflow, pass -http 127.0.0.1:<port> — see Approval Server.
Claude Desktop integration
Section titled “Claude Desktop integration”Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS). Claude Desktop doesn’t expand ${VAR} in env blocks, so wrap the proxy in a secret manager (op run, aws-vault exec, …) — the snippet below uses 1Password CLI, with the token resolved from op:// at exec time and never written to disk:
{ "mcpServers": { "github-audited": { "command": "/opt/homebrew/bin/op", "args": [ "run", "--env-file=/Users/YOU/.local/share/agent-receipts/mcp.env", "--", "/Users/YOU/go/bin/mcp-proxy", "-name", "github", "-key", "/Users/YOU/.local/share/agent-receipts/github-proxy.pem", "-issuer-name", "Claude Desktop", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "/opt/homebrew/bin/github-mcp-server", "stdio" ] } }}mcp.env references the secret by path (GITHUB_PERSONAL_ACCESS_TOKEN=op://Personal/GitHub/token); see the Claude Desktop integration guide for the OS-keychain-launcher fallback and other patterns.
Claude Code integration
Section titled “Claude Code integration”Claude Code uses claude mcp add-json to register servers. Use --scope user to make the proxy available across all projects:
claude mcp add-json github-audited --scope user '{ "command": "/Users/YOU/go/bin/mcp-proxy", "args": [ "-name", "github", "-key", "/Users/YOU/.local/share/agent-receipts/github-proxy.pem", "-issuer-name", "Claude Code", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "/opt/homebrew/bin/github-mcp-server", "stdio" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" }}'Verify registration:
claude mcp listSee the Claude Code integration guide for a full walkthrough including project-scoped setup and .mcp.json configuration.
What receipts look like
Section titled “What receipts look like”Each tool call produces a signed W3C Verifiable Credential. Key fields shown (abbreviated — full receipts include @context, id, type, issuanceDate, and proof):
{ "issuer": { "id": "did:agent:mcp-proxy", "name": "Claude Code", "operator": { "id": "did:web:anthropic.com", "name": "Anthropic" } }, "credentialSubject": { "principal": { "id": "did:user:otto" }, "action": { "type": "data.api.read", "tool_name": "get_issue", "risk_level": "low", "target": { "system": "github" } }, "outcome": { "status": "success" }, "chain": { "sequence": 1, "previous_receipt_hash": null, "chain_id": "9351bc33-..." } }}Receipts are Ed25519-signed, hash-chained per session, and stored in a local SQLite database. Use mcp-proxy list, mcp-proxy inspect, and mcp-proxy verify to query and validate them.
mcp-proxy list gives a compact tabular view. The SERVER column is populated from the server name (defaulting to the wrapped command’s basename if -name is omitted). When you proxy multiple MCP servers — for example GitHub and Atlassian — the SERVER and TOOL columns let you scan activity across all of them at once:
$ mcp-proxy listID SERVER TOOL ACTION RISK STATUS TIMESTAMP---urn:receipt:b4b430f9... atlassian getJiraIssue data.api.read low success 2026-04-24T02:05:19Zurn:receipt:103200d1... github issue_write data.api.write medium success 2026-04-24T01:58:45Zurn:receipt:32506b71... atlassian searchJiraIssuesUsingJql data.api.read low success 2026-04-24T01:56:12Zurn:receipt:f5da030f... atlassian getAccessibleAtlassianResou... data.api.read low success 2026-04-24T01:56:06Zurn:receipt:276a6c2a... github issue_write data.api.write medium success 2026-04-24T01:48:55Zurn:receipt:a72ee10b... github list_issues data.api.read low success 2026-04-24T01:45:07Z
6 receiptsSee Installation to get started, or Configuration for the full set of options.