Codex MCP setup comes down to one shared file: Codex stores MCP server configuration in config.toml, and the ChatGPT desktop app, Codex CLI and IDE extension all read it, according to OpenAI’s Model Context Protocol page. You add servers with codex mcp add or by editing [mcp_servers.<server-name>] tables by hand.
Applies to: Codex CLI, Codex IDE extension and the ChatGPT desktop app, per OpenAI’s MCP documentation. Last checked: October 23, 2026.
On this page
Where Codex keeps MCP configuration
OpenAI’s docs name two locations (source):
~/.codex/config.toml: the default, user-level file..codex/config.tomlin a project: scopes MCP servers to that project, for trusted projects only.
Because the desktop app, CLI and IDE extension share this configuration for the same Codex host, a server configured once is available when you switch between them. If you are deciding which of those surfaces to use, the Codex CLI vs Codex app vs IDE extension guide compares them.
Codex supports two kinds of servers, as listed in its supported MCP features:
| Server type | How Codex reaches it | Authentication the docs list |
|---|---|---|
| STDIO | Starts a local process with a command | Environment variables |
| Streamable HTTP | Connects to a server address | Bearer token, OAuth (including CIMD and DCR), ChatGPT session for trusted first-party servers |
The MCP stdio vs Streamable HTTP guide explains the difference between the two transports at the protocol level.
Add a server with the CLI
OpenAI’s general form for a local stdio server is:
codex mcp add <server-name> --env VAR1=VALUE1 --env VAR2=VALUE2 -- <stdio server-command>
Its example adds Context7, a server for developer documentation:
codex mcp add context7 -- npx -y @upstash/context7-mcp
Other commands from the same docs page:
codex mcp listshows configured servers.codex mcp --helplists every MCP subcommand.codex mcp login <server-name>starts an OAuth login for a server that supports it./mcpinside thecodexterminal UI shows your active MCP servers.
Context7 also has a listing with setup for other clients in the MCP directory.
Configure servers in config.toml
For finer control, edit the file directly. Each server is a [mcp_servers.<server-name>] table. This is OpenAI’s stdio example:
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
env_vars = ["LOCAL_TOKEN"]
[mcp_servers.context7.env]
MY_ENV_VAR = "MY_ENV_VALUE"
Stdio servers take command (required), args, env (variables to set), env_vars (variables to allow and forward), cwd and experimental_environment, which can be set to remote to start the server through a remote executor environment when one is available (OpenAI).
A Streamable HTTP server takes a url instead. OpenAI’s Figma example sends a bearer token read from an environment variable plus a static header:
[mcp_servers.figma]
url = "https://mcp.figma.com/mcp"
bearer_token_env_var = "FIGMA_OAUTH_TOKEN"
http_headers = { "X-Figma-Region" = "us-east-1" }
The documented HTTP keys are url, auth (oauth, the default, or chatgpt for the trusted first-party ChatGPT origin), bearer_token_env_var, http_headers, env_http_headers and http_headers_helper, a local command that prints a JSON object of headers (OpenAI). If no credential source resolves, Codex can connect without authentication.
The full list of options is in OpenAI’s configuration reference.
Limit tools, timeouts and approvals
These keys apply to any server (OpenAI):
| Key | What it does | Default |
|---|---|---|
startup_timeout_sec | Seconds to wait for the server to start | 10 |
tool_timeout_sec | Seconds to wait for a tool to run | 60 |
enabled | false disables a server without deleting it | — |
required | true makes startup fail if this enabled server can’t initialize | — |
enabled_tools | Tool allow list | — |
disabled_tools | Tool deny list, applied after enabled_tools | — |
default_tools_approval_mode | auto, prompt, writes or approve; writes prompts for tools that aren’t marked read-only | — |
tools.<tool>.approval_mode | Per-tool approval override | — |
tools.<tool>.output_token_limit | Token budget for one tool’s output | — |
OpenAI’s example combines several of them for a local Chrome DevTools server:
[mcp_servers.chrome_devtools]
url = "http://localhost:3000/mcp"
enabled_tools = ["open", "screenshot"]
disabled_tools = ["screenshot"] # applied after enabled_tools
default_tools_approval_mode = "prompt"
startup_timeout_sec = 20
tool_timeout_sec = 45
enabled = true
[mcp_servers.chrome_devtools.tools.open]
approval_mode = "approve"
output_token_limit = 30000
The top-level mcp_optional_startup_grace_ms setting controls how long Codex waits for optional servers when it builds the initial tool catalog. It defaults to 1000 milliseconds; 0 waits for each server’s startup_timeout_sec.
Sign in to OAuth servers
Run codex mcp login <server-name> to start an OAuth login. When the authorization server requires a pre-registered client, pass its ID when adding the server, per OpenAI’s OAuth section:
codex mcp add example --url https://mcp.example.com --oauth-client-id my-client
For a confidential client, OpenAI’s example reads the secret from an environment variable:
codex mcp add example --url https://mcp.example.com --oauth-client-id my-client --oauth-client-secret "$MCP_CLIENT_SECRET"
Codex saves that secret as mcp_servers.example.oauth.client_secret in config.toml. OpenAI’s instruction is to keep that file private and out of version control. Codex also prints the callback URL to register with your provider; OpenAI says to always register the exact callback displayed by codex mcp add.
Other documented OAuth settings:
mcp_oauth_callback_port: a fixed global listener port. Without it, Codex picks an ephemeral port.mcp_oauth_callback_url: a custom callback path or remote ingress URL.mcp_servers.<server-name>.scopes: OAuth scopes for one server.codex mcp login <name> --scopes read,writeoverrides them for one login.codex mcp login <server-name> --oauth-client-registration cimdordcr: picks a client registration method for one login; the default isauto.
MCP servers that come with plugins
Installed plugins can bundle MCP servers in their manifest. You don’t set their launch command, but user config can still switch them on or off and set tool policy under plugins.<plugin>.mcp_servers.<server>. This is OpenAI’s example:
[plugins."sample@test".mcp_servers.sample]
enabled = true
default_tools_approval_mode = "prompt"
enabled_tools = ["read", "search"]
[plugins."sample@test".mcp_servers.sample.tools.search]
approval_mode = "approve"





