The short answer
Claude Code uses .mcp.json in the project and ~/.claude.json for you. Cursor uses .cursor/mcp.json and ~/.cursor/mcp.json. VS Code reads a root .mcp.json or .vscode/mcp.json. Windsurf reads ~/.config/devin/mcp_config.json on macOS and Linux. Gemini CLI uses settings.json, Codex uses config.toml, and Claude Desktop has its own file in Application Support. The table below has every path, with its source.
Deedglass
A tool call meets your rules before it runs
Asks to run
DELETE FROM visits;
Deletes every row in visits
Deedglass checks your rules
- Reading dataAllowed
- Deleting a whole table (DROP, TRUNCATE)Never
- Changing or deleting rows without saying which (WHERE)This one
- Other changesWait for a person
The table
| Client | Project file | User file | Top-level key |
|---|---|---|---|
| Claude Code | .mcp.json (project scope)1 |
~/.claude.json (local and user scopes)1 |
mcpServers |
| Claude Desktop | none | macOS ~/Library/Application Support/Claude/claude_desktop_config.json; Windows %APPDATA%\Claude\claude_desktop_config.json2 |
mcpServers |
| Cursor | .cursor/mcp.json3 |
~/.cursor/mcp.json3 |
mcpServers |
| VS Code (portable) | .mcp.json at the workspace root4 |
~/.copilot/mcp-config.json4 |
mcpServers |
| VS Code (its own format) | .vscode/mcp.json4 |
the profile’s mcp.json4 |
servers |
| Copilot CLI | .mcp.json4 |
$COPILOT_HOME/mcp-config.json4 |
mcpServers |
| Windsurf (Cascade) | none | ~/.config/devin/mcp_config.json; Windows %APPDATA%\devin\mcp_config.json5 |
mcpServers |
| Gemini CLI | .gemini/settings.json6 |
~/.gemini/settings.json6 |
mcpServers |
| Codex | .codex/config.toml (trusted projects only)7 |
~/.codex/config.toml7 |
[mcp_servers.<name>] |
A few notes the table can’t hold:
- Claude Code’s default scope is local, which is private to you and stored in
~/.claude.jsonunder the project’s path, not in the repository. Only--scope projectwrites.mcp.json.1 So a teammate can have servers in a repository you can’t see in git. - VS Code labels
.vscode/mcp.jsonand the profile file deprecated in its guided flow, and keeps them for compatibility; they’re also the only places withinputs,envFileand per-server sandboxing.4 - Windsurf’s page describes the legacy Cascade agent.5 If you use the newer agent, check its own settings.
- Codex loads a project’s
.codex/config.tomlonly when you’ve trusted the project.7
Three formats, not one
Copying a server between clients is where configs break. There are three shapes:
Code Data in JSON, the format software uses to pass records and settings.
// mcpServers: Claude Code, Claude Desktop, Cursor, portable VS Code, Copilot CLI, Windsurf, Gemini CLI
{ "mcpServers": { "docs": { "command": "npx", "args": ["-y", "some-mcp-server"] } } }
Code Data in JSON, the format software uses to pass records and settings.
// servers: VS Code's own format (.vscode/mcp.json)
{ "servers": { "docs": { "type": "stdio", "command": "npx", "args": ["-y", "some-mcp-server"] } } }
Code A settings file: the rules a tool reads before it acts.
# Codex (config.toml)
[mcp_servers.docs]
command = "npx"
args = ["-y", "some-mcp-server"]
VS Code warns against copying between its two formats without checking.4 Remote servers differ too: Windsurf accepts serverUrl or url,5 and Gemini CLI uses url for SSE and httpUrl for streaming HTTP.6
Keeping secrets out of the file
Every client lets you reference a secret instead of writing it into the file, and they all spell it differently:
| Client | How to reference a secret |
|---|---|
| Claude Code | ${VAR} or ${VAR:-default} in command, args, env, url, headers1 |
| Cursor | ${env:NAME}; or envFile for local servers only3 |
VS Code (servers format) |
an inputs entry with password: true, used as ${input:id}; or envFile4 |
| Gemini CLI | values in the server’s env block6 |
| Codex | env or env_vars in the server’s table7 |
Project files are usually committed. A token written into .mcp.json is in your git history the moment someone commits it, and rotating the token is the only fix. Our post on API keys in .env files covers why agents find secrets so easily.
Limiting tools per server
Most clients can now hide tools a server exposes, which is a cheap way to drop write tools you don’t need:
| Client | Setting |
|---|---|
| Windsurf | disabledTools5 |
| Gemini CLI | includeTools (allow-list) and excludeTools6 |
| Codex | enabled_tools (allow-list), disabled_tools (applied after)7 |
Gemini CLI also has a setting to watch out for: trust: true bypasses every tool call confirmation for that server.6 Search your configs for it. Codex goes the other way with default_tools_approval_mode, which can make a server’s tools prompt by default.7
Hiding a tool in the client is a convenience, not a boundary. The credential behind the server can still do everything it could before. Read-only modes on the server side, or narrower credentials, are the real limit. The MCP security checklist covers those.
Questions people ask
Where is mcp.json in VS Code?
At the workspace root as .mcp.json (the portable format, with mcpServers), or in .vscode/mcp.json (VS Code’s own format, with servers). User-level servers go in ~/.copilot/mcp-config.json or the profile’s mcp.json.4
Where is the Windsurf MCP config file?
For the legacy Cascade agent, ~/.config/devin/mcp_config.json on macOS and Linux, and %APPDATA%\devin\mcp_config.json on Windows.5
Where does Claude Code store MCP servers?
Project-scope servers go in .mcp.json at the project root. Local-scope servers, the default, and user-scope servers are stored in ~/.claude.json.1
Which files an audit tool reads
If you rely on a tool to find your configs, test what it actually reads. We wrote the same filesystem server into twelve of the locations above and ran deedglass 0.13.0’s scan. It found six: .mcp.json, .cursor/mcp.json, .vscode/mcp.json, ~/.cursor/mcp.json, Windsurf’s ~/.config/devin/mcp_config.json and the Claude Desktop file. It did not read Gemini CLI’s settings.json, Codex’s config.toml, ~/.claude.json or Copilot CLI’s mcp-config.json.8 On October 28, 2026 we ran the same test on 0.14.1 and got the same six.8
Code What the screen or file shows, copied as is.
- `.cursor/mcp.json` (cursor): fs (@modelcontextprotocol/server-filesystem)
- `.mcp.json` (claude-code): fs (@modelcontextprotocol/server-filesystem)
- `.vscode/mcp.json` (vscode): fs (@modelcontextprotocol/server-filesystem)
- `~/.config/devin/mcp_config.json` (windsurf): fs (@modelcontextprotocol/server-filesystem)
- `~/.cursor/mcp.json` (cursor): fs (@modelcontextprotocol/server-filesystem)
- `~/Library/Application Support/Claude/claude_desktop_config.json` (claude-desktop): fs (@modelcontextprotocol/server-filesystem)
So for Gemini CLI, Codex and Claude Code’s private scopes, check by hand:
Code Commands typed in a terminal. The text around it says what happens.
grep -n "mcpServers" ~/.gemini/settings.json .gemini/settings.json 2>/dev/null
grep -n "mcp_servers" ~/.codex/config.toml .codex/config.toml 2>/dev/null
claude mcp list
The ten-minute MCP config audit walks through what to look for once you’ve found the files, and scanning configs in CI keeps project files reviewed on every pull request. If you route servers through a proxy instead, see what an MCP gateway adds.
To see which config files on your machine a scan picks up, run npx deedglass scan in a repository. It reads files locally and sends nothing anywhere. What the grade means explains the scan’s letter. To watch the checks without installing anything, open the playground.
Written with AI assistance and checked against our claims register.