# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview XC-MCP is a Model Context Protocol (MCP) server that provides intelligent access to Xcode command-line tools with advanced caching and progressive disclosure features. It wraps `xcodebuild`, `simctl`, and `idb` commands to solve token overflow issues while maintaining full functionality. ### Architecture (V4.0.0) **70 discrete tools, MCP-spec-modernized, with deferred loading (~1k tokens at startup).** **Evolution:** | Version | Tools | Architecture | |---------|-------|--------------| | Pre-RTFM (v1.2.1) | 51 | Individual tools (~7,850 tokens) | | V1.3.2 (RTFM) | 51 | Individual + RTFM (~3,000 tokens) | | V2.0.0 | 28 | Operation-enum routers + accessibility-first | | V3.0.0 | 30 | Deferred loading + workflows (~1k startup) | | **V4.0.0 (Current)** | **70** | **Discrete tools + MCP spec (annotations / outputSchema / resources) + skill feature parity** | V4.0 modernizes the MCP layer and reaches feature parity with the `ios-simulator-skill`: - **SDK**: `@modelcontextprotocol/sdk@^1.29`, protocol `2025-06-18`. Zod v4. - **Routers dissolved → discrete tools**: the v2 operation-enum routers are gone. Annotations and `outputSchema` are per-tool, so each operation is now its own tool (deferred loading already covers the token cost). See the Migration Guide below. - **Tool annotations**: every tool declares `title` + `readOnlyHint`/`destructiveHint`/`idempotentHint`/`openWorldHint` so clients can gate destructive ops (delete/erase/uninstall/clear). - **Structured output**: high-value tools (xcodebuild-build/-test, accessibility-audit, localization-audit, xcode-model-inspect, visual-diff) declare `outputSchema` and return validated `structuredContent`. - **Resources**: large cached output is exposed via the `resources` capability at `xcmcp://response/{cacheId}`; build/test/list/ui-describe emit `resource_link` blocks (cache IDs retained for back-compat). - **listChanged** capability declared for deferred/dynamic tool loading. - **Deferred loading** retained (`XC_MCP_DEFER_LOADING`); `rtfm` provides progressive docs; old router names still fuzzy-match in `rtfm`. **Tool Categories (V4.0):** - `build`: xcodebuild-version/-list/-build/-clean/-test/-get-details/-showsdks/-inspect-scheme/-validate-capabilities - `simulator`: simctl-list/-get-details/-health-check/-suggest + lifecycle: simctl-boot/-shutdown/-create/-delete/-erase/-clone/-rename - `app`: simctl-install/-uninstall/-launch/-terminate/-get-app-container/-container/-openurl - `idb`: idb-ui-describe/-find-element/-tap/-input/-gesture, accessibility-quality-check, accessibility-audit, idb-targets, idb-list-apps, idb-install/-uninstall/-launch/-terminate - `io`: simctl-io, screenshot - `devicestate`: simctl-appearance, simctl-location - `analysis`: localization-audit, xcode-model-inspect, visual-diff - `diagnostics`: hang-start/-stop/-get-details/-list (HangBuster) - `cache`: cache-get-stats/-get-config/-set-config/-clear - `workflow`: workflow-tap-element/-fresh-install/-build-and-run, test-record-step, test-record-report - `system`: rtfm, persistence-enable/-disable/-status, simctl-push/-addmedia/-pbcopy/-privacy/-status-bar/-stream-logs ### V4.0 Migration Guide (breaking) The v2/v3 operation-enum routers were removed. Call the discrete tool directly: ``` OLD (router) NEW (discrete tool) ───────────────────────────────────────────────────────────────── simctl-device({operation:"boot", ...}) → simctl-boot({...}) simctl-device({operation:"shutdown", ...}) → simctl-shutdown({...}) simctl-device({operation:"create", ...}) → simctl-create({...}) simctl-device({operation:"delete", ...}) → simctl-delete({...}) simctl-device({operation:"erase", ...}) → simctl-erase({...}) simctl-device({operation:"clone", ...}) → simctl-clone({...}) simctl-device({operation:"rename", ...}) → simctl-rename({...}) simctl-app({operation:"install", ...}) → simctl-install({...}) simctl-app({operation:"uninstall", ...}) → simctl-uninstall({...}) simctl-app({operation:"launch", ...}) → simctl-launch({...}) simctl-app({operation:"terminate", ...}) → simctl-terminate({...}) idb-app({operation:"install", ...}) → idb-install({...}) idb-app({operation:"uninstall", ...}) → idb-uninstall({...}) idb-app({operation:"launch", ...}) → idb-launch({...}) idb-app({operation:"terminate", ...}) → idb-terminate({...}) cache({operation:"get-stats"}) → cache-get-stats({...}) cache({operation:"get-config"}) → cache-get-config({...}) cache({operation:"set-config", ...}) → cache-set-config({...}) cache({operation:"clear", ...}) → cache-clear({...}) persistence({operation:"enable", ...}) → persistence-enable({...}) persistence({operation:"disable", ...}) → persistence-disable({...}) persistence({operation:"status"}) → persistence-status({...}) ``` Operation-specific parameters are unchanged; just drop the `operation` field and use the matching tool name. `rtfm({ toolName: "simctl-device" })` still fuzzy-suggests the discrete tools. **New in V4 (feature parity with ios-simulator-skill):** - `simctl-appearance` (theme/Dynamic Type/locale+RTL), `simctl-location` (GPS/city/GPX/waypoints) - `simctl-container` (app sandbox ls/cat/userdefaults/coredata-path) - enhanced `simctl-stream-logs` (severity filter + dedup + statistics) - `accessibility-audit` (WCAG-tier audit), `localization-audit` (.xcstrings), `xcode-model-inspect` (Core Data/SwiftData), `visual-diff` (PNG pixel diff) - HangBuster: `hang-start`/`hang-stop`/`hang-get-details`/`hang-list` (main-thread hang capture + clustering) - `test-record-step`/`test-record-report` (test recording + markdown report) ## Development Commands ### Build and Development - **npm run build** - Compile TypeScript to JavaScript in `dist/` - **npm run dev** - Development mode with TypeScript watch compilation - **npm start** - Start the MCP server from compiled JavaScript - **npm run clean** - Remove `dist/` build artifacts ### Code Quality and Testing - **npm run lint** - Run ESLint on TypeScript source files - **npm run lint:fix** - Auto-fix ESLint issues where possible - **npm run format** - Format code with Prettier - **npm run format:check** - Check code formatting without making changes - **npm test** - Run Jest test suite with ESM support - **npm run test -- --watch** - Run tests in watch mode during development - **npm run test -- --coverage** - Run tests with coverage report (80% threshold required) - **npm run test -- tests/__tests__/utils/** - Run specific test directory - **npm run test -- --testNamePattern="cache"** - Run tests matching pattern ### Git Hooks and Pre-commit - **npm run precommit** - Run lint-staged (triggered automatically by Husky) - **npm run prepare** - Set up Husky git hooks - Lint-staged automatically runs prettier and eslint on staged TypeScript files ### MCP Server Testing - **node dist/index.js** - Run the MCP server directly after building - Use stdio transport for MCP client testing - Validate Xcode installation is available before server operations ## Architecture Overview ### Core Components - **src/index.ts** - Main MCP server with tool registration and request routing - **src/tools/** - Tool implementations organized by command category: - `xcodebuild/` - Build, test, clean, list, version tools with intelligent defaults - `simctl/` - Simulator management with progressive disclosure - `cache/` - Cache management and statistics tools - **src/state/** - Intelligent caching system: - `simulator-cache.ts` - Simulator state with usage tracking and performance metrics - `project-cache.ts` - Project configuration memory and build history - `build-settings-cache.ts` - Xcode build settings with auto-discovery of bundle IDs, deployment targets, and capabilities - **src/utils/** - Shared utilities for command execution and validation - **src/types/** - TypeScript definitions for Xcode data structures ### Key Architectural Features - **Progressive Disclosure**: Returns concise summaries by default, full details on demand via cache IDs - **Intelligent Caching**: 4-layer cache system (simulator, project, build settings, response) with smart invalidation - **Performance Tracking**: Boot times, build metrics, and usage patterns for optimization - **Smart Defaults**: Learns from successful builds and suggests optimal configurations ### Cache System Design - **SimulatorCache**: 1-hour default retention, tracks device usage and boot performance - **ProjectCache**: Remembers successful build configurations per project - **BuildSettingsCache**: 1-hour default retention, auto-discovers bundle IDs, deployment targets, device families, and app capabilities from project build settings - **ResponseCache**: 30-minute retention for progressive disclosure of large outputs - All caches support configurable timeouts and selective clearing ### Tool Response Pattern Tools return structured responses with: - **Success indicators** and error handling - **Cache IDs** for progressive disclosure when outputs exceed token limits - **Smart recommendations** based on usage history - **Performance metrics** for optimization insights ### Critical Tool Categories and Usage Patterns - **xcodebuild-build**: Returns `buildId` for progressive access to full logs via `xcodebuild-get-details` - **xcodebuild-test**: Returns `testId` for progressive access to full test logs via `xcodebuild-get-details` - **simctl-list**: Returns `cacheId` for progressive access to full device data via `simctl-get-details` - **simctl-device**: Consolidated router with 7 operations (boot, shutdown, create, delete, erase, clone, rename) - **simctl-app**: Consolidated router with 4 operations (install, uninstall, launch, terminate) - **cache**: Consolidated router with 4 operations (get-stats, get-config, set-config, clear) - **Progressive Disclosure**: Large outputs (10k+ tokens) automatically cached to prevent MCP token overflow ### Accessibility-First Workflow (V2.0) **Core Philosophy**: XC-MCP promotes accessibility-first automation to encourage inclusive app development while enabling faster, cheaper AI interaction. **Workflow Pattern:** 1. **Assess Quality**: `accessibility-quality-check({ screenContext: "LoginScreen" })` - Returns: `rich` (>3 tappable) | `moderate` (2-3) | `minimal` (≤1) - Cost: ~30 tokens, ~80ms 2. **Decision Branch**: - IF `rich` or `moderate`: Use `idb-ui-find-element` + `idb-ui-tap` (semantic approach) - IF `minimal`: Fall back to `screenshot` (visual approach last resort) 3. **Semantic Element Search**: `idb-ui-find-element({ query: "login" })` - Returns: Tap-ready coordinates (centerX, centerY) with frame boundaries - Cost: ~40 tokens, ~120ms - 3-4x faster and cheaper than screenshot analysis **Performance Comparison:** | Approach | Tokens | Latency | When to Use | |----------|--------|---------|-------------| | Accessibility Tree | ~50 | ~120ms | Rich UIs (>3 tappable elements) | | Screenshot Analysis | ~170 | ~2000ms | Minimal UIs (≤1 tappable element) | | **Efficiency Gain** | **3.4x cheaper** | **16x faster** | When accessibility sufficient | **Why This Matters:** - Encourages developers to build accessible UIs benefiting all users - Enables precise semantic targeting vs visual pattern matching - Reduces token cost and execution time significantly - Promotes inclusive app development practices ### V2.0 Migration Notes **Major Changes from V1.3.2:** - **Tool consolidation**: 51 → 28 tools (21 tools → 6 routers with operation enums) - **Token reduction**: 3,000 → 1,980 tokens (40% additional savings beyond RTFM) - **Accessibility-first**: 3 new tools for semantic UI automation workflow - **Operation enums**: `simctl-device({ operation: "boot" })` instead of `simctl-boot` **Tool Consolidation Mapping:** ``` Old (V1.3.2) → New (V2.0.0) ───────────────────────────────────────────────────────── simctl-boot → simctl-device({ operation: "boot" }) simctl-shutdown → simctl-device({ operation: "shutdown" }) simctl-create → simctl-device({ operation: "create" }) simctl-delete → simctl-device({ operation: "delete" }) simctl-erase → simctl-device({ operation: "erase" }) simctl-clone → simctl-device({ operation: "clone" }) simctl-rename → simctl-device({ operation: "rename" }) simctl-install → simctl-app({ operation: "install" }) simctl-uninstall → simctl-app({ operation: "uninstall" }) simctl-launch → simctl-app({ operation: "launch" }) simctl-terminate → simctl-app({ operation: "terminate" }) idb-install → idb-app({ operation: "install" }) idb-uninstall → idb-app({ operation: "uninstall" }) idb-launch → idb-app({ operation: "launch" }) idb-terminate → idb-app({ operation: "terminate" }) cache-get-stats → cache({ operation: "get-stats" }) cache-get-config → cache({ operation: "get-config" }) cache-set-config → cache({ operation: "set-config" }) cache-clear → cache({ operation: "clear" }) persistence-enable → persistence({ operation: "enable" }) persistence-disable → persistence({ operation: "disable" }) persistence-status → persistence({ operation: "status" }) ``` **New Tools in V2.0:** - `idb-ui-find-element`: Semantic element search by label/identifier - `accessibility-quality-check`: Rapid UI richness assessment - Enhanced `idb-ui-describe`: Optimized accessibility tree queries with progressive disclosure **Removed Tools (Niche Use Cases):** - `xcodebuild-showsdks`: Use `xcodebuild-version` instead - `simctl-suggest`: Use `simctl-list` quick-access recommendations - `simctl-addmedia`, `simctl-privacy`, `simctl-pbcopy`, `simctl-status-bar`: Commented out to reduce schema bloat - `list-cached-responses`: Integrated into main cache tools **For Claude Code (V2.0):** - Use `rtfm()` to discover tools progressively - Prefer `accessibility-quality-check` before screenshots - Use `idb-ui-find-element` for semantic element search - Progressive disclosure via cache IDs (buildId, testId, cacheId, uiTreeId) ### V3.0 Architecture Changes **Major Changes from V2.0:** - **Deferred loading**: Only `tool-search` and `rtfm` visible at startup (~1k tokens vs ~18.7k) - **Tool count**: 28 → 30 tools (added 2 workflow tools) - **Dynamic discovery**: Agents discover tools on-demand via `tool-search` - **Auto-enabling**: Discovered tools automatically added to agent context - **Startup optimization**: 94% reduction in initial context overhead - **Full feature parity**: All V2.0 features preserved with dynamic loading **New Tools in V3.0:** - `tool-search`: Dynamic tool discovery by name, description, category, or capability - `workflow-tap-element`: High-level semantic tap workflow combining accessibility assessment and element interaction - `workflow-fresh-install`: Clean slate installation workflow for testing **Tool Search Usage:** ```javascript // Discover build tools tool-search({ query: "build", category: "build" }) // Find simulator tools tool-search({ query: "boot" }) // List all tools in a category tool-search({ category: "idb" }) ``` **Workflow Tools:** - `workflow-tap-element`: Combines `accessibility-quality-check` + `idb-ui-find-element` + `idb-ui-tap` into single high-level operation - `workflow-fresh-install`: Combines device cleanup, fresh install, and app launch into single operation **For Claude Code (V3.0):** - Start with `tool-search` to discover relevant tools - Use `rtfm()` for detailed documentation once tools are discovered - `workflow-tap-element` for accessibility-first UI interaction - `workflow-fresh-install` for test environment setup - Progressive disclosure via cache IDs (buildId, testId, cacheId, uiTreeId) **Environment Variables:** - `XC_MCP_DEFER_LOADING=false` - Disables deferred loading and loads all tools like V2.x (default: true) ## Development Guidelines ### Code Style and Quality Standards - **ESLint Configuration**: TypeScript-specific rules with Prettier integration - **Formatting**: 100-character line width, 2-space indentation, single quotes - **Language Target**: ES2020+ with Node.js ESM modules (`"type": "module"`) - **Coverage Requirements**: 60% minimum across branches, functions, lines, statements (current: 60.28%) - **Pre-commit Validation**: Husky + lint-staged ensures code quality before commits - **Unused Variables**: Prefix with underscore (`_unused`) to satisfy linting ### Error Handling - All tools validate Xcode installation before execution - Proper async/await patterns with comprehensive error catching - MCP-compliant error responses with appropriate error codes ### Cache Management - Cache validity checks based on file modification times - Configurable cache timeouts via tool parameters - Graceful degradation when caches are invalid or missing ### Progressive Disclosure Implementation - Large command outputs (>token limits) automatically cached with unique IDs - Summary responses provide key information upfront - Detail retrieval tools allow drilling down into cached full outputs - Smart filtering and pagination for large datasets ## Testing and Quality Assurance ### Test Architecture - **Jest with ESM Support**: Uses `ts-jest` preset with ES module transformation - **Test Structure**: Tests in `tests/__tests__/` mirror `src/` structure - **Coverage Thresholds**: 80% minimum across all metrics (enforced in CI) - **Mock Integration**: Custom MCP SDK mocks for testing tool responses - **Test Categories**: State management, utility functions, command execution, and validation ### Running Tests - **All Tests**: `npm test` (includes TypeScript compilation validation) - **Specific Tests**: `npm test tests/__tests__/state/` (test specific modules) - **Coverage Report**: `npm test -- --coverage` (generates HTML + LCOV reports) - **Watch Mode**: `npm test -- --watch` (re-run tests on file changes) - **Pattern Matching**: `npm test -- --testNamePattern="cache"` (test specific functionality) ### Pre-commit Requirements (Automated via Husky) - **TypeScript Compilation**: Must compile without errors - **ESLint Validation**: No errors (warnings acceptable, max 50 on staged files) - **Prettier Formatting**: Automatically applied to staged files - **Test Suite**: All tests must pass before commits - **Git Hooks**: Husky enforces pre-commit validation automatically ### Environment Dependencies - **macOS Required**: Xcode command-line tools must be installed - **Xcode Validation**: Tools validate installation before execution - **Compatibility**: Xcode 15+ and iOS simulators - **Node.js**: Version 18+ required for ESM support ## MCP Integration ### Server Configuration - Uses `@modelcontextprotocol/sdk` for MCP protocol compliance - Stdio transport for Claude Desktop integration - Tool schema definitions with comprehensive parameter validation ### Client Setup Example ```json { "mcpServers": { "xc-mcp": { "command": "node", "args": ["/path/to/xc-mcp/dist/index.js"] } } } ``` ### MCP Tool Implementation Architecture - **Main Server**: `src/index.ts` - Tool registration, request routing, and MCP protocol handling - **Tool Modules**: Organized by command category in `src/tools/` with consistent return patterns - **Shared State**: Global caches in `src/state/` for cross-tool intelligence - **Validation Layer**: `src/utils/validation.ts` validates Xcode installation before tool execution - **Command Execution**: `src/utils/command.ts` handles secure subprocess execution with proper error handling ### Tool Categories - **Project Discovery**: `xcodebuild-list`, `xcodebuild-showsdks`, `xcodebuild-version` - **Build Operations**: `xcodebuild-build`, `xcodebuild-clean`, `xcodebuild-get-details` - **Test Operations**: `xcodebuild-test` (with support for test plans, filtering, and test-without-building) - **Simulator Discovery**: `simctl-list`, `simctl-get-details`, `simctl-suggest` - **Simulator Lifecycle**: `simctl-create`, `simctl-delete`, `simctl-erase`, `simctl-clone`, `simctl-rename`, `simctl-health-check` - **Simulator Control**: `simctl-boot`, `simctl-shutdown` - **App Management**: `simctl-install`, `simctl-uninstall`, `simctl-get-app-container` - **App Control**: `simctl-launch`, `simctl-terminate`, `simctl-openurl` - **I/O & Media**: `simctl-io` (screenshots/videos), `simctl-addmedia` (photo library) - **Advanced Testing**: `simctl-privacy` (permissions), `simctl-push` (notifications), `simctl-pbcopy` (clipboard), `simctl-status-bar` (status bar override) - **Cache Management**: `cache-get-stats`, `cache-set-config`, `cache-get-config`, `cache-clear`, `list-cached-responses` - **Documentation**: `rtfm` (Read The Manual - progressive disclosure documentation for all 51 tools) ## LLM Optimization Patterns XC-MCP implements context engineering patterns specifically optimized for LLM/AI agent usage. These patterns enable agents to reason effectively about simulator state and testing workflows. ### Implemented Patterns #### 1. Semantic Screenshot Naming (simctl-io) Screenshots can be named semantically to help agents understand screen context: - **Parameters**: `appName`, `screenName`, `state` - **Generated filename**: `{appName}_{screenName}_{state}_{date}.png` - **Example**: `MyApp_LoginScreen_Empty_2025-01-23.png` - **Agent benefit**: Agents can reason about which screen was captured and track state progression #### 2. Structured Test Context (simctl-push) Push notifications include structured test tracking: - **Parameters**: `testName`, `expectedBehavior` - **Response includes**: `deliveryInfo` (sent/sentAt) and `testContext` (testName, expectedBehavior, actualBehavior, passed) - **Agent benefit**: Agents can verify push delivery and validate app behavior matches expectations #### 3. Permission Audit Trails (simctl-privacy) Permission changes are tracked with audit context: - **Parameters**: `scenario`, `step` - **Response includes**: `auditEntry` with timestamp, action, service, success, and test context - **Agent benefit**: Agents can track permission state changes across test scenarios and verify permissions at each step ### Design Principles All tools follow these LLM optimization principles: 1. **Semantic Metadata**: Include descriptive parameters that help agents reason about operations (e.g., appName, screenName, state) 2. **Structured Context**: Responses include context objects (semanticMetadata, deliveryInfo, auditEntry, testContext) for agent reasoning 3. **Progressive Disclosure**: Large outputs use cache IDs; summaries provide upfront value 4. **Verification Guidance**: Responses suggest next steps for agents to verify outcomes (e.g., "Take screenshot to confirm visual delivery") 5. **Consistent Naming**: Tool parameters and response fields follow consistent patterns for agent predictability ### Future Optimization Areas See `docs/LLM_OPTIMIZATION.md` for comprehensive patterns including: - Session logging with artifact indexing for workflow reconstruction - Video recording with scene markers and metadata - Test result summaries with structured comparison - Media library with semantic indexing - Status bar before/after snapshots - Operation chaining with explicit dependencies