Codex MCP: add, configure, and debug MCP servers.
To add an MCP server to OpenAI Codex, run
codex mcp add <name> -- <command>
for a local server or
codex mcp add <name> --url <url>
for a remote one. Codex saves it as an
[mcp_servers.<name>] table in
~/.codex/config.toml, which the CLI, the IDE
extension, and the ChatGPT desktop app share. Run
codex mcp list to check it.
Here to connect Codex to a database? Read Connect Codex to your database, or jump to the worked example.
CLI
The codex mcp commands.
The transport depends on what you pass. A command after
-- means stdio, --url
means streamable HTTP. codex mcp --help lists
every option.
| codex mcp add <name> -- <command> [args] | Add a local stdio server. Everything after -- is the command Codex starts. |
| codex mcp add <name> --env KEY=VALUE -- <command> | Same, with environment variables for the server process. Repeat --env for more. |
| codex mcp add <name> --url <url> | Add a streamable HTTP server. If the server supports OAuth, Codex starts the login right away. |
| codex mcp add <name> --url <url> --bearer-token-env-var VAR | Add an HTTP server that expects a bearer token. Codex reads the token from VAR at runtime. |
| codex mcp list | Show configured servers. Add --json for machine-readable output. |
| codex mcp get <name> | Show one server's configuration. Also takes --json. |
| codex mcp remove <name> | Delete a server from the config. |
| codex mcp login <name> | Run the OAuth login for an HTTP server. --scopes a,b requests specific scopes. |
| codex mcp logout <name> | Remove stored OAuth credentials for a server. |
| /mcp | Inside the Codex TUI: list the MCP servers active in this session. |
# stdio: Codex starts the server as a local process
$ codex mcp add context7 -- npx -y @upstash/context7-mcp
# streamable HTTP: Codex connects to a URL
$ codex mcp add valv-desktop --url http://127.0.0.1:4319/mcp
$ codex mcp list Configure MCP servers in config.toml.
The CLI covers the basics. For timeouts, tool filters, and headers,
edit the file. Each server is one table. A
command key makes it stdio, a
url key makes it HTTP.
Local server (stdio)
TOML# ~/.codex/config.toml
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]
startup_timeout_sec = 20
[mcp_servers.context7.env]
MY_ENV_VAR = "MY_ENV_VALUE" Remote server (streamable HTTP)
TOML# ~/.codex/config.toml
[mcp_servers.figma]
url = "https://mcp.figma.com/mcp"
bearer_token_env_var = "FIGMA_OAUTH_TOKEN"
tool_timeout_sec = 120
[mcp_servers.chrome_devtools]
url = "http://localhost:3000/mcp"
enabled_tools = ["open", "screenshot"]
enabled = false Global or per project.
~/.codex/config.toml applies everywhere.
A .codex/config.toml in a repo scopes
servers to that project, and Codex only reads it once you trust the
project. codex mcp add always writes to the
global file, so edit the project file by hand.
Tokens and OAuth.
Keep tokens out of the file. bearer_token_env_var
names a variable, and Codex reads its value when it connects. For
servers that use OAuth, codex mcp add
detects it and opens the login. Run
codex mcp login <name> later if the
session expires.
Reference
The [mcp_servers] keys you'll use.
All of these go inside one server's table. OpenAI's configuration reference lists the rest, mostly OAuth callback settings.
| Key | For | What it does |
|---|---|---|
| command | stdio | The command that starts the server. Required for stdio. |
| args | stdio | Arguments passed to the command, as an array of strings. |
| env | stdio | Environment variables set for the server process, as a table. |
| env_vars | stdio | Variable names to forward from your shell to the server. |
| cwd | stdio | Working directory the server starts in. |
| url | HTTP | The server endpoint. Required for streamable HTTP. |
| bearer_token_env_var | HTTP | Name of an environment variable whose value Codex sends as a bearer token. |
| http_headers | HTTP | Static headers sent with every request. |
| env_http_headers | HTTP | Headers whose values come from environment variables. |
| scopes | HTTP | OAuth scopes to request at login. |
| startup_timeout_sec | Both | How long Codex waits for the server to start. Default 10. |
| tool_timeout_sec | Both | How long one tool call may run. Default 60. |
| enabled | Both | Set false to turn a server off without deleting it. |
| required | Both | Set true to make Codex fail at startup if this server can't initialize. |
| enabled_tools | Both | Allow list. Only these tools are exposed. |
| disabled_tools | Both | Deny list, applied after enabled_tools. |
| default_tools_approval_mode | Both | Approval for this server's tools: auto, prompt, writes, or approve. writes prompts for tools not marked read-only. |
| tools.<tool>.approval_mode | Both | Approval override for a single tool. |
One top-level key matters too: mcp_optional_startup_grace_ms
sets how long Codex waits for servers that aren't required before the
session starts. The default is 1000. Set it to 0 to wait each server's
full startup timeout.
When an MCP server doesn't work in Codex.
Start with codex mcp list to see if the
server is configured, then /mcp in a session
to see if it loaded.
| The server isn't in codex mcp list | Check the table name is [mcp_servers.<name>]. If you put it in a project's .codex/config.toml, Codex only loads that file when you trust the project. |
| A stdio server times out at startup | The first npx or uvx run downloads the package and can take longer than the 10 second default. Raise startup_timeout_sec, or install the package first. |
| A stdio server can't find its API key | Set it under [mcp_servers.<name>.env], or list the variable in env_vars so Codex forwards it from your shell. |
| Long tool calls fail | Each call is capped at 60 seconds by default. Raise tool_timeout_sec for that server. |
| HTTP server returns 401 | If you use bearer_token_env_var, the variable must be set in the shell that starts Codex. For OAuth servers, run codex mcp login <name>. |
| The server connects but a tool is missing | Check enabled_tools and disabled_tools. disabled_tools wins when a tool is in both. Use /mcp in the TUI to see what loaded. |
| Valv: connection refused on 127.0.0.1:4319 | Valv Desktop isn't open, or it picked another port because 4319 was taken. Copy the command from Settings, MCP Server again. |
| Valv: Codex sees the wrong data, or none | Codex works against the workspace that is active in Valv. Switch to the workspace that holds your database. With no workspace open, the server answers 503. |
Worked example
Connect Codex to a database through Valv's MCP server.
Valv Desktop runs a local streamable HTTP server while the app is open. It holds the database connection, so Codex only gets a URL and read-only tools, never the password.
- 1
Add your database in Valv.
Connect Postgres, MySQL, SQLite, ClickHouse, or MongoDB. Hide any table or column Codex shouldn't see in the AI access tab.
- 2
Copy the Codex command.
Open Settings, MCP Server, and expand Codex. Port 4319 is the default. If it's taken, Valv uses another port, so copy the command the app shows.
codex mcp add valv-desktop --url http://127.0.0.1:4319/mcp - 3
Check what Codex saved.
The command adds one HTTP table to your global config. No token or env var is needed for a local agent.
[mcp_servers.valv-desktop] url = "http://127.0.0.1:4319/mcp" - 4
Ask in Codex.
Keep Valv open and start
codex. It works against whichever workspace is active in Valv, and reads Valv's server instructions on how to use the tools.
Tools Codex gets from Valv
list_datasources
Databases and remote MCP servers in the active workspace.
list_resources · describe_resource
Tables and their columns, minus anything hidden in AI access.
query
A structured, read-only query that Valv validates before it runs.
run_code
Several read queries chained in one step.
remember
Proposes a fact for workspace memory. You confirm it in Valv.
read_file · write_file · edit_file
Dashboards and other files in the workspace folder.
run_flow · set_flow_enabled · notify
Test and turn on scheduled checks, send a notification.
With more than one datasource, data tools get a prefix such as
app__query. Remote MCP servers
connected in Valv, like PostHog, come through with their own prefix.
> How many trials converted to paid last month, by plan?
tool list_datasources
tool describe_resource subscriptions
tool query status, plan, trial_ends_at
Conversions per plan as a table. The query
object is right there in the tool call.
> Check this every Monday and tell me if it drops. An illustration of the flow, not a recorded session. Tool names and columns depend on your schema. The second prompt has Codex set up a Valv flow that runs while the app is open.
Only want answers, no files?
The file tools write dashboards into the Valv workspace, not to
the database. If you'd rather Codex didn't, drop them with
disabled_tools.
[mcp_servers.valv-desktop]
url = "http://127.0.0.1:4319/mcp"
disabled_tools = ["write_file", "edit_file"] You can also skip the terminal and run Codex inside Valv, with tables and charts next to the chat. That setup, and how Valv keeps Codex read-only, is in Connect Codex to your database.
Which MCP server to add for what.
Valv is one option for data. It isn't the right pick for everything.
Library docs
Context7 or the OpenAI Docs MCP server give Codex current
documentation. Nothing to set up beyond one
codex mcp add.
Raw SQL and tuning
If Codex should run EXPLAIN, suggest indexes, or write migrations, a standalone database server fits better. Valv doesn't run raw SQL. The Postgres MCP guide compares the options.
Read-only data answers
Valv, when Codex should answer questions from Postgres, MySQL, SQLite, ClickHouse, or MongoDB without write access or your password. See the database MCP guide for other clients.
Codex MCP, answered
How do I add an MCP server to Codex?
Run codex mcp add <name> -- <command> for a local stdio server, or codex mcp add <name> --url <url> for a streamable HTTP server. Codex writes a [mcp_servers.<name>] table to ~/.codex/config.toml. Check it with codex mcp list, or /mcp inside the Codex TUI.
Where does Codex store MCP server config?
In ~/.codex/config.toml by default. You can also put [mcp_servers.<name>] tables in a project's .codex/config.toml, which Codex loads only for trusted projects. codex mcp add always writes to the global file.
Do the Codex CLI and IDE extension share MCP servers?
Yes. The Codex CLI, the IDE extension, and the ChatGPT desktop app read the same MCP configuration on a machine. Add a server once and it shows up in all three. In the IDE extension, open the gear menu and choose MCP servers to manage them from a UI.
How do I disable one tool from an MCP server in Codex?
Add disabled_tools = ["tool_name"] to the server's table in config.toml. To expose only a few tools, use enabled_tools as an allow list instead. To turn off the whole server without deleting it, set enabled = false.
Why does my MCP server time out in Codex?
Codex waits 10 seconds for a server to start and 60 seconds for each tool call. Raise startup_timeout_sec or tool_timeout_sec in the server's table. Slow first starts are common with npx and uvx, which download the package on the first run.
Can Codex query my database over MCP?
Yes. With Valv Desktop open, run codex mcp add valv-desktop --url http://127.0.0.1:4319/mcp. Codex can then list, describe, and query the tables in Valv's active workspace with read-only tools, and it never receives your database password.
Give Codex your database over MCP.
Free for personal use, every feature included. Commercial use needs a seat at beta pricing. See pricing.