Connect an MCP server to Codex
- Spec
2026-07-28- Evidence
- E3Tested in a real clientarm64
- Verified
Tested with Codex CLI 0.164.0 on Linux (arm64), using our TypeScript example server. Windows notes at the end are from public reports and are not yet tested by us.
Where the configuration lives
Section titled “Where the configuration lives”Codex reads MCP servers from config.toml in its home directory: ~/.codex/config.toml, or $CODEX_HOME/config.toml if you set CODEX_HOME. Each server is a [mcp_servers.<name>] table.
Add a local (stdio) server
Section titled “Add a local (stdio) server”codex mcp add hello-ts -- node /absolute/path/to/hello-server/src/server.tsEverything after -- is the command that starts the server. Codex writes:
[mcp_servers.hello-ts]command = "node"args = ["/absolute/path/to/hello-server/src/server.ts"]Environment variables go into a sub-table. codex mcp add hello-py --env API_KEY=… -- uv run … produces:
[mcp_servers.hello-py.env]API_KEY = "…"Add a remote (Streamable HTTP) server
Section titled “Add a remote (Streamable HTTP) server”codex mcp add my-remote --url https://example.com/mcp --bearer-token-env-var MY_TOKEN[mcp_servers.my-remote]url = "https://example.com/mcp"bearer_token_env_var = "MY_TOKEN"The file stores only the variable name. Codex’s documentation says it sends the value of that variable in the Authorization header as a bearer token. We have not yet tested a remote server that requires a token.
Check what Codex sees
Section titled “Check what Codex sees”codex mcp list # all servers, with env values maskedcodex mcp get hello-ts # the settings of one serverThese read the configuration only; they do not start the server. To test the server itself, use the Inspector.
codex exec: “MCP tool call requires approval”
Section titled “codex exec: “MCP tool call requires approval””In non-interactive mode (codex exec), there is nobody to approve a tool call. With the default settings our call to add failed with:
MCP tool call requires approval, but approval policy is neverFor a server you trust, approve its tools. We tested this with the -c override -c 'mcp_servers.hello-ts.default_tools_approval_mode="approve"'; in config.toml the same key is:
[mcp_servers.hello-ts]command = "node"args = ["/absolute/path/to/hello-server/src/server.ts"]default_tools_approval_mode = "approve"With this setting, codex exec called add with {"a": 2, "b": 3} and got {"sum": 5} back. Only do this for servers whose tools are safe to run without a person checking each call.
Two more things that tripped us up in scripts:
codex execwaits for more input on stdin if stdin is open (Reading additional input from stdin...). Redirect it:codex exec "…" < /dev/null.- You can try a server without editing the file by passing it with
-c, for example-c 'mcp_servers.hello-ts.command="node"'together with a matchingargsvalue.
Environment variables are not passed through
Section titled “Environment variables are not passed through”Codex does not hand your shell’s environment to a stdio server. In our test, a server that needs DEMO_API_KEY exited at startup because the variable never arrived, and codex exec printed no MCP error at all: the model just reported that the tool was not available. Either set the value in the server’s env table, or list the variables Codex should forward from its own environment:
[mcp_servers.env-check]command = "node"args = ["/absolute/path/to/env-check.ts"]env_vars = ["DEMO_API_KEY"]With env_vars, the same call succeeded. codex mcp get then shows env: DEMO_API_KEY=*****.
Slow servers and startup timeouts
Section titled “Slow servers and startup timeouts”Codex gives each server a limited time to start (startup_timeout_sec) and to answer each tool call (tool_timeout_sec). Codex’s documentation gives defaults of 10 and 60 seconds, but Codex 0.164.0 waited 30 seconds for a server that never started in our test (MCP client for `hang` timed out after 30 seconds). Go by the number in your own error message; see the startup timeout entry. Servers on the JVM, or packages that npx downloads on first run, can exceed it. Raise it per server:
[mcp_servers.my-java-server]startup_timeout_sec = 30Some older guides use startup_timeout_ms. The current documentation only describes startup_timeout_sec, and in our test startup_timeout_ms had no visible effect while startup_timeout_sec = 5 changed the limit to 5 seconds. Use startup_timeout_sec.
Windows
Section titled “Windows”From public reports, not yet tested by us:
- Backslashes in TOML strings. In a double-quoted TOML string,
\starts an escape sequence, so"C:\Users\me\server.js"is invalid. One bad escape makes the whole file fail to parse, and the desktop app can hang on its loading screen. Use single quotes, which TOML treats literally:args = ['C:\Users\me\server.js'], or use forward slashes. npxis a batch file. Usecommand = "cmd"withargs = ["/c", "npx", …], as described in Connection closed.
Related
Section titled “Related”Sources
MCPDev is community documentation. It is not affiliated with the Model Context Protocol project or with the vendors of the clients it covers.