-
Notifications
You must be signed in to change notification settings - Fork 10.4k
[Windows] read-only sandbox mode causes MCP shell_command to stall indefinitely — no function_call_output returned #13987
Description
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
- Install Codex 0.111.0 on Windows 11
- Configure as MCP server (stdio) as shown above
- From any MCP client, send a task requesting
sandbox: "read-only"that runs a single trivial command (Get-Date) - Observe: the session JSONL shows
function_callemitted forshell_commandbut nofunction_call_outputever 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 ~2ssandbox: "workspace-write"— completes in ~2ssandbox: "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-onlysessions, 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_policyobject forread-onlyis minimal ({"type":"read-only"}) compared toworkspace-writewhich includeswritable_roots,network_access, etc. This might indicate the read-only sandbox is configured differently on Windows. - Windows sandbox infrastructure uses
codex-windows-sandbox-setup.exeandcodex-command-runner.exealongside the maincodex.exe. - The
[windows] sandbox = "unelevated"config applies to all sandbox modes — onlyread-onlystalls.
Suggested Labels
bug, sandbox, mcp-server, windows-os