Product 3 Sep 2026 · 3 min read

Where every MCP client keeps its config: the file, the shape and the reload rule

Fifteen clients, no shared file, no shared schema and no shared idea of when a change takes effect. One table, and the three mistakes that account for nearly every "the tools do not appear".

MR mcprush team · The people who run the gateway

There is no standard config file for MCP and there is not going to be one. Each client owns its own, in its own format, in its own place, with its own rule for when an edit is noticed. The protocol standardised what travels over the wire; it said nothing about the file that starts the conversation, which is why the same server is a different three lines in every editor on the team.

One install, many destinations. The reload rule under each box is the part that costs people an afternoon.One install, many destinations. The reload rule under each box is the part that costs people an afternoon.
One install, many destinations. The reload rule under each box is the part that costs people an afternoon.

One caveat before the table, because it is the honest one: paths and keys move when clients ship. Where this reference and a client’s own documentation disagree, the client wins, and the fastest way to find the current truth is to let the client write the entry itself — most now have an add command — and read what it wrote.

The clients that have a command

Five clients take a server from a command line, which is the least error-prone way in because the client writes its own file. The flags differ, and a remote server that takes a bearer key needs it as a header on every one of them.

# Claude Code — project scope by default; --scope user for everywhere claude mcp add issues -- npx -y @you/issues-mcp claude mcp add --transport http issues https://…/mcp --header "Authorization: Bearer $KEY" # Codex — the key goes in ~/.codex/config.toml as bearer_token_env_var codex mcp add issues -- npx -y @you/issues-mcp codex mcp add issues --url https://…/mcp # Gemini CLI — writes ~/.gemini/settings.json gemini mcp add issues npx -y @you/issues-mcp gemini mcp add --transport http issues https://…/mcp --header "Authorization: Bearer $KEY" # Grok Build — ~/.grok/config.toml; --scope project keeps it with the repo grok mcp add issues -- npx -y @you/issues-mcp grok mcp add --transport http issues https://…/mcp --header "Authorization: Bearer $KEY" # VS Code — the JSON has to survive the shell, so it is quoted code --add-mcp '{"name":"issues","command":"npx","args":["-y","@you/issues-mcp"]}'
Five commands, five files. The header flag is the line that decides whether a remote entry connects.

The clients configured by file

The rest read a file you edit by hand, and the file is where the mistakes live. The shape is nearly the same everywhere — a map of names to entries — but the top-level key, the field names for a remote server and the header syntax differ enough that pasting one client’s entry into another’s file produces a config that parses and never connects.

ClientFileTop-level key · remote fieldsPicks it up
Claude Desktopclaude_desktop_config.json (Application Support / %APPDATA% under Claude)mcpServers · type: "http", url, headersOn launch only — quit and reopen
Cursor~/.cursor/mcp.json, or .cursor/mcp.json in a projectmcpServers · type: "http", url, headersWithout a restart
VS Code.vscode/mcp.json in a workspace, or the user-level fileservers · type: "http", url, headers; secrets via inputsOn window reload
Devin Desktop (formerly Windsurf)~/.config/devin/mcp_config.json, %APPDATA%\devin\mcp_config.json on Windows (legacy Cascade agent)mcpServers · serverUrl (or url), headersNot documented; save the file
Zedsettings.jsoncontext_servers · url, headersOn save
Codex~/.codex/config.toml[mcp_servers.name] · url, bearer_token_env_varNext session
Gemini CLI~/.gemini/settings.jsonmcpServers · httpUrl, headersNext session
Grok Build~/.grok/config.toml; also reads .mcp.json and .cursor/mcp.jsonTOML tables · url, headersNext session
DeepSeek harnessThe harness YAML, one entry per server@deepseek-ai/dsh-mcp-client plugin · transport, url, headersOn restart
Four of these spell the remote address differently — url, serverUrl, httpUrl and a TOML key — for the same server. Copying between files is how "it parses and never connects" happens.

On Windows, paths, npx and backslashes add failures of their own: MCP on Windows has them.

Two of the shapes, side by side, because they are the two most often pasted into the wrong file:

// Cursor and Claude Desktop — the same shape { "mcpServers": { "issues": { "type": "http", "url": "https://…/mcp", "headers": { "Authorization": "Bearer <your key>" } } } } // VS Code — a different top-level key, and the secret behind a prompt { "inputs": [{ "id": "issues-key", "type": "promptString", "password": true }], "servers": { "issues": { "type": "http", "url": "https://…/mcp", "headers": { "Authorization": "Bearer ${input:issues-key}" } } } }
VS Code keeps the key out of the repository; every other file above holds it in plain text on disk.

The clients with no file at all

  • ChatGPT. Settings → Connectors for a remote server, or Settings → MCP servers in the desktop app for a local one. In the API, a remote server is a type: "mcp" tool on the request with the URL and an authorization string.
  • Copilot Studio. Tools → Add a tool → Model Context Protocol, with the address. It runs in Microsoft’s cloud, cannot start a process on your machine, and speaks Streamable HTTP only — a server that offers SSE alone will not connect.
  • Perplexity (macOS app). Settings → Connectors → Add Connector, and the launch command goes in the Command field. Local servers only, for now.
  • OpenAI Agents SDK. No file: MCPServerStreamableHttp in code, with the URL and the header in params.
  • Plain HTTP. Any HTTP client that can POST JSON with a bearer header is an MCP client for the purposes of a script.

The three mistakes

The server’s view and the client’s view of one install. When they disagree, the file is wrong — and the file is the only thing edited by hand.The server’s view and the client’s view of one install. When they disagree, the file is wrong — and the file is the only thing edited by hand.
The server’s view and the client’s view of one install. When they disagree, the file is wrong — and the file is the only thing edited by hand.
  • The wrong file. Two levels — project and user — both exist, and the one you edited is not the one being read. Claude Code alone has three scopes. Check which file the client is reading before changing any of them.
  • The wrong reload rule. Claude Desktop reads its config at launch and only then. Cursor watches the file. VS Code wants the window reloaded. A correct entry under the wrong assumption looks identical to a broken one.
  • The key in the wrong place. A remote entry without its header parses cleanly and answers 401 on the first call. A local entry with the key in args rather than env puts the secret in the process list.

And the trailing comma, which is not a mistake about MCP at all: every one of these files is JSON or TOML, and a client that cannot parse its config almost always says nothing. When the tools do not appear and nothing is logged, validate the file before you doubt the server.