---
title: Codex Integration
description: How to route OpenAI Codex MCP servers through the Agent Receipts proxy for cryptographic audit trails.
---

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.

:::note[Approval workflow]
The default policy includes a `pause_high_risk` rule. When you generate a config with `mcp-proxy init`, the snippet includes `-http 127.0.0.1:7778` so the approval listener starts automatically. If you run the proxy manually without `-http`, the listener is off and paused calls fail fast with `-32003`. Pass `--no-approval` to `mcp-proxy init` to generate a snippet without `-http`. See [Approval Server](/mcp-proxy/approval-ui/).
:::

:::danger[Never put secrets in ~/.codex/config.toml]
`~/.codex/config.toml` (and `.codex/config.toml`) is plaintext on disk, and `codex mcp add --env KEY=VALUE` stores whatever you pass it verbatim. Do **not** put real tokens, API keys, or other credentials there. Use a secret-manager wrapper (`op run`, `aws-vault exec`, …) or an OS keychain launcher script — both are documented below. The literal-token snippet at the bottom is a demo-only path; treat the file as compromised the moment you save a real credential to it.
:::

## Prerequisites

- [mcp-proxy installed](/mcp-proxy/installation/)
- 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:

  ```bash
  brew install github-mcp-server
  ```

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

## Generate a signing key

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

## Configure via CLI

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.

### Recommended: secret manager (`op run`)

Install the 1Password CLI (`brew install 1password-cli`), sign in (`op signin`), and create a referenced env file:

```ini
# ~/.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:

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

### Fallback: OS keychain launcher

Reuse the launcher script described in [Claude Desktop's keychain fallback](/mcp-proxy/claude-desktop/#fallback-os-keychain-launcher-script) (one script works across clients). Register the script path as Codex's command:

```bash
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
```

### Demo only: literal token

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.

```bash
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](/mcp-proxy/claude-code/)) 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](/mcp-proxy/configuration/#cli-flags) for the full set of identity flags.

## Configure via config.toml

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:

```bash
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`:

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

```bash
codex mcp get github-audited
```

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

## Verifying receipts

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

```bash
# 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`.

## Gotchas

**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](/mcp-proxy/approval-ui/). 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.
