---
title: "Codex MCP Setup: config.toml, codex mcp add and Examples"
url: "https://mcpshelf.co/guides/codex"
description: "Add MCP servers to OpenAI Codex with codex mcp add or config.toml. Turn any JSON config into TOML, pass API keys safely, sign in, and fix start-up timeouts."
updated: "2026-11-01"
site: "MCP Shelf"
---

# Adding MCP servers to Codex

By Sophie Filer · Updated 1 Nov 2026

Codex keeps MCP servers in config.toml, written in TOML rather than the JSON most READMEs show. The Codex CLI, the IDE extension and the ChatGPT desktop app share that file, so you set a server up once. Here is how to add one, and how to translate any JSON config.

## The short version

Local server:

```
codex mcp add playwright -- npx -y @playwright/mcp@latest
```

Local server with an API key:

```
codex mcp add firecrawl --env FIRECRAWL_API_KEY=fc-your-key -- npx -y firecrawl-mcp
```

Remote server:

```
codex mcp add notion --url https://mcp.notion.com/mcp
```

See what is set up:

```
codex mcp list
```

Everything after `--` is the command that starts the server. Inside the Codex terminal UI, type `/mcp` to see which servers are running. Every server page on MCP Shelf has a Codex tab with the config.toml block and the command.

## Where the config lives

| File | Applies to |
| --- | --- |
| ~/.codex/config.toml | You, everywhere: the CLI, the IDE extension and the ChatGPT desktop app |
| .codex/config.toml (in a project) | That project, once you have marked it as trusted |

In the IDE extension and the ChatGPT desktop app you can also add servers without the file: open Settings (the gear menu in the extension), choose MCP servers, then Add server, and pick STDIO or Streamable HTTP. Restart when it asks.

## Turning a JSON config into TOML

Each server becomes a table named `[mcp_servers.NAME]`. The fields keep their names, and the env object becomes its own table underneath:

What the README shows (JSON):

```
{
  "mcpServers": {
    "firecrawl": {
      "command": "npx",
      "args": ["-y", "firecrawl-mcp"],
      "env": { "FIRECRAWL_API_KEY": "fc-your-key" }
    }
  }
}
```

The same server in ~/.codex/config.toml:

```
[mcp_servers.firecrawl]
command = "npx"
args = ["-y", "firecrawl-mcp"]

[mcp_servers.firecrawl.env]
FIRECRAWL_API_KEY = "fc-your-key"
```

| JSON | config.toml |
| --- | --- |
| "mcpServers": { "name": { ... } } | [mcp_servers.name] |
| "command": "npx" | command = "npx" |
| "args": ["-y", "pkg"] | args = ["-y", "pkg"] |
| "env": { "KEY": "value" } | [mcp_servers.name.env] then KEY = "value" |
| "url": "https://..." | url = "https://..." |
| "headers": { "X-Key": "..." } | http_headers = { "X-Key" = "..." } |

