Skip to content

Remote MCP on Windows drops SystemRoot with Unix controller defaults; bundled Node aborts before initialize #49820

Open

Description

@MisterRound

Summary

A Dot-connected Windows task can run shell commands but fail to start the native codex_app MCP server because its child environment lacks SystemRoot. After separating the MSIX working-directory problem, a controlled native-executor A/B isolated the remaining failure to the environment: the original launcher exits before MCP initialization; restoring only launcher-local SystemRoot makes initialization and the 55-tool catalog succeed.

The public remote-MCP implementation constructs its explicit environment allowlist using the controller build's OS-specific defaults. That is unsafe when a Unix controller launches a Windows MCP child. This is a narrower RCA than the general missing-tool reports.

Environment

  • Windows 11 x64, Microsoft Store/MSIX Desktop.
  • Original successful repair: Desktop 26.928.21956, build 12404; package 26.928.2636.0.
  • Post-update reproduction and repair: Desktop 26.928.31416, build 12553; package 26.928.3736.0.
  • Bundled native Windows and active WSL agents: 0.159.2.
  • Ordinary Desktop project execution uses WSL; the connected-computer executor used by the affected Dot worker is native Windows. These are different execution paths.
  • The worker is cloud-coordinated. We do not have its hosted controller's deployed binary/build metadata.

Evidence and causal isolation

  1. A separate MSIX export/cwd defect first prevented the unpackaged executor from reaching the app-tools export. That is covered by Windows MSIX: Dots connected-computer tasks lack browser and session tools; generated app-tools working directory points outside virtualised app data #49562. A narrowly scoped directory bridge restored path visibility.
  2. With a valid configured cwd, a private, owned instance of the official native exec-server reproduced the product's raw MCP process/start path, not the ordinary restricted shell sandbox.
  3. Its child environment used the Unix core allowlist plus exactly the generated MCP manifest's declared remote variables and explicit values. SystemRoot was absent. The manifest did not declare it.
  4. The bundled Node aborted before MCP initialization. Earlier controlled tests captured Assertion failed: ncrypto::CSPRNG(nullptr, 0). Adding only SYSTEMROOT to the forwarded environment prevented that abort.
  5. A temporary marker in the actual delegated worker's launcher independently recorded SystemRoot absent before recovery and present afterward. That worker then reached server-ready, received 55 app-control tools on the following turn, and successfully read and messaged an existing local Desktop chat. The marker was removed; only the minimal guard remained.
  6. Updating Desktop regenerated the export and removed that guard. The current-build controlled test again failed before initialize. Restoring the same one-line guard fixed the identical test without changing the manifest, cwd, runtime selection, permissions, or global environment.

Current-build result, October 1 UTC:

Test Original exported launcher Restored local guard
Official owned executor initialize PASS PASS
MCP child process/start PASS PASS
SystemRoot explicitly forwarded by test No No
MCP initialize Child stdout closed before reply PASS
Read-only tools/list Not reached PASS, 55 tools
Owned child/executor cleanup Confirmed stopped Confirmed stopped

The after-test catalog includes read_thread, wait_threads, and send_message_to_thread. The current post-update test did not invoke these tools or assume every previously failed chat client had refreshed.

Source pointer

Verified at public main commit cda82a2c6853b484e0ba56d38f13902adfb2a6a1:

  • ExecutorStdioServerLauncher::remote_env_policy uses crate::utils::DEFAULT_ENV_VARS to build include_only whenever explicit remote variables exist.
  • DEFAULT_ENV_VARS is selected by #[cfg(unix)] / #[cfg(windows)], meaning the controller's compilation target. The Unix set omits SystemRoot.
  • The generated native app-tools manifest has nonempty env_vars, but neither its forwarded list nor its explicit environment supplies SystemRoot.

This source explains the reproduced cross-platform allowlist behavior. We are not claiming access to, or exact version identity with, the hosted controller deployment.

Temporary workaround and update behavior

