Windows: MCP servers with heavy stderr output fail with "Transport closed" error

Open 💬 5 comments Opened Nov 22, 2025 by FBakkensen

What version of Codex is running?

codex-cli 0.63.0

What subscription do you have?

Pro

Which model were you using?

gpt-5.1-codex-max

What platform is your computer?

Microsoft Windows NT 10.0.26200.0 x64

What issue are you seeing?

MCP servers that produce heavy stderr output during tool execution fail with "Transport closed" errors on Windows. This affects servers like bc-code-intelligence-mcp but not servers with minimal stderr like @modelcontextprotocol/server-filesystem.

Error Message:

[WARN] MCP tool call error: "tool call error: tool call failed for `bc-code-intel/set_workspace_info`
    Caused by: tools/call failed: Transport closed"

Key Evidence:

  • bc-code-intel works perfectly when tested manually via stdio
  • bc-code-intel works in Claude Code, GitHub Copilot, and Cursor
  • filesystem MCP works perfectly in Codex (minimal stderr)
  • bc-code-intel ONLY fails in Codex on Windows with heavy stderr (189-237ms of output)

What steps can reproduce the bug?

  1. Configure bc-code-intelligence-mcp in config.toml:
[mcp_servers.bc-code-intel]
command = "node"
args = ["C:\\path\\to\\bc-code-intelligence-mcp\\dist\\index.js"]
startup_timeout_sec = 60
  1. Start Codex and call set_workspace_info tool
  2. Server processes successfully (logs show completion: "📊 Total: 123 topics, 16 specialists")
  3. Error occurs ~7ms after server completes: "Transport closed"

Manual Test (WORKS):

echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"set_workspace_info","arguments":{"workspace_root":"C:/test","available_mcps":["bc-code-intel"]}}}' | node dist/index.js
# Returns valid JSON-RPC response successfully

What is the expected behavior?

MCP servers should work regardless of stderr output volume. The server should complete tool execution and return results without "Transport closed" errors.

Root Cause Analysis

Location: codex-rs/rmcp-client/src/rmcp_client.rs lines 133-149

The Bug: The stderr reading task blocks indefinitely on lines().next_line().await without timeout handling. When MCP servers produce heavy stderr output (like bc-code-intel's 189-237ms of loading logs), this interferes with the stdio transport on Windows.

Code:

if let Some(stderr) = stderr {
    tokio::spawn(async move {
        let mut reader = BufReader::new(stderr).lines();
        loop {
            match reader.next_line().await {  // ← NO TIMEOUT
                Ok(Some(line)) => {
                    info!("MCP server stderr ({program_name}): {line}");
                }
                Ok(None) => break,
                Err(error) => {
                    warn!("Failed to read MCP server stderr ({program_name}): {error}");
                    break;
                }
            }
        }
    });
}

Smoking Gun: This exact pattern was already fixed in commit 73ed30d7e ("Avoid hang when tool's process spawns grandchild that shares stderr/stdout") for shell tool execution in codex-rs/core/src/exec.rs lines 584-625, but was never applied to MCP client code.

Proposed Fix (UNTESTED)

Note: This fix is based on code analysis and the existing pattern in exec.rs, but has NOT been tested locally due to build environment requirements. The Codex team should validate this approach.

Apply the same timeout pattern from exec.rs to prevent stderr blocking:

if let Some(stderr) = stderr {
    tokio::spawn(async move {
        use tokio::time::{timeout, Duration};
        let mut reader = BufReader::new(stderr).lines();
        loop {
            match timeout(Duration::from_secs(5), reader.next_line()).await {
                Ok(Ok(Some(line))) => {
                    info!("MCP server stderr ({program_name}): {line}");
                }
                Ok(Ok(None)) => break,
                Ok(Err(error)) => {
                    warn!("Failed to read MCP server stderr ({program_name}): {error}");
                    break;
                }
                Err(_) => {
                    warn!("MCP server stderr ({program_name}): read timeout after 5s, continuing...");
                }
            }
        }
    });
}

Additional Information

Testing Done:

  • ✅ Verified bc-code-intel works with manual stdio testing
  • ✅ Tested with SDK 0.4.0 and 1.22.0 - same issue
  • ✅ Confirmed filesystem MCP works in Codex (low stderr)
  • ✅ Isolated issue to Codex's stderr handling, not bc-code-intel
  • ❌ Proposed fix NOT tested locally (build environment setup incomplete)

Files Involved:

  • codex-rs/rmcp-client/src/rmcp_client.rs - needs fix
  • codex-rs/core/src/exec.rs - reference implementation

Related Commits:

  • 73ed30d7e - Fixed similar issue for shell tools
  • f828cd289 - Windows MCP server execution fix

This is a Windows-specific race condition in MCP client stderr handling that should be fixed to support MCP servers with verbose diagnostic output.

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