Claude Code documents two variable forms—${VAR} and ${VAR:-default}—for five .mcp.json fields: command, args, env, url, and headers. A report testing Claude Code 2.1.278 on macOS found that bare $VAR stayed literal, while nested defaults behaved inconsistently: they remained partly literal in most tested fields but resolved in headers. That header result is an observation, not a supported feature.
What Claude Code officially supports in .mcp.json
Anthropic’s Claude Code MCP reference says environment-variable expansion is supported in .mcp.json using two forms:
As an Amazon Associate I earn from qualifying purchases.
${VAR}expands to the environment variable’s value.${VAR:-default}uses the variable’s value when set, or the supplied default when it is unset.
The documented fields are command (server executable), args (command-line arguments), env (environment passed to the server), url (HTTP server URL), and headers (HTTP request headers). For reliable configuration, use these documented forms rather than assuming shell syntax or repeated expansion will work.
Does Claude Code expand bare $VAR?
Not according to the reported test. In a report published by Rulestack on September 28, 2026 and edited October 3, the author tested Claude Code 2.1.278 on macOS with Node v22.22.2. Bare $PROBE_SET remained literal in the tested fields; the report says a bare-dollar value in command failed to launch. This is configuration interpolation, not shell expansion: the report does not establish that Claude Code passes the text through a shell for variable substitution.
#1 Best Overall
What happens when a variable is unset?
For an ordinary variable referenced as ${VAR} without a default, Anthropic says the configuration still loads, claude mcp list warns, and the ${VAR} text remains unexpanded. The author’s test likewise reported that ${PROBE_UNSET} stayed literal.
To provide a fallback, use ${VAR:-default}. The report found ${PROBE_UNSET:-fallback} expanded to the fallback in the tested args, env, url, and headers cases. When a variable was set, ${PROBE_SET:-fallback} used its value rather than the fallback.
Rank #2
Do the two documented forms behave the same in all five fields?
The documentation lists all five fields as supported expansion locations. The test report’s detailed examples cover several fields and reveal why its findings should not be read as a complete field-by-field guarantee. The author used a small stdio server to record arguments and environment, then a separate HTTP server to log requests and headers, and reported that the spawn log and tool result agreed byte for byte.
| Form or case | Documented contract | Reported test result |
|---|---|---|
${PROBE_SET} |
Expands to the variable value. | Expanded in tested args and env cases. |
${PROBE_UNSET:-fallback} |
Uses the fallback when the variable is unset. | Expanded to the fallback in tested args, env, url, and headers cases. |
${PROBE_SET:-fallback} |
Uses the set value instead of the fallback. | Expanded to the set value. |
$PROBE_SET |
Not a documented expansion form. | Stayed literal in tested fields; the reported command case failed to launch. |
${PROBE_UNSET} |
Without a default, remains unexpanded with a warning when unset. | Stayed literal in the reported test. |
These observations are from one version and setup, not an independent benchmark. They do not establish that every field or later release will behave identically.
Rank #3
Can .mcp.json use nested variable defaults?
The report tested ${PROBE_UNSET:-${PROBE_SET}}. It remained partly literal in command, args, env, and url, but resolved to the set value in headers. The author also found that a header value containing a variable whose value was itself ${PROBE_SET} resolved to the inner value.
The author inferred that headers received a second expansion pass. Anthropic’s reference documents the two basic forms and the five fields, but does not document this repeated header expansion. Do not depend on nested or indirect expansion as a configuration contract; put the final intended value directly in an environment variable or use a simple documented fallback.
Rank #4
Why can credential variables be empty in remote headers?
Anthropic documents special handling for selected credential-like variable names in remote url and headers: Claude Code reads them as empty, whether set or unset, and ignores a :-default fallback. Listed examples include ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, AWS_BEARER_TOKEN_BEDROCK, HTTPS_PROXY, and NPM_TOKEN. The Rulestack report specifically found that NPM_TOKEN, both with and without a fallback, arrived as an empty header value.
Free tools Windows power users keep installed
One-click scans. No signup required.
If a remote server needs such a value, Anthropic says to copy it into a differently named variable and reference that variable. This exception concerns the documented protected names in remote URL and header expansion; it should not be confused with the ordinary unset-variable behavior.
Best Value
What to do with CLAUDE_PROJECT_DIR
Anthropic notes that CLAUDE_PROJECT_DIR is set in the spawned MCP server’s environment rather than Claude Code’s own environment. As a result, using it for expansion in project-level command or args may require a fallback such as ${CLAUDE_PROJECT_DIR:-.}. Alternatively, let the server read CLAUDE_PROJECT_DIR from its process environment.
Practical rules for MCP configuration
- Use
${VAR}for a required value and${VAR:-default}when a fallback is appropriate. - Do not substitute bare
$VARor assume that nested defaults will be evaluated recursively. - For an unset ordinary variable, check
claude mcp listfor the documented warning and confirm the resulting configuration. - For protected credential names in remote URLs or headers, use a differently named copy if the remote service must receive the value.
- Treat the reported header second-pass behavior as version-specific observation, not a supported workaround.
MCP is an open-source standard for connecting AI applications to external systems such as data sources, tools, and workflows; Claude Code describes uses including issue trackers, databases, monitoring data, and design integrations. For the protocol’s overview, see the Model Context Protocol introduction. For Claude Code’s current configuration reference, consult Anthropic’s MCP documentation. The test details are in the Rulestack report.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




