XcodeBuildMCP
Preferred MCP for Apple build, test, simulator, device, and UI inspection sessions.
Prefer XcodeBuildMCP MCP tools for iOS/macOS build, test, simulator, and UI inspection. A missing tool does not itself authorize CLI or raw Xcode fallback.
| Use when | Building, testing, launching, inspecting UI, or managing simulators/devices for Apple apps |
| Do not use as | A substitute for reading skill workflows; product implementation still goes through foundation skills |
| Canonical in-repo | MCP.md |
| Upstream | xcodebuildmcp.com · CLI · Tools · Workflows |
| Verified against | XcodeBuildMCP 2.6.2 tool catalog (npx xcodebuildmcp tools) + official docs |
Naming: MCP vs CLI
XcodeBuildMCP exposes the same implementations two ways. Names differ:
| Surface | Form | Example |
|---|---|---|
| MCP (agent tool list) | Underscored tool id | build_run_sim, discover_projs, session_show_defaults |
| CLI (shell / CI) | xcodebuildmcp <workflow> <verb> |
xcodebuildmcp simulator build-and-run |
This playbook prefers MCP names. The CLI column is a capability reference, not automatic fallback permission; use it only when the active repository or user policy explicitly permits XcodeBuildMCP CLI fallback.
List everything installed locally:
xcodebuildmcp tools # grouped by workflow
xcodebuildmcp tools --json # machine-readable CLI verbs
xcodebuildmcp simulator build-and-run --help
Interactive config: xcodebuildmcp setup. Optional agent skill install: xcodebuildmcp init. Env diagnostics: xcodebuildmcp doctor (include doctor output on support issues).
Fast path (every MCP session)
- Call
session_show_defaultsbefore the first build/run/test action. - If defaults are empty or wrong:
session_set_defaults(and/or seedsessionDefaultsin config). Usediscover_projsonly when you still need to find projects — not speculatively, and not in parallel with show-defaults. - For simulator run intent, prefer
build_run_sim(one-shot build + install + launch) over separatebuild_sim→install_app_sim→launch_app_sim. - Prefer
simulatorId(exact UDID) over name-only selection; avoid unstable “latest OS” churn when pinning a device for Maestro. - Report active context (project/workspace, scheme, configuration, exact simulator/device) and the exact failing tool on errors.
Capability and fallback ladder
Use the first authorized capability in this order:
| Tier | Path | Authorization rule |
|---|---|---|
| 1 | XcodeBuildMCP MCP tools | Preferred. Use the live tool list and enable the required workflow when possible |
| 2 | XcodeBuildMCP CLI | Only when active repository/user policy explicitly permits CLI fallback; shell access and installation are not permission |
| 3 | Repository-native raw Xcode tooling (xcodebuild, xcrun, simctl, or a documented wrapper) |
Only when active policy authorizes it. Obtain explicit approval when that policy requires it |
| 4 | Blocked report | Required when no authorized capability remains; state the failed capability, policy boundary, unrun checks, and next action |
Any fallback must preserve the project/workspace, scheme, configuration, exact simulator/device, serialized execution, test scope, and applicable repository commands. Every handoff reports those values, the exact tools or commands, outcomes, and residual risk. None of these tiers weakens approvals for destructive actions, deployment, publishing, credentials, or user data.
Install and configure
- Register XcodeBuildMCP in the agent host’s MCP server list (host-specific). Server entrypoint is typically
xcodebuildmcp mcp(stdio). - Create or edit project-local config at the consumer workspace root:
# <workspace-root>/.xcodebuildmcp/config.yaml
schemaVersion: 1
enabledWorkflows: ["simulator", "ui-automation", "debugging"]
# Optional — reduces rediscovery every session:
# sessionDefaults:
# projectPath: "./MyApp.xcodeproj" # or workspacePath (mutually exclusive; workspace wins if both set)
# scheme: "MyApp"
# simulatorId: "<UDID>" # preferred over simulatorName when pinning
# simulatorName: "iPhone 17 Pro"
# configuration: "Debug"
schemaVersion: 1 is required. Layering (highest wins): session tools → config file → env vars. Details: Configuration · Session defaults.
Workflow selection (MCP context)
By default the MCP server advertises simulator tools. Session-management tools (session_show_defaults, session_set_defaults, …) are also available by default. Other workflows stay off until enabled — names from the upstream workflows catalog:
| Need | Enable workflow | Notes |
|---|---|---|
| iOS simulator build/run/test | simulator (default) |
Core build path |
| Show / set / clear defaults; named profiles | session-management (default) |
See session tools below |
| Simulator boot/erase/appearance/location | simulator-management |
Lifecycle & env chrome |
| UI gestures, screenshots, hierarchy automation | ui-automation |
iOS simulator only — not available for macOS apps |
| Physical device | device |
Needs signing in Xcode |
| macOS app build/run/test | macos |
Prefer build_run_macos / test_macos; no UI automation tools |
| SwiftPM packages | swift-package |
|
| Debug attach / breakpoints | debugging |
Stateful (daemon in CLI mode) |
| Scaffold new projects | project-scaffolding |
|
| Project/scheme discovery tools | project-discovery |
discover_projs also appears under other workflows |
| Env / dependency diagnostics | doctor |
|
| Xcode IDE bridge | xcode-ide |
Opt-in |
After changing config: reload or restart the MCP session.
Monorepo named profiles
For multiple apps in one repo, use sessionDefaultsProfiles + activeSessionDefaultsProfile in config, or switch at runtime with session_use_defaults_profile. Profiles are isolated (no inheritance). CLI: --profile <name> on a single invocation. See Named profiles.
Session tools (MCP)
| MCP tool | Purpose |
|---|---|
session_show_defaults |
Read current project/scheme/simulator/device defaults |
session_set_defaults |
Set or patch defaults for the rest of the session (can persist to config) |
session_clear_defaults |
Clear session defaults |
session_use_defaults_profile |
Switch named profile (monorepo) |
Tool map (MCP name → CLI)
Exact advertised set depends on enabledWorkflows and XcodeBuildMCP version. Prefer the host’s live tool list. Mapping verified against 2.6.2 + official docs:
| Intent | MCP tool(s) | CLI equivalent |
|---|---|---|
| Show defaults | session_show_defaults |
(session defaults auto-fill CLI flags from config) |
| Set / clear / profile | session_set_defaults, session_clear_defaults, session_use_defaults_profile |
config sessionDefaults / --profile |
| Find projects | discover_projs |
xcodebuildmcp project-discovery discover-projects (also under simulator / device / macos) |
| List schemes / settings | list_schemes, show_build_settings |
… list-schemes, … show-build-settings |
| List simulators | list_sims |
xcodebuildmcp simulator list |
| Simulator build only | build_sim |
xcodebuildmcp simulator build |
| Simulator build + install + launch (preferred for run) | build_run_sim |
xcodebuildmcp simulator build-and-run |
| Simulator install / launch / stop | install_app_sim, launch_app_sim, stop_app_sim |
simulator install, launch-app, stop |
| Simulator test | test_sim |
xcodebuildmcp simulator test |
| Simulator boot / open | boot_sim, open_sim |
simulator boot, open |
| Screenshot / UI snapshot | screenshot, snapshot_ui |
simulator screenshot, snapshot-ui |
| Record video | record_sim_video |
xcodebuildmcp simulator record-video (daemon/stateful) |
| Device build + run | build_run_device |
xcodebuildmcp device build-and-run |
| Device build / test / install / launch | build_device, test_device, install_app_device, launch_app_device |
device build, test, install, launch |
| macOS build + run | build_run_macos |
xcodebuildmcp macos build-and-run |
| macOS build / test / launch | build_macos, test_macos, launch_mac_app |
macos build, test, launch |
| SwiftPM | swift_package_build, swift_package_test, swift_package_run, … |
xcodebuildmcp swift-package … |
| UI automation | tap, swipe, type_text, gesture, wait_for_ui, … |
xcodebuildmcp ui-automation … |
| Scaffold | scaffold_ios_project, scaffold_macos_project |
project-scaffolding scaffold-ios / scaffold-macos |
| Doctor | doctor |
xcodebuildmcp doctor |
launchArgs vs extraArgs
Official contract (build-and-run and launch tools):
| Parameter | Goes to | Use for |
|---|---|---|
launchArgs |
App process (ProcessInfo.processInfo.arguments) |
Runtime flags, UI-testing hooks (--uitesting, mocks) |
extraArgs |
xcodebuild / build settings only |
e.g. -only-testing:MyAppTests — not passed to the app |
Applies to MCP tools such as build_run_sim, build_run_device, build_run_macos, launch_app_sim, launch_app_device, launch_mac_app (and their CLI counterparts).
CLI recipes (when explicitly permitted)
These examples use the same config file as MCP. They are available only at tier 2
of the capability ladder. Synopsis: xcodebuildmcp <workflow> <tool> [options].
# Build + run simulator (preferred one-shot)
xcodebuildmcp simulator build-and-run \
--scheme MyApp \
--project-path ./MyApp.xcodeproj \
--simulator-id <UDID>
# With runtime launch args (JSON form)
xcodebuildmcp simulator build-and-run --json '{
"scheme": "MyApp",
"projectPath": "./MyApp.xcodeproj",
"simulatorId": "<UDID>",
"launchArgs": ["--uitesting"]
}'
# Tests with live progress + focused suite
xcodebuildmcp simulator test --json '{
"workspacePath": "./MyApp.xcworkspace",
"scheme": "MyApp",
"simulatorId": "<UDID>",
"progress": true,
"extraArgs": ["-only-testing:MyAppTests"]
}'
Long-running CLI calls stream progress. For agent parsers prefer --output jsonl; humans use default text; --output json waits for a single final payload. See CLI · Output formats.
Stateful tools (log capture, video, LLDB, some SwiftPM runs) use a per-workspace daemon in CLI mode (xcodebuildmcp daemon status|logs|…). MCP keeps session state in-process.
Failure modes
| Symptom | Next step |
|---|---|
| No macOS/device/UI tools in the tool list | Enable matching enabledWorkflows; reload/restart MCP |
| Wrong scheme or simulator | session_show_defaults → session_set_defaults or config; prefer simulatorId |
| Empty or wrong project path | Fix workspace root; discover_projs only if defaults still wrong |
| Signing / device install errors | Fix signing in Xcode; enable device only when needed; report exact tool failure |
| MCP is unavailable | Report the exact failure; use CLI only when active policy explicitly permits it, then consider only an authorized repository-native fallback |
Agent used raw xcodebuild |
Stop if authorization was not established; confirm active policy and preserve the complete target/test context in any approved fallback |
| Flaky simulator selection | Pin one simulatorId; avoid useLatestOS / name-only churn for regression |
| MCP and CLI disagree on device | Same UDID + app state for both |
| Daemon / video / debug stuck (CLI) | xcodebuildmcp daemon status · daemon logs · CLI daemon docs |
More rows: Troubleshooting.
Verify after bootstrap or feature work
Goal: Prove the consumer app builds and tests on the intended target.
Constraints: Follow the capability ladder: MCP tools; explicitly permitted XcodeBuildMCP CLI; authorized repository-native tooling; otherwise blocked. No silent fallback.
Inputs: Active consumer project, scheme, simulatorId or macOS target.
Done when: session_show_defaults reported; build_run_sim or build/test executed; outcomes stated.
Verification: Prefer build_run_sim for launch; never claim pass without running the tool.
Related
- Repo
MCP.md - Maestro — pair for UI regression (same simulator ID)
- Verification matrix
- Task recipes
- Troubleshooting