Repository navigation
Windows Codex Desktop MCP tool wrapper reports Transport closed while same stdio server works directly #18486
Description
What version of Codex is running?
Codex Desktop for Windows, observed process package version: OpenAI.Codex_26.415.1938.0_x64__2p2nqsd0c76g0.
What subscription do you have?
Plus
Which model were you using?
GPT-5 Codex desktop session.
What platform is your computer?
Windows, PowerShell shell. Unity Editor is running locally.
What issue are you seeing?
A configured MCP server for Unity is reachable and works when launched directly, but Codex Desktop's built-in MCP tool namespace fails immediately with Transport closed.
The failing Codex tool call is any mcp__unity__ call, for example:
unity_list_instances -> tool call error: tool call failed for `unity/unity_list_instances`
Caused by: Transport closed
This persists after restarting Codex multiple times and after restarting the Unity-side MCP server from within Unity. Claude is able to use the same MCP connection successfully on the same machine.
This may be related to, but appears narrower/different from, #7155. In this case the direct stdio MCP server is healthy and the latest failed Codex wrapper calls do not appear to reach the Unity MCP server log at all.
MCP server config
From ~/.codex/config.toml:
[mcp_servers.unity]
command = "node"
args = ["C:/Users/<user>/Projects/unity-mcp-server/src/index.js"]
env = { UNITY_HUB_PATH = "C:/Program Files/Unity Hub/Unity Hub.exe", UNITY_PORT_RANGE_START = "7890", UNITY_PORT_RANGE_END = "7899", UNITY_BRIDGE_TIMEOUT = "60000" }
[mcp_servers.unity.tools.unity_editor_ping]
approval_mode = "approve"
[mcp_servers.unity.tools.unity_editor_state]
approval_mode = "approve"
[mcp_servers.unity.tools.unity_list_instances]
approval_mode = "approve"
[mcp_servers.unity.tools.unity_select_instance]
approval_mode = "approve"
[mcp_servers.unity.tools.unity_agents_list]
approval_mode = "approve"The server package is anklebreaker-unity-mcp; package.json says 2.28.1, while the MCP server reports serverInfo.version: 2.26.0.
Steps to reproduce
- On Windows, configure Codex Desktop with a local Node MCP server using newline-delimited JSON-RPC over stdio.
- Start Unity with the Unity MCP bridge listening in the range
7890-7899. - In this repro, Unity is on port
7892. - From Codex Desktop, call a configured MCP tool such as
unity_list_instancesorunity_editor_ping. - Observe immediate
Transport closedfrom the Codex MCP tool wrapper. - Launch the exact same server command manually and send newline-delimited MCP JSON-RPC messages over stdio.
- Observe that direct MCP calls succeed.
Expected behavior
Codex should keep the MCP stdio transport open and return the tool result, matching the direct MCP client behavior and Claude's behavior on the same machine.
Actual behavior
Codex reports Transport closed immediately from the MCP tool wrapper. After the first failure, repeated mcp__unity__ calls continue to fail immediately.
Evidence collected
Raw Unity TCP port is open:
Test-NetConnection -ComputerName 127.0.0.1 -Port 7892
# TcpTestSucceeded: TrueUnity MCP instance registration exists:
[
{
"port": 7892,
"projectName": "CosmicCatastrophe",
"projectPath": "C:/Users/<user>/Projects/cosmic-catastrophe/CosmicCatastrophe",
"unityVersion": "6000.4.2f1",
"platform": "WindowsEditor",
"processId": 43084,
"isClone": false,
"cloneIndex": -1
}
]Direct MCP server launch and newline-delimited stdio handshake succeeds:
MCP_RESPONSE {"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{},"resources":{}},"serverInfo":{"name":"unity-mcp","version":"2.26.0"}, ...},"jsonrpc":"2.0","id":1}
Direct tools/call for unity_list_instances succeeds:
{
"instances": [
{
"port": 7892,
"projectName": "CosmicCatastrophe",
"projectPath": "C:/Users/<user>/Projects/cosmic-catastrophe/CosmicCatastrophe",
"unityVersion": "6000.4.2f1",
"isClone": false,
"cloneIndex": -1,
"source": "portscan",
"isSelected": false
}
],
"totalCount": 1,
"selectedPort": null,
"selectedProject": null
}Direct tools/call for unity_editor_ping succeeds:
{
"connected": true,
"status": "ok",
"unityVersion": "6000.4.2f1",
"projectName": "CosmicCatastrophe",
"projectPath": "C:/Users/<user>/Projects/cosmic-catastrophe/CosmicCatastrophe",
"platform": "WindowsEditor",
"isClone": false,
"cloneIndex": -1,
"processId": 43084
}Unity MCP debug log shows prior successful Codex wrapper attempts reaching the server, but the latest failing calls after restart did not add log entries. That suggests the failure is happening before the configured Node MCP server receives the request.
Additional notes
When I tested the server manually, header-framed MCP messages started the server but did not get responses; newline-delimited JSON-RPC over stdio worked. If Codex Desktop's wrapper is using or falling back to a different stdio framing mode for this server, that could explain the symptom, but this is only an inference from the direct smoke tests.
Activity
github-actions commentedon Apr 18, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
DrCord commentedon Apr 19, 2026
Not a duplicate of #16899 — these are distinct bugs.
A bot flagged #16899 as a potential duplicate. After reviewing both issues, they are not the same:
Transport closedimmediately on every call — Unity MCP server logs confirm requests never arrivecodex execsubprocesses#16899 is a session transport lifetime bug (connection degrades over time). This issue is a stdio framing or Codex Desktop wrapper bug that prevents the first call from ever reaching the server. The shared symptom (
Transport closed) does not indicate the same root cause.DrCord commentedon Apr 28, 2026
Update after more debugging: I was able to get native Codex Desktop MCP working with this Unity MCP server.
The original framing hypothesis was incomplete. The decisive failure was that the Unity MCP server wrote a non-JSON status line to stdout during some tool calls, for example queue submission logging like:
Direct smoke clients and some other MCP clients tolerated/ignored that line, but Codex Desktop appears to treat MCP stdio stdout as strict JSON-RPC. When
unity_execute_codeemitted that bridge status line before the JSON-RPC response, Codex closed the transport and surfacedTransport closed.Workaround/fix that restored native Codex MCP:
console.debug(...)withconsole.error(...)for the bridge queue-submission and lazy-load log messages was enough.After restarting Codex Desktop, native MCP calls succeeded end to end:
unity_list_instancesfound the Unity instance.unity_select_instanceselected it.unity_editor_pingreturnedconnected: true.unity_execute_codereturned the active scene successfully instead of closing the transport.So at least one cause of this
Transport closedfailure mode is: MCP server writes non-JSON data to stdout, and Codex Desktop is stricter than clients that ignore such output. A useful Codex-side improvement would be better diagnostics for malformed/non-JSON stdout before closing the transport, but server authors should also ensure stdout is reserved exclusively for MCP JSON-RPC.Necmttn commentedon Jun 22, 2026
A Codex-side diagnostic before closing the transport would help a lot here. Suggested fields: MCP server name, command path, child pid, framing mode, stdout parser state, first non-JSON stdout line or byte offset, stderr tail, and close reason.
That would turn
Transport closedinto an actionable server-author fix: stdout contained non-MCP bytes, Node path failed, process exited, or framing was wrong. Right now several distinct failures collapse into the same message.Generated with ax - https://github.com/Necmttn/ax
Wheels00 commentedon Jul 30, 2026
Another reproducible macOS case: a resumed task retained a dead local-stdio MCP transport while direct and fresh-task checks passed.
Environment:
26.721.41059(build5848, bundlecom.openai.codex)26.0.1(25A362)email_mcpemail-mcp 1.27.0; MCP protocol2025-11-25Timeline (UTC, 30 Jul 2026):
00:42:59: resumed/current task called a harmless read-only tool. It immediately returnedtool call error: tool call failed for email_mcp/email.list_account_statuses/Caused by: Transport closed.00:43:32: an isolated direct stdio probe passed configuration, launch (1 ms), initialize (306 ms), andtools/list(1 ms), discovering 21 tools.01:17:57: provider authentication refresh completed successfully through a new/direct MCP connection.01:20:58: the same resumed task called another Email MCP tool and again failed immediately withTransport closed.01:22:49: a genuinely fresh task completed a harmless Email MCP health call successfully (transport_health: ok). A repeat direct probe at01:23again passed initialize (395 ms), discovered 21 tools, and exited cleanly after stdin closed.Sanitized process snapshot (arguments and environment omitted):
email_mcphad one direct root plus one zombie helper child.This single snapshot shows substantial MCP-generation accumulation but does not by itself prove monotonic growth.
Minimal reproduction:
Transport closed.tools/listprobe against the same configured command; it succeeds.Transport closed.Conclusion: stale task-bound host transport is confirmed in this case because the resumed task fails while the direct probe and fresh task pass. Authentication is not the fault boundary. The retained per-task MCP generations are plausible lifecycle-leak evidence, but growth would need before/after snapshots to confirm.
Related macOS report: #15365.