Skip to main content
Glama
conorluddy

XC-MCP: XCode CLI wrapper

by conorluddy

XC-MCP: Intelligent Xcode MCP Server

npm version npm downloads Node.js version codecov Ask DeepWiki License: MIT

Production-grade MCP server for Xcode workflows — optimized for AI agents with accessibility-first iOS automation

XC-MCP makes Xcode and iOS simulator tooling accessible to AI agents through intelligent context engineering. V3.0.0 adds platform-native — Claude's tool search automatically discovers tools on-demand, minimizing baseline context overhead while maintaining full 29-tool functionality.


Why XC-MCP?

The Problem: Token Overflow Breaks MCP Clients

Traditional Xcode CLI wrappers dump massive output that exceeds MCP protocol limits:

  • simctl list: 57,000+ tokens (unusable in MCP context)

  • Build logs: 135,000+ tokens (catastrophic overflow)

  • Screenshot-first automation: 170 tokens per screen, 2000ms latency

  • No state memory between operations

The Solution: Progressive Disclosure + Accessibility-First

V3.0.0 Architecture:

Platform-native defer_loading on all 29 tools ├─ Claude's tool search discovers tools automatically ├─ Tools loaded on-demand (minimal baseline overhead) ├─ Accessibility-first workflow (50 tokens, 120ms vs 170 tokens, 2000ms) └─ Workflow tools for common operations (fresh-install, tap-element)

Token Efficiency Evolution:

Version

Baseline Tokens

Total Tools

Architecture

Context Available

Pre-RTFM (v1.2.1)

~45k

51

Individual tools

3.9% (155k)

V1.3.2 (RTFM)

~30k

51

Individual + RTFM

1.5% (170k)

V2.0.0

~18.7k

28

Routers + Full Docs

9.3% (181k)

V3.0.0

~0

29

Platform defer_loading

100% (200k)

Key Improvements (V3.0.0):

  • Platform-native defer_loading - All tools deferred; Claude discovers on-demand

  • Workflow tools - High-level abstractions for common operations

  • Zero baseline overhead - Platform handles tool discovery

  • Accessibility-first automation (3-4x faster, 3-4x cheaper than screenshots)

  • Progressive disclosure (summaries → cache IDs → full details on demand)

  • 60% test coverage with comprehensive error handling


Related MCP server: MiniMax MCP Server

Quick Start

# Install globally npm install -g xc-mcp # Or run without installation npx xc-mcp

MCP Configuration (Claude Desktop):

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{ "mcpServers": { "xc-mcp": { "command": "npx", "args": ["-y", "xc-mcp"] } } }

