Skip to content

[BUG] ${VAR} substitution not applied to .mcp.json headers values (HTTP transport) #51581

Description

@Alish3r

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

  1. Set env var in the shell that launches Claude Code:

    export STITCH_API_KEY="AQ.Ab8..."

    (Also confirmed set via "env" block in .claude/settings.local.json — same result.)

  2. Configure .mcp.json:

    {
      "mcpServers": {
        "stitch": {
          "type": "http",
          "url": "https://stitch.googleapis.com/mcp",
          "headers": {
            "X-Goog-Api-Key": "${STITCH_API_KEY}"
          }
        }
      }
    }
  3. Start Claude Code. claude mcp list shows ✓ Connected because initialize is unauthenticated on this server.

  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:mcpbugSomething isn't workinghas reproHas detailed reproduction stepsplatform:windowsIssue specifically occurs on Windows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions