Conditionally start MCP servers based on project
Build iOS plugin starts xcodebuildmcp globally in unrelated Codex workflows; need lazy or project-scoped MCP startup
Summary
Codex Desktop currently starts the build-ios-apps plugin's xcodebuildmcp stdio MCP server globally when the plugin is enabled, even in non-iOS workflows. On my machine this caused xcodebuildmcp helper trees to run and accumulate while I was in a projectless/non-Xcode Codex thread and had not worked on any iOS/Xcode project that day.
This is related to the stdio MCP lifecycle leaks tracked in #17574, #18881, #20349, and fixed/partially addressed by #19753, but the user-facing problem here is broader: enabling an iOS-specific plugin globally affects unrelated Codex workflows. The plugin should ideally be lazy-loaded only when an iOS tool is invoked, or project-scoped to known iOS repositories.
Environment
- Codex Desktop:
26.429.20946 - Bundle version:
2312 - Platform: macOS
26.3build25D125 - Kernel:
Darwin 25.3.0 arm64 - Machine: Apple Silicon Mac
- Codex thread cwd when observed:
/Users/johnsilva/Documents/Codex/2026-04-30/every-time-i-turn-on-codex - This was not an Xcode/iOS project.
Relevant config/source
Global plugin config:
[plugins."build-ios-apps@openai-curated"]
enabled = true
Plugin MCP declaration:
{
"mcpServers": {
"xcodebuildmcp": {
"command": "npx",
"args": ["-y", "xcodebuildmcp@latest", "mcp"],
"env": {
"XCODEBUILDMCP_ENABLED_WORKFLOWS": "simulator,ui-automation,debugging,logging"
}
}
}
}
Because this uses npx -y xcodebuildmcp@latest mcp, leaving the plugin enabled can also trigger npm/package-resolution/network churn in unrelated workflows.
What happened
With build-ios-apps@openai-curated enabled, a non-iOS Codex session had many xcodebuildmcp processes owned by the Codex app-server:
/Applications/Codex.app/Contents/Resources/codex app-server --analytics-default-enabled
npm exec xcodebuildmcp@latest mcp
node .../.bin/xcodebuildmcp mcp
Observed during this session:
27app-server-ownedxcodebuildmcpprocesses targeted for cleanup- about
2.48 GBRSS in those app-server-ownedxcodebuildmcpprocesses - Codex app-server CPU was around
100%during the helper fan-out - after terminating those app-server-owned helpers, app-server CPU dropped back near idle
There was also a separate orphaned Codex CLI process tree with TTY=??, PPID=1, and its own xcodebuildmcp child, despite the terminal tab already being closed:
node /opt/homebrew/bin/codex
.../vendor/aarch64-apple-darwin/codex/codex
npm exec xcodebuildmcp@latest mcp
node .../.bin/xcodebuildmcp mcp
Killing that orphaned tree removed the remaining xcodebuildmcp processes.
Workaround that stopped the issue
Disabling only the iOS plugin globally stopped new xcodebuildmcp startup in unrelated workflows:
[plugins."build-ios-apps@openai-curated"]
enabled = false
After disabling that plugin and killing stale helpers:
pgrep -fl 'xcodebuildmcp@latest mcp|node .*xcodebuildmcp mcp'
# no matches
This is effective, but it is a bad long-term workflow because the plugin is very useful when actively developing an iOS app. It removes mcp__XcodeBuildMCP__... tools for simulator UI automation, screenshots, taps, build/run helpers, etc.
Expected behavior
Enabling build-ios-apps should not impose an always-on xcodebuildmcp cost on unrelated Codex workflows.
Expected behavior could be any of:
- Lazy-load
xcodebuildmcponly when anmcp__XcodeBuildMCP__...tool is actually invoked. - Support project-scoped plugin enablement, so
build-ios-appscan be enabled for/Users/.../squatappor other iOS repos without affecting unrelated workspaces. - Avoid
npx @lateststartup cost by using a pinned/cached plugin-managed executable. - Ensure all plugin-owned stdio MCP process trees are torn down on session close, thread close, app-server refresh, and CLI/app shutdown.
Actual behavior
The plugin is global. If it is enabled, non-iOS workflows can still pay the xcodebuildmcp process, memory, CPU, and network/package-resolution cost.
In practice, the only reliable local mitigation was to keep the plugin disabled globally and manually re-enable it before iOS work, then disable it again and clean up stale xcodebuildmcp after iOS work.
Related issues/PRs
- #17574
- #18881
- #20349
- #19753
The lifecycle fix in #19753 may address part of the stale-process leak, but this report is also asking for plugin/MCP loading semantics that do not start iOS-specific tooling in unrelated sessions.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