Click any words you think contain an error. Click again to unmark.
The `args` value is a single space-delimited string. It must be a JSON array of separate strings, because the host hands it straight to the process spawn as argv.
Think of ordering at a deli counter. If you hand the clerk one sticky note that says 'turkey swiss no mayo on rye', they treat it as one weird sandwich name and look confused. If you list each item separately, turkey, then swiss, then no mayo, then rye, they handle each one correctly. A process launcher works the same way. Each command-line flag, package name, and folder path is a separate instruction. When you cram them into one string, the launcher treats the whole thing as a single mystery argument and the server never starts. Splitting them into an array gives the launcher one clean instruction at a time, exactly the way it expects.
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.
This is a classic spot the error in an MCP server config, and the bug is a single subtle type mistake. The args field is written as one space-delimited string instead of a JSON array of strings. It looks harmless because to a human reader the string contains exactly the right flags and path, in exactly the right order. But the host does not read it the way a human does, and that gap between human intuition and machine behavior is the whole lesson.
The reason this matters comes down to how a Claude Desktop host actually launches a local server. A server entry under mcpServers is a recipe for spawning a child process. The command is the executable to run, and args is the list of arguments handed to that executable. The host passes this list straight into a low-level process-spawn call, where each list element becomes one slot in the process argument vector. Nothing in that path looks at spaces inside a string and decides to split on them.
This deep dive walks through what the config maps onto, what actually goes wrong at launch, how to write the correct shape, why the error message is so misleading, and two adjacent traps that show up constantly in real configs: hardcoded secrets and relative paths. By the end you should be able to name the defect in one sentence and explain the mechanism behind it in an interview.
What the config entry actually describes
An entry under mcpServers is not a generic settings blob. It is a precise instruction for spawning a child process that speaks the stdio transport. The host launches the process, then talks JSON-RPC to it over standard input and standard output. Requests go down the child's stdin, responses come back on its stdout, and that pipe is the entire communication channel.
Three fields drive the launch. The command names the executable, here the npx launcher. The args field is the argument vector handed to that executable. An optional env object supplies environment variables for the child. There is no shell flag and no command-line field; the host is deliberately not running a shell.
The critical detail is the direct mapping. This config maps almost one to one onto a call like child_process.spawn(command, args, { env }) in Node, or execvp at the operating-system level. Both of those take an executable plus an array of arguments. They do not take a command line. That single design choice is the entire reason args must be an array, and it is what the buggy config violates.
Why build it this way at all? Spawning without a shell is the safer default. A shell would interpret spaces, quotes, globs, and variable expansions, which opens an injection surface and makes behavior depend on which shell is installed. By taking an explicit argv array, the host gets deterministic, portable launches across macOS, Linux, and Windows. The cost is that you, the config author, must do the tokenization yourself instead of leaning on a shell to do it.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/alice/projects"],
"env": { "LOG_LEVEL": "info" }
}
}
}| Field | Wrong shape | Correct shape |
|---|---|---|
| args type | Single string | Array of strings |
| How host uses it | One argv element | One element per token |
| npx result | Package not found | Server spawns |
| Secrets | Baked into args | Sibling env object |
| Paths | Relative, may not resolve | Absolute, resolves anywhere |
Real products, models, and research that use this idea.
- The official `@modelcontextprotocol/server-filesystem` server is launched exactly this way in Claude Desktop via an npx command plus an args array.
- Cursor and Zed read the same array-shaped MCP config in 2026, so a malformed args string breaks identically across all three hosts.
What an interviewer would ask next. Try answering before peeking at the approach.
QAfter fixing args, the server still shows as disconnected. How do you debug it?
Run the same command and args by hand in a terminal to see the real error. Then use mcp-inspector to trace the JSON-RPC initialize handshake and check the host logs for the spawn failure.
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.
Writing args as one space-joined string. The host feeds it to spawn as a single argv entry, so the server binary never sees its flags.
60 second bullets to scan on the way to the call.
Why args must be an array and not a string
How command and args map onto a process spawn
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.