Conditionally start MCP servers based on project

Resolved 💬 2 comments Opened Apr 30, 2026 by johnsilvavlogs Closed Jul 1, 2026

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.3 build 25D125
  • 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:

  • 27 app-server-owned xcodebuildmcp processes targeted for cleanup
  • about 2.48 GB RSS in those app-server-owned xcodebuildmcp processes
  • 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 xcodebuildmcp only when an mcp__XcodeBuildMCP__... tool is actually invoked.
  • Support project-scoped plugin enablement, so build-ios-apps can be enabled for /Users/.../squatapp or other iOS repos without affecting unrelated workspaces.
  • Avoid npx @latest startup 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.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