Claude
Skills
Sign in
Back

simulator-workflows

Included with Lifetime
$97 forever

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.

General

What this skill does


# Simulator Workflows

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

## ⚠️ CRITICAL: Always Use MCP Tools First

**This is the most important rule:** When working with iOS simulators, you MUST use the `execute_simulator_command` MCP tool.

- ✅ **DO**: Invoke `execute_simulator_command` for all device/app lifecycle operations
- ✅ **DO**: If the MCP tool fails, adjust parameters and retry
- ✅ **DO**: Read error messages and debug the parameters
- ❌ **NEVER**: Fall back to bash `xcrun simctl` commands
- ❌ **NEVER**: Use `simctl` directly in bash
- ❌ **NEVER**: Run `xcrun simctl` commands in a terminal

**Why?** The MCP tool provides:
- Structured error handling
- Token efficiency (consolidated into 1 tool vs. verbose bash output)
- Proper integration with the xclaude-plugin architecture
- Consistent response formatting

If `execute_simulator_command` fails, the issue is with parameters or device state - not that you should use bash.

## When to Use Bash (And When NOT to)

### ❌ NEVER Use Bash For These (Use MCP Tools Instead)

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

### ✅ Bash is Acceptable For (Non-Simulator Tasks)

- File operations: `mkdir`, `cp`, `rm`, `ls`, etc.
- Text inspection: `grep`, `find`, `cat`, etc.
- Git operations: `git status`, `git log`, etc.
- Environment checks: `which`, `simctl --version`, etc.
- Project exploration: `find . -name "*.app"`, etc.

### The Rule: If it's about simulator management → Use MCP tool, not bash

## Quick Reference

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

## Device Management

### 1. Listing Devices - Use `execute_simulator_command` with operation: "list"

Invoke the `execute_simulator_command` MCP tool:

```json
{
  "operation": "list"
}
```

**Returns (Progressive Disclosure):**
```json
{
  "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.

### 2. Booting a Simulator - Use `execute_simulator_command` with device-lifecycle

Invoke the `execute_simulator_command` MCP tool:

**By Name:**
```json
{
  "operation": "device-lifecycle",
  "sub_operation": "boot",
  "device_id": "iPhone 15"
}
```

**By UDID:**
```json
{
  "operation": "device-lifecycle",
  "sub_operation": "boot",
  "device_id": "ABC123-DEF456-...",
  "parameters": {
    "wait_for_boot": true
  }
}
```

**wait_for_boot:** Blocks until device fully booted (recommended)

### 3. Shutting Down

```json
{
  "operation": "device-lifecycle",
  "sub_operation": "shutdown",
  "device_id": "iPhone 15"
}
```

### 4. Creating a New Simulator

```json
{
  "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:**
- iPhone SE (3rd generation)
- iPhone 14, 14 Plus, 14 Pro, 14 Pro Max
- iPhone 15, 15 Plus, 15 Pro, 15 Pro Max
- iPad (10th generation), iPad Air, iPad Pro

**Check available runtimes:** Use `list` to see installed iOS versions

### 5. Deleting a Simulator

```json
{
  "operation": "device-lifecycle",
  "sub_operation": "delete",
  "device_id": "My iPhone 15 Test"
}
```

**Warning:** This is permanent and cannot be undone.

### 6. Erasing a Simulator

**Remove all data but keep device:**

```json
{
  "operation": "device-lifecycle",
  "sub_operation": "erase",
  "device_id": "iPhone 15"
}
```

**When to erase:**
- Reset app state completely
- Clear test data
- Reproduce fresh install behavior

### 7. Cloning a Simulator

**Duplicate a device with all its data:**

```json
{
  "operation": "device-lifecycle",
  "sub_operation": "clone",
  "device_id": "iPhone 15",
  "parameters": {
    "new_name": "iPhone 15 Clone"
  }
}
```

**Use case:** Preserve a specific test state

## App Management

### 1. Installing an App

```json
{
  "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)
```

### 2. Launching an App

```json
{
  "operation": "app-lifecycle",
  "sub_operation": "launch",
  "device_id": "iPhone 15",
  "app_identifier": "com.example.MyApp"
}
```

**With Arguments:**
```json
{
  "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"
    }
  }
}
```

### 3. Terminating an App

```json
{
  "operation": "app-lifecycle",
  "sub_operation": "terminate",
  "device_id": "iPhone 15",
  "app_identifier": "com.example.MyApp"
}
```

### 4. Uninstalling an App

```json
{
  "operation": "app-lifecycle",
  "sub_operation": "uninstall",
  "device_id": "iPhone 15",
  "app_identifier": "com.example.MyApp"
}
```

### 5. Getting App Container Paths

**For accessing app data:**

```json
{
  "operation": "get-app-container",
  "device_id": "iPhone 15",
  "app_identifier": "com.example.MyApp",
  "parameters": {
    "container_type": "data"
  }
}
```

**Container Types:**
- **data**: App's Documents, Library, tmp directories
- **bundle**: App's .app bundle
- **group**: Shared group containers

**Returns:** File system path to container

**Use case:** Inspect database files, logs, or user defaults

## Capture & Media

### 1. Taking Screenshots

```json
{
  "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

### 2. Recording Video

```json
{
  "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.

## Advanced Operations

#

Related in General