Use the same MCP servers in Claude Code, Codex and Cursor
Claude Code, Codex and Cursor all run the same MCP servers, but each stores them in its own file and format. This guide maps the formats side by side, converts one server across all three, and adds up the context cost of the tested agent tools and MCP servers you plan to enable. Every format claim links the vendor's official docs, checked 2026-10-26.
- Claude Code:
.mcp.json(project) or~/.claude.json, JSONmcpServers. - Codex:
~/.codex/config.tomlor project.codex/config.toml, TOML[mcp_servers.name]. - Cursor:
.cursor/mcp.jsonor~/.cursor/mcp.json, JSONmcpServers. - Same command or URL everywhere; only the wrapper and the env-var syntax change.
Formats · Worked example · Env vars and secrets · Gotchas · Context budget picker · FAQ
Want a ready mcpServers block instead? Our MCP config generator builds one from tested servers with each server's env var names.
Config formats and locations
| Claude Code | Codex | Cursor | |
|---|---|---|---|
| Config file (project) | .mcp.json in the project root (project scope, meant to be committed) | .codex/config.toml in the project (trusted projects only) | .cursor/mcp.json in the project |
| Config file (personal) | ~/.claude.json: local scope (this project only, the default) or user scope (all projects) | ~/.codex/config.toml (default) | ~/.cursor/mcp.json (all projects) |
| Format | JSON, servers under mcpServers | TOML, one [mcp_servers.<name>] table per server | JSON, servers under mcpServers |
| Add from CLI | claude mcp add [--scope local|project|user] <name> -- <command>; claude mcp add-json | codex mcp add <name> --env K=V -- <command> | No CLI add in the docs we read; edit mcp.json or use Customize / Marketplace |
| stdio fields | command, args, env | command, args, env, env_vars (names to forward), cwd | type: "stdio", command, args, env, envFile |
| Remote fields | type: "http" (required with url; alias streamable-http), url, headers, headersHelper | url, bearer_token_env_var, http_headers, env_http_headers, http_headers_helper | url, headers, auth (static OAuth) |
| Env var syntax in config | ${VAR}, ${VAR:-default} | No interpolation syntax; name the variable (env_vars, bearer_token_env_var, env_http_headers) | ${env:NAME}, plus ${workspaceFolder}, ${userHome} |
| OAuth sign-in | /mcp or claude mcp login <name> | codex mcp login <name> | Customize / one-click; PKCE, dynamic or static client |
| List / check | claude mcp list, /mcp | codex mcp list, /mcp in the TUI | Customize; Output panel → MCP Logs |
| Source (checked 2026-10-26) | docs | docs | docs |
Claude Code scopes, from its docs: local (default; this project, only you, in ~/.claude.json), project (.mcp.json, shared through version control) and user (all your projects, in ~/.claude.json). If one name is defined in more than one scope, local wins over project, project over user, and entries are not merged (Anthropic: Claude Code MCP docs). Codex says the ChatGPT desktop app, Codex CLI and IDE extension share the same config.toml (OpenAI: Codex MCP docs). Cursor reads project .cursor/mcp.json and global ~/.cursor/mcp.json (Cursor: MCP docs).
stdio vs remote HTTP
A stdio server is a command the client starts on your machine (npx, uvx, a binary). A remote server is a URL using Streamable HTTP. All three clients support both (Anthropic: Claude Code MCP docs; OpenAI: Codex MCP docs; Cursor: MCP docs). The difference is how you mark a remote entry: Claude Code needs "type": "http" next to url, and skips an entry that has a url but no type (it prints a warning and the other servers still load); Codex treats a table with url as Streamable HTTP; Cursor accepts url on its own. SSE is deprecated in Claude Code's docs. More on running remote servers: how to host an MCP server.
Worked example: Context7 in all three clients
Context7 (@upstash/context7-mcp) is a server we test (listing) and the example Codex's own docs use. The stdio version needs no key. Add it the same way in each client:
Claude Code
CLI (local scope; add --scope project to write .mcp.json):
claude mcp add --transport stdio context7 -- npx -y @upstash/context7-mcpOr in .mcp.json:
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"]
}
}
}Codex
CLI:
codex mcp add context7 -- npx -y @upstash/context7-mcpOr in ~/.codex/config.toml:
[mcp_servers.context7]
command = "npx"
args = ["-y", "@upstash/context7-mcp"]Cursor
In .cursor/mcp.json or ~/.cursor/mcp.json:
{
"mcpServers": {
"context7": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"]
}
}
}Remote variant with an API key
Context7's README gives a remote URL, https://mcp.context7.com/mcp, with the key in an Authorization: Bearer header (Context7 README). Export CONTEXT7_API_KEY in your shell, then reference it instead of pasting it. We have tested the stdio package, not this remote endpoint.
Claude Code .mcp.json:
{
"mcpServers": {
"context7": {
"type": "http",
"url": "https://mcp.context7.com/mcp",
"headers": { "Authorization": "Bearer ${CONTEXT7_API_KEY}" }
}
}
}Codex config.toml:
[mcp_servers.context7]
url = "https://mcp.context7.com/mcp"
bearer_token_env_var = "CONTEXT7_API_KEY"Cursor mcp.json:
{
"mcpServers": {
"context7": {
"url": "https://mcp.context7.com/mcp",
"headers": { "Authorization": "Bearer ${env:CONTEXT7_API_KEY}" }
}
}
}Env vars and secrets
- Claude Code expands
${VAR}and${VAR:-default}incommand,args,env,urlandheaders. An unset variable with no default stays as literal text, with a warning. In a remote server'surlandheaders, Claude Code's own and cloud-provider credentials such asANTHROPIC_API_KEYalways read as empty; copy the value into a variable with your own name (Anthropic: Claude Code MCP docs). - Codex has no
${}syntax in the docs we read: set values in[mcp_servers.name.env], list names to forward inenv_vars, or name the variable inbearer_token_env_var/env_http_headers. A client secret passed tocodex mcp add --oauth-client-secretis saved inconfig.toml, so keep that file private (OpenAI: Codex MCP docs). - Cursor uses
${env:NAME}incommand,args,env,urlandheaders; stdio servers can also load anenvFile, remote servers cannot (Cursor: MCP docs). - See our API key rotation checklist and MCP servers that need an API key or sign-in.
Gotchas
- Headless runs load project servers. Anthropic's docs say that in
claude -pruns and Agent SDK sessions Claude Code cannot show the approval prompt and loads project-scoped servers from.mcp.jsonwithout asking. To keep one out, add it todisabledMcpjsonServers, exclude project settings with--setting-sources, or use--strict-mcp-configwith--mcp-config(Anthropic: Claude Code MCP docs). Check this before runningclaude -pin a repo you cloned. - A
urlwithouttypeis skipped in Claude Code. Claude Code prints a warning (Skipped — invalid MCP server config) and the other servers still load, so that server just doesn't appear. Add"type": "http"to Cursor-style remote entries. - Different variable syntax.
${VAR}(Claude Code) vs${env:VAR}(Cursor). Copying one into the other leaves a literal string. - Codex project config needs a trusted project, per its docs.
- Server names:
claude mcpaccepts only letters, numbers, hyphens and underscores. - Timeouts differ: Codex defaults to 10 s startup and 60 s per tool call (
startup_timeout_sec,tool_timeout_sec); Claude Code usesMCP_TIMEOUTand a per-servertimeout. --matters in bothclaude mcp addandcodex mcp add: everything after it is the server command.
Context budget picker
Every server you enable sends its tool definitions to the model. Tick the servers you plan to keep on in all three clients to see the sum. Figures are the same measured numbers as our lowest context cost ranking: 107 of 187 servers we list have a measured tools/list; the rest show not measured and add nothing.
How the tokens are counted
Method: tiktoken cl100k_base over the compact JSON of each tool's name, description and inputSchema, from the tools/list we captured (latest capture 2026-10-31). It is an approximation: Claude, GPT and other models use their own tokenizers, and each client adds its own wrapping, so the real count in your session will differ. Some clients also load tools on demand rather than all up front (Claude Code documents a tool search mode, docs).
Loading…
Ticked servers stay in the total even when the filter hides them. Clear unticks everything and empties the filter.
- Needs JavaScript. The full list is on the ranking page.
FAQ
Can Claude Code, Codex and Cursor share one config file?
No. Claude Code and Cursor both use JSON with an mcpServers key, but in different files; Codex uses TOML in config.toml. The server command or URL is the same in all three, so you copy the entry and convert the format.
Where does each client keep project MCP servers?
Claude Code: .mcp.json in the project root. Codex: .codex/config.toml in the project, for trusted projects only. Cursor: .cursor/mcp.json in the project. Checked on each vendor's docs on Oct 26, 2026.
Does claude -p start project .mcp.json servers without asking?
Yes, per Anthropic's docs: in claude -p runs, Agent SDK sessions and some cloud sessions, Claude Code cannot show the approval prompt and loads project-scoped servers without asking. Block one with disabledMcpjsonServers, or start with --strict-mcp-config and pass only --mcp-config.
How do I keep API keys out of a shared config?
Reference an environment variable instead of pasting the value: ${VAR} in Claude Code's .mcp.json, ${env:VAR} in Cursor's mcp.json, and bearer_token_env_var, env_vars or env_http_headers in Codex. Do not commit files that hold real keys.
How many MCP servers should I turn on?
There is no single number. Use the context budget picker on this page to add up the tool definitions of the servers you want, then turn off what you do not use in that project.
Testing status (2026-10-26)
We ran Claude Code and Codex logged out, with an isolated HOME (none of our own configs or tokens). What we saw:
- Claude Code skipped a
urlentry with notype, printed a warning, and kept loading the other servers. - Codex read the project
.codex/config.tomlonly after we marked the project trusted. - A Codex stdio server did not get environment variables missing from
env_vars. - The stdio Context7 server lists 2 tools when we query it directly. It shows Connected in
claude mcp listand enabled incodex mcp list.
Not tested: listing tools inside each client (needs a login), whether claude -p starts project servers automatically (needs a login, so that Gotcha comes from Anthropic's docs), Cursor (not on our test machine), and every remote variant (we had no API key).
What we haven't tested
- Cursor, and tool listing inside Claude Code and Codex: apart from the testing status above, the formats come from each vendor's docs.
- The remote Context7 endpoint, in any client.
- Each client's real token count in a session (the picker uses one tokenizer for all).
No product here is rated or ranked, and this page has no affiliate links. How we test: methodology.
Sources (accessed 2026-10-26)
- Anthropic: Connect Claude Code to tools via MCP
- OpenAI: Codex Model Context Protocol
- Cursor: Model Context Protocol (MCP)
- Upstash Context7 README
Docs checked 2026-10-26