Skip to main content
Glama
conorluddy

XC-MCP: XCode CLI wrapper

by conorluddy

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
XCODE_CLI_MCP_TIMEOUTNoOperation timeout in seconds300
XCODE_CLI_MCP_CACHE_DIRNoCustom cache directory path
XCODE_CLI_MCP_LOG_LEVELNoLogging verbosity level

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}
prompts
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
xcodebuild-versionA

xcodebuild-version

Get Xcode and SDK version information with structured output

What it does

Retrieves comprehensive version information about your Xcode installation and available SDKs. Returns structured JSON data that's easy to parse and validate, eliminating the need to parse raw command-line output. Validates Xcode installation before execution to provide clear error messages if Xcode is not properly configured.

Why you'd use it

  • Validate environment before running builds or tests (CI/CD validation)

  • Check SDK availability for specific platform versions

  • Ensure consistent Xcode versions across team or build environments

  • Get structured version data for automated tooling and scripts

Parameters

Optional

  • sdk (string): Query specific SDK version (e.g., "iphoneos", "iphonesimulator")

  • outputFormat (string, default: 'json'): "json" or "text" output format

Returns

Structured JSON response containing Xcode version, build number, and SDK information. Falls back gracefully to text format for older Xcode versions that don't support JSON output.

Examples

Get Xcode version as JSON

const result = await xcodebuildVersionTool({ outputFormat: "json" });

Query specific SDK

const sdkInfo = await xcodebuildVersionTool({ sdk: "iphoneos" });
  • xcodebuild-showsdks: Show all available SDKs

  • xcodebuild-list: List project information

xcodebuild-listA

xcodebuild-list

List project targets, schemes, and configurations with intelligent caching

What it does

Discovers and returns all available build targets, schemes, and configurations for an Xcode project or workspace. Uses 1-hour intelligent caching to remember results and avoid expensive re-runs of project discovery. Validates both Xcode installation and project path before execution to provide clear error messages if something is misconfigured.

Why you'd use it

  • Discover available schemes before building or testing (essential for automation)

  • Validate project structure and configuration

  • Get structured project metadata for CI/CD pipelines

  • Avoid expensive repeated queries with 1-hour caching

Parameters

Required

  • projectPath (string): Path to .xcodeproj or .xcworkspace file

Optional

  • outputFormat (string, default: 'json'): "json" or "text" output format

Returns

Structured JSON containing all targets, schemes, configurations, and project information. Consistent format across .xcodeproj and .xcworkspace project types. Results are cached for 1 hour to speed up subsequent queries.

Examples

List schemes for a project

const info = await xcodebuildListTool({
  projectPath: "/path/to/MyApp.xcodeproj"
});

List with text output

const textInfo = await xcodebuildListTool({
  projectPath: "/path/to/MyApp.xcworkspace",
  outputFormat: "text"
});
  • xcodebuild-build: Build discovered schemes

  • xcodebuild-test: Test discovered schemes

xcodebuild-buildA

xcodebuild-build

Build Xcode projects with intelligent defaults and performance tracking

What it does

Builds Xcode projects and workspaces with advanced learning capabilities that remember successful configurations and suggest optimal simulators per project. Uses progressive disclosure to provide concise summaries by default, with full build logs available on demand. Tracks build performance metrics (duration, errors, warnings) and learns from successful builds to improve future build suggestions.

Why you'd use it

  • Automatic smart defaults: remembers which simulator and config worked last time

  • Progressive disclosure: concise summaries prevent token overflow, full logs on demand

  • Performance tracking: measures build times and provides optimization insights

  • Structured errors: clear error messages instead of raw CLI stderr

Parameters

Required

  • projectPath (string): Path to .xcodeproj or .xcworkspace file

  • scheme (string): Build scheme name (use xcodebuild-list to discover)

Optional

  • configuration (string, default: 'Debug'): Build configuration (Debug/Release, defaults to cached or "Debug")

  • destination (string): Build destination (e.g., "platform=iOS Simulator,id=")

  • sdk (string): SDK to build against (e.g., "iphonesimulator", "iphoneos")

  • derivedDataPath (string): Custom derived data path for build artifacts

Returns

Structured JSON response with buildId (for progressive disclosure), success status, build summary (errors, warnings, duration), and intelligence metadata showing which smart defaults were applied. Use xcodebuild-get-details with buildId to retrieve full logs.

Examples

Minimal build with smart defaults

const result = await xcodebuildBuildTool({
  projectPath: "/path/to/MyApp.xcodeproj",
  scheme: "MyApp"
});

Explicit configuration

const release = await xcodebuildBuildTool({
  projectPath: "/path/to/MyApp.xcworkspace",
  scheme: "MyApp",
  configuration: "Release",
  destination: "platform=iOS Simulator,id=ABC-123"
});
  • xcodebuild-test: Run tests after building

  • xcodebuild-clean: Clean build artifacts

  • xcodebuild-get-details: Get full build logs (use with buildId)

xcodebuild-cleanA

xcodebuild-clean

Clean build artifacts with validation and structured output

What it does

Removes build artifacts and intermediate files for an Xcode project or workspace. Pre-validates that the project exists and Xcode is properly installed before executing, providing clear error messages if something is misconfigured. Returns structured JSON responses with execution status, duration, and any errors encountered during the clean operation.

Why you'd use it

  • Resolve build issues by removing stale or corrupted build artifacts

  • Free up disk space occupied by intermediate build files

  • Ensure clean builds from scratch without cached compilation results

  • Get structured feedback with execution time and success status

Parameters

Required

  • projectPath (string): Path to .xcodeproj or .xcworkspace file

  • scheme (string): Build scheme name to clean

Optional

  • configuration (string): Build configuration to clean (e.g., "Debug", "Release")

Returns

Structured JSON response containing success status, command executed, execution duration, output messages, and exit code. Includes both stdout and stderr for comprehensive debugging. Operation typically completes in under 3 minutes.

Examples

Clean default configuration

const result = await xcodebuildCleanTool({
  projectPath: "/path/to/MyApp.xcodeproj",
  scheme: "MyApp"
});

Clean specific configuration

const cleanRelease = await xcodebuildCleanTool({
  projectPath: "/path/to/MyApp.xcworkspace",
  scheme: "MyApp",
  configuration: "Release"
});
  • xcodebuild-build: Build after cleaning

  • xcodebuild-list: Discover available schemes

xcodebuild-testA

xcodebuild-test

Run Xcode tests with intelligent defaults and progressive disclosure

What it does

Executes unit and UI tests for Xcode projects with advanced learning that remembers successful test configurations and suggests optimal simulators per project. Provides detailed test metrics (passed/failed/skipped) with progressive disclosure to prevent token overflow. Supports test filtering (-only-testing, -skip-testing), test plans, and test-without-building mode for faster iteration. Learns from successful test runs to improve future suggestions.

Why you'd use it

  • Automatic smart defaults: remembers which simulator and config worked for tests

  • Detailed test metrics: structured pass/fail/skip counts instead of raw output

  • Progressive disclosure: concise summaries with full logs available via testId

  • Test filtering: run specific tests or skip problematic ones with -only-testing/-skip-testing

Parameters

Required

  • projectPath (string): Path to .xcodeproj or .xcworkspace file

  • scheme (string): Test scheme name (use xcodebuild-list to discover)

Optional

  • configuration (string, default: 'Debug'): Build configuration (Debug/Release, defaults to cached or "Debug")

  • destination (string): Test destination (e.g., "platform=iOS Simulator,id=")

  • sdk (string): SDK to test against (e.g., "iphonesimulator")

  • derivedDataPath (string): Custom derived data path

  • testPlan (string): Test plan name to execute

  • onlyTesting (string[]): Array of test identifiers to run exclusively

  • skipTesting (string[]): Array of test identifiers to skip

  • testWithoutBuilding (boolean): Run tests without building (requires prior build)

Returns

Structured JSON with testId (for progressive disclosure), success status, test summary (total/passed/failed/skipped counts), failure details (first 3 failures), and cache metadata showing which smart defaults were applied. Use xcodebuild-get-details with testId for full logs.

Examples

Run all tests with smart defaults

const result = await xcodebuildTestTool({
  projectPath: "/path/to/MyApp.xcodeproj",
  scheme: "MyApp"
});

Run specific tests only

const filtered = await xcodebuildTestTool({
  projectPath: "/path/to/MyApp.xcworkspace",
  scheme: "MyApp",
  onlyTesting: ["MyAppTests/testLogin", "MyAppTests/testLogout"]
});

Fast iteration with test-without-building

const quick = await xcodebuildTestTool({
  projectPath: "/path/to/MyApp.xcodeproj",
  scheme: "MyApp",
  testWithoutBuilding: true
});

Complete JSON Examples

Run All Tests

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp"}

Run Specific Test Plan

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp", "testPlan": "IntegrationTests"}

Run Only Specific Tests

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp", "onlyTesting": ["MyAppTests/LoginTests", "MyAppTests/AuthTests/testLogin"]}

Skip Specific Tests

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp", "skipTesting": ["MyAppTests/SlowTests", "MyAppUITests"]}

Test Without Building (Using Previous Build)

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp", "testWithoutBuilding": true}

Test with Specific Destination

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp", "destination": "platform=iOS Simulator,name=iPhone 16 Pro,OS=18.0"}

Release Configuration Testing

{"projectPath": "/path/to/MyApp.xcodeproj", "scheme": "MyApp", "configuration": "Release"}
  • xcodebuild-build: Build before testing

  • xcodebuild-get-details: Get full test logs (use with testId)

  • simctl-list: See available test simulators

xcodebuild-get-detailsA

xcodebuild-get-details

🔍 Retrieve detailed build or test output from cached results - Progressive disclosure for logs.

Provides on-demand access to full build and test logs that were cached during xcodebuild-build or xcodebuild-test execution. Implements progressive disclosure pattern: initial build/test responses return concise summaries to prevent token overflow, while this tool allows drilling down into full logs, filtered errors, warnings, or metadata when needed for debugging.

Advantages

• Access full build logs without cluttering initial responses • Filter to just errors or warnings for faster debugging • Retrieve exact command executed and exit code • Inspect build metadata and cache information

Parameters

Required

  • buildId (string): Cache ID from xcodebuild-build or xcodebuild-test response

  • detailType (string): Type of details to retrieve

    • "full-log": Complete stdout and stderr output

    • "errors-only": Lines containing errors or build failures

    • "warnings-only": Lines containing warnings

    • "summary": Build metadata and configuration used

    • "command": Exact xcodebuild command executed

    • "metadata": Cache info and output sizes

Optional

  • maxLines (number): Maximum lines to return (default: 100)

Returns

  • Tool execution results with requested build or test details

  • Full logs or filtered errors/warnings with line counts

  • Build metadata and execution information

  • xcodebuild-build: Build iOS projects (returns buildId)

  • xcodebuild-test: Run tests (returns testId)

  • simctl-get-details: Get simulator list details

Notes

  • Tool is auto-registered with MCP server

  • Requires valid cache ID from recent build/test

  • Cache IDs expire after 30 minutes

  • Use for debugging build failures and test issues

simctl-listA

simctl-list

List iOS simulators with intelligent progressive disclosure and caching.

Overview

Retrieves comprehensive simulator information including devices, runtimes, and device types. Returns concise summaries by default with cache IDs for progressive access to full details, preventing token overflow while maintaining complete functionality. Shows booted devices and recently used simulators first for faster workflows. Full output mode limits results to the most recently used devices for efficient browsing.

Parameters

Required

None - all parameters are optional

Optional

  • deviceType (string): Filter by device type (e.g., "iPhone", "iPad")

  • runtime (string): Filter by iOS runtime version (e.g., "17", "iOS 17.0")

  • availability (string, default: "available"): Filter by availability ("available", "unavailable", "all")

  • outputFormat (string, default: "json"): Output format ("json" or "text")

  • concise (boolean, default: true): Return concise summary with cache ID

  • max (number, default: 5): Maximum devices to return in full mode, sorted by lastUsed date (most recent first)

Returns

  • Concise mode: Summary with cacheId for detailed retrieval via simctl-get-details

  • Full mode: Limited device list (default 5 most recently used) with metadata showing total available and limit applied

Device Limiting in Full Mode

When concise: false, the response includes:

  • devices: Top N devices across all runtimes, sorted by lastUsed date (most recent first)

  • metadata: Shows total devices in cache, devices returned, and limit applied

  • Devices without lastUsed date are placed at the end

  • Total limit applies across all runtimes, not per-runtime

Examples

Get concise summary (default - prevents token overflow)

await simctlListTool({});

Get full list for iPhone devices (limited to 5 most recent)

await simctlListTool({
  deviceType: "iPhone",
  concise: false
});

Get full list with custom device limit

await simctlListTool({
  concise: false,
  max: 10
});

Filter by iOS version

await simctlListTool({ runtime: "17.0" });
  • simctl-get-details: Retrieve full device list using cache ID (bypasses max limit)

  • simctl-device: Boot, shutdown, or manage specific simulators

  • simctl-app: Install and launch apps on simulators

Notes

  • Prevents token overflow (raw output = 10k+ tokens) via concise summaries and device limiting

  • Default max=5 limits output to ~2.5k tokens (90% reduction from full 50-device list)

  • 1-hour intelligent caching eliminates redundant queries

  • Shows booted devices and recently used simulators first in concise mode

  • Use simctl-get-details with cacheId for progressive access to full data (ignores max limit)

  • Device sorting: mostRecent (with lastUsed) → oldest (with lastUsed) → unknown (no lastUsed)

  • Smart filtering by device type, runtime, and availability

  • Essential: Use this instead of 'xcrun simctl list' for better performance

cacheA

cache

Unified cache management - get statistics, get configuration, set configuration, clear cache.

Overview

Single tool for cache management. Routes to specialized handlers while maintaining clean operation semantics.

Operations

get-stats

Get cache statistics and metrics.

Example:

await cacheTool({ operation: 'get-stats' })

Returns: Cache statistics including size, hit rates, and usage metrics.


get-config

Get cache configuration for specific cache type.

Parameters:

  • cacheType (string, optional): Cache type - 'simulator', 'project', 'response', or 'all'

Example:

await cacheTool({
  operation: 'get-config',
  cacheType: 'simulator'
})

Returns: Current configuration including max age settings.


set-config

Set cache configuration.

Parameters:

  • cacheType (string): Cache type - 'simulator', 'project', 'response', or 'all'

  • maxAgeMs (number, optional): Maximum age in milliseconds

  • maxAgeMinutes (number, optional): Maximum age in minutes

  • maxAgeHours (number, optional): Maximum age in hours

Example:

await cacheTool({
  operation: 'set-config',
  cacheType: 'simulator',
  maxAgeHours: 2
})

clear

Clear cache for specific type.

Parameters:

  • cacheType (string, optional): Cache type - 'simulator', 'project', 'response', or 'all'

Example:

await cacheTool({
  operation: 'clear',
  cacheType: 'simulator'
})

Cache Types

  • simulator: Simulator list and state cache

  • project: Project configuration and build settings cache

  • response: Large response output cache for progressive disclosure

  • all: All caches (default when not specified)

  • list-cached-responses: View cached response IDs

  • xcodebuild-get-details: Retrieve cached build output

  • simctl-get-details: Retrieve cached simulator details

persistenceA

persistence

Unified cache persistence management - enable, disable, check status.

Overview

Single tool for persistence configuration. Routes to specialized handlers while maintaining clean operation semantics.

Operations

enable

Enable cache persistence to disk.

Parameters:

  • cacheDir (string, optional): Custom cache directory path

Example:

await persistenceTool({
  operation: 'enable',
  cacheDir: '/path/to/cache'
})

Notes: Persists cache data across sessions. Useful for long-running projects or CI environments.


disable

Disable cache persistence.

Parameters:

  • clearData (boolean, optional): Clear existing persistent data on disable

Example:

await persistenceTool({
  operation: 'disable',
  clearData: true
})

status

Check persistence status.

Parameters:

  • includeStorageInfo (boolean, optional): Include storage usage details

Example:

await persistenceTool({
  operation: 'status',
  includeStorageInfo: true
})

Returns: Persistence status (enabled/disabled), cache directory path, and optional storage information.


When to Use

Enable persistence:

  • Long-running projects that benefit from cross-session cache

  • CI/CD environments where cache survives across builds

  • Development workflows where build history is valuable

Disable persistence:

  • Temporary debugging sessions

  • Testing with clean cache state

  • Clearing sensitive cached information

  • cache: Cache management and configuration

rtfmA

rtfm

📖 Read The Manual - Progressive disclosure documentation system for all XC-MCP tools.

Overview

The rtfm tool provides access to comprehensive documentation for any of the 28 consolidated tools in this MCP server (v2.0+). This implements progressive disclosure: tool descriptions in the main list include full documentation (~18.7k tokens total for optimal agent understanding), while rtfm provides additional context and examples on demand.

Version History:

  • v1.x: 51 individual tools (~3,000-7,850 tokens depending on approach)

  • v2.0+: 28 consolidated tools (~18.7k tokens) - Comprehensive docs for optimal reasoning

Why rtfm?

Problem Solved: Tool documentation was originally stored in .md files within the src/ directory, which wouldn't be available in the published npm package (only dist/ is included in package.json "files" field).

Solution: Documentation is now embedded as TypeScript constants in each tool file, bundled into the compiled JavaScript, and accessible via this rtfm tool. This ensures documentation is always available, whether in development or in the published npm package.

Parameters

  • toolName (optional): Name of specific tool to get documentation for

    • Examples: "xcodebuild-build", "simctl-device", "idb-app", "cache", "persistence"

    • Case-sensitive, must match exact tool registration name

  • categoryName (optional): Browse tools in a specific category

    • Examples: "build", "simulator", "app", "idb", "cache", "system"

    • Omit both parameters to see all categories

Examples

// Get documentation for consolidated simulator device tool
rtfm({ toolName: "simctl-device" })

// Get documentation for consolidated app management tool
rtfm({ toolName: "idb-app" })

// Browse all tools in the cache category
rtfm({ categoryName: "cache" })

// View all categories (no parameters)
rtfm({})

Migration from v1.x to v2.0

Old individual tools are now consolidated into single tools with operation parameters:

  • simctl-boot, simctl-shutdown, simctl-create, simctl-delete, simctl-erase, simctl-clone, simctl-renamesimctl-device (operation enum)

  • simctl-install, simctl-uninstall, simctl-launch, simctl-terminatesimctl-app (operation enum)

  • idb-install, idb-uninstall, idb-launch, idb-terminateidb-app (operation enum)

  • cache-get-stats, cache-get-config, cache-set-config, cache-clearcache (operation enum)

  • persistence-enable, persistence-disable, persistence-statuspersistence (operation enum)

  • idb-targets extended with idb-connect and idb-disconnect operations

For detailed examples and parameter specifications for each operation, use rtfm({ toolName: "simctl-device" }) etc.

Response Format

Success Response

Returns full markdown documentation including:

  • Tool description and purpose

  • Advantages over direct CLI usage

  • Parameter specifications with types and descriptions

  • Usage examples

  • Related tools

  • Common patterns and best practices

Tool Not Found Response

If toolName doesn't match any registered tool:

  • Error message with the attempted tool name

  • Suggestions based on partial matches (up to 5)

  • Complete list of all available tools

Example:

No documentation found for tool: "simctl-boo"

Did you mean one of these?
  - simctl-boot
  - simctl-shutdown

