Claude Desktop Integration
Claude Desktop connects to MCP servers via claude_desktop_config.json. The Agent Receipts proxy wraps any MCP server transparently — Claude Desktop 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 -
The MCP server you want to audit. The example below wraps 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 Desktop:
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. To run the daemon as a background service on macOS, see Daemon Setup. Use absolute paths everywhere — Claude Desktop launches MCP servers with a clean environment where ~ expansion and $PATH are not available.
You can scaffold a starting config with mcp-proxy init, which prints a claude_desktop_config.json snippet to paste below.
Configure claude_desktop_config.json
Section titled “Configure claude_desktop_config.json”Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows).
Claude Desktop doesn’t shell-expand config values, so paste absolute paths. On macOS/Linux, print yours:
echo "command: $(which mcp-proxy)"echo "server: $(which github-mcp-server)"On Windows (PowerShell), use (Get-Command mcp-proxy).Source, $env:USERPROFILE, and (Get-Command github-mcp-server).Source to obtain the equivalent values.
If the file doesn’t exist yet, create it.
If it already contains app preferences (for example, {"preferences": {...}}), that’s normal. Add mcpServers as another top-level key rather than replacing the file — the result should look like {"preferences": {...}, "mcpServers": {...}} (mind the comma between sibling keys).
The token needs to reach the MCP server’s environment without being written into the config file. Pick whichever pattern matches your secrets setup; all three produce an equivalent wrapped server, only the credential plumbing differs.
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 Desktop at op run — it resolves the op:// reference at exec time, injects the value into the child process’s env, and never writes the token to disk. Find your op path with which op:
{ "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 Desktop", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "/opt/homebrew/bin/github-mcp-server", "stdio" ] } }}aws-vault exec, chamber exec (AWS Parameter Store), and direnv with op:// references all follow the same wrapping pattern — substitute whichever your team already deploys.
Fallback: OS keychain launcher script
Section titled “Fallback: OS keychain launcher script”If you don’t have a secret manager, store the token in the OS keychain and add a small launcher that execs mcp-proxy with the secret in env. The launcher itself contains no secrets.
macOS — store the token, then create the launcher:
security add-generic-password -s github-mcp -a "$USER" -w# (paste the PAT when prompted)#!/usr/bin/env bash# ~/.local/share/agent-receipts/run-mcp-proxy-github.sh — chmod 700set -euo pipefailGITHUB_PERSONAL_ACCESS_TOKEN="$(security find-generic-password -s github-mcp -a "$USER" -w)" \ exec /Users/YOU/go/bin/mcp-proxy "$@"Linux: swap the keychain calls for secret-tool store --label=github-mcp service github-mcp account "$USER" and secret-tool lookup service github-mcp account "$USER" (matching the same account qualifier on store and lookup avoids ambiguity if you ever store more than one entry under the same service name). Windows: a .ps1 wrapper using the SecretManagement module (Get-Secret github-mcp) plays the same role.
Point Claude Desktop at the launcher — no env block, since the script sets it:
{ "mcpServers": { "github-audited": { "command": "/Users/YOU/.local/share/agent-receipts/run-mcp-proxy-github.sh", "args": [ "-name", "github", "-issuer-name", "Claude Desktop", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "/opt/homebrew/bin/github-mcp-server", "stdio" ] } }}Demo only: literal token
Section titled “Demo only: literal token”Useful for kicking the tyres against a throwaway PAT before wiring up secret management. Treat the file as compromised the moment you save a real credential, and rotate the PAT before moving to either pattern above.
{ "mcpServers": { "github-audited": { "command": "/Users/YOU/go/bin/mcp-proxy", "args": [ "-name", "github", "-issuer-name", "Claude Desktop", "-operator-id", "did:web:anthropic.com", "-operator-name", "Anthropic", "/opt/homebrew/bin/github-mcp-server", "stdio" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_TOKEN" } } }}The approval listener is off by default. If the policy pauses a call (e.g. a high-risk tool your server exposes), it fails immediately with JSON-RPC code -32003 (no approver configured). To enable approvals, add -http 127.0.0.1:<port> to args in any of the three configurations above and run an approver — see Approval Server.
Restart Claude Desktop. The GitHub MCP server now runs behind the proxy — every tool call goes through it transparently.
Verifying receipts
Section titled “Verifying receipts”The daemon signs and stores every tool call. After making calls through Claude Desktop, 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 TYPE4 2026-04-24T01:55:09Z default issue_write3 2026-04-24T01:48:55Z default list_issues2 2026-04-24T01:44:20Z default list_pull_requests1 2026-04-24T01:40:02Z default get_issueagent-receipts verify prints Chain default: VALID (4 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 Desktop 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.
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 Desktop launches the proxied server, or emits fail. Confirm with pgrep -f 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.