Skip to content

Latest commit

 

History

History
335 lines (231 loc) · 9.81 KB

File metadata and controls

335 lines (231 loc) · 9.81 KB

XcodeBuildMCP CLI

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.

Installation

# Install globally
npm install -g xcodebuildmcp@beta

# Or run via npx
npx xcodebuildmcp@beta --help

Quick Start

# 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 --check

Upgrade

xcodebuildmcp 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

Flags

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.

Install method behavior

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.

Non-interactive mode

When stdin is not a TTY (CI, pipes, scripts):

  • --check works normally and exits 0.
  • --yes runs the upgrade for Homebrew and npm-global installs.
  • Without --check or --yes, the command prints the manual upgrade command and exits 1 (it cannot prompt for confirmation).

GitHub API failures

If the release check fails (network error, rate limit, timeout), the command prints the detected install method and manual upgrade instructions, then exits 1.

Tool Options

Each tool supports --help for detailed options:

xcodebuildmcp simulator build --help

Common 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

Examples

Build and Run Workflow

# 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.xcodeproj

Human-readable build-and-run output

For 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.

Testing

# 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.

Configuration

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-discovery

See CONFIGURATION.md for the full schema.

To create/update config interactively, run xcodebuildmcp setup.

Environment Variables

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

CLI vs MCP Mode

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.

Per-Workspace Daemon

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-ide bridge tools are a special-case daemon-backed path for persistent bridge sessions.

How It Works

  • 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).

Daemon Commands

# 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 --json

Daemon Status Output

Daemon 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)

Daemon List Output

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)

Stateful vs Stateless Tools

Stateless Tools (run in-process)

Most tools run directly without the daemon:

  • build, test, clean
  • list, list-schemes, discover-projects
  • boot, install, launch-app etc.

Stateful Tools (require daemon)

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.

Global Options

Option Description
--socket <path> Override the daemon socket path (hidden)
-h, --help Show help
-v, --version Show version

Troubleshooting

Daemon won't start

# Check for stale sockets
xcodebuildmcp daemon list

# Force restart
xcodebuildmcp daemon restart

# Run in foreground to see logs
xcodebuildmcp daemon start --foreground

Tool timeout

Increase the daemon startup timeout:

# Default is 5 seconds
export XCODEBUILDMCP_STARTUP_TIMEOUT_MS=10000

Socket permission errors

The socket directory (~/.xcodebuildmcp/daemons/) should have mode 0700. If you encounter permission issues:

chmod 700 ~/.xcodebuildmcp
chmod -R 700 ~/.xcodebuildmcp/daemons