Available tools (28 total):
  - xcodebuild-*
  - simctl-*
  - idb-*
  - cache
  - persistence
  - rtfm

Available Tool Categories (v2.0)

Xcodebuild Tools (7)

  • xcodebuild-version, xcodebuild-list, xcodebuild-showsdks

  • xcodebuild-build, xcodebuild-clean, xcodebuild-test

  • xcodebuild-get-details

Simctl Lifecycle Tools (6)

  • simctl-list, simctl-get-details, simctl-device (consolidated: boot/shutdown/create/delete/erase/clone/rename)

  • simctl-suggest, simctl-health-check

Simctl App Management Tools (3)

  • simctl-app (consolidated: install/uninstall/launch/terminate)

  • simctl-get-app-container, simctl-openurl

Simctl I/O & Testing Tools (7)

  • simctl-io, simctl-addmedia, simctl-privacy, simctl-push

  • simctl-pbcopy, simctl-status-bar, screenshot

IDB Tools (6)

  • idb-targets (extended: list/describe/focus/connect/disconnect)

  • idb-ui-tap, idb-ui-input, idb-ui-gesture, idb-ui-describe, idb-list-apps

  • idb-app (consolidated: install/uninstall/launch/terminate)

Cache Management Tools (2)

  • list-cached-responses

  • cache (consolidated: get-stats/get-config/set-config/clear)

Persistence Tools (1)

  • persistence (consolidated: enable/disable/status)

Documentation Tool (1)

  • rtfm (this tool!)

Implementation Details

Documentation Storage

Each tool file exports a TOOL_NAME_DOCS constant containing its full documentation in markdown format:

// Example from src/tools/simctl/boot.ts
export const SIMCTL_BOOT_DOCS = `
# simctl-boot
...
`;

Central Registry

All documentation constants are imported and mapped in src/tools/docs-registry.ts:

export const TOOL_DOCS: Record<string, string> = {
  'simctl-boot': SIMCTL_BOOT_DOCS,
  'xcodebuild-build': XCODEBUILD_BUILD_DOCS,
  // ... 49 more tools
};

Progressive Disclosure Pattern

  1. Tool list shows concise descriptions (~300-400 tokens)

  2. Each description ends with: "📖 Use rtfm with toolName: '{name}' for full documentation."

  3. Full documentation accessed only when explicitly requested via rtfm

  4. Prevents token overflow while maintaining comprehensive documentation access

Benefits

Self-contained: No external file dependencies ✅ NPM package ready: Documentation bundled in compiled JavaScript ✅ Token efficient: Progressive disclosure keeps default views concise ✅ Always available: Works in development and production ✅ Type-safe: TypeScript constants with proper typing ✅ Searchable: Fuzzy matching with suggestions for typos ✅ Comprehensive: Full documentation including examples and parameters

Common Use Cases

Explore available tools:

// Intentionally use invalid tool name to see full list
rtfm({ toolName: "help" })

Learn specific tool usage:

rtfm({ toolName: "simctl-boot" })

Understand tool parameters:

rtfm({ toolName: "xcodebuild-build" })

Find related tools:

// Search by category prefix
rtfm({ toolName: "simctl" })  // Shows simctl-* suggestions
  • list-cached-responses: View cached progressive disclosure responses

  • cache-get-stats: Monitor cache performance and usage

Notes

  • Tool names are case-sensitive and must match exact registration names

  • Fuzzy matching provides suggestions for close matches

  • Documentation format is consistent markdown across all tools

  • Each tool's documentation is independently maintained in its source file

  • The TOOL_DOCS registry is automatically updated when tools are added/removed

simctl-get-detailsA

simctl-get-details

🔍 Get detailed simulator information from cached list results - Progressive disclosure for devices.

Retrieves on-demand access to full simulator and runtime lists that were cached during simctl-list execution. Implements progressive disclosure pattern: initial simctl-list responses return concise summaries to prevent token overflow, while this tool allows drilling down into full device lists, filtered by device type or runtime when needed.

Advantages

• Access full device lists without cluttering initial responses • Filter to specific device types (iPhone, iPad, etc.) • Filter to specific runtime versions • Get only available (booted) devices or all devices • Paginate results to manage token consumption

Parameters

Required

  • cacheId (string): Cache ID from simctl-list response

Optional

  • detailType (string): Type of details to retrieve

    • "full-list": Complete device and runtime information

    • "devices-only": Just device information

    • "runtimes-only": Just available runtimes

    • "available-only": Only booted devices

  • deviceType (string): Filter by device type (iPhone, iPad, etc.)

  • runtime (string): Filter by iOS runtime version

  • maxDevices (number): Maximum number of devices to return (default: 20)

Returns

  • Tool execution results with detailed simulator information

  • Complete device lists with full state and capabilities

  • Available devices and compatible runtimes

  • simctl-list: List available simulators and runtimes

  • xcodebuild-get-details: Get build or test details

Notes

  • Tool is auto-registered with MCP server

  • Requires valid cache ID from recent simctl-list

  • Cache IDs expire after 1 hour

  • Use for discovering available devices and runtimes

simctl-deviceA

simctl-device

Unified iOS simulator device management - boot, shutdown, create, delete, erase, clone, rename.

Overview

Single tool for all simulator device lifecycle operations. Routes to specialized handlers while maintaining clean operation semantics.

Complete JSON Examples

Boot a Simulator

{"operation": "boot", "deviceId": "ABCD1234-5678-90EF-GHIJ-KLMNOPQRSTUV", "waitForBoot": true, "openGui": true}

Shutdown Running Simulator

{"operation": "shutdown", "deviceId": "booted"}

Create New Simulator

{"operation": "create", "name": "Test iPhone 16", "deviceType": "iPhone 16 Pro", "runtime": "iOS-18-0"}

Delete Simulator

{"operation": "delete", "deviceId": "ABCD1234-5678-90EF-GHIJ-KLMNOPQRSTUV"}

Factory Reset (Erase)

{"operation": "erase", "deviceId": "simulator-udid", "force": true}

Clone Simulator

{"operation": "clone", "deviceId": "source-udid", "newName": "Snapshot Before Tests"}

Rename Simulator

{"operation": "rename", "deviceId": "simulator-udid", "newName": "My Test Device"}

Operations

boot

Boot iOS simulator device with performance tracking.

Parameters:

  • deviceId (string): Device UDID, "booted" for current, or "all"

  • waitForBoot (boolean, default: true): Wait for device to finish booting

  • openGui (boolean, default: true): Open Simulator.app GUI

Example:

await simctlDeviceTool({ operation: 'boot', deviceId: 'ABC-123-DEF' })

shutdown

Shutdown iOS simulator devices.

Parameters:

  • deviceId (string): Device UDID, "booted" for all booted devices, or "all"

Example:

await simctlDeviceTool({ operation: 'shutdown', deviceId: 'ABC-123-DEF' })

create

Create new iOS simulator device.

Parameters:

  • name (string): Display name for new simulator

  • deviceType (string): Device type (e.g., "iPhone 16 Pro")

  • runtime (string, optional): iOS version - defaults to latest

Example:

await simctlDeviceTool({ operation: 'create', name: 'TestDevice', deviceType: 'iPhone 16 Pro' })

delete

Permanently delete iOS simulator device.

Parameters:

  • deviceId (string): Device UDID to delete

Example:

await simctlDeviceTool({ operation: 'delete', deviceId: 'ABC-123-DEF' })

erase

Reset simulator to factory settings.

Parameters:

  • deviceId (string): Device UDID to erase

  • force (boolean, optional): Force erase even if booted

Example:

await simctlDeviceTool({ operation: 'erase', deviceId: 'ABC-123-DEF' })

clone

Clone simulator with complete state preservation.

Parameters:

  • deviceId (string): Source device UDID

  • newName (string): Name for cloned simulator

Example:

await simctlDeviceTool({ operation: 'clone', deviceId: 'ABC-123-DEF', newName: 'Snapshot' })

rename

Rename simulator device.

Parameters:

  • deviceId (string): Device UDID to rename

  • newName (string): New display name

Example:

await simctlDeviceTool({ operation: 'rename', deviceId: 'ABC-123-DEF', newName: 'Production' })

  • simctl-list: Discover simulators and their UDIDs

  • simctl-app: Install and launch apps on devices

  • simctl-io: Take screenshots and record videos

simctl-health-checkA

simctl-health-check

Comprehensive iOS simulator environment health check.

Overview

Performs a complete diagnostic check of your iOS development environment, validating Xcode tools, simulators, runtimes, and disk space. Returns actionable recommendations for any issues found. Checks 6 critical areas in seconds: Xcode Command Line Tools, simctl availability, available simulators, booted simulators, available runtimes, and disk space.

Parameters

None - performs complete environment check automatically.

Returns

Health report with pass/fail status for each check, specific guidance for failures, summary of passed/failed checks, and overall healthy status indicator.

Examples

Run complete health check

await simctlHealthCheckTool();

Check before CI/CD pipeline

// Validate environment before running test suite
const health = await simctlHealthCheckTool();
if (!health.healthy) {
  console.error('Environment issues detected');
}
  • simctl-list: See available simulators after health check passes

  • simctl-create: Create simulators if none found

  • simctl-suggest: Get intelligent simulator recommendations

Notes

  • Checks 6 critical areas: Xcode tools, simctl, simulators, booted devices, runtimes, disk space

  • Provides specific solutions for each failed check

  • Validates entire toolchain in seconds

  • Warns if disk usage over 80% (simulators require significant space)

  • Perfect for troubleshooting when operations fail unexpectedly

  • Use before CI/CD pipeline execution to ensure environment health

simctl-appA

simctl-app

Unified iOS app lifecycle management - install, uninstall, launch, terminate.

Overview

Single tool for app management on simulators. Routes to specialized handlers while maintaining clean operation semantics.

