Unwait

Codex MCP servers: config.toml, the add command, and what the docs skip

· 5 min read codex codex cli mcp config toml integrations ai coding agents

How to add MCP servers to Codex CLI with codex mcp add and config.toml, every key worth knowing, where tokens should live instead of the file, per-tool approval modes, and the version gaps between the docs and the CLI you actually have installed.

Codex keeps MCP servers in config.toml, as [mcp_servers.<name>] tables. You can write those tables by hand or let codex mcp add write them for you. The CLI, the IDE extension, and the desktop app are documented as sharing that one configuration.

Most guides stop at the add command. This one covers the keys that decide whether a server is safe and reliable, and the places where the current docs describe flags that the Codex version on your machine may not have yet. We checked everything below against Codex CLI 0.147.0.

Adding a server

A local stdio server:

codex mcp add context7 -- npx -y @upstash/context7-mcp

A remote streamable HTTP server:

codex mcp add figma --url https://mcp.figma.com/mcp --bearer-token-env-var FIGMA_OAUTH_TOKEN

The usage line explains the shape: codex mcp add [OPTIONS] <NAME> (--url <URL> | -- <COMMAND>...). Every server is either a URL or a command. For a command, the -- is required, and everything after it belongs to the server. Put Codex's own options before the --, or they get passed to the server instead.

Two flags only work for one kind of server:

The other subcommands are list, get, remove, login, and logout. Both list and get accept --json, which is the version to use in scripts.

The same thing in config.toml

[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
env_vars = ["LOCAL_TOKEN"]

[mcp_servers.figma]
url = "https://mcp.figma.com/mcp"
bearer_token_env_var = "FIGMA_OAUTH_TOKEN"
http_headers = { "X-Figma-Region" = "us-east-1" }

Editing the file directly is the only way to reach most of the useful keys below, so it helps to be comfortable with it.

Keep tokens out of the file

config.toml is plain text that gets copied between machines, pasted into chats, and sometimes committed by accident. Two pairs of keys decide whether a secret ends up in it:

The rule is simple: a value that would hurt if the file leaked should be a variable name in the file, not the value itself.

For OAuth servers, codex mcp login <name> runs the flow. Where the credentials are stored is set by the top-level mcp_oauth_credentials_store key, which takes auto, file, or keyring. On a shared machine, choosing keyring explicitly is the safer option.

Approvals per tool

This part has no direct equivalent in most MCP setups, and it is the most useful thing in the schema.

[mcp_servers.github]
url = "https://example.com/mcp"
default_tools_approval_mode = "prompt"

[mcp_servers.github.tools.search_code]
approval_mode = "auto"

default_tools_approval_mode sets the policy for every tool on a server, and tools.<tool>.approval_mode overrides it for a single tool. Both take auto, prompt, writes, or approve. The pattern that works is to set a cautious default for the server and turn on auto only for the read-only tools you trust. That beats deciding a whole server's trust level in one yes-or-no.

You can also narrow what a server exposes in the first place:

tools.<tool>.output_token_limit caps how much of your context a single tool result can use. Servers that return entire documents or long logs are the reason this key exists.

Timeouts and failure modes

The defaults are short, and they are the first thing to check when a server looks broken:

codex -c 'mcp_servers.figma.enabled=false'

Project scope, and the flag that is not there

Codex documents project-scoped MCP servers in .codex/config.toml, for trusted projects only. An untrusted project's .codex/ layer is skipped entirely, and that includes its MCP servers.

What codex mcp add does not have in 0.147.0 is a way to target that file. The command has no --scope flag, so it always writes to your user config. Adding a server to a project means editing .codex/config.toml yourself. Guides that describe a --scope project option are describing something your CLI may not support. Check with codex mcp add --help before you rely on it.

The same applies to OAuth. The current docs describe codex mcp login <name> --oauth-client-registration cimd|dcr for choosing how the client registers. That flag is not in 0.147.0 either, where login accepts --scopes. The docs follow the newest release, and your install may be behind it, so the --help output is the reference that matches the binary you are running.

One open report is worth knowing about if you use the desktop app: issue #13025, filed against 0.104.0, says Codex Desktop loaded MCP servers from ~/.codex/config.toml but ignored a trusted project's .codex/config.toml, even though the docs say the surfaces share configuration. If a project server shows up in the CLI but not in the desktop app, that is the likely reason. Moving the server into your user config is the workaround.

Coming from Claude Code

If you set up MCP in Claude Code first, here is what differs:

A setup worth copying

mcp_oauth_credentials_store = "keyring"

[mcp_servers.docs]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
env_vars = ["CONTEXT7_API_KEY"]
startup_timeout_sec = 30
default_tools_approval_mode = "auto"

[mcp_servers.tracker]
url = "https://mcp.example.com/mcp"
bearer_token_env_var = "TRACKER_TOKEN"
default_tools_approval_mode = "prompt"
disabled_tools = ["delete_issue"]

Read-only documentation servers get auto and a generous startup timeout. Anything that can write gets prompt, and its destructive tools are removed entirely. Tokens stay as variable names, and OAuth credentials go to the keychain.

After any change, run codex mcp list --json to confirm Codex sees the configuration you intended. With startup_timeout_sec and required left at their defaults, a server that fails to start does not raise an error. It just is not there.

Unwait does this for you

A macOS menu bar app that watches your Claude Code and Codex sessions, shows a short card while they work, and puts a strip on screen the moment one finishes. Free for two weeks, no card and no sign up.

Try for free
← All posts