iOS Simulator device and app management with simctl. Use when managing simulator devices (boot, create, delete), installing/launching apps, or troubleshooting simulator issues. Covers device lifecycle, app lifecycle, and diagnostics.
Inherits all available tools
Additional assets for this skill
This skill inherits all available tools. When active, it can use any tool Claude has access to.
Use the execute_simulator_command MCP tool for all simulator management
The xclaude-plugin provides the execute_simulator_command MCP tool which consolidates all simctl operations into a single, token-efficient dispatcher.
This is the most important rule: When working with iOS simulators, you MUST use the execute_simulator_command MCP tool.
execute_simulator_command for all device/app lifecycle operationsxcrun simctl commandssimctl directly in bashxcrun simctl commands in a terminalWhy? The MCP tool provides:
If execute_simulator_command fails, the issue is with parameters or device state - not that you should use bash.
| Task | ❌ WRONG (Bash) | ✅ RIGHT (MCP Tool) |
|---|---|---|
| List devices | xcrun simctl list | execute_simulator_command op: "list" |
| Boot simulator | xcrun simctl boot <UDID> | execute_simulator_command op: "device-lifecycle" sub: "boot" |
| Install app | xcrun simctl install <UDID> <app.app> | execute_simulator_command op: "app-lifecycle" sub: "install" |
| Launch app | xcrun simctl launch <UDID> <bundle-id> | execute_simulator_command op: "app-lifecycle" sub: "launch" |
| Screenshot | xcrun simctl io <UDID> screenshot | execute_simulator_command op: "io" sub: "screenshot" |
mkdir, cp, rm, ls, etc.grep, find, cat, etc.git status, git log, etc.which, simctl --version, etc.find . -name "*.app", etc.| Task | MCP Tool | Operation | Sub-Operation |
|---|---|---|---|
| List devices | execute_simulator_command | list | - |
| Boot device | execute_simulator_command | device-lifecycle | boot |
| Shutdown device | execute_simulator_command | device-lifecycle | shutdown |
| Create device | execute_simulator_command | device-lifecycle | create |
| Delete device | execute_simulator_command | device-lifecycle | delete |
| Install app | execute_simulator_command | app-lifecycle | install |
| Launch app | execute_simulator_command | app-lifecycle | launch |
| Screenshot | execute_simulator_command | io | screenshot |
| Health check | execute_simulator_command | health-check | - |
execute_simulator_command with operation: "list"Invoke the execute_simulator_command MCP tool:
{
"operation": "list"
}
Returns (Progressive Disclosure):
{
"summary": {
"total_devices": 47,
"available_devices": 31,
"booted_devices": 1
},
"booted": [
{
"name": "iPhone 15",
"udid": "ABC123...",
"state": "Booted",
"runtime": "iOS 17.0"
}
],
"cache_id": "sim-list-xyz789",
"next_steps": [
"Use device name or UDID for operations",
"Query cache_id for full device list if needed"
]
}
Note: Large device lists use progressive disclosure to save tokens.
execute_simulator_command with device-lifecycleInvoke the execute_simulator_command MCP tool:
By Name:
{
"operation": "device-lifecycle",
"sub_operation": "boot",
"device_id": "iPhone 15"
}
By UDID:
{
"operation": "device-lifecycle",
"sub_operation": "boot",
"device_id": "ABC123-DEF456-...",
"parameters": {
"wait_for_boot": true
}
}
wait_for_boot: Blocks until device fully booted (recommended)
{
"operation": "device-lifecycle",
"sub_operation": "shutdown",
"device_id": "iPhone 15"
}
{
"operation": "device-lifecycle",
"sub_operation": "create",
"device_id": "My iPhone 15 Test",
"parameters": {
"device_type": "iPhone 15",
"runtime": "iOS 17.0"
}
}
Returns: New device UDID
Available Device Types:
Check available runtimes: Use list to see installed iOS versions
{
"operation": "device-lifecycle",
"sub_operation": "delete",
"device_id": "My iPhone 15 Test"
}
Warning: This is permanent and cannot be undone.
Remove all data but keep device:
{
"operation": "device-lifecycle",
"sub_operation": "erase",
"device_id": "iPhone 15"
}
When to erase:
Duplicate a device with all its data:
{
"operation": "device-lifecycle",
"sub_operation": "clone",
"device_id": "iPhone 15",
"parameters": {
"new_name": "iPhone 15 Clone"
}
}
Use case: Preserve a specific test state
{
"operation": "app-lifecycle",
"sub_operation": "install",
"device_id": "iPhone 15",
"app_identifier": "/path/to/MyApp.app"
}
Note: app_identifier is the path to .app bundle for install operation.
Build + Install Pattern:
1. execute_xcode_command (operation: build) → Get .app path
2. execute_simulator_command (operation: app-lifecycle, sub_operation: install)
{
"operation": "app-lifecycle",
"sub_operation": "launch",
"device_id": "iPhone 15",
"app_identifier": "com.example.MyApp"
}
With Arguments:
{
"operation": "app-lifecycle",
"sub_operation": "launch",
"device_id": "iPhone 15",
"app_identifier": "com.example.MyApp",
"parameters": {
"arguments": ["--test-mode", "--mock-data"],
"environment": {
"API_URL": "https://staging.example.com"
}
}
}
{
"operation": "app-lifecycle",
"sub_operation": "terminate",
"device_id": "iPhone 15",
"app_identifier": "com.example.MyApp"
}
{
"operation": "app-lifecycle",
"sub_operation": "uninstall",
"device_id": "iPhone 15",
"app_identifier": "com.example.MyApp"
}
For accessing app data:
{
"operation": "get-app-container",
"device_id": "iPhone 15",
"app_identifier": "com.example.MyApp",
"parameters": {
"container_type": "data"
}
}
Container Types:
Returns: File system path to container
Use case: Inspect database files, logs, or user defaults
{
"operation": "io",
"sub_operation": "screenshot",
"device_id": "iPhone 15",
"parameters": {
"output_path": "/path/to/screenshot.png"
}
}
Auto-generated path: If output_path omitted, creates temp file
{
"operation": "io",
"sub_operation": "video",
"device_id": "iPhone 15",
"parameters": {
"output_path": "/path/to/video.mp4",
"duration": 30
}
}
Note: Duration in seconds. Press Ctrl+C to stop recording manually.
{
"operation": "openurl",
"device_id": "iPhone 15",
"parameters": {
"url": "myapp://deep-link/path"
}
}
Use cases:
{
"operation": "push",
"device_id": "iPhone 15",
"app_identifier": "com.example.MyApp",
"parameters": {
"payload": {
"aps": {
"alert": "Test notification",
"badge": 1,
"sound": "default"
}
}
}
}
Payload: Standard APNs JSON payload
Verify iOS development environment:
{
"operation": "health-check"
}
Checks:
Returns:
{
"xcode_installed": true,
"xcode_version": "15.0",
"simctl_available": true,
"issues": []
}
{
"device_id": "iPhone 15"
}
Pro: Readable, easy to remember Con: May match multiple devices
{
"device_id": "ABC123-DEF456-GHI789..."
}
Pro: Unique, guaranteed single match Con: Long, hard to remember
Some tools (like IDB) accept "booted" to target the currently booted simulator:
{
"target": "booted"
}
Note: Only works with IDB operations, not simctl
1. boot → Start simulator
2. uninstall → Remove existing app
3. install → Install fresh build
4. launch → Start app
5. (UI automation) → Test flow
6. terminate → Stop app
7. shutdown → Stop simulator
1. build → Compile latest code
2. install → Update app on simulator (already booted)
3. terminate → Stop running app
4. launch → Start updated app
Note: No need to boot/shutdown between iterations
1. list → Get available devices
2. For each device:
- boot → Start device
- install → Install app
- launch → Start app
- (run tests) → Execute test suite
- terminate → Stop app
- shutdown → Stop device
Problem: "Unable to find device: iPhone 15"
Solutions:
list to see exact device namesProblem: Boot fails or times out
Solutions:
killall -9 com.apple.CoreSimulator.CoreSimulatorServicehealth-check to validate environmentProblem: Install operation fails
Solutions:
Problem: Launch succeeds but app crashes immediately
Solutions:
Booting is slow (~5-10 seconds). Keep simulator running during development.
Device lists can be large. Summary provides what you need 95% of the time.
Creating/deleting is slower than erasing. Reuse devices when possible.
Boot multiple simulators in parallel for multi-device testing:
Launch 3 boot operations concurrently
Wait for all to complete
Proceed with testing
1. execute_xcode_command (build) → Get .app bundle
2. execute_simulator_command (install) → Install to simulator
3. execute_simulator_command (launch) → Start app
1. execute_simulator_command (boot) → Start device
2. execute_idb_command (describe) → Query UI
3. execute_idb_command (tap) → Interact
1. execute_simulator_command (boot) → Start device
2. execute_xcode_command (test) → Run tests on device
3. execute_simulator_command (shutdown) → Stop device
This Skill works with execute_simulator_command tool:
execute_simulator_command toolxc://operations/simulator: Complete simctl operations referencexc://reference/device-specs: Available device types and runtimesxc://reference/error-codes: Common simulator errorsTip: Use list to discover, boot by name for convenience, use UDID for reliability.