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”-
A signing key pair generated (see below)
-
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.
Generate a signing key
Section titled “Generate a signing key”mcp-proxy init --name github-proxy# creates ~/.agent-receipts/github-proxy.pem (0600) and ~/.agent-receipts/github-proxy.pem.pub# prints a claude_desktop_config.json snippet — paste it as a starting pointRe-running init is safe — it warns and skips if the key already exists. Use absolute paths everywhere — Claude Desktop launches MCP servers with a clean environment where ~ expansion and $PATH are not available.
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 "key: $HOME/.agent-receipts/github-proxy.pem"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:
# ~/.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/.agent-receipts/mcp.env", "--", "/Users/YOU/go/bin/mcp-proxy", "-name", "github", "-key", "/Users/YOU/.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" ] } }}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# ~/.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/.agent-receipts/run-mcp-proxy-github.sh", "args": [ "-name", "github", "-key", "/Users/YOU/.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" ] } }}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", "-key", "/Users/YOU/.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" ], "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”After making tool calls, inspect the receipt store from your terminal:
# List all receipts (uses the default ~/.agent-receipts/receipts.db)mcp-proxy list
# Verify chain integritymcp-proxy verify \ -key ~/.agent-receipts/github-proxy.pem.pub \ <chain-id>$ mcp-proxy listID SERVER TOOL ACTION RISK STATUS TIMESTAMP---urn:receipt:64b00b98... github issue_write data.api.write medium success 2026-04-24T01:55:09Zurn: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:07Zurn:receipt:a125fd30... github list_pull_requests data.api.read low success 2026-04-24T01:44:20Z
4 receiptsThe SERVER column reflects the -name github flag you passed to mcp-proxy. Read operations show data.api.read / low; writes show data.api.write / medium.
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.
Per-session chain IDs. By default the proxy generates a new chain ID each session. Pass -chain <id> to persist a chain across sessions.
Old receipts show unknown. If you upgraded from a version before v0.2.0, existing receipts in the DB will always show Action: unknown — the tool name was never stored. Clear the DB and start fresh after upgrading.