Skip to content

[Windows] read-only sandbox mode causes MCP shell_command to stall indefinitely — no function_call_output returned #13987

@brohirrim

Description

@brohirrim

Summary

When Codex 0.111.0 is invoked as an MCP server (codex.exe mcp-server) on Windows 11 with sandbox: "read-only", shell commands execute in the sandbox but the result never flows back to the MCP session. The function_call_output event is never written to the session JSONL. The calling MCP client (Claude Code in this case) waits indefinitely.

The same command (Get-Date) with sandbox: "workspace-write" or sandbox: "danger-full-access" returns instantly.

Environment

  • OS: Windows 11 Home (10.0.26200)
  • Codex version: codex-cli 0.111.0 (installed via Scoop)
  • Shell: PowerShell 7 (pwsh.exe)
  • MCP caller: Claude Code (stdio transport)
  • Config: [windows] sandbox = "unelevated" in ~/.codex/config.toml

MCP server config

{
  "mcpServers": {
    "codex": {
      "type": "stdio",
      "command": "C:/Users/<USER>/scoop/apps/codex/current/codex.exe",
      "args": ["mcp-server"]
    }
  }
}

Reproduction Steps

  1. Install Codex 0.111.0 on Windows 11
  2. Configure as MCP server (stdio) as shown above
  3. From any MCP client, send a task requesting sandbox: "read-only" that runs a single trivial command (Get-Date)
  4. Observe: the session JSONL shows function_call emitted for shell_command but no function_call_output ever appears. The MCP client blocks indefinitely.

The simplest test is three MCP calls with different sandbox modes, same prompt ("Run Get-Date"):

  • sandbox: "danger-full-access" — completes in ~2s
  • sandbox: "workspace-write" — completes in ~2s
  • sandbox: "read-only" — stalls indefinitely, no result returned

Expected Behavior

function_call_output should be written to the session JSONL after the sandboxed command completes (or after it is blocked by policy), and the result should flow back to the MCP client.

Actual Behavior

The function_call_output event is never written. The turn never completes (task_complete is never emitted). The MCP client waits forever.

In earlier sessions with more complex commands, the stall lasted 130-534 seconds before user abort. Some commands got "blocked by policy" responses (which is correct behavior for read-only), but the stall occurs even for commands that should be allowed to execute in read-only mode (like Get-Date).

Session Log Evidence

Working session (workspace-write):

{"timestamp":"...T16:31:48.049Z","type":"turn_context","payload":{"sandbox_policy":{"type":"workspace-write","writable_roots":["C:\\Users\\<USER>\\.codex\\memories"],"network_access":false}}}
{"timestamp":"...T16:31:51.810Z","type":"response_item","payload":{"type":"function_call","name":"shell_command","arguments":"{\"command\":\"Get-Date\",\"workdir\":\"c:/Users/<USER>/projects/<PROJECT>\",\"timeout_ms\":10000}","call_id":"call_AAA"}}
{"timestamp":"...T16:31:52.881Z","type":"response_item","payload":{"type":"function_call_output","call_id":"call_AAA","output":"Exit code: 0\nWall time: 0.3 seconds\nOutput:\n\r\nSunday, March 8, 2026 9:31:52 AM\r\n\r\n"}}
{"timestamp":"...T16:31:53.939Z","type":"event_msg","payload":{"type":"task_complete","turn_id":"2"}}

Stalled session (read-only) — same command, same prompt:

{"timestamp":"...T16:32:07.648Z","type":"turn_context","payload":{"sandbox_policy":{"type":"read-only"}}}
{"timestamp":"...T16:32:09.983Z","type":"response_item","payload":{"type":"function_call","name":"shell_command","arguments":"{\"command\":\"Get-Date\",\"workdir\":\"c:/Users/<USER>/projects/<PROJECT>\",\"timeout_ms\":10000}","call_id":"call_BBB"}}
{"timestamp":"...T16:32:09.990Z","type":"event_msg","payload":{"type":"token_count",...}}
<!-- SESSION ENDS HERE. No function_call_output. No task_complete. -->

Earlier stalled session (read-only) — commands hung 534 seconds before user abort:

{"timestamp":"...T07:48:21.813Z","type":"response_item","payload":{"type":"function_call","name":"shell_command","arguments":"{\"command\":\"bat --plain CLAUDE.md\",...}","call_id":"call_CCC"}}
{"timestamp":"...T07:57:15.519Z","type":"response_item","payload":{"type":"function_call_output","call_id":"call_CCC","output":"Wall time: 533.7 seconds\naborted by user"}}

Additional Context

  • In some read-only sessions, commands are correctly rejected with "blocked by policy" (e.g., where.exe, bat, gh --version). The rejection flows back instantly. The stall only happens for commands the sandbox attempts to execute rather than block.
  • The sandbox_policy object for read-only is minimal ({"type":"read-only"}) compared to workspace-write which includes writable_roots, network_access, etc. This might indicate the read-only sandbox is configured differently on Windows.
  • Windows sandbox infrastructure uses codex-windows-sandbox-setup.exe and codex-command-runner.exe alongside the main codex.exe.
  • The [windows] sandbox = "unelevated" config applies to all sandbox modes — only read-only stalls.

Suggested Labels

bug, sandbox, mcp-server, windows-os

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmcp-serverIssues related to the use of the `codex mcp-server` subcommand

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions