gemini-cli - ✅(Solved) Fix Environment Variable Expansion Failure in mcpServers Configuration [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
google-gemini/gemini-cli#25939Fetched 2026-04-25 06:22:06
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
commented ×1cross-referenced ×1labeled ×1renamed ×1

Error Message

than the actual credential, leading to authentication failures (e.g., Error [TokenInvalid]).

Fix Action

Fix / Workaround

Direct Evidence: In Docker logs for the Discord MCP server, the reported "Token length" was exactly 16, which is the character count of the literal string ${DISCORD_TOKEN}. This confirmed that no expansion took place. 2. Scope: The issue appears to affect any key within the mcpServers[name].args array. 3. Workaround: We successfully bypassed the issue for Docker by changing the argument from -e DISCORD_TOKEN=${DISCORD_TOKEN} to just -e DISCORD_TOKEN, which allows Docker to inherit the variable directly from the parent process environment. However, the expansion logic within Gemini CLI itself remains broken. 4. Impact: This makes it impossible to use environment variables for any MCP server that doesn't support direct environment inheritance (e.g., npx based servers where tokens must be passed as CLI arguments).

PR fix notes

PR #25963: fix(mcp): expand env vars in stdio args

Description (problem / solution / changelog)

mcpServers stdio args were passed through to the child process without the env expansion already used for explicit env entries, so placeholders like ${DISCORD_TOKEN} reached Docker unchanged.

This expands each arg against the same environment before spawning and keeps the Xcode mcpbridge special-case check aligned with the final args. Added a regression test covering ${DISCORD_TOKEN} expansion in args.

Fixes #25939

Changed files

  • packages/core/src/tools/mcp-client.test.ts (modified, +33/-0)
  • packages/core/src/tools/mcp-client.ts (modified, +6/-2)
RAW_BUFFERClick to expand / collapse

What happened?

The Gemini CLI fails to expand environment variables using the ${VARIABLE_NAME} syntax when they are used within the args array of an MCP server configuration in settings.json.

Instead of injecting the actual value from the environment, the CLI passes the literal string (e.g., "${DISCORD_TOKEN}") directly to the execution command. In the case of Docker-based MCPs, this causes the container to receive a 16-character string (the literal text ${DISCORD_TOKEN}) rather than the actual credential, leading to authentication failures (e.g., Error [TokenInvalid]).

What did you expect to happen?

I expected the ${VARIABLE_NAME} placeholders in the mcpServers configuration to be replaced with the corresponding values from the host's environment before the server process is spawned.

Client information

Client information

  • Platform: Linux (WSL2 / Ubuntu 24.04)
  • CLI Version: 0.39.1
  • Git Commit: 4d73f3413
  • Session ID: 81bb18df-c7f6-4cf2-bdbe-7eeafca07688
  • Operating System: linux v20.20.2
  • Sandbox Environment: no sandbox
  • Model Version: auto-gemini-3
  • Auth Type: oauth-personal
  • Memory Usage: 245.3 MB
  • Terminal Name: Unknown
  • Terminal Background: #300a24
  • Kitty Keyboard Protocol: Unsupported

Login information

Logging in via Google Account using OAuth Personal authentication.

Anything else we need to know?

Direct Evidence: In Docker logs for the Discord MCP server, the reported "Token length" was exactly 16, which is the character count of the literal string ${DISCORD_TOKEN}. This confirmed that no expansion took place. 2. Scope: The issue appears to affect any key within the mcpServers[name].args array. 3. Workaround: We successfully bypassed the issue for Docker by changing the argument from -e DISCORD_TOKEN=${DISCORD_TOKEN} to just -e DISCORD_TOKEN, which allows Docker to inherit the variable directly from the parent process environment. However, the expansion logic within Gemini CLI itself remains broken. 4. Impact: This makes it impossible to use environment variables for any MCP server that doesn't support direct environment inheritance (e.g., npx based servers where tokens must be passed as CLI arguments).

extent analysis

TL;DR

The Gemini CLI fails to expand environment variables in the args array of an MCP server configuration, causing authentication failures.

Guidance

  • The issue is likely caused by the Gemini CLI not replacing the ${VARIABLE_NAME} placeholders with the actual environment variable values before spawning the server process.
  • To verify, check the Docker logs for the MCP server to see if the literal string (e.g., ${DISCORD_TOKEN}) is being passed instead of the actual variable value.
  • As a temporary workaround, modify the args array to allow Docker to inherit the environment variables directly, as described in the issue.
  • Investigate the Gemini CLI code to determine why the environment variable expansion is not working as expected.

Example

No code snippet is provided as the issue does not include specific code examples.

Notes

The issue appears to be specific to the Gemini CLI and its handling of environment variables in the args array of an MCP server configuration. The workaround provided in the issue may not be applicable to all use cases, especially for servers that do not support direct environment inheritance.

Recommendation

Apply the workaround by modifying the args array to allow Docker to inherit the environment variables directly, as this is the only known solution at this time.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING