TL;DR: Codex and Codex CLI don't use the mcp.json file that Claude Desktop and Claude Code read. MCP servers live in config.toml, by default at ~/.codex/config.toml, shared by the ChatGPT desktop app, Codex CLI, and the IDE extension. Add one with codex mcp add, or hand-edit the TOML directly for OAuth, bearer tokens, or per-tool approval rules. All the exact keys are below.
If you've set up an MCP server in Claude Desktop or Claude Code before, and you point Codex at the same config file expecting it to work, it won't. Codex doesn't read that file at all. The protocol underneath is the same one, but Codex stores its half of the handshake in a different format, with different field names, and a different set of CLI verbs for managing it. This post separates what's true everywhere (the MCP spec itself), what Codex specifically adds on top, and how to point the Prompt Architects MCP server at Codex and Codex CLI without guessing at a config shape that may have moved since whatever tutorial you last read.
What does "MCP" mean before you even get to Codex?
Model Context Protocol is a spec, not a Codex feature, so it's worth separating what the protocol defines from what any one client decides to do with it. The current spec, dated July 28, 2026 at modelcontextprotocol.io, names exactly two standard transports. Stdio is for a local process the client starts and owns. Streamable HTTP is for a server reached at a URL. Every message on either transport is JSON-RPC, and the spec states plainly that protocol semantics are identical across transports: a transport decides framing and delivery, not meaning.
Tool discovery is spec-level too. A server that supports tools declares that capability during setup, and the protocol's own tools page describes the intended pattern directly: tool use is meant to be model-controlled, so that "the language model can discover and invoke tools automatically based on its contextual understanding and the user's prompts." What the spec does not define is how a client decides whether to actually run a discovered tool without asking you first. That part is left entirely to the client, and it's exactly where Codex, Claude, and Cursor genuinely differ from each other.
Where does Codex actually store MCP configuration?
In config.toml. OpenAI's own Codex docs are specific about the path: by default that's ~/.codex/config.toml, and you can scope servers to one project with a .codex/config.toml file in that repo, loaded only for projects you've marked trusted. The same file, and the same MCP servers configured in it, are shared across the ChatGPT desktop app, Codex CLI, and the IDE extension. Set a server up once, and switching between the CLI, the desktop app, and the editor extension doesn't require redoing anything.
That single-file, many-surfaces design is worth sitting with for a second if you're coming from Claude's world, where Claude Desktop and Claude Code each read their own config independently. There's also a documented precedence order when more than one layer applies: CLI flags and --config overrides win first, then project config files closest to your working directory, then a named profile file if you passed --profile, then the user-level config.toml, then a system-wide config on Unix, then Codex's own built-in defaults. In practice this mostly matters for one thing: an MCP server set in ~/.codex/config.toml applies everywhere unless a project-scoped file overrides it, and an untrusted project skips its own .codex/ layer entirely and falls back to your personal settings.
How do you add an MCP server from Codex CLI?
For a local, stdio-based server, the documented form is one command:
codex mcp add context7 -- npx -y @upstash/context7-mcp
That example, straight from OpenAI's own docs, adds Context7, a free MCP server for developer documentation, as a subprocess Codex starts on demand. The general shape also takes environment variables:
codex mcp add <server-name> --env VAR1=VALUE1 --env VAR2=VALUE2 -- <stdio server-command>
For a remote server reached over a URL, codex mcp add also takes --url, and if the server needs a pre-registered OAuth client, --oauth-client-id:
codex mcp add example --url https://mcp.example.com --oauth-client-id my-client
Once a server is added, three more commands cover almost everything you'll need day to day. codex mcp list shows every configured server and its state. codex mcp login <server-name> starts an OAuth login for a server that supports it. Inside the interactive codex terminal UI, typing /mcp shows your active servers for that session without leaving the conversation.
What do the config.toml keys actually look like, for each server type?
Codex's docs name specific keys for each of the two server types, and they barely overlap between stdio and Streamable HTTP:
| Feature | STDIO server | Streamable HTTP server |
|---|---|---|
| What it is | A local process Codex starts and owns | A remote server reached at a URL |
| Required key | command | url |
| Optional keys | args, env, env_vars, cwd | auth, bearer_token_env_var, http_headers, env_http_headers |
| Typical fit | A CLI tool or script already installed locally | A hosted service, like a vendor's own MCP endpoint |
| Auth | Whatever the process reads from its own environment | OAuth by default, or a bearer token |
For the HTTP case, the auth key defaults to oauth, which uses stored MCP OAuth credentials. Setting it to chatgpt instead reuses your current ChatGPT session for a trusted first-party server, falling back to OAuth if that session isn't available. If no credential source resolves at all, Codex still connects to a server without authentication rather than failing outright, which is worth knowing if a server you expected to prompt for a login silently doesn't.
A hand-edited example for a hosted HTTP server with a bearer token, matching the shape in Codex's own docs:
[mcp_servers.example]
url = "https://mcp.example.com"
bearer_token_env_var = "EXAMPLE_MCP_TOKEN"
http_headers = { "X-Example-Region" = "us-east-1" }
Beyond the connection itself, Codex documents a handful of per-server controls worth knowing before you add anything with write access. enabled_tools and disabled_tools let you allow-list or block specific tools from a server, with the deny list applied after the allow list. startup_timeout_sec and tool_timeout_sec bound how long Codex waits before giving up. required = true makes Codex refuse to start at all if that server can't initialize: useful for a server your workflow genuinely depends on, and a footgun for one you don't.
How does OAuth actually get registered for a new server?
This is the part most tutorials skip, and it's genuinely more involved than "click sign in." When your authorization server requires a pre-registered OAuth client, you provide its client ID when adding the server, and Codex displays a callback URL to register with your provider, something like http://127.0.0.1/callback. Codex saves that callback alongside the client ID for later logins.
For servers that don't require a pre-registered client, Codex chooses automatically between two registration mechanisms. Client ID Metadata Documents, or CIMD, is the default when the authorization server advertises support for it and the callback uses a supported loopback URL; Codex then points at a ChatGPT-hosted metadata document specific to that MCP server. Dynamic Client Registration, or DCR, is the fallback when CIMD isn't available. You can force a specific choice for one login with codex mcp login <server-name> --oauth-client-registration cimd or --oauth-client-registration dcr, though the default of auto is right for nearly everyone. None of this changes what you type day to day; it only matters if a login is failing and you need to know which mechanism to debug.
How do you connect the Prompt Architects MCP server to Codex or Codex CLI?
Prompt Architects runs an MCP server at https://mcp.prompt-architects.com/mcp, and its own integrations page states the client list directly: "One connector — works in Claude Desktop, Claude.ai, Cursor, Claude Code, Codex, and any other MCP-aware client." Codex and Codex CLI each get their own setup tab on that page alongside the others; this isn't a Claude-only or Cursor-only integration, and Cursor is genuinely on the list too.
The server exposes four tools, each also callable as a slash command inside a client that supports them. Improve (/mcp__pa__improve) rewrites a prompt for clarity and structure. Refine (/mcp__pa__refine) asks one to three clarifying questions before producing a tailored result. Shorten (/mcp__pa__shorten) trims a prompt down. Enhance (/mcp__pa__enhance) adds structure, role-framing, and depth for a higher-stakes prompt. None of them touch your repository; they operate on prompt text you hand them, the same way Codex's own file-editing and shell tools are a separate, unrelated capability.
For the quickest path, treat it like any other remote HTTP server and let OAuth handle the rest:
codex mcp add prompt-architects --url https://mcp.prompt-architects.com/mcp
codex mcp login prompt-architects
That opens a browser tab to sign in with your Prompt Architects account and consent once, matching the OAuth-by-default flow the integrations page describes for every client. For a headless machine or a CI job with no browser available, generate a personal access token instead. The page documents this as a pa_live_… token from Settings → MCP, explicitly labelled for "Headless / CI" use, and wires in by hand:
[mcp_servers.prompt-architects]
url = "https://mcp.prompt-architects.com/mcp"
bearer_token_env_var = "PA_MCP_TOKEN"
Then export PA_MCP_TOKEN with the generated token before running Codex. Prompt Architects' free plan covers five prompt enhancements a day, per the FAQ page, before any paid tier applies. That's worth knowing if a script that calls improve in a loop stops responding partway through a batch; it's usually the daily cap, not a broken connection.
Does the same setup work in Claude Desktop, or do you start over?
You start over, at least for the config file itself. Claude Desktop and Claude Code both read a JSON configuration; Codex reads config.toml, a different format with different key names for overlapping ideas. The word url still means the same thing in both worlds, but there's no copy-paste path from one file to the other. If you've already set the Prompt Architects server up in Claude Code, the setup steps for scopes and auth there don't transfer to Codex; you'll add it a second time using the commands above. The same applies in reverse to setting a server up in Claude Desktop: a working Codex config doesn't save you that step either.
What does carry over is your mental model. The distinction between a stdio server and an HTTP server, what OAuth buys you over a bearer token, and the fact that a client decides tool-approval policy on its own rather than the spec deciding it for them: none of that is Codex-only. Every MCP client reinvents its own version of it, using its own vocabulary, and once you've learned Codex's version, reading another client's docs goes noticeably faster.
What's Codex-specific about tool approval, versus part of the protocol?
The protocol stops at letting a model discover and call tools; it says nothing about whether a client should run a tool without asking first. Codex fills that gap with default_tools_approval_mode per server, with documented values auto, prompt, writes (which prompts only for tools not marked read-only), and approve, plus a per-tool override with tools.<tool>.approval_mode. That's a Codex safety decision layered on top of a spec that's silent on the question. Claude Code and Cursor each answer it their own way, and neither answer is more correct by the protocol's own rules; they're just different products making different defaults.
If an MCP server connects in Codex, but every tool call from it stalls waiting on a prompt you didn't expect, checking default_tools_approval_mode for that server in config.toml is usually faster than assuming the server itself is broken. When a server won't connect at all, Codex's own config documents a log_dir setting: point it at a directory and Codex writes a plaintext session log, codex-tui.log, that's opt-in rather than on by default. Turning that on before you touch config.toml again is often faster than guessing whether the problem is your TOML syntax, a wrong URL, or the server itself refusing the connection. For the wider set of MCP failure modes that aren't Codex-specific, the general MCP troubleshooting guide covers the symptom-cause-fix pairs that show up across every client, config path included.
Where do config.toml's other agent-facing settings fit in?
MCP is one piece of a larger config file, and it's easy to confuse Codex's broader agent settings, like approval_policy, sandbox_mode, and model_reasoning_effort, with anything MCP-specific, because they all live in the same config.toml. They aren't part of MCP configuration at all. They govern how Codex behaves when running its own tools, independent of any server you've connected. If you're building a habit of tuning Codex's config file, context engineering for coding agents covers the broader discipline that MCP servers are one input to, not the whole of it.
What other MCP servers is Codex actually tested against?
OpenAI's own docs list a small, named set as working examples rather than an exhaustive catalog: the OpenAI Docs MCP server for searching developer docs, Context7 for up-to-date library documentation, Figma's local and remote servers for design access, a Playwright server for browser control, Chrome DevTools for inspecting a running page, Sentry for reading error logs, and GitHub's own server for managing issues and pull requests beyond what plain git covers. None of that list is exclusive to Codex; it's the same ecosystem every MCP client draws from, which is the whole point of the protocol being a shared spec rather than a per-vendor integration.
Stop rewriting prompts. Start shipping.
Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 4.8★ on the Chrome Web Store.
Create An AccountNone of this is likely to stay still for long. Codex's own docs describe MCP support that has grown non-trivially just in the areas this post touches; OAuth client registration alone has three sub-mechanisms, with their own fallback rules for which callback URL gets used in which situation. Treat the exact key names here as accurate as of the access date noted above, not as permanent. Check developers.openai.com/codex/mcp directly before a production setup, the same way this post did.