Minimal Mode (for Claude Code and other clients that don't support defer_loading):

{ "mcpServers": { "xc-mcp": { "command": "npx", "args": ["-y", "xc-mcp", "--mini"] } } }

The --mini flag reduces tool descriptions from ~18.7k tokens to ~540 tokens (~97% reduction). Use rtfm for full documentation on-demand.

Build-Only Mode (for build-focused workflows without UI automation):

{ "mcpServers": { "xc-mcp": { "command": "npx", "args": ["-y", "xc-mcp", "--build-only"] } } }

The --build-only flag loads only 11 tools (vs 30): xcodebuild tools, simctl-list, cache, and system tools. Excludes IDB/UI automation and workflow tools. Combine with --mini for maximum reduction: ["--mini", "--build-only"].


Token Optimization Architecture

Progressive Disclosure Pattern

XC-MCP returns concise summaries first, with cache IDs for on-demand detail retrieval:

Example: Simulator List (96% token reduction)

// 1. Get summary (2,000 tokens vs 57,000 raw) simctl-list({ deviceType: "iPhone" }) // Returns: { cacheId: "sim-abc123", summary: { totalDevices: 47, availableDevices: 31, bootedDevices: 1 }, quickAccess: { bootedDevices: [...], recentlyUsed: [...] } } // 2. Get full details only if needed simctl-get-details({ cacheId: "sim-abc123", detailType: "available-only", maxDevices: 10 })

Example: Build Operations

// 1. Build returns summary + buildId xcodebuild-build({ projectPath: "./MyApp.xcworkspace", scheme: "MyApp" }) // Returns: { buildId: "build-xyz789", success: true, summary: { duration: 7075, errorCount: 0, warningCount: 1 } } // 2. Access full logs only when debugging xcodebuild-get-details({ buildId: "build-xyz789", detailType: "full-log" })

RTFM On-Demand Documentation

Discovery Workflow:

// 1. Browse tool categories rtfm({ categoryName: "build" }) // Returns: List of build tools with brief descriptions // 2. Get comprehensive docs for specific tool rtfm({ toolName: "xcodebuild-build" }) // Returns: Full documentation with parameters, examples, related tools // 3. Execute with consolidated operations xcodebuild-build({ scheme: "MyApp", configuration: "Debug" })

Why RTFM?

  • Tool descriptions: <10 words + "See rtfm for details"

  • Full docs retrieved only when needed

  • 80% token savings vs traditional verbose MCP servers

Operation Enum Consolidation

Before V2.0: 21 individual tools

simctl-boot, simctl-shutdown, simctl-create, simctl-delete, simctl-erase, simctl-clone, simctl-rename, simctl-install, simctl-uninstall, simctl-launch, simctl-terminate...

V2.0: 6 consolidated routers

simctl-device({ operation: "boot" | "shutdown" | "create" | "delete" | "erase" | "clone" | "rename" }) simctl-app({ operation: "install" | "uninstall" | "launch" | "terminate" }) idb-app({ operation: "install" | "uninstall" | "launch" | "terminate" }) cache({ operation: "get-stats" | "get-config" | "set-config" | "clear" }) persistence({ operation: "enable" | "disable" | "status" }) idb-targets({ operation: "list" | "describe" | "connect" | "disconnect" })

Result: 40% token reduction through shared parameter schemas and unified documentation.


Accessibility-First iOS Automation

Our Philosophy

XC-MCP promotes accessibility-first automation because it:

  1. Encourages better apps: Developers building accessible UIs benefit all users (screen readers, voice control, assistive technologies)

  2. Enables precise AI interaction: Semantic element discovery via accessibility tree vs visual guesswork from screenshots

  3. Improves efficiency: 3-4x faster execution, 3-4x cheaper token cost

  4. Reduces energy usage: Skip computationally expensive image processing entirely

Objective Performance Data

Approach

Tokens

Latency

Use Case

Accessibility Tree

~50

~120ms

Rich UIs with >3 tappable elements

Screenshot Analysis

~170

~2000ms

Minimal UIs with ≤1 tappable element

Efficiency Gain

3.4x cheaper

16x faster

When accessibility sufficient

Accessibility-First Workflow

// 1. ALWAYS assess quality first accessibility-quality-check({ screenContext: "LoginScreen" }) // Returns: { quality: "rich" | "moderate" | "minimal", recommendation: "accessibility-ready" | "consider-screenshot", elementCounts: { total: 12, tappable: 8, textFields: 2 } } // 2. Decision branch based on quality if (quality === "rich" || quality === "moderate") { // Use accessibility tree (faster, cheaper) idb-ui-find-element({ query: "login" }) // Returns: { centerX: 200, centerY: 400, label: "Login" } idb-ui-tap({ x: 200, y: 400 }) // Precise coordinate-based interaction } else if (quality === "minimal") { // Fall back to screenshot (last resort) screenshot({ size: "half", screenName: "LoginScreen" }) // Visual analysis when accessibility insufficient }

Why This Matters:

  • For Users: Encourages inclusive app development benefiting everyone

  • For AI Agents: Precise semantic targeting vs visual pattern matching

  • For Efficiency: 50 tokens (accessibility) vs 170 tokens (screenshot)

  • For Speed: 120ms (accessibility) vs 2000ms (screenshot)

  • For Energy: Skip image encoding/decoding/analysis entirely

Accessibility Tools (3 specialized)

accessibility-quality-check: Rapid assessment without full tree query

  • Returns: rich (>3 tappable) | moderate (2-3) | minimal (≤1)

  • Use case: Decision point before screenshot vs accessibility

  • Cost: ~30 tokens, ~80ms

idb-ui-find-element: Semantic element search by label/identifier

  • Returns: Tap-ready coordinates (centerX, centerY) with frame boundaries

  • Use case: Find specific button, field, or cell without visual analysis

  • Cost: ~40 tokens, ~120ms

idb-ui-describe: Full accessibility tree with progressive disclosure

  • Operation all: Summary + uiTreeId for full tree retrieval

  • Operation point: Element details at specific coordinates

  • Use case: Discover all interactive elements, validate tap coordinates

  • Cost: ~50 tokens for summary, ~500 tokens for full tree


Platform defer_loading (V3.0.0 Feature)

How It Works

XC-MCP V3.0 adds the defer_loading: true flag to all 29 tool registrations. Claude's platform-native tool search automatically:

  1. Discovers tools on-demand — No custom tool-search implementation needed

  2. Loads tools when relevant — Based on conversation context

  3. Minimizes baseline overhead — Zero tokens at startup

RTFM: On-Demand Documentation

Use rtfm to get comprehensive documentation for any tool:

// 1. Browse tool categories rtfm({ categoryName: "build" }) // Returns all build-related tools with descriptions // 2. Get comprehensive docs for specific tool rtfm({ toolName: "xcodebuild-build" }) // Returns full documentation with parameters, examples, related tools // 3. Execute with discovered parameters xcodebuild-build({ scheme: "MyApp", configuration: "Debug" })

Environment Variable: Disable defer_loading

Default (V3.0.0): All tools have defer_loading enabled

# Platform discovers and loads tools automatically # Zero baseline token overhead

Disable defer_loading (for debugging/testing):

# Set environment variable to load all tools at startup export XC_MCP_DEFER_LOADING=false # All 29 tools loaded immediately (~18.7k tokens) # Useful for: Testing, debugging, MCP client compatibility

Workflow Tools (New in V3.0.0)

XC-MCP provides 2 high-level workflow tools that combine common operations into single steps:

workflow-tap-element — High-Level Semantic Tap

Combines accessibility quality check + element search + tap into one operation:

workflow-tap-element({ elementQuery: "Login", screenContext: "LoginScreen", inputText: "user@example.com", // optional: type after tap verifyResult: true // optional: screenshot after action }) // Does: // 1. Quality check screen accessibility // 2. Find element by name/label // 3. Tap coordinates // 4. Optionally type text // 5. Optionally take verification screenshot // Returns: { success: true, tappedElement: {...}, screenshot?: {...} }

Cost: ~90 tokens (vs 130 tokens separately) Latency: ~300ms (vs ~400ms separately) Use case: User login, form submission, navigation flows

workflow-fresh-install — Clean Install Workflow

Performs complete app refresh: shutdown → (erase) → boot → build → install → launch

workflow-fresh-install({ projectPath: "./MyApp.xcworkspace", scheme: "MyApp", simulatorUdid: "...", // optional: auto-detects eraseSimulator: true, // optional: wipe simulator data configuration: "Debug", launchArguments: ["--resetData"] }) // Does: // 1. Shutdown simulator if running // 2. Erase simulator state (if requested) // 3. Boot simulator fresh // 4. Build app // 5. Install app // 6. Launch app with arguments // Returns: { success: true, buildTime: 7000, bootTime: 3000, launchTime: 500 }

Cost: ~200 tokens (vs 300+ tokens separately) Latency: ~20s (vs 25+ seconds separately) Use case: CI/CD pipelines, clean state testing, fresh debugging sessions


Tool Reference

6 Consolidated Router Tools

simctl-device — Simulator lifecycle (7 operations)

  • boot, shutdown, create, delete, erase, clone, rename

  • Auto-UDID detection, performance tracking, smart defaults

simctl-app — App management (4 operations)

  • install, uninstall, launch, terminate

  • Bundle ID resolution, launch arguments, environment variables

idb-app — IDB app operations (4 operations)

  • install, uninstall, launch, terminate

  • Physical device + simulator support via IDB

cache — Cache management (4 operations)

  • get-stats, get-config, set-config, clear

  • Multi-layer caching (simulator, project, response, build settings)

persistence — Persistence control (3 operations)

  • enable, disable, status

  • File-based cache across server restarts

idb-targets — Target management (2 operations)

  • list, describe, connect, disconnect

  • Physical device and simulator discovery

22 Individual Specialized Tools

Build & Test (6 tools)

  • xcodebuild-build: Build with progressive disclosure via buildId

  • xcodebuild-test: Test with filtering, test plans, cache IDs

  • xcodebuild-clean: Clean build artifacts

  • xcodebuild-list: List targets/schemes with smart caching

  • xcodebuild-version: Get Xcode and SDK versions

  • xcodebuild-get-details: Access cached build/test logs

UI Automation (6 tools)

  • idb-ui-describe: Accessibility tree queries (all | point operations)

  • idb-ui-tap: Coordinate-based tapping with percentage conversion

  • idb-ui-input: Text input with keyboard control

  • idb-ui-gesture: Swipes, pinches, rotations with coordinate transforms

  • idb-ui-find-element: Semantic element search (NEW in v2.0)

  • accessibility-quality-check: Rapid UI richness assessment (NEW in v2.0)

I/O & Media (2 tools)

  • simctl-io: Screenshots and video recording with semantic naming

  • screenshot: Vision-optimized base64 screenshots (inline, max 800px)

Discovery & Health (3 tools)

  • simctl-list: Progressive disclosure simulator listing (96% token reduction)

  • simctl-get-details: On-demand full simulator data retrieval

  • simctl-health-check: Xcode environment validation

Utilities (5 tools)

  • simctl-openurl: Open URLs and deep links

  • simctl-get-app-container: Get app container paths (bundle, data, group)

  • simctl-push: Simulate push notifications

  • rtfm: On-demand comprehensive documentation

Workflow Tools (2 high-level abstractions) - NEW in V3.0.0

  • workflow-tap-element: High-level semantic tap (find + tap in one call)

  • workflow-fresh-install: Clean install workflow (shutdown → erase → boot → build → install → launch)

Total: 29 active tools (27 core + 2 workflow abstractions)


Usage Examples

Example 1: Accessibility-First Login Automation

// 1. Quality check before choosing approach accessibility-quality-check({ screenContext: "LoginScreen" }) // → { quality: "rich", tappableElements: 12, textFields: 2 } // 2. Find email field semantically idb-ui-find-element({ query: "email" }) // → { centerX: 200, centerY: 150, label: "Email", type: "TextField" } // 3. Tap and input email idb-ui-tap({ x: 200, y: 150 }) idb-ui-input({ operation: "text", text: "user@example.com" }) // 4. Find and tap login button idb-ui-find-element({ query: "login" }) // → { centerX: 200, centerY: 400, label: "Login", type: "Button" } idb-ui-tap({ x: 200, y: 400 }) // 5. Verify (screenshot only for confirmation, not primary interaction) screenshot({ screenName: "HomeScreen", state: "LoggedIn" })

Efficiency Comparison:

  • Accessibility approach: 4 queries × 50 tokens = 200 tokens, ~500ms total

  • Screenshot approach: 3 screenshots × 170 tokens = 510 tokens, ~6000ms total

  • Savings: 2.5x cheaper, 12x faster

Example 2: RTFM Discovery Workflow

// 1. Browse tool categories rtfm({ categoryName: "build" }) // Returns: { category: "build", tools: [ { name: "xcodebuild-build", description: "Build Xcode projects with smart defaults" }, { name: "xcodebuild-test", description: "Run tests with filtering and test plans" }, ... ] } // 2. Get comprehensive docs for specific tool rtfm({ toolName: "xcodebuild-build" }) // Returns: { tool: "xcodebuild-build", description: "Full comprehensive documentation...", parameters: { projectPath: "...", scheme: "...", configuration: "..." }, examples: [...], relatedTools: ["xcodebuild-clean", "xcodebuild-get-details"] } // 3. Execute with discovered parameters xcodebuild-build({ projectPath: "./MyApp.xcworkspace", scheme: "MyApp", configuration: "Debug" })

Example 3: Progressive Disclosure Build Workflow

// 1. Build returns summary + buildId xcodebuild-build({ projectPath: "./MyApp.xcworkspace", scheme: "MyApp" }) // Returns: { buildId: "build-abc123", success: true, summary: { duration: 7075, errorCount: 0, warningCount: 1, configuration: "Debug", sdk: "iphonesimulator" }, nextSteps: [ "Build completed successfully", "Use 'xcodebuild-get-details' with buildId for full logs" ] } // 2. Access full logs only when debugging xcodebuild-get-details({ buildId: "build-abc123", detailType: "full-log", maxLines: 100 }) // Returns: Full compiler output, warnings, errors

CLAUDE.md Template for End Users

Copy this into your project's CLAUDE.md to guide AI agents toward optimal XC-MCP usage:

# XC-MCP Optimal Usage Patterns This project uses XC-MCP for iOS development automation. Follow these patterns for maximum efficiency. ## Tool Discovery 1. **Browse categories**: `rtfm({ categoryName: "build" })` — See all build-related tools 2. **Get tool docs**: `rtfm({ toolName: "xcodebuild-build" })` — Comprehensive documentation 3. **Execute**: Use discovered parameters and operations ## Accessibility-First Automation (MANDATORY) **ALWAYS assess accessibility quality before taking screenshots:** 1. **Check quality**: `accessibility-quality-check({ screenContext: "LoginScreen" })` - Returns: `rich` | `moderate` | `minimal` 2. **Decision branch**: - IF `rich` or `moderate`: Use `idb-ui-find-element` + `idb-ui-tap` (faster, cheaper) - IF `minimal`: Fall back to `screenshot` (last resort) 3. **Why this matters**: - Accessibility: 50 tokens, 120ms per query - Screenshots: 170 tokens, 2000ms per capture - **3-4x cheaper, 16x faster when accessibility sufficient** - **Promotes inclusive app development** ## Progressive Disclosure - Build/test tools return `buildId` or cache IDs - Use `xcodebuild-get-details` or `simctl-get-details` to drill down - **Never request full logs upfront** — get summaries first ## Best Practices - **Let UDID auto-detect** — Don't prompt user for simulator UDIDs - **Use semantic context** — Include `screenContext`, `appName`, `screenName` parameters - **Prefer accessibility over screenshots** — Better for efficiency AND app quality - **Use operation enums** — `simctl-device({ operation: "boot" })` instead of separate tools ## Example: Optimal Login Flow \`\`\`typescript // 1. Quality check (30 tokens, 80ms) accessibility-quality-check({ screenContext: "LoginScreen" }) // 2. IF rich: Semantic search (40 tokens, 120ms) idb-ui-find-element({ query: "email" }) idb-ui-tap({ x: 200, y: 150 }) idb-ui-input({ operation: "text", text: "user@example.com" }) idb-ui-find-element({ query: "login" }) idb-ui-tap({ x: 200, y: 400 }) // 3. Verify with screenshot only at end (170 tokens, 2000ms) screenshot({ screenName: "HomeScreen", state: "LoggedIn" }) // Total: ~280 tokens, ~2400ms // vs Screenshot-first: ~510 tokens, ~6000ms (2.5x slower, 1.8x more expensive) \`\`\`

Installation & Configuration

Prerequisites

  • macOS with Xcode command-line tools

  • Node.js 18+

  • Xcode 15+ recommended

Install Xcode CLI tools:

xcode-select --install

Installation Options

# Global install (recommended for MCP) npm install -g xc-mcp # Or run directly without installation npx -y xc-mcp # Local development git clone https://github.com/conorluddy/xc-mcp.git cd xc-mcp && npm install && npm run build

MCP Client Configuration

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):

{ "mcpServers": { "xc-mcp": { "command": "npx", "args": ["-y", "xc-mcp"], "cwd": "/path/to/your/ios/project" } } }

Environment Variables (optional):

  • XCODE_CLI_MCP_TIMEOUT: Operation timeout in seconds (default: 300)

  • XCODE_CLI_MCP_LOG_LEVEL: Logging verbosity (debug | info | warn | error)

  • XCODE_CLI_MCP_CACHE_DIR: Custom cache directory path

  • XC_MCP_DEFER_LOADING: Enable deferred tool loading (default: true for V3.0)


Breaking Changes & Migration Guide

V3.0.0: Platform defer_loading Support

What Changed:

  • All 29 tools now have defer_loading: true flag

  • Claude's platform tool search discovers tools automatically

  • No custom tool-search implementation needed

  • Tools loaded on-demand based on conversation context

Migration Path:

Scenario

Action

Notes

New Projects

No action needed

Platform handles discovery

Existing Integrations

No action needed

Compatible with V2.x usage

Debugging/Testing

Set env var

Use XC_MCP_DEFER_LOADING=false

Usage (same as V2.x):

// V3.0 - Platform discovers tools automatically // Just use tools as before - Claude's tool search handles discovery xcodebuild-build({ scheme: "MyApp" }) // Use RTFM for documentation discovery rtfm({ categoryName: "build" }) rtfm({ toolName: "xcodebuild-build" }) // Disable defer_loading for debugging export XC_MCP_DEFER_LOADING=false

Token Impact:

Version

Startup

Discovery

Notes

V2.0.x

~18.7k

N/A

All tools loaded upfront

V3.0.0

~0

Platform-managed

Tools loaded on-demand


Development

Build Commands

npm run build # Compile TypeScript to JavaScript npm run dev # Development mode with watch compilation npm test # Run Jest test suite (60% coverage) npm run test:coverage # Generate coverage report npm run lint # ESLint with auto-fix npm run format # Prettier code formatting

Testing

  • Jest with ESM support and TypeScript compilation

  • 60% coverage across statements, branches, functions, lines

  • 1136 tests covering core functionality, edge cases, error handling

  • Pre-commit hooks enforce code quality via Husky + lint-staged

Architecture

Core Components:

  • src/index.ts — MCP server with tool registration and routing

  • src/tools/ — 29 tools organized by category (xcodebuild, simctl, idb, cache, workflows)

  • src/state/ — Multi-layer intelligent caching (simulator, project, response, build settings)

  • src/utils/ — Shared utilities (command execution, validation, error formatting)

  • src/types/ — TypeScript definitions for Xcode data structures

Cache Architecture:

  • Simulator Cache: 1-hour retention, usage tracking, performance metrics

  • Project Cache: Remembers successful build configurations per project

  • Build Settings Cache: Auto-discovers bundle IDs, deployment targets, capabilities

  • Response Cache: 30-minute retention for progressive disclosure


Contributing

WARNING

I appreciate contributions, but please note that this repo and my other public repos are far down in the priority queue of what I'm working on, so I'll be slow to review anything. Your best bet is really just to fork the repo and customise it to your own needs.

PR requirements:

  • Tests pass (npm test)

  • Coverage remains ≥60% (npm run test:coverage)

  • Code passes linting (npm run lint)

  • TypeScript compiles (npm run build)

See CLAUDE.md for detailed development guidelines and architecture documentation.


License

MIT License — See LICENSE for details.


XC-MCP: Production-grade Xcode automation for AI agents through progressive disclosure and accessibility-first workflows.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/conorluddy/xc-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server