Claude Code Integration
Claude Code is a CLI-based agent that connects to MCP servers for tools like GitHub, databases, and file systems. The Agent Receipts proxy wraps any MCP server transparently — Claude Code doesn’t know or care that the proxy is there.
Prerequisites
Section titled “Prerequisites”-
agent-receipts-daemoninstalled, initialised, and running — it holds the signing key and writes every receipt -
Claude Code installed (
npm install -g @anthropic-ai/claude-code) -
The MCP server you want to audit. The examples below wrap GitHub’s official MCP server:
Terminal window brew install github-mcp-serverThis puts a
github-mcp-serverbinary on your$PATH. Verify withwhich github-mcp-server.
Start the daemon
Section titled “Start the daemon”The proxy holds no signing key of its own — agent-receipts-daemon owns the key and writes every receipt (ADR-0010). Initialise the key once and start the daemon before launching Claude Code:
agent-receipts-daemon --init # one-time: generates the Ed25519 signing key pairagent-receipts-daemon # start the daemon (listens on a Unix socket)The proxy reaches the daemon over its default platform socket automatically — no extra flag needed. See Daemon Setup for install options, socket paths, and running it as a service. Use absolute paths everywhere in the config below — Claude Code launches MCP servers with a clean environment where ~ expansion and $PATH may not behave as expected.
Register the proxy with Claude Code
Section titled “Register the proxy with Claude Code”Use claude mcp add-json to register a proxied server. The example below wraps github-mcp-server. Your shell resolves the proxy and server paths at paste time.
The token needs to reach mcp-proxy’s environment without being written into the stored config. Pick whichever pattern matches your secrets setup.
Recommended: secret manager (op run, aws-vault exec, …)
Section titled “Recommended: secret manager (op run, aws-vault exec, …)”Install the 1Password CLI (brew install 1password-cli), sign in (op signin), and create a referenced env file:
# ~/.local/share/agent-receipts/mcp.env (chmod 600)GITHUB_PERSONAL_ACCESS_TOKEN=op://Personal/GitHub/tokenPoint Claude Code at op run — it resolves the op:// reference at exec time and injects the value into mcp-proxy’s env. No env block is needed in the config. Find your op path with which op.
bash / zsh:
# heredoc terminator (JSON) must be alone on its line; closing ) follows on the nextJSON_BODY=$(cat <<JSON{ "command": "$(which op)", "args": [ "run", "--env-file=$HOME/.local/share/agent-receipts/mcp.env", "--", "$(which mcp-proxy)", "-name", "github", "-issuer-name", "Claude Code", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "$(which github-mcp-server)", "stdio" ]}JSON)
claude mcp add-json github-audited --scope user "$JSON_BODY"fish:
set OP (which op)set MCP_PROXY (which mcp-proxy)set GITHUB_MCP (which github-mcp-server)set ENV_FILE $HOME/.local/share/agent-receipts/mcp.env
set json (printf '{ "command": "%s", "args": [ "run", "--env-file=%s", "--", "%s", "-name", "github", "-issuer-name", "Claude Code", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "%s", "stdio" ]}' $OP $ENV_FILE $MCP_PROXY $GITHUB_MCP | string collect)
claude mcp add-json github-audited --scope user "$json"aws-vault exec, chamber exec (AWS Parameter Store), and similar tools follow the same wrapping pattern — substitute whichever your team already deploys.
Alternative: shell environment (Claude Code only)
Section titled “Alternative: shell environment (Claude Code only)”Unlike Claude Desktop, Claude Code expands ${VAR} placeholders in env blocks at server-launch time. This means you can keep the credential in your shell environment and reference it by name in the config.
bash / zsh — \$ escapes the placeholder so bash leaves it intact at paste time:
# heredoc terminator (JSON) must be alone on its line; closing ) follows on the nextJSON_BODY=$(cat <<JSON{ "command": "$(which mcp-proxy)", "args": [ "-name", "github", "-issuer-name", "Claude Code", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "$(which github-mcp-server)", "stdio" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_PERSONAL_ACCESS_TOKEN}" }}JSON)
claude mcp add-json github-audited --scope user "$JSON_BODY"fish (no heredoc support — build JSON via printf instead; the single-quoted format string passes the placeholder through literally):
set MCP_PROXY (which mcp-proxy)set GITHUB_MCP (which github-mcp-server)set json (printf '{ "command": "%s", "args": [ "-name", "github", "-issuer-name", "Claude Code", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "%s", "stdio" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}" }}' $MCP_PROXY $GITHUB_MCP | string collect)
claude mcp add-json github-audited --scope user "$json"Set GITHUB_PERSONAL_ACCESS_TOKEN in your shell rc (~/.zshrc, ~/.config/fish/config.fish, etc.) before launching Claude Code. Verify the placeholder reached the stored config (and was not expanded at paste time) with claude mcp get github-audited.
--scope user makes the server available across all projects. Omit it for project-local scope only.
-issuer-name, -operator-id, and -operator-name stamp the signed receipt with the agent and the organisation running it. Setting -issuer-name to Claude Code here (and to Codex in the Codex integration) is what lets you tell at receipt-inspection time which client made a given call — without it, every receipt just shows the daemon’s default did:agent-receipts-daemon:local issuer. See the configuration reference for the full set of identity flags.
Verify the server is registered:
claude mcp listProject-scoped setup via .mcp.json
Section titled “Project-scoped setup via .mcp.json”For a shared team configuration, add a .mcp.json file at the project root. This is committed to version control — do not put tokens directly in it.
Since .mcp.json is a static JSON file, print the absolute paths you need first and paste them into the template below:
echo "command: $(which mcp-proxy)"echo "server: $(which github-mcp-server)"Recommended: secret manager
Section titled “Recommended: secret manager”Point Claude Code at op run, same as the claude mcp add-json pattern above. Each developer needs ~/.local/share/agent-receipts/mcp.env on their machine with their own op:// reference (or whichever secret manager the team uses).
{ "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", "-issuer-name", "Claude Code", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "/opt/homebrew/bin/github-mcp-server", "stdio" ] } }}Alternative: shell environment
Section titled “Alternative: shell environment”Claude Code expands ${VAR} placeholders at server-launch time, so each developer can set GITHUB_PERSONAL_ACCESS_TOKEN in their shell environment and have it picked up automatically.
{ "mcpServers": { "github-audited": { "command": "/Users/YOU/go/bin/mcp-proxy", "args": [ "-name", "github", "-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}" } } }}The proxy path will need to be consistent across the team, or handled via a wrapper script.
Verifying receipts
Section titled “Verifying receipts”The daemon signs and stores every tool call. After making calls through Claude Code, query and verify the store with the agent-receipts CLI (installed alongside the daemon). It opens the database read-only, so it is safe to run while the daemon is writing:
# List recent receipts (newest first)agent-receipts list
# Verify the chain's signatures and hash linksagent-receipts verify \ --public-key ~/.local/share/agent-receipts/signing.key.pub$ agent-receipts listSEQ TIMESTAMP CHAIN TOOL / ACTION TYPE5 2026-04-24T01:45:07Z default list_issues4 2026-04-24T01:44:20Z default list_pull_requests3 2026-04-24T00:51:57Z default add_reply_to_pull_request2 2026-04-24T00:43:40Z default request_copilot_review1 2026-04-24T00:19:35Z default issue_writeagent-receipts verify prints Chain default: VALID (5 receipts) when signatures and hash links are intact. Inspect a single receipt — including its action type, risk level, and parameters hash — with agent-receipts show <seq>. See the CLI reference for all subcommands.
Gotchas
Section titled “Gotchas”Absolute paths required. Claude Code launches MCP servers with a clean PATH. Use the full path to mcp-proxy (find it with which mcp-proxy) and the full path to the wrapped server binary.
fish shell. Fish does not support heredocs — pasting the bash/zsh snippet as-is fails with Expected a string, but found a redirection. Use the fish alternative above, which builds the JSON via printf and stores it in a variable.
Want human-in-the-loop approvals? Opt in with -http. The approval listener is off by default. If your server exposes tools that cross the risk-score threshold (e.g. create_token = 50, update_auth_config = 70), pass -http 127.0.0.1:<port> and run an approver — see Approval Server. Without it, a paused call fails immediately with JSON-RPC code -32003 (no approver configured). To prevent pausing entirely, drop pause/block rules from a custom -rules YAML.
Classic PATs for org-owned repos. GitHub’s fine-grained PATs can fail for org-level write operations even when permissions appear correct. Use a classic PAT with repo scope for org-owned repositories.
Chain IDs are daemon-managed. The proxy no longer has a -chain flag — chain IDs are assigned by agent-receipts-daemon. By default the daemon writes all receipts to the default chain. Use --chain-id (or AGENTRECEIPTS_CHAIN_ID) on agent-receipts read and verify commands when working with a multi-chain store.
No receipts appearing? The daemon must be running before Claude Code launches the proxied server, or emits fail. Confirm with pgrep agent-receipts-daemon, and see the daemon troubleshooting guide. If you run the daemon on a non-default socket, set AGENTRECEIPTS_SOCKET for both the daemon and the proxy.