[Cross-platform] build-ios-apps starts XcodeBuildMCP on non-macOS hosts in Desktop and VS Code (autogen selfreport from codex)

Open 💬 4 comments Opened Aug 14, 2026 by nos1609
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What versions are affected?

Two independent current reproductions:

| Host and client | Codex version | Plugin |
| --- | --- | --- |
| Windows 11 ARM64, Codex Desktop | MSIX 26.810.4967.0 | build-ios-apps 0.1.2 |
| Rocky Linux 10.2 x86_64, VS Code Web extension | extension 26.810.41047-linux-x64, CLI/app-server 0.147.0 | build-ios-apps 0.1.2 |

What issue are you seeing?

The build-ios-apps plugin starts XcodeBuildMCP on non-macOS hosts where Xcode and Apple simulator tooling cannot exist.

The packaged plugin manifest has no platform declaration. Its MCP definition unconditionally executes:

npx -y xcodebuildmcp@latest mcp

This reproduces through two different Codex clients and two operating systems. Therefore the missing gate is not limited to one Desktop renderer or one OS-specific process launcher.

Reproduction A: Windows Codex Desktop

Environment:

  • Windows 11 Pro ARM64, build 28000
  • OpenAI Codex Desktop 26.810.4967.0, ARM64
  • Node.js v24.14.1, ARM64

Under one unchanged Desktop app-server, five complete XcodeBuildMCP generations accumulated over approximately four and a half hours.

Each generation retained this process chain:

cmd.exe /c npx -y xcodebuildmcp@latest mcp
  node.exe ... npx-cli.js -y xcodebuildmcp@latest mcp
    cmd.exe /c xcodebuildmcp mcp
      node.exe ... xcodebuildmcp/build/cli.js mcp

Snapshot:

| Scope | Processes | Working set | Private memory |
| --- | ---: | ---: | ---: |
| XcodeBuildMCP, 5 generations | 20 | 18.7 MiB | 1,121.5 MiB |
| Complete Codex Desktop tree | 75 | 1,867.9 MiB | 6,401.1 MiB |

Most XcodeBuildMCP pages had already been paged out on the 16 GiB host, but the processes still retained about 1.1 GiB of private commit.

Detailed Windows-only report: #38572.

Reproduction B: Linux VS Code extension

Environment:

  • Rocky Linux 10.2, x86_64
  • VS Code Web with Codex extension 26.810.41047-linux-x64
  • Codex CLI/app-server 0.147.0

Two live VS Code extensionHost processes each owned a Codex app-server. Those app-servers retained:

owner app-server 1:  1 XcodeBuildMCP generation
owner app-server 2: 16 XcodeBuildMCP generations
total:              17 generations

Each Linux generation retained two processes:

npm exec xcodebuildmcp@latest mcp
  node .../xcodebuildmcp mcp

Measured Linux snapshot:

| Scope | Value |
| --- | ---: |
| XcodeBuildMCP generations | 17 |
| Processes | 34 |
| Combined RSS | 2,556.9 MiB |
| Owning VS Code app-servers | 2 |

The Linux host had no macOS/Xcode capability. The processes were children of VS Code extension app-servers, not a standalone CLI session.

No iOS or Xcode operation is required to trigger the retained helpers. Ordinary task restoration and tool-context activity are sufficient.

Why this needs a plugin/core platform fix

The generic MCP lifecycle issues remain relevant, but lifecycle cleanup alone is insufficient. A macOS-only MCP must not be spawned on Windows or Linux at all.

The fix should be enforced at one or both of these layers:

  1. The plugin manifest must declare a supported OS or capability requirement for each MCP server.
  2. The Codex plugin loader must reject incompatible plugin MCP definitions before starting a process.

A user-level plugin alias or catalog provenance difference should not determine whether a physically impossible MCP starts. Platform compatibility must be checked after resolving the effective plugin package and before process creation.

What steps can reproduce the bug?

  1. Use Codex Desktop on Windows or the Codex VS Code extension on Linux.
  2. Have build-ios-apps available through the plugin catalog.
  3. Start or restore normal tasks. Do not request iOS, Xcode, or simulator work.
  4. Continue normal task switching, tool use, or context creation.
  5. Inspect descendants of each Codex app-server.
  6. Observe one or more retained xcodebuildmcp@latest mcp process groups.
  7. Continue working and observe the generation count and memory grow.

Windows inventory:

Get-CimInstance Win32_Process |
  Where-Object CommandLine -Match 'xcodebuildmcp' |
  Select-Object ProcessId, ParentProcessId, Name, CreationDate, CommandLine

Linux inventory:

ps -eo pid,ppid,etimes,rss,args |
  grep -E 'xcodebuildmcp(@latest)? mcp'

What is the expected behavior?

  • XcodeBuildMCP must be available only on macOS hosts with the required Xcode capability.
  • Codex must not start it on Windows or Linux.
  • Non-Xcode skills from the same plugin may remain available if they are genuinely portable.
  • Unsupported MCP tools should be reported as unavailable without launching npm or Node.js.
  • Failed, idle, or superseded MCP process groups must be reaped at a bounded lifecycle boundary.
  • Codex should not repeatedly execute an unpinned @latest package on an unsupported platform.
  • Plugin diagnostics should show the resolved plugin ID, source, compatibility decision, and owning task/context.

