Skip to content

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.

  • mcp-proxy installed

  • 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-server

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

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

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

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:

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

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

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

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:

Terminal window
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 700
set -euo pipefail
GITHUB_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"
]
}
}
}

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.

After making tool calls, inspect the receipt store from your terminal:

Terminal window
# List all receipts (uses the default ~/.agent-receipts/receipts.db)
mcp-proxy list
# Verify chain integrity
mcp-proxy verify \
-key ~/.agent-receipts/github-proxy.pem.pub \
<chain-id>
$ mcp-proxy list
ID SERVER TOOL ACTION RISK STATUS TIMESTAMP
---
urn:receipt:64b00b98... github issue_write data.api.write medium success 2026-04-24T01:55:09Z
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
urn:receipt:a125fd30... github list_pull_requests data.api.read low success 2026-04-24T01:44:20Z
4 receipts

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

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.