Skip to content

cmd 1.4.6 sends literal ${...} placeholders in HTTP MCP headers and stdio env values #599

Description

@kartikkabadi

TL;DR: I set "x-api-key": "${EXA_API_KEY}" in mcp.json and cmd literally sends the string ${EXA_API_KEY} to the server, so every API-key MCP gets a 401. Same for stdio env values. I had to write a stdio proxy to make exa and peekaboo work. Want to delete the workaround.

From here on the slop:

Summary:
mcp.json values like "x-api-key": "${EXA_API_KEY}" are sent to the server as the literal string ${EXA_API_KEY} instead of being resolved from the environment. The same happens for env values passed to stdio MCP servers. This breaks all API-key authenticated HTTP MCP servers and makes stdio env values useless.

Expected behavior:
Placeholders are resolved at runtime from process.env before they are sent or passed to the child.

Actual behavior:
The raw ${VAR} text is sent, causing HTTP 401 errors for servers like exa and peekaboo.

Steps to reproduce:

  1. cmd mcp add --transport http exa https://mcp.exa.ai/mcp --header "x-api-key: \${EXA_API_KEY}"
  2. cmd -p 'use exa to search for something'
  3. exa returns 401 because the header value is the literal string ${EXA_API_KEY}.

I confirmed this with a local fake MCP server: the incoming HTTP header was authorization: Bearer ${FAKE_TOKEN}.

Version: 1.4.6
OS: macOS
Terminal/shell: ghostty / zsh

Additional context:

  • cmd mcp get exa redacts the header, so the bug is not visible there.
  • droid and other clients expand the same placeholders correctly.
  • env values for stdio servers are also passed literally, overriding any inherited env var with the placeholder text.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions