Add a Remote MCP Server to Codex: config.toml and Fixes | MCP Hunter

Add a Remote MCP Server to Codex: config.toml and Fixes

How to add a remote MCP server to Codex in config.toml, keep its token out of the file, sign in with codex mcp login, and fix timeouts and servers that work locally but not in the cloud.

MCP Hunter team 6 min read

A remote MCP server goes into Codex as a table in config.toml with a url [1]:

[mcp_servers.my-server]
url = "https://mcp.example.com/mcp"

That file is ~/.codex/config.toml by default, and the Codex CLI, the IDE extension and the ChatGPT desktop app all read the same one [1]. Run codex mcp list to check it loaded [1]. If the server asks you to sign in, run codex mcp login my-server [1].

Everything below is checked against OpenAI's Codex MCP documentation on 12 October 2026 [1].

One thing first, because the search results mix them up. codex mcp manages the servers Codex connects to, which is what this page covers. codex mcp-server does the opposite: it runs Codex itself as an MCP server for another client to call. If you came here to plug Codex into Claude or Cursor, you want codex mcp-server instead.

TL;DR:

  • One [mcp_servers.<name>] table with a url in ~/.codex/config.toml, or in .codex/config.toml for one project (trusted projects only) [1].
  • Keep the token out of the file with bearer_token_env_var or env_http_headers [1].
  • Sign in with codex mcp login <name>. For a server that needs a pre-registered client, pass --oauth-client-id [1].
  • Tool calls time out at 60 seconds by default. Raise tool_timeout_sec for a slow tool [1].

Add the server

The url is the only required key for a remote server. It is the MCP endpoint itself, usually ending in /mcp, not the product's homepage [1].

For a server that takes a token, name the environment variable that holds it instead of writing the token into the file. Codex sends it as Authorization: Bearer ... [1]:

[mcp_servers.my-server]
url = "https://mcp.example.com/mcp"
bearer_token_env_var = "MY_SERVER_TOKEN"

For any other header, http_headers takes fixed values and env_http_headers takes the names of environment variables to read them from [1]:

[mcp_servers.my-server]
url = "https://mcp.example.com/mcp"
http_headers = { "X-Region" = "us-east-1" }
env_http_headers = { "X-Api-Key" = "MY_SERVER_KEY" }

Use the env_ form for anything secret, and especially in a project's .codex/config.toml, which is usually committed.

Choose which tools Codex sees

enabled_tools is an allow list and disabled_tools a deny list applied after it. enabled = false switches a server off without deleting its table [1]. Trimming tools you do not use keeps the list the model chooses from short, which how many tools an MCP server should have explains in numbers.

Sign in to a server that needs it

Run codex mcp login my-server and finish the sign-in in your browser [1]. Codex shows the callback URL to register with the provider, http://127.0.0.1/callback [1]. If the provider insists on a fixed port, set one, either for every server or just this one [1]:

mcp_oauth_callback_port = 5555

[mcp_servers.my-server.oauth]
callback_port = 5555

Most servers let Codex register itself. Some only accept clients registered in advance; for those, register an app with the provider and add the server with its client ID [1]:

codex mcp add my-server --url https://mcp.example.com/mcp --oauth-client-id my-client

That second case is rare. We read the authorization metadata of 169 real servers that ask for credentials, from our registry census on 9 October 2026: 162 offered Dynamic Client Registration, 33 accepted Client ID Metadata Documents, and only 6 offered neither [2]. Dynamic Client Registration explains both methods.

Timeouts

Codex has two, both in seconds [1]:

Setting Default What it covers
startup_timeout_sec 10 The server starting and answering its first request
tool_timeout_sec 60 One tool call
[mcp_servers.my-server]
url = "https://mcp.example.com/mcp"
tool_timeout_sec = 180

A tool that runs past 60 seconds fails on this limit even though the server is fine: one tool is slow. Raising the limit is the quick fix. The lasting fix is to return early and let the client poll, which MCP server errors covers along with 406s, CORS and -32601.

Works locally, fails in the cloud

The Codex CLI and IDE extension connect from your machine, so they can reach localhost, your VPN and hosts behind your firewall. OpenAI's own note is that local MCP servers "may not be available in the cloud", so check connectivity and authentication separately when Codex runs a task remotely [1]. The same split applies to ChatGPT, which always calls your server from OpenAI's network (add an MCP server to ChatGPT).

What you see Usual cause Fix
The server is missing from codex mcp list TOML error, or the table is in a project file for an untrusted project Check the file parses; trust the project, or move the table to ~/.codex/config.toml
Startup times out Wrong URL, or a server that is slow to answer Use the exact endpoint path, usually /mcp; raise startup_timeout_sec
401 with a token configured The environment variable is unset where Codex runs Export it in the shell Codex starts from
Sign-in fails on the redirect The callback URL or port is not registered Register http://127.0.0.1/callback with the port you set
Works locally, not in a cloud task The server is only reachable from your network Give it a public address
A tool times out at 60 seconds One slow tool Raise tool_timeout_sec, or make the tool return early

Check it from outside before you share it

Our MCP connection test calls your server from our network, runs the handshake and tools/list, and reports what a stranger on the internet gets back, with a dated URL you can share. That answers the cloud question before a remote task runs into it.

The same setup in other clients is in Claude Code, Cursor, VS Code, Claude Desktop and ChatGPT, and remote MCP server vs stdio covers whether your server should have a public address at all.

Sources

  1. Model Context Protocol, Codex docs
  2. Dynamic Client Registration, MCP Hunter glossary