xcodebuildmcp is a unified command-line interface that provides both an MCP server and direct tool access via a first-class CLI.
Use xcodebuildmcp CLI to invoke tools or start the MCP server by passing the mcp argument.
# Install globally
npm install -g xcodebuildmcp@beta
# Or run via npx
npx xcodebuildmcp@beta --help# List available tools
xcodebuildmcp tools
# View CLI help
xcodebuildmcp --help
# View tool help
xcodebuildmcp <workflow> <tool> --help
# Run interactive setup for .xcodebuildmcp/config.yaml
xcodebuildmcp setup
# Check for updates
xcodebuildmcp upgrade --checkxcodebuildmcp upgrade checks for a newer release and optionally runs the upgrade.
# Check for updates without upgrading
xcodebuildmcp upgrade --check
# Upgrade automatically (skip confirmation prompt)
xcodebuildmcp upgrade --yes| Flag | Description |
|---|---|
--check |
Report the latest version and exit. Never prompts or runs an upgrade. |
--yes / -y |
Skip the confirmation prompt and run the upgrade command automatically. |
When both --check and --yes are supplied, --check wins.
The command detects how XcodeBuildMCP was installed and adapts accordingly:
| Method | Auto-upgrade | Command |
|---|---|---|
| Homebrew | Yes | brew update && brew upgrade xcodebuildmcp |
| npm global | Yes | npm install -g xcodebuildmcp@latest |
| npx | No | npx resolves @latest on each run; update the pinned version in your client config if needed. |
| Unknown | No | Manual instructions for all supported channels are shown. |
When stdin is not a TTY (CI, pipes, scripts):
--checkworks normally and exits 0.--yesruns the upgrade for Homebrew and npm-global installs.- Without
--checkor--yes, the command prints the manual upgrade command and exits 1 (it cannot prompt for confirmation).
If the release check fails (network error, rate limit, timeout), the command prints the detected install method and manual upgrade instructions, then exits 1.
Each tool supports --help for detailed options:
xcodebuildmcp simulator build --helpCommon patterns:
# Pass options as flags
xcodebuildmcp simulator build --scheme MyApp --project-path ./MyApp.xcodeproj
# Pass complex options as JSON
xcodebuildmcp simulator build --json '{"scheme": "MyApp", "projectPath": "./MyApp.xcodeproj"}'
# Control output format
xcodebuildmcp simulator list --output json# Discover projects
xcodebuildmcp simulator discover-projects
# List schemes
xcodebuildmcp simulator list-schemes --project-path ./MyApp.xcodeproj
# Build
xcodebuildmcp simulator build --scheme MyApp --project-path ./MyApp.xcodeproj
# Boot simulator
xcodebuildmcp simulator boot --simulator-name "iPhone 17 Pro"
# Install and launch
xcodebuildmcp simulator install --simulator-id <UDID> --app-path ./build/MyApp.app
xcodebuildmcp simulator launch-app --simulator-id <UDID> --bundle-id io.sentry.MyApp
# Or... build and run in a single command
xcodebuildmcp simulator build-and-run --scheme MyApp --project-path ./MyApp.xcodeprojFor xcodebuild-backed build-and-run tools:
- CLI text mode prints a durable preflight block first
- interactive terminals then show active phases as live replace-in-place updates
- warnings, errors, failures, summaries, and next steps are durable output
- success output order is: front matter -> runtime state/diagnostics -> summary -> execution-derived footer -> next steps
- failed structured xcodebuild runs do not render next steps
- compiler/build diagnostics should be grouped into a readable failure block before the failed summary
- the final footer should only contain execution-derived values such as app path, bundle ID, app ID, or process ID
- requested values like scheme, project/workspace, configuration, and platform stay in front matter and should not be repeated later
- when the tool computes a concrete value during execution, prefer showing it directly in the footer instead of relegating it to a hint or redundant next step
For example, a successful build-and-run footer should prefer:
✅ Build & Run complete
└ App Path: /tmp/.../MyApp.app
rather than forcing the user to run another command just to retrieve a value the tool already knows.
MCP uses the same human-readable formatting semantics, but buffers the rendered output instead of streaming it to stdout live. It is the same section model and ordering, just a different sink.
--output json is still streamed JSONL events, not the human-readable section format.
# Run all tests
xcodebuildmcp simulator test --scheme MyAppTests --project-path ./MyApp.xcodeproj
# Run with specific simulator
xcodebuildmcp simulator test --scheme MyAppTests --simulator-name "iPhone 17 Pro"
# Run with pre-resolved test discovery and live progress
xcodebuildmcp simulator test --json '{"workspacePath":"./MyApp.xcworkspace","scheme":"MyApp","simulatorName":"iPhone 17 Pro","progress":true,"extraArgs":["-only-testing:MyAppTests"]}'Simulator test output now pre-resolves concrete Swift XCTest and Swift Testing cases when it can, then streams filtered milestones for package resolution, compilation, and test execution plus a grouped failure summary instead of raw xcodebuild noise.
For a full list of workflows and tools, see TOOLS-CLI.md.
The CLI respects the same configuration as the MCP server:
# .xcodebuildmcp/config.yaml
sessionDefaults:
scheme: MyApp
projectPath: ./MyApp.xcodeproj
simulatorName: iPhone 17 Pro
enabledWorkflows:
- simulator
- project-discoverySee CONFIGURATION.md for the full schema.
To create/update config interactively, run xcodebuildmcp setup.
| Variable | Description |
|---|---|
XCODEBUILDMCP_SOCKET |
Override socket path for all commands |
XCODEBUILDMCP_DAEMON_IDLE_TIMEOUT_MS |
Daemon idle timeout in ms (default 600000, set 0 to disable) |
XCODEBUILDMCP_DISABLE_SESSION_DEFAULTS |
Disable session defaults |
| Feature | CLI (xcodebuildmcp <tool>) |
MCP (xcodebuildmcp mcp) |
|---|---|---|
| Invocation | Direct terminal | MCP client (Claude, etc.) |
| Session state | Stateless direct + daemon for stateful tools | In-process |
| Use case | Scripts, CI, manual | AI-assisted development |
| Configuration | Same config.yaml | Same config.yaml |
Both share the same underlying tool implementations.
The CLI uses a per-workspace daemon architecture only when needed:
- Stateless tools run directly in the CLI process.
- Stateful tools route through the daemon (auto-started as needed).
- Dynamic
xcode-idebridge tools are a special-case daemon-backed path for persistent bridge sessions.
- Workspace identity: The workspace root is determined by the location of
.xcodebuildmcp/config.yaml, or falls back to the current directory. - Socket location: Each daemon runs on a Unix socket at
~/.xcodebuildmcp/daemons/<workspace-key>/daemon.sock - Auto-start: The daemon starts automatically when you invoke a stateful tool - no manual setup required.
- Auto-shutdown: The daemon exits after 10 minutes of inactivity, but only when there are no active stateful sessions (log capture, debugging, video capture, background swift-package processes).
# Check daemon status for current workspace
xcodebuildmcp daemon status
# Manually start the daemon
xcodebuildmcp daemon start
# Stop the daemon
xcodebuildmcp daemon stop
# Restart the daemon
xcodebuildmcp daemon restart
# List all daemons across workspaces
xcodebuildmcp daemon list
# List in JSON format
xcodebuildmcp daemon list --jsonDaemon Status: Running
PID: 12345
Workspace: /Users/you/Projects/MyApp
Socket: /Users/you/.xcodebuildmcp/daemons/c5da0cbe19a7/daemon.sock
Started: 2024-01-15T10:30:00.000Z
Tools: 94
Workflows: (default)
Daemons:
[running] c5da0cbe19a7
Workspace: /Users/you/Projects/MyApp
PID: 12345
Started: 2024-01-15T10:30:00.000Z
Version: 1.15.0
[stale] a1b2c3d4e5f6
Workspace: /Users/you/Projects/OldProject
PID: 99999
Started: 2024-01-14T08:00:00.000Z
Version: 1.14.0
Total: 2 (1 running, 1 stale)
Most tools run directly without the daemon:
build,test,cleanlist,list-schemes,discover-projectsboot,install,launch-appetc.
Some tools maintain state and route through the daemon:
- Video recording:
record-video - Debugging:
attach,continue, etc. - Background processes:
run,stop
When you invoke a stateful tool, the daemon auto-starts if needed.
| Option | Description |
|---|---|
--socket <path> |
Override the daemon socket path (hidden) |
-h, --help |
Show help |
-v, --version |
Show version |
# Check for stale sockets
xcodebuildmcp daemon list
# Force restart
xcodebuildmcp daemon restart
# Run in foreground to see logs
xcodebuildmcp daemon start --foregroundIncrease the daemon startup timeout:
# Default is 5 seconds
export XCODEBUILDMCP_STARTUP_TIMEOUT_MS=10000The socket directory (~/.xcodebuildmcp/daemons/) should have mode 0700. If you encounter permission issues:
chmod 700 ~/.xcodebuildmcp
chmod -R 700 ~/.xcodebuildmcp/daemons