Operations

install

Install iOS app to simulator.

Parameters:

  • udid (string): Simulator UDID (from simctl-list)

  • appPath (string): Path to .app bundle

Example:

await simctlAppTool({
  operation: 'install',
  udid: 'ABC-123-DEF',
  appPath: '/path/to/MyApp.app'
})

uninstall

Uninstall iOS app from simulator.

Parameters:

  • udid (string): Simulator UDID

  • bundleId (string): App bundle ID (e.g., com.example.MyApp)

Example:

await simctlAppTool({
  operation: 'uninstall',
  udid: 'ABC-123-DEF',
  bundleId: 'com.example.MyApp'
})

launch

Launch iOS app on simulator.

Parameters:

  • udid (string): Simulator UDID

  • bundleId (string): App bundle ID

  • arguments (string[], optional): Command-line arguments

  • environment (object, optional): Environment variables

Example:

await simctlAppTool({
  operation: 'launch',
  udid: 'ABC-123-DEF',
  bundleId: 'com.example.MyApp',
  arguments: ['--verbose'],
  environment: { 'DEBUG': '1' }
})

terminate

Terminate running iOS app on simulator.

Parameters:

  • udid (string): Simulator UDID

  • bundleId (string): App bundle ID

Example:

await simctlAppTool({
  operation: 'terminate',
  udid: 'ABC-123-DEF',
  bundleId: 'com.example.MyApp'
})

  • simctl-device: Boot/shutdown simulators

  • simctl-list: Discover simulators and their UDIDs

  • idb-app: IDB-based app management

simctl-get-app-containerA

simctl-get-app-container

Access iOS app file system containers for inspection and debugging.

What it does

Retrieves the file system path to an app's container directories on a simulator, enabling direct access to app bundle, data directories, and shared group containers for debugging and testing.

Why you'd use it

  • Debug data access: Inspect app Documents and Library folders

  • File inspection: View database files, preferences, and cached data

  • Testing validation: Confirm app writes data to correct locations

  • Container types: Access bundle (app binary), data (Documents/Library), and group (shared) containers

Parameters

  • udid (string, required): Simulator UDID (from simctl-list)

  • bundleId (string, required): App bundle ID (e.g., com.example.MyApp)

  • containerType (string, optional): Container type - bundle, data, or group (default: data)

Container Types

  • bundle: App binary and resources (read-only)

  • data: App's Documents and Library directories (read-write)

  • group: Shared containers for app groups (read-write)

Returns

JSON response with:

  • Container path for file system access

  • Container type information

  • Guidance for accessing and inspecting files

  • Simulator state and validation

Examples

Get app data container path

await simctlGetAppContainerTool({
  udid: 'ABC-123-DEF',
  bundleId: 'com.example.MyApp'
})

Get app bundle path

await simctlGetAppContainerTool({
  udid: 'ABC-123-DEF',
  bundleId: 'com.example.MyApp',
  containerType: 'bundle'
})

Common Use Cases

  1. Debugging data persistence: Access app's Documents folder to inspect saved files

  2. Database inspection: View SQLite database files and validate schema

  3. Preferences debugging: Check UserDefaults plist files

  4. Cache validation: Verify cached data is stored correctly

  5. Bundle inspection: Access app binary and embedded resources

Error Handling

  • App not installed: Returns error if app is not installed on simulator

  • Invalid bundle ID: Validates bundle ID format (must contain '.')

  • Simulator not found: Validates simulator exists in cache

  • Container access failure: Reports if container cannot be accessed

Next Steps After Getting Container Path

  1. View files: cd "<container-path>" && ls -la

  2. Open in Finder: open "<container-path>/Documents"

  3. Find files: find "<container-path>" -type f | head -20

  4. Inspect specific file: cat "<container-path>/Documents/data.json"

simctl-openurlA

simctl-openurl

Open URLs in a simulator, including web URLs, deep links, and special URL schemes.

What it does

