Home › Articles

One MCP server, three configs: Claude Code, Cursor and Codex

Updated 2026-10-29

In short: all three tools speak MCP, but each keeps its servers in a different file. Claude Code uses .mcp.json at the repo root, Cursor uses .cursor/mcp.json, and Codex uses [mcp_servers.<name>] tables in .codex/config.toml. The JSON files look alike, but two details break copy-paste: Claude Code needs "type": "http" on remote servers, and every tool writes environment variables differently. Below is the same two-server setup written for each tool, the differences that matter, and how to check that each one loaded.

Where each tool looks

Claude CodeCursorCodex
Project file (commit it).mcp.json at the project root.cursor/mcp.json.codex/config.toml, trusted projects only
Personal file~/.claude.json (user scope, and local scope per project)~/.cursor/mcp.json~/.codex/config.toml
FormatJSON, mcpServersJSON, mcpServersTOML, [mcp_servers.<name>]
Env variable in a value${VAR} or ${VAR:-default}${env:VAR}Name the variable in a field such as bearer_token_env_var
See what loadedclaude mcp list, /mcpCustomize, MCP Logs in the Output panelcodex mcp list, /mcp

Sources: the Claude Code MCP docs, the Cursor MCP docs and the Codex MCP docs, all checked on 2026-10-29. Some third-party guides still say Codex has no project-level MCP config. The current Codex docs say it does: put the tables in .codex/config.toml in the repo, and Codex loads them once you trust the project.

The same setup, written three ways

The example has two servers: Context7, a local stdio server that the Codex docs use as their example (npx -y @upstash/context7-mcp), and team-docs, a stand-in for a remote HTTP server that needs a bearer token. mcp.example.com and TEAM_DOCS_TOKEN are placeholders; swap in your server's URL and auth. The token value never appears in a file. Each developer sets TEAM_DOCS_TOKEN in their own shell.

We checked that all three files parse (JSON and TOML). We didn't run them inside the three tools, so test them in yours before you rely on them.

Claude Code: .mcp.json

{
  "mcpServers": {
    "context7": {
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp"]
    },
    "team-docs": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${TEAM_DOCS_TOKEN}"
      }
    }
  }
}

Cursor: .cursor/mcp.json

{
  "mcpServers": {
    "context7": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@upstash/context7-mcp"]
    },
    "team-docs": {
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer ${env:TEAM_DOCS_TOKEN}"
      }
    }
  }
}

Codex: .codex/config.toml

# .codex/config.toml  (loaded only in a trusted project)
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]

[mcp_servers.team-docs]
url = "https://mcp.example.com/mcp"
bearer_token_env_var = "TEAM_DOCS_TOKEN"

Adding servers from the command line

# Claude Code: write the server into .mcp.json for the team
claude mcp add --transport http --scope project team-docs https://mcp.example.com/mcp
claude mcp add --transport stdio --scope project context7 -- npx -y @upstash/context7-mcp

# Codex: add a stdio server to your Codex config
codex mcp add context7 -- npx -y @upstash/context7-mcp

# Check what loaded
claude mcp list
codex mcp list

In claude mcp add, everything after -- is the server's own command, so its flags aren't read as Claude's. Without --scope, Claude Code uses local scope: the server goes into your entry for this project inside ~/.claude.json, not into .mcp.json, and your teammates won't see it. For a remote server in Codex, the docs show codex mcp add <name> --url <url>, and codex mcp login <name> starts an OAuth sign-in. Cursor adds servers through Customize or by editing mcp.json.

Which definition wins

Approvals and trust

A committed MCP config runs commands on every machine that opens the repo, so each tool puts a gate in front of it:

Read a server's source before you approve it, and give it a narrowly scoped token. If you're also keeping agents away from secrets files, our .env guide covers the file-access side for all three tools.

Keeping three files in sync

There's no shared MCP file that all three tools read, so you maintain three. A few habits keep that manageable:

Checklist

  1. Write .mcp.json, .cursor/mcp.json and .codex/config.toml with the same server names.
  2. Add "type": "http" to every remote server in .mcp.json.
  3. Replace every secret with a variable: ${VAR}, ${env:VAR}, or a Codex *_env_var field.
  4. Run claude in the repo and approve the project servers, then check claude mcp list.
  5. Trust the project in Codex, then check codex mcp list or /mcp.
  6. In Cursor, check the servers are on in Customize and look at MCP Logs in the Output panel if one fails.

FAQ

Where does each tool keep project MCP servers?

Claude Code reads .mcp.json at the project root. Cursor reads .cursor/mcp.json in the project. Codex reads [mcp_servers.<name>] tables in .codex/config.toml, but only in a project you've trusted. The personal versions are ~/.claude.json, ~/.cursor/mcp.json and ~/.codex/config.toml.

Can I copy Cursor's mcp.json into Claude Code's .mcp.json?

Not as is. Both use an mcpServers object, but Claude Code treats an entry with no "type" as a stdio server, so a remote server with only a "url" is skipped with an error until you add "type": "http". Environment variables also differ: Cursor writes ${env:NAME}, Claude Code writes ${NAME} or ${NAME:-default}.

Does Codex support project-level MCP servers?

Yes. Current Codex docs let you add [mcp_servers.<name>] tables to .codex/config.toml in the repo. Codex loads project .codex/ layers only for trusted projects, and the config closest to your working directory wins. The ChatGPT desktop app, Codex CLI and IDE extension share this configuration.

How do I keep API keys out of a committed MCP config?

Commit only variable references. In Claude Code use ${TOKEN} in .mcp.json, in Cursor use ${env:TOKEN}, and in Codex name the variable with bearer_token_env_var, env_http_headers or env_vars instead of writing the value. Each developer sets the variable in their own shell. Codex stores an OAuth client secret in config.toml, so keep that kind of setup in your personal ~/.codex/config.toml.

Why does my project MCP server not show up in Claude Code?

Claude Code asks you to approve project servers from .mcp.json in an interactive session. Until you do, claude mcp list shows the server as pending approval. Run claude in the folder and accept the trust dialog and the server prompt. To ask again later, run claude mcp reset-project-choices.

Sources

Official docs, checked 2026-10-29.

Get the free rules sampler + new tips by email

Confirm your email and we'll send you straight to the sampler download. Then one short email every two weeks covering tool format changes (Cursor, Claude Code, Codex, Windsurf, Copilot), new rules and kit updates. No spam.

We store only your email, with our email provider Resend. See the privacy policy.

Unsubscribe anytime from any email. Rather skip email? Get the sampler on GitHub or download the zip directly.