Claude Desktop reads claude_desktop_config.json; each server lives under mcpServers, with command plus args for a stdio launch, or a url field for a remote Streamable HTTP server.
Think of the config file as a contacts list for tools. Claude Desktop reads one JSON file at startup to learn which tool servers exist. Under a single mcpServers heading, each server gets a name and instructions for reaching it. A local server is like a program on your machine, so you give the command to run it plus the args, the arguments handed to that command, exactly as you would type them in a terminal. A remote server already runs somewhere on the network, so instead of launching anything you just hand over its url. Same address book, two ways to write a contact: dial a local number, or point at a web address.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Configuring an MCP server in Claude Desktop is mostly a matter of knowing one file, one key, and a small branch based on transport. Candidates lose points not because the structure is hard, but because they blur the fields together or forget which ones belong to a local versus a remote server. The fill-in here is really a probe of whether you have actually wired a server up by hand, because the answers are memorable only once you have.
The mental model is simple. Claude Desktop is the host. At startup it reads a JSON file, learns which servers exist, and either launches them locally or connects to them over the network. Once connected, it runs the MCP handshake, asks each server what it can do, and exposes the resulting tools to the model. Your entire job in the config is to describe, per server, how the host should reach it. The protocol takes over from there.
This deep dive names every field in the fill-in, explains what each one does, walks the stdio launch sequence step by step, contrasts it with the remote Streamable HTTP shape, covers the env field for secrets, and closes with the operational gotchas that separate a working config from one that silently loads nothing.
The file and the top-level key
Claude Desktop reads a single JSON file named claude_desktop_config.json. It lives in the per-user application support directory; the exact path depends on the operating system, and the Settings dialog can open it for editing directly. On macOS it sits under the Claude application support folder, and on Windows under the per-user app data path. The host reads this file once, at launch, which has consequences we return to later.
Inside the file, the key that matters is mcpServers. It is an object whose keys are server names you invent, such as filesystem, github, or postgres, and whose values are connection specs. The names are labels only. They let you disambiguate servers, read logs, and resolve tool-name collisions when two servers expose the same tool, but the labels carry no behavior themselves. You can register as many servers under this one key as you like; the host connects to each independently.
The single most common structural mistake is putting server entries at the top level of the JSON instead of nesting them under mcpServers. The host looks only inside that object, so a misplaced entry is simply invisible. There is no error popup, no warning toast; the server just never appears in the tool list. This silent-failure behavior is exactly why naming the mcpServers key correctly is the first thing an interviewer probes.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"],
"env": { "LOG_LEVEL": "info" }
},
"remote-tools": {
"url": "https://tools.example.com/mcp"
}
}
}| Field | stdio (local) server | Streamable HTTP (remote) server |
|---|---|---|
| Top-level key | mcpServers | mcpServers |
| How it connects | command + args spawn a subprocess | url points at an HTTP endpoint |
| Wire transport | JSON-RPC over stdin/stdout | JSON-RPC over Streamable HTTP |
| Where secrets go | env object (process env vars) | OAuth bearer token on the transport |
Real products, models, and research that use this idea.
- A filesystem server entry sets command to npx and args to the @modelcontextprotocol/server-filesystem package plus an allowed directory.
- A GitHub server uses command npx with the GitHub MCP package and an env block holding a personal access token.
What an interviewer would ask next. Try answering before peeking at the approach.
QWhy does a stdio server's command often need an absolute path or a launcher like npx?
The spawned subprocess does not inherit your interactive shell PATH; talk about the launch environment and how npx self-resolves the package.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Putting servers at the JSON top level instead of under mcpServers, or expecting command and args to work for a remote server that needs url.
60 second bullets to scan on the way to the call.
The exact config file name Claude Desktop reads
The single top-level key all servers nest under
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.