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.

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:

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

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

# ~/.local/share/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/.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.

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
# ~/.local/share/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/.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"
]
}
}
}

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.

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:

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
4 2026-04-24T01:55:09Z default issue_write
3 2026-04-24T01:48:55Z default list_issues
2 2026-04-24T01:44:20Z default list_pull_requests
1 2026-04-24T01:40:02Z default get_issue

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

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.