> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neuraltrust.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Codex

> Add a TrustGate MCP consumer to Codex — config.toml streamable HTTP, OAuth login, header auth, and tool policy.

Codex connects to TrustGate as a **streamable HTTP** MCP server. One entry covers the
Codex CLI, the ChatGPT desktop app, and the IDE extension: they share the same
`config.toml` for a given Codex host.

Copy the endpoint from the [MCP consumer](/trustgate/mcp/overview) **Connect** tab:

```text theme={null}
https://<mcp-host>/<consumer-slug>/mcp
```

MCP credentials are consumer credentials — OAuth, or an API key prefixed `ag_`. A TrustGuard
collector key (`tgk_…`) never authenticates MCP.

## Where the config lives

| Scope       | Path                   | Notes                                |
| ----------- | ---------------------- | ------------------------------------ |
| **User**    | `~/.codex/config.toml` | Applies to every session             |
| **Project** | `.codex/config.toml`   | Loaded only for **trusted** projects |

Each server is one `[mcp_servers.<name>]` table. The key is snake\_case (`mcp_servers`, not
`mcpServers`). `url` selects HTTP transport; `command` selects stdio. Mixing keys from both
in one table is rejected.

## OAuth consumers (recommended)

`auth` defaults to `oauth`, so the URL is the whole entry:

```toml theme={null}
[mcp_servers.TrustGate]
url = "https://<mcp-host>/<consumer-slug>/mcp"
```

Then log in once:

```bash theme={null}
codex mcp login TrustGate
```

Codex opens the browser, registers a client (CIMD or dynamic registration) against the
discovery documents TrustGate publishes, and stores the tokens. TrustGate exposes
`/.well-known/oauth-authorization-server`, `/.well-known/oauth-protected-resource`, and a
registration endpoint, so no client ID or secret is pasted.

Codex logs in against TrustGate, not against your IdP directly, so nothing has to be
registered per developer. Override the callback only when the machine needs a fixed port or
a non-loopback base, such as a remote devbox:

```toml theme={null}
mcp_oauth_callback_port = 5555
mcp_oauth_callback_url = "https://devbox.example.internal/callback"
```

Codex appends a server-specific callback id to that base. TrustGate accepts `https` URLs,
`http` loopback URLs, and private-use schemes, and rejects anything else with
`invalid_redirect_uri`.

Which IdP backs the login is a consumer setting, attached once in the console — see
[Okta](/trustgate/concepts/authorization/okta) or
[Entra ID](/trustgate/concepts/authorization/entra-id).

## API-key consumers

Keep the key out of the file with `env_http_headers`, which reads the value from the
environment at connect time:

```toml theme={null}
[mcp_servers.TrustGate]
url = "https://<mcp-host>/<consumer-slug>/mcp"
env_http_headers = { "X-AG-API-Key" = "TRUSTGATE_MCP_API_KEY" }
```

Static values, when a shared machine has no environment to read:

```toml theme={null}
[mcp_servers.TrustGate]
url = "https://<mcp-host>/<consumer-slug>/mcp"
http_headers = { "X-AG-API-Key" = "ag_…" }
```

`bearer_token_env_var` also works — TrustGate accepts `Authorization: Bearer ag_…`
alongside `X-AG-API-Key` and `x-api-key`:

```toml theme={null}
[mcp_servers.TrustGate]
url = "https://<mcp-host>/<consumer-slug>/mcp"
bearer_token_env_var = "TRUSTGATE_MCP_API_KEY"
```

Authenticating to TrustGate is separate from authenticating to the upstream servers. For a
registry with **OAuth (forwarded)**, the first call for a user without a stored credential
returns a connect link; after that one authorization TrustGate vaults and refreshes the
credential.

## Private (Hybrid) data plane

Add the gateway slug unless the MCP host already scopes the gateway:

```toml theme={null}
[mcp_servers.TrustGate]
url = "https://<mcp-host>/<consumer-slug>/mcp"
http_headers = { "X-AG-Gateway-Slug" = "<gateway-slug>" }
```

Combine with `env_http_headers` for the API key when the consumer is not OAuth.

## Tool policy and limits

Which tools exist is decided in the NeuralTrust console — consumer **Routing**, or a
[role](/trustgate/concepts/roles) for Identity-based consumers. The keys below are Codex's
own client-side policy over that catalog.

| Key                           | Effect                                                   |
| ----------------------------- | -------------------------------------------------------- |
| `enabled_tools`               | Allow list of tool names                                 |
| `disabled_tools`              | Deny list, applied after `enabled_tools`                 |
| `default_tools_approval_mode` | `auto`, `prompt`, `writes`, or `approve` for this server |
| `tools.<name>.approval_mode`  | Per-tool override                                        |
| `enabled`                     | Turn the server off without deleting the entry           |
| `required`                    | Fail session startup when the server cannot initialize   |
| `startup_timeout_sec`         | Default `10` — raise for cold upstreams                  |
| `tool_timeout_sec`            | Default `60` — raise for slow tools                      |

```toml theme={null}
[mcp_servers.TrustGate]
url = "https://<mcp-host>/<consumer-slug>/mcp"
default_tools_approval_mode = "prompt"
required = true
tool_timeout_sec = 90
```

These keys only bind this machine. Restrict tools on the consumer or role so the limit
holds for every client, and attach the
[Per-Tool Rate Limiter](/trustgate/policies/tool-governance) policy when you need an
execution ceiling on MCP tool calls.

## GUI setup

| Client                  | Steps                                                                                                                  |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **ChatGPT desktop app** | **Settings → MCP servers → Add server** → name, **Streamable HTTP**, URL → **Restart**. Use **Authenticate** for OAuth |
| **IDE extension**       | Gear menu → **MCP servers → Add server** → same fields → **Restart extension**                                         |

Both write the same `config.toml`, so a server added in one client shows up in the others.

## Verify

```bash theme={null}
codex mcp list
```

In the CLI TUI, `/mcp` lists active servers. Then call a tool bound to the consumer and
confirm the request in TrustGate telemetry — see
[Metrics](/trustgate/observability/metrics).

## Troubleshooting

| Symptom                      | Cause                                                                                                                |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Config parse error           | `command` and `url` in the same table, or `mcpServers` instead of `mcp_servers`                                      |
| Server initializes, no tools | Consumer has no bound registries, restrictions exclude everything, or the upstream connect link was never authorized |
| `401` after login            | Revoked `ag_…` key, wrong plane URL, or `X-AG-Gateway-Slug` missing on Hybrid                                        |
| OAuth never completes        | Overridden callback base is not `https`, an `http` loopback, or a private-use scheme (`invalid_redirect_uri`)        |
| Project entry ignored        | Project is not trusted, so `.codex/config.toml` is not loaded                                                        |
| Startup timeouts             | Raise `startup_timeout_sec`; check the data plane can reach each upstream MCP server                                 |

## Related

* [MCP overview](/trustgate/mcp/overview) — consumers, catalog merging, upstream auth
* [Auth](/trustgate/concepts/auth) — MCP consumers use API key or OAuth2
* [TrustGuard Codex](/trustguard/integrations/ide/codex) — firewall hooks (separate plane)
* [Codex MCP docs](https://developers.openai.com/codex/mcp)