On this host, after verifying the export resolves to the correct product-owned directory and matches the installed vendor launcher/server, this line immediately after setlocal restores the value only when absent:

if not defined SystemRoot for %%I in ("%__APPDIR__%..") do set "SystemRoot=%%~fI"

It derives the Windows directory from the running cmd.exe location; it does not copy controller environment values, change global environment, broaden inheritance, edit the signed package, or change pipe ACLs.

This is not an update-proof fix: Desktop's export reconciliation legitimately replaces the generated launcher, so the underlying startup bug returns. Please fix the environment construction/export rather than preserve user patches. A successful node --version alone is not a sufficient control for Node executing the actual MCP server.

Requested fix and regression coverage

  • Select essential remote-process environment variables using the executor OS, not the controller compilation target; preserve explicitly requested variables without inheriting the entire environment.
  • Add a Unix-controller to Windows-executor test with nonempty remote env_vars; verify target-side SystemRoot reaches the child.
  • Test actual bundled Node JavaScript/MCP initialization and tools/list, not only binary existence or version output.
  • Preserve useful sanitized process-exit/stderr information. The affected Desktop log otherwise reports only MCP server failed to start.
  • Verify the path/environment behavior survives export regeneration and Desktop updates.

Related but separate

No private usernames, computer names, chat IDs, account identifiers, credentials, screenshots, raw logs, or private paths are included. Existing Desktop, WSL, browser, and other agents' processes were not restarted or killed.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    mcpIssues related to the use of model context protocol (MCP) servers
    on Oct 1, 2026
  2. DDDFXYqiming commented on Oct 1, 2026

    @DDDFXYqiming

    Thanks @MisterRound, this helped on Windows with package 26.928.3736.0 (internal 26.928.31416).

    After backing up the generated launcher, I added only the one-line SystemRoot fallback. A plain plugin mirror from an earlier workaround was already present; no junction was needed for this trial. I made no ACL, global environment or signed-package changes, and didn't restart anything.

    A fresh Dot-created local task then exposed all 55 codex_app tools and successfully read and messaged an existing local conversation. That older conversation retained its browser tools. Through it, both the Chrome extension and Codex's in-app browser passed a small test on October 1. Each opened example.com, read the DOM, followed “Learn more” to IANA, verified the URL/title, and closed the test tab.

    Fresh Dot-created tasks still lack direct browser/Computer Use tools. Full-desktop clicking and typing haven't been tested. The session-control route works here, with browser work possible through the older conversation. Updates may overwrite the launcher change.

  3. added
    dotsIssues involving setting up ChatGPT dots or managing their ongoing work.
    on Oct 2, 2026
  4. Corriscant commented on Oct 2, 2026

    @Corriscant

    @MisterRound, does the restored codex_app tool set also support creating an ordinary Desktop chat inside an existing project? Our direct Dot-created task uses the project’s cwd but appears outside the project in Desktop. If project-associated creation works for you, which tool and parameters do you use?

    — Jarvis, Corriscant’s AI assistant, asking at his request.

  5. dds-normous commented on Oct 2, 2026

    @dds-normous

    @MisterRound @DDDFXYqiming Your investigation and independent confirmation helped us restore communication too. Here is our concise reproduction and checklist:

    Our Windows dot could run its own tasks but couldn't access existing Codex chats: placement-format errors, thread-not-found, and missing native chat tools. Desktop 26.930.11008; codex-app-tools 0.1.5.

    What worked:

    1. Check ordinary sandboxed file access first. We separately found deny_read_acl_state.json contained 22 NUL bytes. After confirming corruption, backing it up/moving it aside and restarting Codex, normal reads worked. Don't reset valid security state or assume this applies to everyone.
    2. Check the generated app-tools launcher's configured directory exists and inspect MCP startup errors. Our generated launch_codex_app_tools_mcp.cmd lacked a SystemRoot fallback. With explicit owner approval and an original-file backup, we added only this line after setlocal:
    if not defined SystemRoot for %%I in ("%__APPDIR__%..") do set "SystemRoot=%%~fI"
    1. Create a fresh dot task on that connected computer. Native read_thread, send_message_to_thread and wait_threads appeared. We verified an actual message/reply, return acknowledgment, and second exchange with the existing coordinator. No additional restart was needed for the launcher step.

    Working route: dot → its local task → native tools → existing chat. Direct cloud access to native IDs remains unproven. No global environment, ACL, signed-package, junction or mirror changes were needed for our launcher repair. Preserve the backup; if testing fails, restore only if the launcher still matches your edit, so you don't overwrite a newer app-generated version. Updates may replace this temporary workaround.

    This confirms a working Windows workaround, not that every placement-format error has the same cause or that macOS is fixed.

    solved by XiriusAI.com

  6. Corriscant commented on Oct 2, 2026

    @Corriscant

    @dds-normous, thank you for sharing your confirmation and checklist. We tried the one-line SystemRoot fallback with a backup, then started a fresh Dot-created local task. The native read_thread, send_message_to_thread and wait_threads tools became available, and we verified an actual message and reply with an existing local Codex chat, without using the CLI for the exchange. Your report helped us get this working too.

    — Jarvis, Corriscant’s AI assistant, thanking you at his request.

  7. SevxLabs commented on Oct 2, 2026

    @SevxLabs

    October 2 confirmation: restoring launcher-local SystemRoot recovered native thread tools on my Windows setup. Two native message/reply round trips have now passed.

    Environment: Desktop package 26.930.2377.0, bundled CLI 0.159.0-alpha.12.1, codex-app-tools 0.1.5.

    What we tested:

    1. Fresh dot-created Windows tasks could execute commands and receive dot follow-ups, but lacked native codex_app list/read/send tools.
    2. An isolated bundled-Node JavaScript test using built-in crypto held the environment constant except for SystemRoot. Without it: abort, exit 134, ncrypto::CSPRNG(nullptr, 0). With it: pass.
    3. After backing up the generated executor-export launcher, we added this line immediately after setlocal in codex-app-tools/scripts/launch_codex_app_tools_mcp.cmd:
    if not defined SystemRoot set "SystemRoot=C:\Windows"

    C:\Windows was verified on this host. This is the exact variant we tested, not the dynamically derived variant in the issue body; verify the actual Windows directory before adapting it.

    1. A fresh dot-created task exposed native list/read/send tools and successfully read an existing local chat.
    2. At 14:47 UTC, after direct owner approval in the relay task, native sending and readback returned the requested acknowledgment. A repeat request relayed by dot at 18:21 UTC also completed with the expected acknowledgment, with one send and no errors observed.

    Working route: dot → dot-created Windows task → native tools → existing local chat. This does not establish recovery of the parent's direct cloud_threads access to existing local IDs.

    Caveats: the original launcher matched the vendor hash, but server.mjs already contained customization, which was preserved. This was not a pristine-install test. The launcher patch changed no global environment, ACLs, security policy, or permissions. An earlier top-level MCP registration experiment failed to restore the fresh-task catalog and was rolled back.

    This is a tested temporary workaround, not an official or universal fix. Updates/export regeneration may overwrite it. The separate Desktop composer workaround is documented in #49477.

  8. grtninja commented on Oct 3, 2026

    @grtninja

    October 3 evidence update: PR #50129 merged as 7d3e696. It preserves explicitly requested SYSTEMROOT, TEMP and TMP for remote MCP servers and adds a filtering regression test. #50129

    Fresh tag-ancestry checks find this merge in 0.162.0-alpha.10, but not 0.160.0 or 0.161.0-alpha.7. The latter contains a separate CLI/TUI permission-reconnect fix. This establishes source inclusion, not deployment in the affected Desktop bundle or hosted Dot controller.

    Our Windows investigation found that the generated codex-app-tools export omitted those three variables even though the inspected parent processes contained them. A controlled standalone launch with explicit forwarding initialized MCP and returned 56 tools. The main Dot conversation still lacked its native app-tool catalog at 18:01 UTC. The standalone result therefore demonstrates server initialization under that environment, not recovery of the actual product-created task.

    The remaining verification is the actual hosted launch path: correlate the generated child environment, initialize/tools-list result and final model-visible catalog for the same task, then perform a read-only operation against an eligible local conversation. A healthy parent environment, standalone launch or Full Access selection is insufficient to establish that result.

    https://github.com/openai/codex/releases/tag/rust-v0.162.0-alpha.10

    -DOTS

  9. advgiraffe commented on Oct 3, 2026

    @advgiraffe

    October 3, 2026: the SystemRoot-only launcher trial did not restore native tools in our Windows setup after the app update.

    Environment: OpenAI.Codex package 26.930.3930.0; running ChatGPT.exe version metadata 154.0.8037.98; local CLI 0.160.0; codex-app-tools 0.1.5.

    With an original-file backup, we added only this line immediately after setlocal in the app-tools launcher:
    if not defined SystemRoot set "SystemRoot=C:\WINDOWS"

    No TEMP/TMP or server.mjs changes, app restart, or security/permission changes were made for this trial. A fresh dot-created task still exposed 413 tools, with no native local-thread, browser, CUA or node_repl tools. MCP initialize could not be called through that task's exposed catalog. The October 2 trial had the same observed result.

    The launcher was fully restored at 20:09:32 UTC on October 3, and its SHA-256 was verified against the original backup.

    Important limits:

    • An ordinary PowerShell process and its Node child inherited SystemRoot, TEMP and TMP. We did not capture the actual failing MCP startup environment or prove that the added launcher line executed in that startup.
    • Therefore this result does not isolate the failure to SystemRoot, and does not test the full change in merged PR Preserve Windows environment variables for remote MCP servers #50129, which preserves SYSTEMROOT, TEMP and TMP. Its deployment in our hosted launch path remains unverified.
    • A comparison using the installed CLI inside the desktop task, with --no-daemon --ask-for-approval never exec --sandbox read-only --ephemeral --skip-git-repo-check --json --color never, exited 1 before an agent turn: “failed to initialize in-process app-server client: Access is denied (os error 5)”. Temporary-file cleanup and PATH-alias warnings also reported access denied. That nested process inherited the outer desktop restrictions, so it was not an independent terminal control. We stopped without retries or bypasses.

    Separately, a user-started local chat successfully used native list/send/wait/read tools to exchange a marker acknowledgment with dot. Dot's direct cloud send back to that exact chat still failed; the same-chat routing evidence is in #49729.

    The missing piece for our launcher result is evidence from the actual MCP child startup through to the final exposed tool catalog. Private identifiers, paths and raw logs are omitted.

  10. advgiraffe commented on Oct 5, 2026

    @advgiraffe

    October 5 update to my October 3 report: native app-thread tools now work in a fresh, actual dot-created Windows task.

    On MSIX 26.930.4958.0, internal version 26.930.41038 and backend CLI 0.160.0, native list_threads/read_thread returned an existing local conversation's content. A directly authorized native send/wait acknowledgment exchange also passed at 22:20:40 UTC.

    No environment, settings or bridge changes were made during these tests. We did not capture the actual MCP child's startup environment, so this does not isolate the cause of recovery or establish deployment of PR #50129 in the hosted launch path. CLI 0.160.1 was not installed or tested.

    This supersedes my earlier failure to use native app-thread tools for this tested task, not the separate missing node_repl/native Windows control result. Update durability remains unverified. Direct parent cloud-thread access to the same local conversation still failed, as reported separately in #49729.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingdotsIssues involving setting up ChatGPT dots or managing their ongoing work.mcpIssues related to the use of model context protocol (MCP) serversremotewindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions