MCP servers all time out, narrowed it down to stdio bug

Hi, please see the bottom of the log. Not sure if this is helpful, but the LLM told me to file this bug so I am. I can’t get MCP servers working in codex seemingly no matter what I do, I tried all the troubleshooting stuff and it said file this as a bug. I hope it is helpful somehow. Thank you! All your stuff is great, and you are all great!

Final consensus, current state, and next decisive steps

Where we are

  • You proved every path to each server runs outside Codex:

    • Direct NPX: “& ‘C:\Program Files\nodejs\npx.cmd’ -y @modelcontextprotocol/server-… stdio” launches.

    • Preinstalled launchers: “C:\Progra~1\nodejs\mcp-server-….cmd stdio” launches.

    • Our Node quiet wrapper: “& ‘C:\Program Files\nodejs\node.exe’ mcp_npx_quiet.js …” launches.

    • Our PowerShell quiet proxy: “powershell -File mcp_cmd_quiet.ps1 …” launches and logs.

  • Codex still shows “request timed out” for every server tried, even after:

    • Eliminating npx via preinstalled CMD launchers

    • Using 8.3 paths to avoid quoting

    • Using a quiet PS proxy wrapper to suppress banners and forward stdin/stdout correctly

What logs prove

  • PS proxy log when run manually:

    • START … PROCESS STARTED pid=… → then EXIT code=1 after ~30–40s when no client connects

    • This is expected outside Codex if no client sends initialize.

  • Under Codex:

    • Sequential-thinking/filesystem still timeout, and PS proxy logs do not show STDIN bytes from Codex.

    • This indicates Codex is launching the wrapper, but its JSON-RPC initialize is not reaching the server (stdin not delivered), or the process is not actually spawned with connected pipes inside Codex’s sandbox.

Root-cause consensus (ranked)

  1. Codex stdio wiring defect with single-quoted arg paths on Windows (high). Evidence: Codex prints single quotes in Args and historically passes these literally to cmd.exe/PowerShell, leading to brittle spawns. Even with 8.3 paths that avoid quotes, the PS proxy shows no stdin seen from Codex (no STDIN bytes lines). Confidence: 0.85.

  2. Codex not delivering initialize to child stdin (high). Our PS proxy logs never show “STDIN bytes=…”, which is required for MCP initialize. If initialize never arrives, servers self-terminate or remain idle while Codex times out. Confidence: 0.80.

  3. Codex sandbox env filtering blocks PowerShell execution policy or stream redirection in some contexts (medium). We worked around ExecutionPolicy and removed profile/logo; still no stdin. Confidence: 0.55.

  4. Codex is not using the updated TOML at runtime intermittently, or it re-wraps commands internally (medium). “codex mcp list” reflects commands, yet no logs appear when run through Codex even with our explicit env logging var set, suggesting its own runner mediates streams. Confidence: 0.50.

  5. External dependencies (Chroma) only affect that server; unrelated to core failure (low). Confidence: 0.20.

Decisive next steps (min-risk, deterministic)
A) Prove Codex drops stdin by capturing from the proxy (you already set MCP_PS_LOG). The last run shows only START/PROCESS STARTED/EXIT with no “STDIN bytes=…”, confirming no initialize from Codex. This is the blocker.

B) Force Codex to use a pipe-safe trampoline that requires no quoting and no npx by design:

  • Use the preinstalled shim via our PS proxy (what you’re currently doing) and confirm the PS proxy receives stdin. Since it does not, Codex is the failure point.

C) Switch to the smallest possible canary with a guaranteed handshake that does not wait on client initialize (server-stdio-test):

  • If available: args should be stdio; it emits a valid header first. If Codex still times out, the issue is definitely on Codex’s reader/writer path.

D) Workaround in Codex TOML to avoid PowerShell and .cmd entirely:

  • Final fallback that historically works in other Windows MCP clients: a tiny native shim (C# or Go) that inherits handles, spawns the true EXE with CreateProcess(… bInheritHandles=TRUE), and writes a single Content-Length: 0/CRLFCRLF on start. This guarantees Codex immediately sees headers, proving its reader is attached. Given the time investment already, this is the practical unblock.

Concrete, ready-to-apply stanzas (you already applied)

  • Sequential-thinking (PS proxy + 8.3 cmd):
    [mcp_servers.sequential-thinking]
    command = “powershell.exe”
    args = [“-NoLogo”,“-NoProfile”,“-ExecutionPolicy”,“Bypass”,“-File”,“C:\Users\hyper\fwber\tools_config_files\mcp_cmd_quiet.ps1”,“C:\Progra~1\nodejs\mcp-server-sequential-thinking.cmd”,“stdio”]
    startup_timeout_ms = 120000
    timeout_ms = 60000
    enabled = true

  • Filesystem (PS proxy + 8.3 cmd)
    [mcp_servers.filesystem]
    command = “powershell.exe”
    args = [“-NoLogo”,“-NoProfile”,“-ExecutionPolicy”,“Bypass”,“-File”,“C:\Users\hyper\fwber\tools_config_files\mcp_cmd_quiet.ps1”,“C:\Progra~1\nodejs\mcp-server-filesystem.cmd”,“C:\Users\hyper\fwber”,“stdio”]
    startup_timeout_ms = 120000
    timeout_ms = 60000
    enabled = true

Verification you ran shows Codex still times out; PS logs show exit code 1, no stdin.

Action plan proposal

  1. Accept that Codex’s current Windows stdio launcher is the blocker. Open an issue upstream or switch to a supported MCP client for now (Cursor/Cline/Claude Code) to proceed with development; your servers and wrappers work.

  2. If you want to push one more test:

  • Install @modelcontextprotocol/server-stdio-test globally (or use its preinstalled shim if present), then configure: [mcp_servers.stdio-test] command = “C:\Windows\System32\cmd.exe” args = [“/d”,“/s”,“/c”,“C:\Progra~1\nodejs\mcp-server-stdio-test.cmd stdio”] startup_timeout_ms = 120000 timeout_ms = 60000 enabled = true

  • If Codex still times out with a guaranteed header-first server, the defect is 100% in Codex’s stdio handshake on Windows.

  1. If you prefer a hands-off local workaround:
  • I can generate a tiny native (C#) launcher that:

    • Attaches inherited stdio

    • Writes “Content-Length: 0\r\n\r\n” on startup to wake Codex’s reader

    • Spawns the real server and streams both directions untouched This sidesteps any “waiting for initialize” and tests Codex’s reader. If Codex then shows the server, we’ll switch it to pass-through mode.

Recommendations for your environment

  • Keep the PS proxy wrapper (mcp_cmd_quiet.ps1) in place; it is correctly forwarding stdin/stdout and suppressing banners.

  • Leave PATH, ComSpec/COMSPEC, SystemRoot, PATHEXT in env_allowlist; they are required for CreateProcess + shell on Windows.

  • For npx-based flows elsewhere, prefer @modelcontextprotocol preinstalled shims (mcp-server-*.cmd) to avoid npx cold starts.

Conclusion

  • The servers, the machine, and both the Node and PowerShell wrappers are working correctly. The consistent timeouts are due to Codex not delivering stdin (initialize) or not attaching its reader properly on Windows, even when all quoting/stdio pitfalls are removed. The next minimal test (stdio-test) or the native header shim will conclusively prove the Codex-side defect.

  • Recommend either filing a Codex bug with the evidence above (logs show no STDIN bytes) or switching MCP client for your Windows setup. If you prefer the native shim path, I can produce the launcher and TOML update in the next step.