Skip to content

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/

  • 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-daemon when --socket is 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

no

yes

approved

denied

timeout

Tool call arrives

Score risk 0-100

Match policy rules — most restrictive wins

pass or flag

Forward to MCP server

pause

Listener configured?

-32003 no approver

Approver responds?

-32002 denied

block

-32001 blocked

Sign receipt and store

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 chain

The 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.

stdio / JSON-RPC

stdio / JSON-RPC

Unix socket

MCP Client

mcp-proxy

MCP Server

agent-receipts-daemon

receipts.db

Terminal window
# 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 stdio

To enable the approval workflow, pass -http 127.0.0.1:<port> — see Approval Server.

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 uses claude mcp add-json to register servers. Use --scope user to make the proxy available across all projects:

Terminal window
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:

Terminal window
claude mcp list

See the Claude Code integration guide for a full walkthrough including project-scoped setup and .mcp.json configuration.

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 list
ID SERVER TOOL ACTION RISK STATUS TIMESTAMP
---
urn:receipt:b4b430f9... atlassian getJiraIssue data.api.read low success 2026-04-24T02:05:19Z
urn:receipt:103200d1... github issue_write data.api.write medium success 2026-04-24T01:58:45Z
urn:receipt:32506b71... atlassian searchJiraIssuesUsingJql data.api.read low success 2026-04-24T01:56:12Z
urn:receipt:f5da030f... atlassian getAccessibleAtlassianResou... data.api.read low success 2026-04-24T01:56:06Z
urn:receipt:276a6c2a... github issue_write data.api.write medium success 2026-04-24T01:48:55Z
urn:receipt:a72ee10b... github list_issues data.api.read low success 2026-04-24T01:45:07Z
6 receipts

See Installation to get started, or Configuration for the full set of options.