Skip to content

Codex Integration

OpenAI Codex (CLI and IDE extension) stores MCP configuration in ~/.codex/config.toml. The Agent Receipts proxy wraps any MCP server transparently — Codex doesn’t know or care that the proxy is there.

  • mcp-proxy installed

  • A signing key pair generated (see below)

  • Codex installed (npm install -g @openai/codex or via the IDE extension)

  • The MCP server you want to audit. The examples below wrap 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

Re-running init is safe — it warns and skips if the key already exists. Use absolute paths everywhere — Codex launches MCP servers with a clean environment where ~ expansion and $PATH may not behave as expected.

Use codex mcp add to register the proxy wrapping any MCP server. The shell resolves the proxy, key, and server paths at paste time. Pick whichever secrets pattern below matches your setup; do not pass --env GITHUB_PERSONAL_ACCESS_TOKEN=… in the recommended or fallback forms — the value would be persisted to config.toml verbatim, defeating the point.

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

Register op run as the command — it resolves op:// references at exec time and injects them into the proxy’s env without touching disk:

Terminal window
codex mcp add github-audited \
-- "$(which op)" run "--env-file=$HOME/.agent-receipts/mcp.env" -- \
"$(which mcp-proxy)" \
-name github \
-key "$HOME/.agent-receipts/github-proxy.pem" \
-issuer-name Codex \
-operator-id did:web:openai.com \
-operator-name OpenAI \
"$(which github-mcp-server)" stdio

aws-vault exec, chamber exec, and direnv with op:// references follow the same wrapping pattern.

Reuse the launcher script described in Claude Desktop’s keychain fallback (one script works across clients). Register the script path as Codex’s command:

Terminal window
codex mcp add github-audited \
-- "$HOME/.agent-receipts/run-mcp-proxy-github.sh" \
-name github \
-key "$HOME/.agent-receipts/github-proxy.pem" \
-issuer-name Codex \
-operator-id did:web:openai.com \
-operator-name OpenAI \
"$(which github-mcp-server)" stdio

For kicking the tyres against a throwaway PAT. Treat config.toml as compromised the moment you save a real credential, and rotate before moving to either pattern above.

Terminal window
codex mcp add github-audited \
--env GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_TOKEN \
-- "$(which mcp-proxy)" \
-name github \
-key "$HOME/.agent-receipts/github-proxy.pem" \
-issuer-name Codex \
-operator-id did:web:openai.com \
-operator-name OpenAI \
"$(which github-mcp-server)" stdio

Add --scope user to any of the above to make the server available across all projects (default is project-scoped).

-issuer-name, -operator-id, and -operator-name stamp the signed receipt with the agent and the organisation running it. Setting -issuer-name to Codex here (and to Claude Code in the Claude Code integration) is what lets you tell at receipt-inspection time which client made a given call — without it, every receipt just shows the default did:agent:mcp-proxy issuer. See the configuration reference for the full set of identity flags.

Alternatively, edit ~/.codex/config.toml directly. TOML doesn’t shell-expand and Codex doesn’t expand ${VAR} in env tables, so use the same secrets patterns as the CLI form above. Print your absolute paths first:

Terminal window
echo "command: $(which mcp-proxy)"
echo "key: $HOME/.agent-receipts/github-proxy.pem"
echo "server: $(which github-mcp-server)"
echo "op: $(which op)"

The recommended (secret-manager) form — op run resolves the op:// reference in mcp.env at exec time, no env table needed in config.toml:

[mcp_servers.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", "Codex",
"-operator-id", "did:web:openai.com",
"-operator-name", "OpenAI",
"/opt/homebrew/bin/github-mcp-server", "stdio"
]
enabled = true

The keychain-launcher and demo-only equivalents follow the same shape — for the launcher, set command to the launcher script path and drop the env table (the script sets GITHUB_PERSONAL_ACCESS_TOKEN); for the demo path, use the original command = "/path/to/mcp-proxy" form and add [mcp_servers.github-audited.env] with the literal token (throwaway PATs only).

For project-scoped setup, place the same config in .codex/config.toml at the project root (only applies in trusted projects).

Verify the server is registered:

Terminal window
codex mcp get github-audited

Or check active servers inside the Codex TUI with /mcp.

After making tool calls through Codex, 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:58b9c7ff... github create_pull_request data.api.write medium success 2026-04-15T00:06:48Z
urn:receipt:3384715f... github get_pull_request data.api.read low success 2026-04-15T00:06:26Z
urn:receipt:c2e7b34f... github push_files data.api.write medium success 2026-04-15T00:01:39Z
urn:receipt:ccc6860a... github list_issues data.api.read low success 2026-04-14T23:54:09Z
4 receipts

The SERVER column reflects the -name github flag you passed to mcp-proxy. The -issuer-name Codex flag stamps each receipt so you can tell Codex sessions apart from Claude Code or Claude Desktop when reviewing a shared audit store — that issuer/operator metadata doesn’t appear in the tabular view, but it’s visible via mcp-proxy list -json.

Absolute paths required. Codex 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.

TOML syntax for args. Unlike JSON (Claude Desktop) or the -- CLI pattern (Claude Code), Codex config.toml uses a TOML array for args. Each flag and its value must be a separate string in the array.

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.

Want human-in-the-loop approvals? Opt in with -http. The approval listener is off by default. If your server exposes tools that cross the risk-score threshold (e.g. create_token = 50, update_auth_config = 70), pass -http 127.0.0.1:<port> and run an approver — see Approval Server. Without it, a paused call fails immediately with JSON-RPC code -32003 (no approver configured). To prevent pausing entirely, drop pause/block rules from a custom -rules YAML.