Additional information

Related but not duplicate:

  • #38572 is the focused Windows ARM64 / Desktop reproduction.
  • #37672 tracks broader Windows code-mode helper fan-out and configuration handling.
  • #17574 tracks supported macOS subagent lifecycle leaks involving XcodeBuildMCP.

This issue is specifically about the missing non-macOS platform/capability gate across both Desktop and VS Code extension surfaces.

No task IDs, project names, usernames, hostnames, addresses, local paths, prompts, credentials, tokens, or raw logs are included.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 13 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #38572

Powered by Codex Action

nos1609 · 13 days ago

Memory-accounting refinement

A follow-up proportional-memory measurement avoids overcounting shared Node.js mappings.

Linux, across the same 34 XcodeBuildMCP processes:

  • summed RSS: 2,556.9 MiB (shared mappings counted once per process);
  • summed PSS from /proc/<pid>/smaps_rollup: 752.6 MiB;
  • summed private clean + private dirty: 734.2 MiB.

Thus the current proportional physical-memory cost on Linux is approximately 0.75 GiB, not the raw 2.56 GiB RSS sum. This remains substantial for a platform-incompatible MCP.

Windows, across the same 20 XcodeBuildMCP processes:

  • private bytes: 1,121.2 MiB;
  • total working set: 15.5 MiB;
  • private working set: 9.0 MiB.

Windows had already paged almost all of this allocation out under memory pressure. The Windows impact at that snapshot was primarily commit/pagefile pressure and paging churn, while the Linux processes still occupied about 0.75 GiB of proportional resident memory.

The process-generation counts and platform-gating diagnosis are unchanged.

nos1609 · 2 days ago

Remote SSH reproduction: plugin-level disable is ignored, and live MCP reload multiplies XcodeBuildMCP

I reproduced the same defect through Codex Desktop Remote SSH. This adds a third client path to the Windows Desktop and Linux VS Code cases in the issue body.

Environment:

  • Windows 11 ARM64 client
  • Codex Desktop MSIX 26.818.8289.0
  • Remote Linux x86_64 app-server
  • Codex CLI/app-server 0.149.0
  • build-ios-apps plugin 0.1.2
  • effective catalog ID: build-ios-apps@openai-curated-remote

The remote app-server started XcodeBuildMCP for unrelated remote tasks. The Desktop-side and remote user configs both contained these disable entries:

[plugins."build-ios-apps@openai-curated-remote"]
enabled = false

[plugins."build-ios-apps@openai-curated-remote".mcp_servers.xcodebuildmcp]
enabled = false

These entries did not stop the MCP. Three XcodeBuildMCP process stacks remained under the long-lived remote app-server.

I then called the supported app-server RPC:

config/mcpServer/reload

The RPC returned success with an empty result. However, the reload increased the XcodeBuildMCP count from 3 stacks to 8 stacks. The resulting layout was approximately one stack per loaded remote task. Each stack contained an npm launcher and a Node.js XcodeBuildMCP child.

Representative individual RSS readings were:

  • Node.js XcodeBuildMCP child: approximately 212-216 MiB
  • npm launcher: approximately 131-164 MiB

These are per-process RSS readings and include shared mappings. I am not presenting their sum as proportional memory. During this state, the owning app-server reached approximately 1.8 GiB RSS and about 44% CPU in one sample.

I terminated only the exact XcodeBuildMCP child trees. I did not restart the app-server or stop the active remote tasks.

A top-level server-name override is an effective workaround:

[mcp_servers.xcodebuildmcp]
command = "npx"
args = ["-y", "xcodebuildmcp@latest", "mcp"]
enabled = false

After adding that entry, codex mcp get xcodebuildmcp reported the server as disabled. I called config/mcpServer/reload again. The RPC returned success, and the XcodeBuildMCP process count remained zero at checks after 0, 5, and 20 seconds.

This narrows the configuration defect:

  1. The remote catalog resolves the plugin as build-ios-apps@openai-curated-remote.
  2. Plugin-level enabled = false and nested MCP enabled = false do not reliably suppress its MCP in a running Remote SSH app-server.
  3. A live MCP reload can fan the disabled server out across loaded remote tasks.
  4. A top-level [mcp_servers.xcodebuildmcp] disable by server name does suppress it.

Expected behavior:

  • The effective remote plugin ID must honor enabled = false.
  • A nested disabled plugin MCP must not start.
  • config/mcpServer/reload must remove or retain the disabled state. It must not create one process stack per loaded task.
  • Platform-incompatible MCP servers must be rejected before process creation on Linux and Windows.

This report omits task IDs, project names, usernames, hostnames, addresses, local paths, prompts, credentials, and raw logs.

nos1609 · 2 days ago

Still there in 26.820.60940