[BUG] ${VAR} substitution not applied to .mcp.json headers values (HTTP transport)
Environment
- Claude Code version: 2.1.112
- OS: Windows 10 Pro (native, not WSL)
- Terminal: bash (Git Bash)
Bug Description
In .mcp.json for an HTTP-transport MCP server, ${ENV_VAR} placeholders in the headers map are not substituted with the environment variable value. The literal string ${ENV_VAR} is sent to the server. The same substitution works correctly in the env block for stdio-transport servers.
This is the same root cause as the previously reported (and bot-auto-closed) #6204. Filing a fresh report per that thread's guidance ("please file a new issue and reference this one"), adding native-Windows repro and additional diagnostic evidence.
Steps to Reproduce
- Set env var in the shell that launches Claude Code:
``bash`
export STITCH_API_KEY="AQ.Ab8..."
"env"
(Also confirmed set via block in .claude/settings.local.json` — same result.)
- Configure
.mcp.json:
``json``
{
"mcpServers": {
"stitch": {
"type": "http",
"url": "https://stitch.googleapis.com/mcp",
"headers": {
"X-Goog-Api-Key": "${STITCH_API_KEY}"
}
}
}
}
- Start Claude Code.
claude mcp listshows✓ Connectedbecauseinitializeis unauthenticated on this server.
- Invoke any tool → server returns 401 because Claude Code sent no key. Claude Code then attempts OAuth DCR, which Google does not support, so the tool becomes unusable.
Expected Behavior
${STITCH_API_KEY} in headers should be substituted with the env var value, exactly as it is in env blocks.
Actual Behavior
Placeholder sent verbatim. Verified with a mitmproxy between Claude Code and the server — header value is the literal string \${STITCH_API_KEY}.
Workaround
Hardcode the secret directly in headers, then gitignore .mcp.json. Functional but defeats the whole point of env-var substitution.
"headers": { "X-Goog-Api-Key": "AQ.Ab8...actual-value..." }
Impact
Any remote MCP server requiring API-key-style header auth (Google Cloud services, internal enterprise MCP gateways, etc.) cannot use secrets hygiene with Claude Code's .mcp.json — forced to either paste secrets into source control or build a local command wrapper.
Related
- #6204 (closed by stale-bot; still reported as occurring by multiple users at close time)
- #16497 (meta: auto-close bot closing live bugs)
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