Windows Codex Desktop stdio MCP child process does not inherit user env vars for mcp-remote header substitution
Summary
On Windows Codex Desktop, a stdio MCP server launched via npx mcp-remote did not receive a user-level environment variable used in a custom Authorization header. As a result, mcp-remote forwarded the literal placeholder ${AMINER_MCP_AUTH_HEADER} to the remote MCP server instead of a JWT, causing authentication failures.
This looks like a Codex stdio MCP environment propagation/documentation issue rather than a remote MCP server issue: the same token works when connecting with the Python MCP SDK directly, and also works when the stdio server is launched through a PowerShell wrapper that explicitly loads the User environment variable.
Environment
- OS: Windows
- App: Codex Desktop
- Codex CLI shown in local docs/config:
0.133.0 - MCP server type: stdio wrapper around remote SSE via
mcp-remote - Remote MCP:
https://mcp.aminer.cn/sse - Node/npm available through
npx
Original config shape
[mcp_servers.AMiner_Scholar_MCP]
command = "npx"
args = [
"-y",
"mcp-remote@latest",
"https://mcp.aminer.cn/sse",
"--header",
"Authorization:${AMINER_MCP_AUTH_HEADER}",
"--transport",
"sse-only",
"--silent"
]
enabled = true
startup_timeout_sec = 120
AMINER_MCP_AUTH_HEADER was set as a Windows User environment variable and was visible from normal PowerShell/Python processes.
Expected behavior
Either:
- Codex should pass the relevant user/process environment to stdio MCP child processes so that
mcp-remotecan expand${AMINER_MCP_AUTH_HEADER}fromprocess.env, or - Codex documentation/config examples should make clear that
${VAR}inargsis not expanded by Codex and that stdio MCP child processes may not receive Windows User environment variables unless explicitly provided through MCP config or a shell wrapper.
Actual behavior
The launched mcp-remote process received the literal string as its header value. A process command-line shape check showed the Authorization value had:
- length: 25
- contained
$ - contained
{and} - had 1 JWT segment instead of 3
The remote AMiner MCP tool call returned:
{
"code": 40308,
"success": false,
"msg": "Token Parse Error"
}
Verification that the token/server were not the issue
Using the same token:
- Python MCP SDK direct SSE connection to
https://mcp.aminer.cn/ssesucceeded. list_toolsreturned 16 tools.search_paperreturnedcode: 200and paper data.- Launching the stdio server through a PowerShell wrapper also succeeded.
Workaround that fixed it
[mcp_servers.AMiner_Scholar_MCP]
command = "powershell.exe"
args = [
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$env:AMINER_MCP_AUTH_HEADER = [Environment]::GetEnvironmentVariable('AMINER_MCP_AUTH_HEADER', 'User'); if (-not $env:AMINER_MCP_AUTH_HEADER) { throw 'AMINER_MCP_AUTH_HEADER missing' }; & npx -y mcp-remote@latest https://mcp.aminer.cn/sse --header 'Authorization:${AMINER_MCP_AUTH_HEADER}' --transport sse-only --silent"
]
enabled = true
startup_timeout_sec = 120
After this change, Codex exposed the AMiner MCP tool and search_paper returned code: 200.
Request
Please consider one of:
- ensuring stdio MCP servers inherit expected process/user environment variables on Windows Desktop,
- supporting explicit environment-variable expansion in MCP
args, - adding a config-supported way to map an existing user env var into the stdio child process without embedding secrets in
config.toml, or - documenting the expected behavior and recommended Windows workaround.
No secrets are included in this report.
3 Comments
Solution: Windows MCP Child Process Environment Variable Inheritance
Problem
On Windows Codex Desktop, stdio MCP servers do not receive User-level environment variables.
${AMINER_MCP_AUTH_HEADER}is passed literally instead of expanded, causing auth failures.Root Cause
On Windows, User environment variables are stored in
HKCU\Environmentand loaded at login. When Codex Desktop is launched from certain contexts (service, background, or before vars are set),process.envdoes not include User env vars. The MCP child process inherits this incomplete environment.Proposed Fix
1. Merge User Environment on Windows:
2. Support env: in MCP Config (Feature):
3. Document the behavior and provide the PowerShell wrapper workaround.
Workaround
Full solution:
solutions/codex-24362-windows-mcp-env-vars-fix.mdI checked current
main(9f42c89) and this looks consistent with the current local stdio MCP environment handling, rather thanmcp-remotereceiving a fully inherited process environment. One small correction to the previous direction: the relevant code path here is in the Rust stdio MCP launcher.For local stdio MCP servers, Codex does not pass the full ambient environment through.
codex-rs/rmcp-client/src/utils.rs:12-23builds the child env from Codex's default env allowlist, plus variables explicitly listed in the server configenv_vars, plus literalenventries. The local launcher then calls.env_clear().envs(envs)before spawning the child (codex-rs/rmcp-client/src/stdio_server_launcher.rs:248-260).So with the config shown here,
AMINER_MCP_AUTH_HEADERis not in the child environment unless it is either listed inenv_varsor loaded by a wrapper such as the PowerShell workaround. The config parser supports stdioenv_vars(codex-rs/config/src/mcp_types.rs:320-342,:426-435), and there is regression coverage that a whitelistedenv_varsvalue reaches a stdio MCP server (codex-rs/core/tests/suite/rmcp_client.rs:1476-1580).codex doctoralso checks named stdioenv_varsand reports if one is missing (codex-rs/cli/src/doctor.rs:1463-1501).A minimal config-side workaround to try, without embedding the secret value in
config.toml, would be:If that still fails specifically in Windows Desktop, the remaining thing to check is whether the Codex Desktop/app-server process itself can see
AMINER_MCP_AUTH_HEADERwhen it starts. Existing Windows processes generally do not gain newly-created User environment variables automatically, so a full Desktop/app restart after setting the variable may be required. There may also be a docs/config clarity gap here: stdio MCP servers needenv_varswhen a child process should receive non-default environment variables.Solution Proposal: Windows MCP Child Process Environment Variable Inheritance
Problem Analysis
On Windows, stdio MCP servers launched via
npx mcp-remotedo not receive user-level environment variables used for authentication headers.Proposed Fix
CreateProcessusesCREATE_UNICODE_ENVIRONMENTand properly inherits user env varsTimeline: 3-4 days
Pricing: $2,000 - $3,000
We have deep MCP integration and cross-platform deployment expertise.