From 91c0ea5dd1e12b9b767e02ccdce65fdcc8b9ba94 Mon Sep 17 00:00:00 2001 From: andrewgu-oai Date: Mon, 5 Oct 2026 10:00:03 -0700 Subject: [PATCH] Backport Windows remote MCP environment preservation to 0.160 (#51121) Backport #50129 to the 0.160 release line so a Unix host can start remote stdio MCP servers on Windows when explicit remote environment variables are configured. Preserve `SYSTEMROOT`, `TEMP`, and `TMP` in the remote environment allowlist. The existing regression test checks these variables survive while unrequested secrets remain excluded. This is the exact single-file patch from #50129, based on the immutable 0.160.0 release's content commit (`cb7799623b2241f536d799f2d46259148fb987ce`). No unrelated main changes are included. Validation: - Patch ID matches #50129 exactly: `990a7674801ac5adbc6c8c6380568e18b3d396e2`. - `cargo build -p codex-cli --bin codex` passed. - `just test -p codex-rmcp-client`: 332 passed, 9 skipped, 4 setup failures initially. After building the CLI, all three `streamable_http_remote` integration tests passed on retry. The remaining OAuth auth-status test cannot create its lock directory in the read-only local home. - The remote environment filtering regression passed, including preservation of Windows variables and exclusion of unrequested secrets. - Core MCP environment-propagation integration validation is in progress. - The supported publisher dry run selects 0.160.1 from the exact candidate SHA. CI currently reports unrelated failures in unchanged formatter tests, lint imports, spelling checks, manifest-feature exceptions, and unlinked-file checks. The Linux and Windows production build checks passed; remaining checks are running. --- .../rmcp-client/src/stdio_server_launcher.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/codex-rs/rmcp-client/src/stdio_server_launcher.rs b/codex-rs/rmcp-client/src/stdio_server_launcher.rs index 433f532a13..195e00765f 100644 --- a/codex-rs/rmcp-client/src/stdio_server_launcher.rs +++ b/codex-rs/rmcp-client/src/stdio_server_launcher.rs @@ -687,8 +687,12 @@ impl ExecutorStdioServerLauncher { // environment, not copied from Codex. Start from `All` only so the // named remote variable is available to the filter below; the // effective child env is still limited by `include_only`. + // The orchestrator may be Unix while the executor is Windows. + // Preserve Windows runtime initialization and temporary-directory + // inputs even when explicit remote vars activate this allowlist. crate::utils::DEFAULT_ENV_VARS .iter() + .chain(["SYSTEMROOT", "TEMP", "TMP"].iter()) .map(|name| (*name).to_string()) .chain(remote_env_vars.iter().cloned()) .collect() @@ -763,6 +767,15 @@ mod tests { let env = shell_environment::create_env_from_vars( [ ("PATH".to_string(), "/remote/bin".to_string()), + ("SystemRoot".to_string(), r"C:\Windows".to_string()), + ( + "TEMP".to_string(), + r"C:\Users\test\AppData\Local\Temp".to_string(), + ), + ( + "TMP".to_string(), + r"C:\Users\test\AppData\Local\Temp".to_string(), + ), ("REMOTE_TOKEN".to_string(), "remote-secret".to_string()), ( "UNREQUESTED_SECRET".to_string(), @@ -774,6 +787,16 @@ mod tests { ); assert_eq!(env.get("PATH").map(String::as_str), Some("/remote/bin")); + assert_eq!( + env.get("SystemRoot").map(String::as_str), + Some(r"C:\Windows") + ); + for name in ["TEMP", "TMP"] { + assert_eq!( + env.get(name).map(String::as_str), + Some(r"C:\Users\test\AppData\Local\Temp") + ); + } assert_eq!( env.get("REMOTE_TOKEN").map(String::as_str), Some("remote-secret")