AgentFixFind a fix
Claude CodePartial workaroundUpdated Aug 20, 2026

Claude Desktop passes a literal ${VAR} to an MCP server

Diagnose Claude Desktop on Windows when an MCP env value stays as a literal ${VAR}, while the same user-scope configuration expands in Claude Code CLI.

Exact error

Match the message before using the fix

MCP server receives the literal string ${VAR}${MY_SECRET} is not expanded in mcpServers.<name>.envMCP server connects but authentication falls back to anonymous access

Quick answer

Start here

Test with a non-secret sentinel value first. If Claude Code CLI expands `${VAR}` but Claude Desktop passes the placeholder literally on the same machine, restarting Windows will not address the confirmed branch. Use the CLI for that MCP server, or use a server-documented secret-file option such as `<VAR>_FILE`. Do not paste a real token into troubleshooting output or leave it hardcoded in `.claude.json`.

Diagnosis

Why it happens

  • In the confirmed Windows report, the Desktop app had the environment variable but skipped placeholder substitution in its MCP spawn path.
  • The server started normally and received the literal placeholder, so the visible symptom appeared later as an authentication or anonymous-access failure.
  • A missing process environment variable is a different branch: current Claude Code documentation says an unset required variable should fail configuration parsing rather than be passed through literally.

Safest first

Fixes, in order

01

Prove literal substitution failure without exposing a secret

Applies when: When an MCP server starts in Desktop but authentication or configuration is unexpectedly wrong

A harmless sentinel separates skipped `${VAR}` expansion from stale credentials, a missing variable, or a server-side authentication problem.

  1. Create a temporary non-secret user environment variable with a recognizable value such as `agentfix-env-test`.
  2. Reference that test variable in the same MCP `env` location that is failing.
  3. Use a test tool or redacted debug output that can show only the sentinel value; never print the real token.
  4. Compare the same configuration in Claude Code CLI and Claude Desktop.

Expected: CLI returns the sentinel value while Desktop returns the literal `${TEST_VAR}`, matching the confirmed bug branch.

02

Run the affected MCP server through Claude Code CLI

Applies when: When the same user-scope configuration expands correctly in CLI

The original reporter confirmed the CLI path expands the placeholder on the same Windows machine.

  1. Keep the secret in the user environment rather than copying it into JSON.
  2. Start Claude Code CLI from a fresh shell that inherits the variable.
  3. Connect to the same user-scope MCP server.
  4. Verify authentication with a harmless read-only MCP call.

Expected: The server receives the expanded value and authenticates without plaintext secrets in the MCP configuration.

03

Use a documented secret-file option

Applies when: Only when the specific MCP server documents a `<VAR>_FILE` or equivalent file-based credential setting

The reporter used the server's file convention as a Desktop workaround; it is not a universal MCP feature.

  1. Check the MCP server's official documentation for its exact file-based variable name.
  2. Store the secret in a file readable only by the intended Windows user.
  3. Pass the non-secret file path in the documented configuration field.
  4. Remove the temporary sentinel and restart Desktop.

Expected: The server reads the credential from its protected file without relying on Desktop placeholder expansion.

Verification

Prove the fix worked

  1. Use a read-only MCP operation that requires authentication.
  2. Confirm logs do not contain a literal `${VAR}` and do not contain the secret value.
  3. Reopen the chosen client and verify the server still authenticates.

Escalation

If it still fails

  • Confirm whether the definition comes from user, project, plugin, or another higher-precedence scope.
  • Check that the variable exists in the client process without printing its value.
  • Do not treat hardcoding a token in `.claude.json` as the preferred repair; rotate any secret that was exposed during testing.

Scope

Environment and version notes

  • The first-hand Desktop report used Claude Desktop 1.24012.1, Claude Code CLI 2.1.215, and Windows 11 Pro.
  • The issue remained open on August 20, 2026. The npm registry listed Claude Code 2.1.237, but no Desktop fixed version was confirmed.
  • Sources rechecked August 20, 2026.

Evidence

Sources

Source labels describe the evidence available on the checked date. A closed issue is not automatically a shipped fix.