> **Watch out:** Codex connects to local (stdio) servers and Streamable HTTP URLs. For a server that only offers an older SSE endpoint, run it through [mcp-remote](https://mcpshelf.co/guides/mcp-remote).

## Keeping keys out of config.toml

Instead of writing the key into the file, Codex can pass on a variable that is already set in the environment you start it from:

```
[mcp_servers.firecrawl]
command = "npx"
args = ["-y", "firecrawl-mcp"]
env_vars = ["FIRECRAWL_API_KEY"]

[mcp_servers.github]
url = "https://api.githubcopilot.com/mcp/"
bearer_token_env_var = "GITHUB_PAT"
```

`env_vars` forwards the named variables to a local server. `bearer_token_env_var` sends a variable as `Authorization: Bearer ...` to a remote one; the command-line version is `codex mcp add github --url https://api.githubcopilot.com/mcp/ --bearer-token-env-var GITHUB_PAT`. `env_http_headers` does the same for other header names.

## Signing in to remote servers

After adding a URL, Codex may say the server could need a login. Run `codex mcp login notion` to open the browser, or add `--no-browser` on a machine without one, which prints the address to open elsewhere. `codex mcp logout notion` removes the saved sign-in. In the app and extension, the server list shows an Authenticate button instead.

## Options that save you trouble

| Option | What it does |
| --- | --- |
| startup_timeout_sec = 60 | How long Codex waits for the server to start. The default is 10 seconds, which a first npx or uvx download can miss. |
| tool_timeout_sec = 120 | How long one tool call may run. The default is 60. |
| enabled = false | Switch a server off without deleting it. |
| enabled_tools = ["read", "search"] | Only offer these tools to the model. |
| disabled_tools = ["delete_page"] | Hide these tools, applied after enabled_tools. |
| default_tools_approval_mode = "writes" | Ask before tools that are not marked read-only. Other values: auto, prompt, approve. |

A careful database setup:

```
[mcp_servers.postgres]
command = "docker"
args = ["run", "-i", "--rm", "-e", "DATABASE_URI", "crystaldba/postgres-mcp", "--access-mode=restricted"]
env_vars = ["DATABASE_URI"]
startup_timeout_sec = 60
default_tools_approval_mode = "prompt"
```

That example starts [Postgres MCP Pro](https://mcpshelf.co/servers/postgres-mcp-pro) in Docker, in its read-only restricted mode, takes the connection string from your environment and asks before every call. See its page for the full setup.

## Popular servers to try in Codex

| Server | What it gives your assistant | You need |
| --- | --- | --- |
| [Sequential Thinking](https://mcpshelf.co/servers/sequential-thinking) | A numbered scratchpad the model fills in, revises and branches while it works. | Node.js 24 or newer (the package asks for it) |
| [Context7](https://mcpshelf.co/servers/context7) | Pulls current, version-specific library docs into the conversation. | Node.js 22.13 or newer for the ctx7 setup command, or Node.js 18 or newer for the local server alone |
| [Playwright MCP](https://mcpshelf.co/servers/playwright) | Microsoft's browser automation server: navigate, click, type, read. | Node.js 18 or newer |
| [GitHub](https://mcpshelf.co/servers/github) | GitHub's own server for repos, issues, pull requests and Actions. | A GitHub account |
| [Blender MCP](https://mcpshelf.co/servers/blender) | Prompt-driven modelling in a running copy of Blender. | Blender 3.0 or newer |
| [Serena](https://mcpshelf.co/servers/serena) | IDE-style "find symbol" and "edit symbol" for an agent, backed by language servers. | uv, which installs Serena and the Python 3.13 it runs on |
| [MCP Toolbox for Databases](https://mcpshelf.co/servers/mcp-toolbox-for-databases) | Google's toolbox for Postgres, MySQL, BigQuery, Spanner and other databases. | Node.js 18 or newer |
| [Framelink Figma MCP](https://mcpshelf.co/servers/framelink-figma) | Feeds Figma layout and styling to coding agents so the UI matches the design. | A Figma personal access token |

## Questions

### Does ChatGPT on the web use my Codex servers?

No. ChatGPT on the web does not read config.toml; it uses remote servers added as plugins. The ChatGPT desktop app, the Codex CLI and the IDE extension share config.toml. See [Using MCP servers in ChatGPT](https://mcpshelf.co/guides/chatgpt).

### Codex says the server timed out on start-up. What do I change?

Add startup_timeout_sec = 60 under the server in config.toml. The first run of an npx or uvx server downloads the package, which often takes longer than the 10-second default.

### Can I edit config.toml by hand and use codex mcp add as well?

Yes. codex mcp add writes the same tables you would write yourself, and codex mcp list reads them back, which is a quick way to check your TOML parses.

---

From [MCP Shelf](https://mcpshelf.co/): A short shelf of MCP servers that are worth installing. Index for agents: https://mcpshelf.co/llms.txt

