Installation
Install
Section titled “Install”Homebrew (macOS, Linux)
Section titled “Homebrew (macOS, Linux)”brew install agent-receipts/tap/obsignaPrebuilt binaries
Section titled “Prebuilt binaries”Download the obsigna_<version>_<os>_<arch> tarball for your platform (darwin/linux, amd64/arm64) from the releases page and move obsigna-mcp (and the mcp-proxy shim, if you still rely on the old name) onto your $PATH.
From source
Section titled “From source”go install github.com/agent-receipts/ar/mcp-proxy/cmd/mcp-proxy@latestRequires Go 1.26.1+. No CGO or external C libraries needed — the proxy builds as a single static binary. (It holds no store of its own; the receipt database lives in obsigna-daemon.)
Verify installation
Section titled “Verify installation”mcp-proxy -versionIf mcp-proxy isn’t found after go install (bash/zsh say command not found; fish says Unknown command), the Go bin directory isn’t on your $PATH. go install writes binaries to $GOBIN when it’s set, otherwise to $(go env GOPATH)/bin (usually ~/go/bin). Add whichever applies to your shell profile:
# bash / zshexport PATH="$(go env GOPATH)/bin:$PATH"# fishfish_add_path (go env GOPATH)/binBasic usage
Section titled “Basic usage”Wrap any MCP server by passing its command as arguments. For a quick smoke test, use the official filesystem MCP server (requires Node.js/npx — if you don’t have it, substitute any MCP server command you already have):
mcp-proxy npx -y @modelcontextprotocol/server-filesystem ~/DocumentsThe proxy intercepts stdin/stdout, scores and classifies every tool call, applies policy, and forwards messages transparently. Completed events are emitted to obsigna-daemon over the --socket path (defaults to the platform socket; set --socket="" to disable emission) — the daemon signs, chains, and stores each receipt. The proxy holds no signing key and no store of its own (ADR-0010). Press Ctrl-C to stop.
For wiring the proxy into an actual client, jump to Claude Code, Claude Desktop, Codex, Cursor, Windsurf, VS Code Copilot, JetBrains AI Assistant, or Cline.
Approval server (opt-in)
Section titled “Approval server (opt-in)”The default policy contains pause_high_risk (min_risk_score: 50), but the approval listener is off by default. A paused call without a listener configured fails immediately with JSON-RPC code -32003 (no approver configured…) — a fast, obvious failure rather than a 60-second timeout.
Most GitHub MCP tools don’t reach the threshold — create_pull_request scores 20, merge_pull_request scores 10, reads score 0. Combinations that actually cross 50: write + sensitive keyword (create_token = 50, update_auth_config = 70), delete + sensitive (delete_credential = 70), delete + config (delete_config = 60), execute + SQL-no-WHERE (60). Plain writes, plain deletes (40), update_config alone (40), and sensitive-keyword reads like get_token (30) do not pause.
If you want human-in-the-loop approvals: this section is for you. Pass -http 127.0.0.1:<port> to start the listener, then run an approver against it. The dedicated Approval Server page documents the HTTP routes (POST /api/tool-calls/{id}/approve and /deny) and shows a minimal shell approver.
If you don’t want approvals at all: omit -http (the default) and paused calls will fail fast. To prevent pausing entirely, load a custom -rules YAML with no pause or block rules — see opting out.
Seeing -32002 on a tool that shouldn’t pause? It’s most likely client-side denial by the MCP client (e.g. Claude Code), not the proxy. See the -32002 troubleshooting entry for how to distinguish the two sources.
Signing keys live in the daemon
Section titled “Signing keys live in the daemon”mcp-proxy no longer holds a signing key — obsigna-daemon owns the Ed25519 key and is the sole writer of receipts (ADR-0010). Generate the key once and start the daemon:
obsigna-daemon --init # one-time: generates the signing key pairobsigna-daemon # start the daemon (listens on a Unix socket)mcp-proxy init is a convenience that scaffolds a client config: it creates the data directory (~/.local/share/agent-receipts/) and prints a claude_desktop_config.json starter snippet. It does not generate keys.
mcp-proxy init # print a starter snippet for the "default" instancemcp-proxy init --name github # label the snippet for a specific serverOnce the daemon is running, the proxy reaches it over the default platform socket automatically:
mcp-proxy npx -y @modelcontextprotocol/server-filesystem ~/DocumentsSee Daemon Setup for key paths, socket configuration, and running the daemon as a service.
Next steps
Section titled “Next steps”- Approval Server — opt-in human-in-the-loop approval workflow
- Configuration for CLI flags, policy rules, redaction, and encryption
- CLI Commands for querying and verifying the audit trail