Skip to content

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.

  • mcp-proxy installed

  • agent-receipts-daemon installed, 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-server

    This puts a github-mcp-server binary on your $PATH. Verify with which github-mcp-server.

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:

Terminal window
agent-receipts-daemon --init # one-time: generates the Ed25519 signing key pair
agent-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.

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.

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/token

Point 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:

Terminal window
# heredoc terminator (JSON) must be alone on its line; closing ) follows on the next
JSON_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:

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

Terminal window
# heredoc terminator (JSON) must be alone on its line; closing ) follows on the next
JSON_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):

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

Terminal window
claude mcp list

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:

Terminal window
echo "command: $(which mcp-proxy)"
echo "server: $(which github-mcp-server)"

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"
]
}
}
}

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.

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:

Terminal window
# List recent receipts (newest first)
agent-receipts list
# Verify the chain's signatures and hash links
agent-receipts verify \
--public-key ~/.local/share/agent-receipts/signing.key.pub
$ agent-receipts list
SEQ TIMESTAMP CHAIN TOOL / ACTION TYPE
5 2026-04-24T01:45:07Z default list_issues
4 2026-04-24T01:44:20Z default list_pull_requests
3 2026-04-24T00:51:57Z default add_reply_to_pull_request
2 2026-04-24T00:43:40Z default request_copilot_review
1 2026-04-24T00:19:35Z default issue_write

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

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.