Codex CLI MCP server not loading from config.toml: the fixes
By Jake Marsh, who builds Taskhold. Updated 2026-10-31. Facts about other tools checked 2026-10-31. 5 min read.
Short answer: Run codex mcp list, then /mcp verbose inside Codex. Servers must be [mcp_servers.<name>] tables in ~/.codex/config.toml, or in a project .codex/config.toml, which loads only in trusted projects. Startup times out after 10 seconds by default, and stdio servers get only a short list of your environment variables.
You added an MCP server to ~/.codex/config.toml, started Codex, and the tools aren't there. The usual causes are a table Codex doesn't read, a project file it skips, a server that times out or never gets its API key, and tools filtered out by config. This guide shows how to tell which one you have and the fix for each.
The last section covers Taskhold's own server, which feeds the live board where Codex's tasks and steps show up. Setup is on the Codex page, and Taskhold's error codes are in Taskhold troubleshooting.
Start with codex mcp list and /mcp
Run codex mcp list in a terminal to see the servers Codex found in its config. Inside a session, /mcp lists the servers and tools Codex can call right now, and /mcp verbose adds diagnostics for each server. /debug-config prints every config layer in order, so you can see which file a setting came from.
The ChatGPT desktop app, the Codex CLI and the IDE extension share this configuration, so a fix in config.toml applies to all three.
Codex never reads the server
- Each server is a TOML table named [mcp_servers.<name>]. An mcpServers block pasted from a Cursor or Claude Code JSON file means nothing to Codex. Convert it: command, args and env for stdio servers, url for remote ones.
- User config lives in ~/.codex/config.toml. If CODEX_HOME is set, Codex reads $CODEX_HOME/config.toml instead.
- A project's .codex/config.toml loads only when Codex trusts the project. In an untrusted project, Codex skips project config, hooks and rules, and still loads your user config. Trust the folder when Codex asks, or add [projects."/path/to/repo"] with trust_level = "trusted" to your user config.
- enabled = false on a server turns it off without deleting it. Look for one left over from an earlier test.
- The retired setting approval_policy = "untrusted" can stop Codex from starting at all. Remove it from user config, project config and profile files.
[mcp_servers.docs]
command = "npx"
args = ["-y", "some-mcp-server"]
env_vars = ["DOCS_API_KEY"]
startup_timeout_sec = 30
[mcp_servers.remote]
url = "https://mcp.example.com/mcp"
bearer_token_env_var = "REMOTE_MCP_TOKEN"The server is configured but fails to start
- Codex gives a server 10 seconds to start. A server that downloads packages on first run (npx -y, uvx) can miss that. Raise it with startup_timeout_sec.
- Stdio servers don't get your whole shell environment. Codex passes a short allowlist (on macOS and Linux: HOME, LOGNAME, PATH, SHELL, USER, LANG, LC_ALL, TERM, TMPDIR, TZ) plus whatever you set in env or name in env_vars. A server that needs OPENAI_API_KEY or GITHUB_TOKEN from your shell gets nothing until you list it in env_vars.
- Set cwd when the server needs a working folder, and use absolute paths for local scripts.
- A slow optional server can miss the first tool list. Codex waits mcp_optional_startup_grace_ms (1000 by default) for optional servers when it builds the catalog. Set it to 0 to wait each server's full startup timeout, or set required = true on a server so startup fails loudly if it can't initialize.
Remote servers: auth problems
- bearer_token_env_var names a variable; it doesn't hold the token. Export that variable in the shell that starts Codex.
- http_headers sends fixed values, and env_http_headers reads header values from environment variables.
- For a server that uses OAuth, run codex mcp login <name>, or /mcp login <name> inside a session.
- If no credential resolves, Codex can still connect with no authentication, so a protected server answers 401 and its tools never appear. /mcp verbose shows the details.
Loaded, but some tools are missing
Codex filters tools with enabled_tools and disabled_tools on the server. enabled_tools is an allow list and disabled_tools is applied after it, so a tool named in both stays off. Approval settings sit next to them: default_tools_approval_mode for the whole server (auto, prompt, writes or approve) and [mcp_servers.<name>.tools.<tool>] for one tool.
Taskhold-specific checks
Taskhold is a remote server at https://taskhold.com/api/mcp. When the taskhold tools don't show up in Codex, check these in order:
- codex mcp list shows taskhold. If not, run codex mcp add taskhold --url https://taskhold.com/api/mcp, then codex mcp login taskhold to sign in through the browser.
- Using a key instead? Put it in http_headers as "Authorization" = "Bearer atd_sk_...", or set bearer_token_env_var = "TASKHOLD_API_KEY" and export that variable. A 401 names the problem: missing_key, bad_header, not_a_taskhold_key or unknown_key.
- A 402 means the key works but the trial ended or the plan was canceled. Restarting the plan fixes it with no config change.
- Settings in Taskhold shows Connected once the first call arrives. Ask Codex to call taskhold_list to test.
Codex may ask before Taskhold calls that change the list. If that holds up long runs, Codex CLI waiting for approval covers alerts and approval settings. The same checks for other clients: Cursor and Claude Code.
See how far along your coding agents are.
$12/month or $120/year after the trial. Card up front. Cancel before day 7 and you pay nothing. Every agent you run is included.
Questions
- Where does Codex store MCP servers?
- In config.toml, as [mcp_servers.<name>] tables: ~/.codex/config.toml for every project, or .codex/config.toml in a trusted project. codex mcp add writes to ~/.codex/config.toml.
- Why does Codex ignore my project's .codex/config.toml?
- Codex loads project config only for trusted projects. Mark the project trusted when Codex asks, or set trust_level = "trusted" for its path under [projects] in your user config. /debug-config shows which layers loaded.
- How long does Codex wait for an MCP server to start?
- 10 seconds by default. Set startup_timeout_sec on the server to change it. Tool calls have their own tool_timeout_sec, 60 seconds by default.
Sources
- Codex docs: Model Context Protocol (config.toml keys, OAuth), checked 2026-10-31
- Codex docs: config basics (layers, project trust), checked 2026-10-31
- Codex docs: advanced config (CODEX_HOME, project config files), checked 2026-10-31
- Codex docs: slash commands (/mcp, /debug-config), checked 2026-10-31
- Codex source: environment passed to stdio MCP servers, checked 2026-10-31
Related
Updated 2026-10-31. Something wrong or out of date? Email hello@greatwork.company.