Opens a URL in the simulator, which can be a web URL (http/https), custom app deep link (myapp://), or special URL scheme (mailto:, tel:, sms:). The system will route the URL to the appropriate app handler.

Parameters

  • udid (string, required): Simulator UDID (from simctl-list)

  • url (string, required): URL to open (e.g., https://example.com or myapp://deeplink?id=123)

Supported URL Schemes

  • HTTP/HTTPS: Web URLs (opens in Safari)

  • Custom schemes: Deep links to your app (myapp://, yourapp://)

  • mailto: Email composition (opens Mail app)

  • tel: Phone dialer (opens Phone app on iPhone)

  • sms: SMS composition (opens Messages app)

  • facetime: FaceTime calls

  • maps: Apple Maps URLs

Returns

JSON response with:

  • URL open status

  • Detected URL scheme

  • Guidance for testing URL handling and deep links

Examples

Open web URL

await simctlOpenUrlTool({
  udid: 'device-123',
  url: 'https://example.com'
})
await simctlOpenUrlTool({
  udid: 'device-123',
  url: 'myapp://open?id=123&action=view'
})
await simctlOpenUrlTool({
  udid: 'device-123',
  url: 'mailto:test@example.com?subject=Hello'
})
await simctlOpenUrlTool({
  udid: 'device-123',
  url: 'tel:+1234567890'
})

Common Use Cases

  1. Deep link testing: Verify app handles custom URL schemes correctly

  2. Universal links: Test https:// URLs that open your app

  3. Navigation testing: Confirm deep links navigate to correct screens

  4. Parameter parsing: Verify URL parameters are parsed correctly

  5. Fallback handling: Test behavior when no handler is registered

Important Notes

  • Simulator must be booted: URLs can only be opened on running simulators

  • Handler registration: Custom schemes require an app that handles them

  • URL encoding: Ensure URL parameters are properly encoded

  • Timing: Consider launching app first if testing immediate URL handling

Error Handling

  • No handler registered: Error if no app handles the URL scheme

  • Simulator not booted: Indicates simulator must be booted first

  • Invalid URL format: Validates URL has proper scheme and format

  • Simulator not found: Validates simulator exists in cache

  1. Install app: simctl-install <udid> /path/to/App.app

  2. Launch app: simctl-launch <udid> <bundleId>

  3. Open deep link: simctl-openurl <udid> myapp://route?param=value

  4. Take screenshot: simctl-io <udid> screenshot to verify navigation

  5. Check logs: Monitor console for URL handling logs

Testing Strategies

  • Parameter variations: Test different query parameters

  • Invalid URLs: Verify error handling for malformed URLs

  • Background handling: Test URLs when app is backgrounded

  • Fresh launch: Test URLs when app is not running

  • State preservation: Verify app state is maintained after URL handling

simctl-ioA

simctl-io

Capture screenshots or record videos from iOS simulators with automatic optimization.

What it does

Captures simulator screen as optimized PNG images or records video with configurable codecs. Screenshots are automatically resized to tile-aligned dimensions for token efficiency and support semantic naming for AI agent reasoning.

Parameters

  • udid (string, optional): Simulator UDID (auto-detects booted device if omitted)

  • operation (string, required): "screenshot" or "video"

  • outputPath (string, optional): Custom file path (auto-generated if omitted)

  • codec (string, optional): Video codec - h264, hevc, or prores (default: h264)

  • size (string, optional): Screenshot size - half, full, quarter, thumb (default: half)

  • appName (string, optional): App name for semantic naming

  • screenName (string, optional): Screen/view name for semantic naming

  • state (string, optional): UI state for semantic naming

Screenshot Size Optimization

Screenshots are automatically optimized for token efficiency:

  • half (default): 256×512 pixels, 1 tile, 170 tokens (50% savings)

  • full: Native resolution, 2 tiles, 340 tokens

  • quarter: 128×256 pixels, 1 tile, 170 tokens

  • thumb: 128×128 pixels, 1 tile, 170 tokens

Semantic Naming (LLM Optimization)

Provide appName, screenName, and state to generate semantic filenames:

  • Format: {appName}_{screenName}_{state}_{date}.png

  • Example: MyApp_LoginScreen_Empty_2025-01-23.png

  • Enables AI agents to reason about screen context and track state progression

Returns

JSON response with:

  • File path and size information

  • Screenshot optimization metadata (dimensions, token count, savings)

  • Coordinate transform for mapping resized coordinates to device

  • Semantic metadata when provided

  • Guidance for viewing and using the capture

Examples

Capture optimized screenshot (default 256×512)

await simctlIoTool({
  udid: 'device-123',
  operation: 'screenshot'
})

Capture full-size screenshot

await simctlIoTool({
  udid: 'device-123',
  operation: 'screenshot',
  size: 'full'
})

Capture with semantic naming

await simctlIoTool({
  udid: 'device-123',
  operation: 'screenshot',
  appName: 'MyApp',
  screenName: 'LoginScreen',
  state: 'Empty'
})

Record video with custom codec

await simctlIoTool({
  udid: 'device-123',
  operation: 'video',
  codec: 'hevc'
})

Common Use Cases

  1. UI testing: Capture screenshots for visual regression testing

  2. Bug reporting: Record videos demonstrating issues

  3. Documentation: Create screenshots for app documentation

  4. State tracking: Use semantic naming to track UI state progression

  5. Token optimization: Use half/quarter sizes for LLM-based analysis

Coordinate Transform

When screenshots are resized (size ≠ 'full'), a coordinate transform is provided:

  • scaleX: Multiply screenshot X coordinates by this to get device coordinates

  • scaleY: Multiply screenshot Y coordinates by this to get device coordinates

  • guidance: Human-readable scaling instructions

This enables accurate element tapping even with optimized screenshots.

Important Notes

  • Auto-detection: If udid is omitted, automatically uses the booted device

  • Temp files: Screenshots saved to /tmp unless custom path specified

  • Video recording: Press Ctrl+C to stop video recording

  • Simulator must be booted: Operations require running simulator

  • File permissions: Ensure output path is writable

Error Handling

  • Simulator not booted: Indicates simulator must be booted first

  • Simulator not found: Validates simulator exists in cache

  • File path errors: Reports if output path is not writable

  • Invalid operation: Validates operation is "screenshot" or "video"

Next Steps After Capture

  1. View screenshot: open "<file-path>"

  2. Copy to clipboard: pbcopy < "<file-path>"

  3. Analyze with LLM: Use optimized size for token-efficient analysis

  4. Use coordinates: Apply transform to map screenshot coords to device

simctl-pushA

simctl-push

Send simulated push notifications to apps on simulators with test context tracking.

What it does

Sends push notifications with custom JSON payloads to apps, simulating remote notifications from APNS. Supports test tracking to verify push delivery and validate app behavior.

Parameters

  • udid (string, required): Simulator UDID (from simctl-list)

  • bundleId (string, required): App bundle ID (e.g., com.example.MyApp)

  • payload (string, required): JSON payload with APS dictionary

  • testName (string, optional): Test name for tracking

  • expectedBehavior (string, optional): Expected app behavior description

Payload Format

Must be valid JSON with an "aps" dictionary:

{
  "aps": {
    "alert": "Notification text",
    "badge": 1,
    "sound": "default"
  },
  "custom": "Additional data"
}

LLM Optimization

The testName and expectedBehavior parameters enable structured test tracking. This allows AI agents to verify push notification delivery and validate that app behavior matches expectations (e.g., navigation, UI updates, data refresh).

Returns

JSON response with:

  • Push delivery status

  • Delivery information (sent timestamp)

  • Test context with expected vs actual behavior

  • Guidance for verifying notification handling

Examples

Simple alert notification

await simctlPushTool({
  udid: 'device-123',
  bundleId: 'com.example.MyApp',
  payload: JSON.stringify({
    aps: { alert: 'Test notification' }
  })
})

Notification with badge and sound

await simctlPushTool({
  udid: 'device-123',
  bundleId: 'com.example.MyApp',
  payload: JSON.stringify({
    aps: {
      alert: 'New message',
      badge: 5,
      sound: 'default'
    }
  })
})

Rich notification with custom data

await simctlPushTool({
  udid: 'device-123',
  bundleId: 'com.example.MyApp',
  payload: JSON.stringify({
    aps: {
      alert: {
        title: 'New Order',
        body: 'Order #1234 has been placed'
      },
      badge: 1
    },
    orderId: '1234',
    action: 'view_order'
  })
})

Push with test context tracking

await simctlPushTool({
  udid: 'device-123',
  bundleId: 'com.example.MyApp',
  payload: JSON.stringify({
    aps: { alert: 'Product available' },
    productId: '567'
  }),
  testName: 'PushNotification_DeepLinkTest',
  expectedBehavior: 'App navigates to ProductDetail view for product 567'
})

Common Use Cases

  1. Notification delivery testing: Verify app receives and displays notifications

  2. Deep link navigation: Test notification taps navigate to correct screens

  3. Badge updates: Verify badge count is updated correctly

  4. Custom data handling: Test app processes custom payload data

  5. Background behavior: Test app behavior when notification arrives in background

Important Notes

  • App must be running: Launch app first or test background notification handling

  • Payload validation: JSON must be valid and include "aps" dictionary

  • Immediate delivery: Notification is delivered immediately (no delay)

  • No user interaction: Notification appears automatically without tapping

  • Visual verification: Use simctl-io screenshot to confirm notification display

Error Handling

  • Invalid JSON: Error if payload is not valid JSON

  • App not running: May fail if app is not running (test background handling)

  • Simulator not booted: Indicates simulator must be booted first

  • Invalid bundle ID: Validates bundle ID format (must contain '.')

Testing Workflow

  1. Launch app: simctl-launch <udid> <bundleId>

  2. Send push: simctl-push <udid> <bundleId> <payload>

  3. Take screenshot: simctl-io <udid> screenshot to verify delivery

  4. Check navigation: Verify app navigated to expected screen

  5. Validate data: Confirm app processed custom payload data

Test Context Tracking

The testContext in the response includes:

  • testName: Identifier for this push notification test

  • expectedBehavior: What should happen when notification is received

  • actualBehavior: What actually happened (delivery success/failure)

  • passed: Whether test passed

This enables agents to track push notification tests and verify expected behavior.

Advanced Testing

  • Multiple notifications: Send sequential pushes to test badge accumulation

  • Different payload types: Test alert, sound-only, silent notifications

  • Content extensions: Test notification service extensions with custom content

  • Action buttons: Test notification actions and user responses

  • Notification grouping: Test thread-id for notification grouping

screenshotA

simctl-screenshot-inline

Capture optimized screenshots with inline base64 encoding for direct MCP response transmission.

What it does

Captures simulator screenshots and returns them as base64-encoded images directly in the MCP response. Automatically optimizes images for token efficiency with tile-aligned resizing and WebP/JPEG compression. Includes interactive element detection and coordinate transforms.

Parameters

  • udid (string, optional): Simulator UDID (auto-detects booted device if omitted)

  • size (string, optional): Screenshot size - half, full, quarter, thumb (default: half)

  • appName (string, optional): App name for semantic context

  • screenName (string, optional): Screen/view name for semantic context

  • state (string, optional): UI state for semantic context

  • enableCoordinateCaching (boolean, optional): Enable view fingerprinting for coordinate caching

Screenshot Size Optimization

Automatically optimizes screenshots for token efficiency:

  • half (default): 256×512 pixels, 1 tile, ~170 tokens (50% savings)

  • full: Native resolution, 2 tiles, ~340 tokens

  • quarter: 128×256 pixels, 1 tile, ~170 tokens

  • thumb: 128×128 pixels, 1 tile, ~170 tokens

Automatic Optimization Process

  1. Capture: Screenshot taken at native resolution

  2. Resize: Automatically resized to tile-aligned dimensions (unless size='full')

  3. Compress: Converted to WebP format at 60% quality (falls back to JPEG if unavailable)

  4. Encode: Base64-encoded for inline MCP response transmission

  5. Extract: Interactive elements detected from accessibility tree

  6. Transform: Coordinate mapping provided for resized screenshots

Returns

MCP response with:

  • Base64-encoded optimized image (inline)

  • Screenshot optimization metadata (dimensions, tokens, savings)

  • Interactive elements with coordinates and properties

  • Coordinate transform for mapping screenshot to device coordinates

  • View fingerprint (if enableCoordinateCaching is true)

  • Semantic metadata (if provided)

Examples

Simple optimized screenshot (256×512)

await simctlScreenshotInlineTool({
  udid: 'device-123'
})

Full resolution screenshot

await simctlScreenshotInlineTool({
  udid: 'device-123',
  size: 'full'
})

Screenshot with semantic context

await simctlScreenshotInlineTool({
  udid: 'device-123',
  appName: 'MyApp',
  screenName: 'LoginScreen',
  state: 'Empty'
})

Screenshot with coordinate caching enabled

await simctlScreenshotInlineTool({
  udid: 'device-123',
  enableCoordinateCaching: true
})

Interactive Element Detection

Automatically extracts interactive elements from the accessibility tree:

  • Element type (Button, TextField, etc.)

  • Label and identifier

  • Bounds (x, y, width, height)

  • Tappability status

Limited to top 20 elements to avoid token overflow. Elements are filtered to only include those with bounds and hittable status.

Coordinate Transform

When screenshots are resized (size ≠ 'full'), provides automatic coordinate transformation:

Use the coordinateTransformHelper field in the response with idb-ui-tap:

  1. Identify element coordinates visually from the screenshot

  2. Call idb-ui-tap with applyScreenshotScale: true plus scale factors

  3. The tool automatically transforms screenshot coordinates to device coordinates

Example:

idb-ui-tap {
  x: 256,              // Screenshot coordinate
  y: 512,              // Screenshot coordinate
  applyScreenshotScale: true,
  screenshotScaleX: 1.67,
  screenshotScaleY: 1.66
}
// Tool automatically calculates: deviceX = 256 * 1.67, deviceY = 512 * 1.66

Manual Transformation (For Reference)

If not using automatic transformation:

  • scaleX: Multiply screenshot X coordinates by this to get device coordinates

  • scaleY: Multiply screenshot Y coordinates by this to get device coordinates

  • coordinateTransform.guidance: Human-readable instructions

Important: Most agents should use the automatic transformation via idb-ui-tap's applyScreenshotScale parameter. Manual calculation is provided for reference only.

View Fingerprinting (Opt-in)

When enableCoordinateCaching is true, computes a structural hash of the view:

  • elementStructureHash: SHA-256 hash of element hierarchy

  • cacheable: Whether view is stable enough to cache coordinates

  • elementCount: Number of elements in hierarchy

  • orientation: Device orientation

Excludes loading states, animations, and dynamic content from caching.

Common Use Cases

  1. Visual analysis: LLM-based screenshot analysis with token optimization

  2. UI automation: Detect interactive elements and get tap coordinates

  3. Bug reporting: Capture and transmit screenshots inline

  4. Test documentation: Screenshot with semantic context for test tracking

  5. Coordinate caching: Store element coordinates for repeated interactions

Token Efficiency

Screenshots are optimized for minimal token usage:

  • Default (half): ~170 tokens (50% savings vs full)

  • Full: ~340 tokens (native resolution)

  • Quarter: ~170 tokens (75% savings vs full)

  • Thumb: ~170 tokens (smallest, for thumbnails)

Token counts are estimates based on Claude's image processing (170 tokens per 512×512 tile).

Important Notes

  • Auto-detection: If udid is omitted, uses the currently booted device

  • Temp files: Uses temp directory for processing, auto-cleans up

  • WebP fallback: Attempts WebP compression, falls back to JPEG if unavailable

  • Element extraction: Requires app to be running with accessibility enabled

  • Coordinate accuracy: Transform provides pixel-perfect coordinate mapping

Error Handling

  • Simulator not found: Validates simulator exists in cache

  • Simulator not booted: Indicates simulator must be booted first

  • Capture failure: Reports if screenshot capture fails

  • Optimization failure: Falls back to original if optimization fails

  • Element extraction: Gracefully degrades if accessibility is unavailable

Next Steps After Screenshot

  1. Analyze visually: LLM processes inline image for visual analysis

  2. Interact with elements: Use coordinates from interactiveElements

  3. Tap elements: Apply coordinate transform if resized, then use simctl-tap

  4. Query specific elements: Use simctl-query-ui for targeted element discovery

  5. Cache coordinates: Store fingerprint for reuse on identical views

Comparison with simctl-io

Feature

screenshot-inline

simctl-io

Returns

Base64 inline

File path

Optimization

Automatic

Manual

Elements

Auto-detected

Not included

Transform

Included

Included

Use case

MCP responses

File storage

Token usage

Optimized

Depends on size

idb-targetsA

idb-targets

Unified IDB target management - discover, inspect, focus, and manage connections.

Overview

Single tool for IDB target discovery and connection management. Routes to specialized handlers while maintaining clean operation semantics.

Operations

list

List all available IDB targets.

Parameters:

  • state (string, optional): Filter by state - 'Booted' or 'Shutdown'

  • type (string, optional): Filter by type - 'device' or 'simulator'

Example:

await idbTargetsToolUnified({
  operation: 'list',
  state: 'Booted'
})

Returns: List of targets with metadata, state, and type information.


describe

Get detailed information about a specific target.

Parameters:

  • udid (string): Target UDID

Example:

await idbTargetsToolUnified({
  operation: 'describe',
  udid: 'ABC-123-DEF'
})

Returns: Detailed target information including screen dimensions, device model, iOS version.


focus

Focus simulator window for interactive testing.

Parameters:

  • udid (string): Simulator UDID

Example:

await idbTargetsToolUnified({
  operation: 'focus',
  udid: 'ABC-123-DEF'
})

connect

Establish IDB companion connection to target.

Parameters:

  • udid (string, optional): Target UDID - auto-detects if omitted

Example:

await idbTargetsToolUnified({
  operation: 'connect',
  udid: 'ABC-123-DEF'
})

Notes: Establishes persistent gRPC connection for faster subsequent operations. Useful for warming up connections before automated testing.


disconnect

Close IDB companion connection to target.

Parameters:

  • udid (string, optional): Target UDID

Example:

await idbTargetsToolUnified({
  operation: 'disconnect',
  udid: 'ABC-123-DEF'
})

  • idb-app: App management on IDB targets

  • idb-ui-tap, idb-ui-input, idb-ui-gesture: UI automation on targets

idb-ui-tapA

idb-ui-tap

🎯 Tap at coordinates on iOS screen - core UI automation primitive with screenshot coordinate transformation

What it does

Sends precise tap events to iOS targets at specified screen coordinates with automatic coordinate transformation from screenshot space to device space. Supports single tap, double tap, and long press gestures. Validates coordinates against device screen bounds and provides semantic action tracking for test documentation. Works on both simulators and physical devices over USB/WiFi.

Why you'd use it

  • Automate UI interactions from screenshot analysis - tap elements identified visually

  • Transform screenshot coordinates automatically when screenshots are resized for token efficiency

  • Validate tap coordinates against device bounds before execution to prevent out-of-range errors

  • Track test scenarios with semantic metadata (actionName, expectedOutcome, testScenario, step)

Parameters

Required

  • x (number): X coordinate (device coords or screenshot coords with applyScreenshotScale)

  • y (number): Y coordinate (device coords or screenshot coords with applyScreenshotScale)

Optional

  • udid (string): Target identifier - auto-detects if omitted

  • numberOfTaps (number, default: 1): Number of taps (set 2 for double-tap)

  • duration (number): Long press duration in milliseconds

  • applyScreenshotScale (boolean): Transform screenshot coords to device coords

  • screenshotScaleX (number): Scale factor for X axis from screenshot-inline

  • screenshotScaleY (number): Scale factor for Y axis from screenshot-inline

  • actionName (string): Semantic action name (e.g., "Login Button Tap")

  • screenContext (string): Screen name for context (e.g., "LoginScreen")

  • expectedOutcome (string): Expected result (e.g., "Navigate to HomeScreen")

  • testScenario (string): Test scenario name (e.g., "Happy Path Login")

  • step (number): Step number in test workflow

Returns

Tap execution status with transformed coordinates, input coordinate details (if transformed), action context metadata for test tracking, error details if failed, and verification guidance.

Examples

Tap from screenshot coordinates (auto-transformed)

const result = await idbUiTapTool({
  x: 150, y: 300,
  applyScreenshotScale: true,
  screenshotScaleX: 2.0, screenshotScaleY: 2.0,
  actionName: "Login Button Tap",
  expectedOutcome: "Navigate to HomeScreen"
});
  • idb-ui-describe: Discover tappable elements and their coordinates

  • screenshot: Capture screenshot to identify tap targets

  • idb-ui-gesture: For swipes and hardware buttons

idb-ui-inputA

idb-ui-input

⌨️ Input text and keyboard commands - automated text entry and special key presses for form automation

What it does

Sends text input and keyboard commands to focused elements on iOS targets. Types text strings into active text fields, presses special keys (home, return, delete, arrows), and executes key sequences for complex input workflows. Automatically redacts sensitive data (passwords) in responses and provides semantic field context tracking for test documentation.

Why you'd use it

  • Automate form filling without manual keyboard interaction - login flows, search, data entry

  • Execute keyboard shortcuts and navigation (tab, return, arrows) for multi-field workflows

  • Safely handle sensitive data with automatic redaction in tool responses and logs

  • Track input operations with semantic metadata (actionName, fieldContext, expectedOutcome)

Parameters

Required

  • operation (string): "text" | "key" | "key-sequence"

Operation-specific parameters

  • text (string, required for text operation): String to type into focused field

  • key (string, required for key operation): Special key name (home, return, delete, tab, arrows, etc.)

  • keySequence (string[], required for key-sequence operation): Array of key names to press in order

Optional

  • udid (string): Target identifier - auto-detects if omitted

  • actionName (string): Semantic action name (e.g., "Enter Email")

  • fieldContext (string): Field name for context (e.g., "Email TextField")

  • expectedOutcome (string): Expected result (e.g., "Email field populated")

  • isSensitive (boolean): Mark as sensitive to redact from output

Returns

Input execution status with operation details (redacted if sensitive), duration, input context metadata for test tracking, error details if failed, and troubleshooting guidance specific to text vs. key operations.

Examples

Type email into focused field

const result = await idbUiInputTool({
  operation: 'text',
  text: 'user@example.com',
  actionName: 'Enter Email',
  fieldContext: 'Email TextField'
});

Press return to submit

await idbUiInputTool({ operation: 'key', key: 'return' });
  • idb-ui-tap: Tap to focus text fields before typing

  • idb-ui-describe: Find text field coordinates

idb-ui-gestureA

idb-ui-gesture

👆 Perform gestures and hardware button presses - swipes, scrolls, and device controls for navigation

What it does

Executes swipe gestures (directional or custom paths) and hardware button presses on iOS targets. Supports standard swipe directions (up, down, left, right) with automatic screen-relative path calculation using configurable profiles (flick, swipe, drag), custom swipe paths with precise start/end coordinates, and hardware button simulation (HOME, LOCK, SIRI, SCREENSHOT, APP_SWITCH). Automatically validates velocity to ensure iOS recognizes gestures as swipes (>6000 px/sec). Validates coordinates against device bounds and provides semantic action tracking.

Why you'd use it

  • Automate scroll and navigation gestures - swipe to reveal content, dismiss modals, page through carousels

  • Use optimized swipe profiles for different UIs - flick for fast page changes, swipe for standard scrolling, drag for slow interactions

  • Test hardware button interactions without physical device access - home button, lock, app switching

  • Execute precise custom swipe paths for complex gesture-based UIs (drawing, map navigation)

  • Track gesture-based test scenarios with semantic metadata (actionName, expectedOutcome)

Parameters

Required

  • operation (string): "swipe" | "button"

Swipe operation parameters

  • direction (string): "up" | "down" | "left" | "right" - auto-calculates screen-relative path

  • profile (string, default: "standard"): "standard" | "flick" | "gentle" - gesture profile

  • startX, startY, endX, endY (numbers): Precise POINT coordinates for custom swipe path

  • duration (number, default: 200): Swipe duration in MILLISECONDS (e.g., 200 for 200ms) - uses profile default if omitted

Button operation parameters

  • buttonType (string): "HOME" | "LOCK" | "SIDE_BUTTON" | "APPLE_PAY" | "SIRI" | "SCREENSHOT" | "APP_SWITCH"

Optional

  • udid (string): Target identifier - auto-detects if omitted

  • actionName (string): Semantic action name (e.g., "Scroll to Bottom")

  • expectedOutcome (string): Expected result (e.g., "Reveal footer content")

Swipe Profiles (Empirically Tested)

  • standard: Default balance (75% distance, 200ms, 1475 points/sec) - perfect for general navigation

  • flick: Fast page changes (85% distance, 120ms, 2775 points/sec) - use for carousel/rapid navigation

  • gentle: Slow scrolling (50% distance, 300ms, 653 points/sec) - reliable but near-minimum threshold

All coordinates in POINT space (393×852 for iPhone 16 Pro), NOT pixel space. All profiles tested and verified working on iOS 18.5 home screen.

Complete JSON Examples

Swipe Up (Scroll Down)

{"operation": "swipe", "direction": "up", "profile": "standard", "actionName": "Scroll Down"}

Swipe Down (Scroll Up)

{"operation": "swipe", "direction": "down", "profile": "standard", "actionName": "Scroll Up"}

Swipe Left (Navigate Forward)

{"operation": "swipe", "direction": "left", "profile": "standard", "actionName": "Go to Next Page"}

Swipe Right (Navigate Back)

{"operation": "swipe", "direction": "right", "profile": "standard", "actionName": "Go to Previous Page"}

Flick Swipe (Fast Page Navigation)

{"operation": "swipe", "direction": "left", "profile": "flick", "duration": 120, "actionName": "Fast Swipe to Next"}

Gentle Swipe (Slow Scrolling)

{"operation": "swipe", "direction": "up", "profile": "gentle", "duration": 300, "actionName": "Slow Scroll Down"}

Custom Swipe Path (Precise Coordinates)

{"operation": "swipe", "startX": 196, "startY": 600, "endX": 196, "endY": 200, "duration": 200, "actionName": "Custom Scroll"}

Press Home Button

{"operation": "button", "buttonType": "HOME", "actionName": "Background App"}

Press Lock Button

{"operation": "button", "buttonType": "LOCK", "actionName": "Lock Device"}

Press Side Button

{"operation": "button", "buttonType": "SIDE_BUTTON", "actionName": "Trigger Side Button Action"}

Press Siri Button

{"operation": "button", "buttonType": "SIRI", "actionName": "Activate Siri"}

Press Screenshot Button

{"operation": "button", "buttonType": "SCREENSHOT", "actionName": "Capture Screenshot"}

Press App Switch Button

{"operation": "button", "buttonType": "APP_SWITCH", "actionName": "Show App Switcher"}

Returns

Gesture execution status with operation details (direction/button, path coordinates for swipes), duration, velocity info, gesture context metadata, error details if failed, and verification guidance.

Examples

Standard swipe up (default profile)

const result = await idbUiGestureTool({
  operation: 'swipe',
  direction: 'up',
  actionName: 'Scroll to Bottom',
  expectedOutcome: 'Reveal footer content'
});

Flick swipe for fast page navigation

await idbUiGestureTool({
  operation: 'swipe',
  direction: 'left',
  profile: 'flick',
  actionName: 'Go to Next Page'
});

Press home button

await idbUiGestureTool({ operation: 'button', buttonType: 'HOME' });
  • idb-ui-tap: For precise element tapping

  • idb-ui-describe: Find element coordinates

idb-ui-describeA

idb-ui-describe

🔍 Query UI accessibility tree - discover tappable elements and text fields for precise automation

What it does

Queries iOS accessibility tree to discover UI elements, their properties (type, label, enabled state), coordinates (frame, centerX, centerY), and accessibility identifiers. Returns full tree with progressive disclosure (summary + cache ID for full data), element-at-point queries for tap validation, and data quality assessment (rich/moderate/minimal) to guide automation strategy. Automatically parses NDJSON output to extract all elements (not just first), includes AXFrame coordinate parsing for precise tapping, and caches large outputs to prevent token overflow.

Progressive Filtering: Supports 4 filter levels for element discovery - start conservative with moderate filtering (default), escalate to permissive/none if minimal data found.

iOS Compatibility: Recognizes iOS-specific accessibility fields (role, role_description, AXLabel, AXFrame) in addition to standard fields.

Why you'd use it

  • Discover all tappable elements from accessibility tree - buttons, cells, links identified by JSON element objects

  • Get precise tap coordinates (centerX, centerY) for elements without needing screenshots

  • Assess data quality before choosing automation approach - rich data enables precise targeting, minimal data requires screenshots

  • Validate tap coordinates by querying elements at specific points before execution

  • Progressive disclosure prevents token overflow on complex UIs - get summary first, full tree on demand

  • Progressive filter escalation - start with moderate filtering, escalate to permissive/none if minimal data found

Parameters

Required

  • operation (string): "all" | "point"

Point operation parameters

  • x (number, required for point operation): X coordinate to query

  • y (number, required for point operation): Y coordinate to query

Optional

  • udid (string): Target identifier - auto-detects if omitted

  • screenContext (string): Screen name for context (e.g., "LoginScreen")

  • purposeDescription (string): Query purpose (e.g., "Find tappable button")

  • filterLevel (string): "strict" | "moderate" | "permissive" | "none" (default: "moderate")

    • strict: Only obvious interactive elements via type field (original behavior)

    • moderate: Include iOS roles (role, role_description) - DEFAULT, fixes iOS button detection

    • permissive: Any element with role/type/label information

    • none: Return everything (debugging)

Returns

For "all": UI tree summary with element counts (total, tappable, text fields), data quality assessment (rich/moderate/minimal), top 20 interactive elements preview with centerX/centerY coordinates, uiTreeId for full tree retrieval, current filter level, and guidance on automation strategy including suggestions to escalate filter level if minimal data found.

For "point": Element details at coordinates including type, label, value, identifier, frame coordinates (x, y, centerX, centerY), enabled state, and tappability.

Examples

Query full UI tree with default moderate filtering

const result = await idbUiDescribeTool({
  operation: 'all',
  screenContext: 'LoginScreen',
  purposeDescription: 'Find email and password fields'
});
// Result includes elements with centerX, centerY for direct tapping

Progressive filter escalation pattern

// 1. Start with default (moderate)
let result = await idbUiDescribeTool({ operation: 'all' });

// 2. If minimal data, try permissive
if (result.summary.dataQuality === 'minimal') {
  result = await idbUiDescribeTool({
    operation: 'all',
    filterLevel: 'permissive'
  });
}

// 3. If still minimal, try none (return everything)
if (result.summary.dataQuality === 'minimal') {
  result = await idbUiDescribeTool({
    operation: 'all',
    filterLevel: 'none'
  });
}

// 4. If STILL minimal, fall back to screenshots
if (result.summary.dataQuality === 'minimal') {
  // Use screenshot-based approach
}

Validate element at tap coordinates

const element = await idbUiDescribeTool({
  operation: 'point',
  x: 200,
  y: 400
});
// Element includes frame coordinates if available
  • idb-ui-tap: Tap discovered elements using centerX/centerY coordinates

  • screenshot: Capture screenshot for visual element identification

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

  • accessibility-quality-check: Quick assessment before choosing approach

idb-ui-find-elementA

idb-ui-find-element

Find UI elements by semantic search in accessibility tree - no screenshots needed.

Overview

Queries the accessibility tree and searches for elements matching a label or identifier. Returns matching elements with tap-ready coordinates (centerX, centerY), enabling agents to find specific UI controls without visual analysis. Fast semantic search replaces screenshot-based visual scanning for complex UIs.

Parameters

Required

  • query (string): Search term to match against element labels or identifiers

Optional

  • udid (string): Target identifier - auto-detects if omitted

Returns

Array of matching elements with:

  • Type, label, identifier

  • Tap-ready coordinates (centerX, centerY)

  • Full frame boundaries (x, y, width, height)

Returns empty array if no matches found.

Examples

Find login button

const result = await idbUiFindElementTool({
  query: 'login'
});

Find email field on specific device

const emailField = await idbUiFindElementTool({
  query: 'email',
  udid: 'DEVICE-UDID'
});

Find by identifier partial match

const search = await idbUiFindElementTool({
  query: 'submit'
});

How It Works

  1. Query accessibility tree: Calls idb ui describe-all (~80ms)

  2. Filter by query: Searches element labels and identifiers (case-insensitive partial match)

  3. Return coordinates: Provides tap-ready centerX/centerY for direct use with idb-ui-tap

  • accessibility-quality-check: Quick assessment of accessibility data richness

  • idb-ui-describe: Full accessibility tree with all element details

  • idb-ui-tap: Tap elements using coordinates

  • screenshot: Visual fallback if accessibility insufficient

Notes

  • Uses case-insensitive partial matching ("log" matches "Login")

  • Returns all matching elements (filter in agent logic if needed)

  • Only returns elements with valid frame coordinates

  • Much faster than visual analysis (~80ms vs 2000ms for screenshot)

  • 5-6x cheaper token cost (~40 tokens vs ~170 for screenshot)

accessibility-quality-checkA

accessibility-quality-check

Quick assessment of accessibility tree richness - decide whether to use accessibility or screenshots.

Overview

Rapidly queries the accessibility tree and assesses data richness without returning full element details. Returns a quality score and recommendation (accessibility-ready or screenshot-fallback) in ~80ms with minimal token cost. Prevents agents from wasting tokens on expensive screenshots when accessibility data is sufficient.

Parameters

Optional

  • udid (string): Target identifier - auto-detects if omitted

  • screenContext (string): Screen name for semantic tracking (e.g., "LoginScreen")

Returns

  • quality: "rich" | "moderate" | "minimal"

  • recommendation: "accessibility-ready" | "consider-screenshot"

  • elementCounts: Total elements, tappable elements, text fields, element types

  • queryTime: Query execution time in milliseconds

  • queryGuidance: Next steps based on quality assessment

Examples

Quick check of current screen

const check = await accessibilityQualityCheckTool({
  screenContext: 'LoginScreen'
});

if (check.quality === 'rich') {
  // Use accessibility: idb-ui-describe
} else {
  // Fall back to screenshot
}

Check before deciding automation approach

const assessment = await accessibilityQualityCheckTool({
  udid: 'DEVICE-UDID'
});

// Workflow guided by quality

Quality Levels

Rich (✅ Use accessibility)

  • 3 tappable elements, OR

  • Text input fields detected

  • Recommendation: Use idb-ui-describe and accessibility-based navigation

Moderate (⚠️ Try accessibility first)

  • 2-3 tappable elements

  • Some custom UI that may not be recognized

  • Recommendation: Try accessibility tree first, fall back to screenshot if needed

Minimal (📸 Use screenshot)

  • ≤1 element, OR

  • No tappable elements found

  • Recommendation: Take screenshot for visual analysis

How It Works

  1. Quick query: Calls idb ui describe-all (~80ms)

  2. Assess richness: Counts tappable elements, text fields

  3. Return score: Quality assessment + recommendation

  4. No elements returned: Just the counts and guidance

Cost Comparison

  • accessibility-quality-check: ~80ms, 30 tokens

  • Full idb-ui-describe: ~120ms, 50 tokens

  • screenshot: ~2000ms, 170 tokens

  • idb-ui-describe: Full accessibility tree with element details

  • idb-ui-find-element: Search for specific element by name

  • screenshot: Visual fallback when accessibility insufficient

Notes

  • Returns quality assessment only (not full element tree)

  • Recommended as first step before choosing automation approach

  • Saves tokens by preventing unnecessary screenshots

  • Identifies when UI has minimal accessibility support

idb-list-appsA

idb-list-apps

List installed applications - discover apps available for testing with bundle IDs and running status.

Overview

Enumerates all installed applications on iOS targets with structured metadata including bundle ID, app name, install type (system/user/internal), running status, debuggability, and architecture. Filters apps by install type or running status to focus on user apps or active processes. Parses IDB's pipe-separated output into structured JSON for easy programmatic access.

Parameters

Required

None - all parameters are optional

Optional

  • udid (string): Target identifier - auto-detects if omitted

  • filterType (string): Filter by install type ("system", "user", or "internal")

  • runningOnly (boolean): Show only currently running apps

Returns

Structured app list with summary counts (total, running, debuggable, by install type), separate arrays for running vs. installed apps, applied filter details, and actionable guidance for launching, terminating, installing, or debugging apps.

Examples

List user-installed apps to find test target

const result = await idbListAppsTool({
  filterType: 'user'
});

Find running app for UI automation

const running = await idbListAppsTool({ runningOnly: true });

List all apps on specific device

const all = await idbListAppsTool({
  udid: 'DEVICE-UDID-123'
});
  • idb-launch: Launch app by bundle ID discovered here

  • idb-terminate: Stop running app found in list

  • idb-install: Install new app to target

Notes

  • IDB outputs pipe-separated text, converted to structured JSON

  • Output format: bundle_id | app_name | install_type | arch | running | debuggable

  • Filter by install type to focus on user apps vs system apps

  • Running status helps identify active processes for UI automation

  • Debuggable status indicates if debugger can be attached

idb-appA

idb-app

Unified IDB app lifecycle management - install, uninstall, launch, terminate.

Overview

Single tool for IDB-based app management. Routes to specialized handlers while maintaining clean operation semantics.

Operations

install

Install iOS app via IDB.

Parameters:

  • appPath (string): Path to .app bundle

  • udid (string, optional): Target device UDID

Example:

await idbAppTool({
  operation: 'install',
  appPath: '/path/to/MyApp.app'
})

uninstall

Uninstall iOS app via IDB.

Parameters:

  • bundleId (string): App bundle ID

  • udid (string, optional): Target device UDID

Example:

await idbAppTool({
  operation: 'uninstall',
  bundleId: 'com.example.MyApp'
})

launch

Launch iOS app via IDB.

Parameters:

  • bundleId (string): App bundle ID

  • udid (string, optional): Target device UDID

  • arguments (string[], optional): Command-line arguments

  • environment (object, optional): Environment variables

  • streamOutput (boolean, optional): Stream app output

Example:

await idbAppTool({
  operation: 'launch',
  bundleId: 'com.example.MyApp',
  arguments: ['--debug'],
  streamOutput: true
})

terminate

Terminate running iOS app via IDB.

Parameters:

  • bundleId (string): App bundle ID

  • udid (string, optional): Target device UDID

Example:

await idbAppTool({
  operation: 'terminate',
  bundleId: 'com.example.MyApp'
})

  • idb-targets: List and manage IDB targets

  • idb-ui-tap, idb-ui-input, idb-ui-gesture: UI automation

  • simctl-app: Simctl-based app management

workflow-tap-elementA

workflow-tap-element

High-level semantic UI interaction - find and tap elements by name without coordinate hunting.

Overview

Orchestrates accessibility-first UI automation in a single call:

  1. Check Accessibility - Assess UI richness for automation approach

  2. Find Element - Semantic search by label/identifier

  3. Tap Element - Execute tap at discovered coordinates

  4. Input Text (optional) - Type into tapped field

  5. Verify Result (optional) - Screenshot for confirmation

This workflow keeps intermediate results internal, reducing agent context usage by ~80% compared to calling each tool manually.

Parameters

Required

  • elementQuery (string): Search term for element (e.g., "Login", "Submit", "Email")

    • Case-insensitive partial matching ("log" matches "Login")

Optional

  • inputText (string): Text to type after tapping (for text fields)

  • verifyResult (boolean): Take screenshot after action (default: false)

  • udid (string): Target device - auto-detected if omitted

  • screenContext (string): Screen name for tracking (e.g., "LoginScreen")

Returns

Consolidated result with:

  • success: Overall workflow success

  • tappedElement: Found element details (type, label, coordinates)

  • inputText: Text entry status (if requested)

  • verified: Screenshot status (if requested)

  • accessibilityQuality: UI richness assessment

  • totalDuration: Total workflow time

  • guidance: Next steps

Examples

Tap Login Button

{"elementQuery": "Login"}

Finds and taps the Login button.

Tap Email Field and Enter Text

{
  "elementQuery": "Email",
  "inputText": "user@example.com",
  "screenContext": "LoginScreen"
}

Finds email field, taps it, enters text.

Full Verification Workflow

{
  "elementQuery": "Submit",
  "verifyResult": true,
  "screenContext": "SignupForm"
}

Taps Submit button and captures verification screenshot.

Why Use This Workflow?

Token Efficiency

  • Manual approach: 4-5 tool calls × ~50 tokens each = ~200+ tokens in responses

  • Workflow approach: 1 call with consolidated response = ~80 tokens

Reduced Context Pollution

  • Intermediate accessibility data not exposed

  • Element search results summarized

  • Only actionable outcome returned

Error Handling

  • Graceful degradation on partial failures

  • Helpful guidance when element not found

  • Clear troubleshooting steps

  • idb-ui-find-element: Direct element search (used internally)

  • idb-ui-tap: Direct tap (used internally)

  • accessibility-quality-check: Direct quality check (used internally)

  • workflow-fresh-install: Clean app installation workflow

Notes

  • Falls back gracefully if accessibility is minimal

  • Non-fatal errors (input, screenshot) don't fail the workflow

  • Element matching uses partial, case-insensitive search

  • Small delay between tap and input for keyboard appearance

workflow-fresh-installA

workflow-fresh-install

Clean slate app installation - build, install, and launch with fresh simulator state.

Overview

Orchestrates a complete clean installation cycle in a single call:

  1. Select Simulator - Auto-detect or use specified device

  2. Shutdown - Ensure simulator is stopped

  3. Erase (optional) - Wipe all simulator data

  4. Boot - Start fresh simulator

  5. Build - Compile the Xcode project

  6. Install - Install the built app

  7. Launch - Start the app

This workflow keeps intermediate results internal, reducing agent context usage by ~70% compared to calling each tool manually.

Parameters

Required

  • projectPath (string): Path to .xcodeproj or .xcworkspace

  • scheme (string): Build scheme name

Optional

  • simulatorUdid (string): Target simulator - auto-detected if omitted

  • eraseSimulator (boolean): Wipe simulator data before install (default: false)

  • configuration ("Debug" | "Release"): Build configuration (default: Debug)

  • launchArguments (string[]): App launch arguments

  • environmentVariables (Record<string, string>): App environment variables

Returns

Consolidated result with:

  • success: Overall workflow success

  • project: Build configuration details

  • simulator: Target simulator info

  • app: Installed app details (bundleId, path, launched)

  • totalDuration: Total workflow time

  • guidance: Next steps

Examples

Basic Fresh Install

{
  "projectPath": "/path/to/MyApp.xcodeproj",
  "scheme": "MyApp"
}

Auto-selects simulator, builds, installs, and launches.

Clean Install with Erased Simulator

{
  "projectPath": "/path/to/MyApp.xcworkspace",
  "scheme": "MyApp",
  "eraseSimulator": true,
  "configuration": "Debug"
}

Erases all simulator data for truly fresh state.

Specific Simulator with Launch Arguments

{
  "projectPath": "/path/to/MyApp.xcodeproj",
  "scheme": "MyApp",
  "simulatorUdid": "ABC123-DEF456",
  "launchArguments": ["-UITesting", "-ResetState"],
  "environmentVariables": {"DEBUG_MODE": "1"}
}

Targets specific simulator with custom launch configuration.

Why Use This Workflow?

Token Efficiency

  • Manual approach: 6-7 tool calls × ~100 tokens each = ~600+ tokens in responses

  • Workflow approach: 1 call with consolidated response = ~150 tokens

Reduced Context Pollution

  • Build logs not exposed (only success/failure)

  • Intermediate states summarized

  • Only actionable outcome returned

Consistent State

  • Shutdown ensures clean starting point

  • Optional erase for truly fresh state

  • Proper boot sequencing

  • workflow-tap-element: UI interaction after install

  • xcodebuild-build: Direct build (used internally)

  • simctl-device: Direct simulator control (used internally)

  • simctl-app: Direct app management (used internally)

Notes

  • Shutdown failures are non-fatal (simulator may already be off)

  • Auto-suggests best simulator based on project requirements

  • Build artifacts are located automatically

  • Bundle ID is discovered from build settings

Prompts

Interactive templates invoked by user choice

NameDescription
debug-workflowComplete iOS debug workflow: build → install → test cycle with validation to prevent testing stale app versions

Resources

Contextual data attached and managed by the client

NameDescription

No resources

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