# io.github.EthanAckerman-git/preflight-ios-mcp (npm · preflight-ios-mcp)

57 tools for AI-powered iOS Simulator automation — tap, swipe, type, screenshots, and more.

- Trust score: 68/100 (medium)
- Change this week: +22
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `preflight-ios-mcp`: 68/100 (this document), [markdown](https://verifymcp.io/servers/ethanackerman-git-preflight-ios-mcp/preflight-ios-mcp.md), [page](https://verifymcp.io/servers/ethanackerman-git-preflight-ios-mcp/preflight-ios-mcp)

## Channel facts

- Registry: `npm`
- Package: `preflight-ios-mcp`
- Version: `1.0.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 80/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (95 of 99), so this covers what we could see, not the whole tree.
  - Runs a script at install time (postinstall) that we could not recognise. It may be perfectly ordinary, but we do not read the published tarball, so we cannot say what it does.
  - Only part of the dependency tree could be resolved (95 of 99), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 128 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 81/100
  - AI-judged instruction clarity (excellent).
  - Tool/resource definitions use about 4547 tokens (~79/item across 57 items; 57 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add ethanackerman-git-preflight-ios-mcp -- npx -y preflight-ios-mcp
```

### Codex

```bash
codex mcp add ethanackerman-git-preflight-ios-mcp -- npx -y preflight-ios-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "ethanackerman-git-preflight-ios-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "preflight-ios-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add ethanackerman-git-preflight-ios-mcp --command npx --arg -y --arg preflight-ios-mcp
```

### Hermes

```yaml
mcp_servers:
  ethanackerman-git-preflight-ios-mcp:
    command: "npx"
    args: ["-y", "preflight-ios-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "ethanackerman-git-preflight-ios-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "preflight-ios-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 68, +4)

- [functional improvement] Stability: unverified → 0.27

### 2026-08-02 (score 64, +43)

- [security regression] Provenance: unverified → fail
- [security improvement] Known CVEs: unverified → partial
- [security improvement] Install scripts: unverified → partial
- [security improvement] Malware scan: unverified → pass
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [security] The scripts that run when this package is installed changed: postinstall
- [functional improvement] Schema quality: unverified → excellent
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] MCP protocol: unverified → pass
- [functional] Licence: MIT

### 2026-08-01 (score 21, +16)

- [functional improvement] Tool coverage: unverified → 100

### 2026-07-31 (score 5, −19)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 24, −22)

- [functional regression] Tool coverage: 100 → unverified
- [functional] First check of Schema quality: unverified

### 2026-07-27 (score 46)

First indexed and scored.

## MCP tools (57)

### `simulator_screenshot` (~122 tokens)

Take a screenshot of the iOS Simulator screen. Returns the image directly for viewing.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `display` (string): Display to capture (default: internal)
- `format` (string): Image format (default: jpeg). JPEG recommended for AI — smaller, faster.
- `mask` (string): For non-rectangular displays, handle mask by policy
- `savePath` (string): Optional: save a copy to this path on disk

### `simulator_list_devices` (~39 tokens)

List iOS Simulator devices. Shows name, UDID, state, and runtime.

Input parameters:

- `filter` (string): Filter devices (default: all)

### `simulator_list_apps` (~60 tokens)

List all installed apps on the simulator with their bundle IDs.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `includeSystem` (boolean): Include system apps (default: false)

### `simulator_app_info` (~71 tokens)

Get detailed metadata about an installed app (bundle ID, paths, version, etc.).

Input parameters:

- `bundleId` (string, required): App bundle identifier (e.g., "com.apple.mobilesafari")
- `deviceId` (string): Device UDID, name, or "booted" (default: booted)

### `simulator_get_clipboard` (~33 tokens)

Read the text content of the simulator clipboard.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_get_screen_info` (~44 tokens)

Get diagnostic info about the Simulator window geometry and coordinate mapping. Useful for debugging tap/swipe accuracy.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_tap` (~122 tokens)

Tap at a point on the simulator screen. Coordinates are in simulator screen points (e.g., 0-393 for iPhone width). Take a screenshot first to identify coordinates.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `duration` (number): Press duration in seconds (decimal allowed, e.g. 0.5). Default: normal tap
- `x` (number, required): X coordinate in simulator screen points
- `y` (number, required): Y coordinate in simulator screen points

### `simulator_swipe` (~200 tokens)

Swipe/drag from one point to another on the simulator screen. Coordinates are in simulator screen points. Use for scrolling, pulling down, or any drag gesture.

Input parameters:

- `delta` (number): Step size in pixels between each touch point (idb only, default: device decides)
- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `durationMs` (number): Swipe duration in milliseconds (default: 300). Use 400-600ms for edge-swipe-back
- `endX` (number, required): End X in simulator screen points
- `endY` (number, required): End Y in simulator screen points
- `startX` (number, required): Start X in simulator screen points. Use 1 to trigger iOS left-edge-swipe-back gesture (iOS recognizes edge touches within ~20pt of edge)
- `startY` (number, required): Start Y in simulator screen points

### `simulator_long_press` (~99 tokens)

Long press at a point on the simulator screen. Useful for context menus, drag-and-drop initiation, etc.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `durationMs` (number): Press duration in milliseconds (default: 1000)
- `x` (number, required): X coordinate in simulator screen points
- `y` (number, required): Y coordinate in simulator screen points

### `simulator_describe_point` (~85 tokens)

Returns the accessibility element at given coordinates on the iOS Simulator screen. Shows element type, label, value, and frame.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `x` (number, required): X coordinate in simulator screen points
- `y` (number, required): Y coordinate in simulator screen points

### `simulator_type_text` (~73 tokens)

Type text into the currently focused text field in the simulator. Make sure a text field is focused first (tap on it).

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `text` (string, required): Text to type into the currently focused field

### `simulator_press_key` (~122 tokens)

Press a special key (return, escape, delete, tab, arrows, etc.) with optional modifiers (command, shift, option, control).

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `key` (string, required): Key name: return, escape, delete, tab, space, up, down, left, right, home, end, pageup, pagedown, f1-f12
- `modifiers` (array): Modifier keys: command, shift, option, control

### `simulator_boot` (~69 tokens)

Boot an iOS Simulator device. Opens the Simulator app. Use simulator_list_devices to find device names/UDIDs.

Input parameters:

- `deviceId` (string, required): Device UDID or name to boot
- `waitForBoot` (boolean): Wait until device is fully booted before returning (default: true)

### `simulator_shutdown` (~39 tokens)

Shut down a running simulator device.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)

### `simulator_erase` (~40 tokens)

Factory reset a simulator device. Erases all content and settings.

Input parameters:

- `deviceId` (string, required): Device UDID or name to erase (factory reset)

### `simulator_open_url` (~88 tokens)

Open a URL or deep link in the simulator (e.g., "https://example.com" or "myapp://screen").

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `url` (string, required): URL or deep link to open (e.g., "https://example.com" or "myapp://path")

### `simulator_open_simulator` (~17 tokens)

Opens the iOS Simulator application.

### `simulator_get_booted_sim_id` (~25 tokens)

Get the UDID of the currently booted iOS Simulator.

### `simulator_launch_app` (~116 tokens)

Launch an app by bundle ID. Optionally pass launch arguments and environment variables.

Input parameters:

- `args` (array): Launch arguments to pass to the app
- `bundleId` (string, required): App bundle identifier to launch
- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `env` (object): Environment variables to set (will be prefixed with SIMCTL_CHILD_)
- `terminateRunning` (boolean): Terminate the app first if already running (default: false)

### `simulator_terminate_app` (~57 tokens)

Force-terminate a running app by bundle ID.

Input parameters:

- `bundleId` (string, required): App bundle identifier to terminate
- `deviceId` (string): Device UDID, name, or "booted" (default: booted)

### `simulator_install_app` (~65 tokens)

Install a .app bundle onto the simulator from a local file path.

Input parameters:

- `deviceId` (string): Device UDID, name, or "booted" (default: booted)
- `path` (string, required): Path to .app bundle or .ipa file to install

### `simulator_uninstall_app` (~58 tokens)

Uninstall an app from the simulator by bundle ID.

Input parameters:

- `bundleId` (string, required): App bundle identifier to uninstall
- `deviceId` (string): Device UDID, name, or "booted" (default: booted)

### `simulator_get_logs` (~182 tokens)

Get recent device/app logs. Filter by process name, subsystem, log level, time range, and message content. Essential for debugging app behavior.

Input parameters:

- `category` (string): Filter by log category
- `deviceId` (string): Device (default: booted)
- `level` (string): Minimum log level (default: default)
- `limit` (number): Max number of log lines to return (default: 100)
- `messageContains` (string): Filter messages containing this text
- `process` (string): Filter by process name (e.g., "MyApp", "SpringBoard")
- `since` (string): Time range: "5m", "1h", "30s", or ISO date (default: "1m")
- `subsystem` (string): Filter by log subsystem (e.g., "com.apple.UIKit")

### `simulator_stream_logs` (~129 tokens)

Start/read/stop a live log stream. Use action="start" to begin, "read" to get the buffer, "stop" to end. Great for watching app behavior in real-time.

Input parameters:

- `action` (string, required): "start" begins streaming, "read" returns current buffer, "stop" ends the stream
- `bufferSize` (number): Max lines to keep in buffer (default: 200)
- `deviceId` (string): Device (default: booted)
- `level` (string): Minimum log level
- `process` (string): Filter by process name

### `simulator_get_app_container` (~78 tokens)

Get the filesystem path to an app's container (bundle, data, or shared groups). Use this to find where the app stores its files.

Input parameters:

- `bundleId` (string, required): App bundle identifier
- `containerType` (string): Container type (default: data)
- `deviceId` (string): Device (default: booted)

### `simulator_list_app_files` (~91 tokens)

List files in an app's data container. Shows Documents, Library, Preferences, Caches, tmp, etc. Use to find databases, plists, caches.

Input parameters:

- `bundleId` (string, required): App bundle identifier
- `deviceId` (string): Device (default: booted)
- `subPath` (string): Subdirectory to list (e.g., "Documents", "Library/Preferences")

### `simulator_read_app_file` (~102 tokens)

Read a file from an app's data container. Handles plists (converts to JSON), SQLite databases (shows schema), and text files. Specify path relative to data container.

Input parameters:

- `bundleId` (string, required): App bundle identifier
- `deviceId` (string): Device (default: booted)
- `filePath` (string, required): Relative path within the data container (e.g., "Documents/data.json", "Library/Preferences/com.app.plist")

### `simulator_get_crash_logs` (~107 tokens)

Retrieve crash reports from ~/Library/Logs/DiagnosticReports/. Shows stack traces, exception info, and thread states. Filter by process name.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `limit` (number): Max number of crash reports (default: 5)
- `processName` (string): Filter by process/app name
- `since` (string): Only crashes since this ISO date (e.g., "2026-03-22")

### `simulator_diagnose` (~44 tokens)

Generate a diagnostic summary: booted devices, Xcode version, disk usage, and system info.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_accessibility_audit` (~49 tokens)

Get the accessibility element tree of the current Simulator screen. Shows roles, labels, values, and positions of UI elements.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_set_location` (~66 tokens)

Set the simulated GPS location (latitude, longitude). Useful for testing location-based features.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `latitude` (number, required): Latitude (-90 to 90)
- `longitude` (number, required): Longitude (-180 to 180)

### `simulator_send_push` (~91 tokens)

Send a push notification to an app. Provide the full APNs payload JSON (e.g., {"aps": {"alert": "Hello"}}).

Input parameters:

- `bundleId` (string, required): App bundle ID to receive the push
- `deviceId` (string): Device (default: booted)
- `payload` (object, required): Push notification JSON payload (e.g., {"aps": {"alert": "Hello"}})

### `simulator_set_clipboard` (~52 tokens)

Set text on the simulator clipboard. Useful for pasting content into apps.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `text` (string, required): Text to copy to simulator clipboard

### `simulator_add_media` (~56 tokens)

Add photos or videos to the simulator's camera roll from local file paths.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `filePaths` (array, required): Paths to photo/video files to add to camera roll

### `simulator_grant_permission` (~106 tokens)

Grant, revoke, or reset app permissions (camera, location, photos, contacts, microphone, etc.).

Input parameters:

- `action` (string, required): Permission action
- `bundleId` (string, required): App bundle ID
- `deviceId` (string): Device (default: booted)
- `service` (string, required): Permission service: all, calendar, contacts-limited, contacts, location, location-always, photos-add, photos, media-library, microphone, motion, reminders, siri

### `simulator_set_appearance` (~42 tokens)

Switch the simulator between light and dark mode.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `mode` (string, required): Appearance mode

### `simulator_override_status_bar` (~201 tokens)

Override the simulator status bar: set time, battery, signal bars, carrier name, network type. Use clear=true to reset.

Input parameters:

- `batteryLevel` (number): Battery level 0-100
- `batteryState` (string): Battery state
- `cellularBars` (number): Cellular signal bars 0-4
- `clear` (boolean): Set to true to clear all overrides
- `deviceId` (string): Device (default: booted)
- `networkType` (string): Data network type: wifi, 3g, 4g, lte, lte-a, lte+, 5g, 5g+, 5g-uwb, 5g-uc
- `operatorName` (string): Carrier/operator name
- `time` (string): Status bar time string (e.g., "9:41")
- `wifiBars` (number): WiFi signal bars 0-3

### `simulator_record_video` (~96 tokens)

Start recording the simulator screen to a video file. Use simulator_stop_recording to stop. Supports H.264 and HEVC codecs.

Input parameters:

- `codec` (string): Video codec (default: h264)
- `deviceId` (string): Device (default: booted)
- `display` (string): Display to capture (default: internal)
- `mask` (string): For non-rectangular displays, handle mask by policy

### `simulator_stop_recording` (~81 tokens)

Stop an active video recording and save the file.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `maxFrames` (number): Max number of key frames to extract (default: 3, max: 6)
- `savePath` (string): Optional: save the video file to this path instead of discarding it

### `simulator_navigate_back` (~59 tokens)

Navigate back in the current app. Sends Cmd+[ (standard back navigation). Works in Safari and apps with standard UINavigationController. Workaround for edge-swipe-back gesture limitation.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_icloud_sync` (~43 tokens)

Trigger iCloud sync on the device. Requires the device to be signed into an Apple ID.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_keychain` (~97 tokens)

Manipulate the device keychain: add root certificates, add certificates, or reset the entire keychain.

Input parameters:

- `action` (string, required): "add-root-cert" to add trusted root CA, "add-cert" to add certificate, "reset" to clear keychain
- `deviceId` (string): Device (default: booted)
- `path` (string): Path to certificate file (required for add-root-cert and add-cert)

### `simulator_set_content_size` (~62 tokens)

Set the preferred content size for Dynamic Type testing. Test your app with accessibility text sizes without changing device settings manually.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `size` (string, required): Preferred content size category for Dynamic Type testing

### `simulator_set_increase_contrast` (~59 tokens)

Enable or disable the Increase Contrast accessibility setting. Test how your app responds to high contrast mode.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `enabled` (boolean, required): Enable or disable Increase Contrast accessibility setting

### `simulator_location_scenario` (~104 tokens)

Run predefined GPS location scenarios (Freeway Drive, City Run, City Bicycle Ride). Simulates realistic movement patterns for testing location features.

Input parameters:

- `action` (string, required): "list" available scenarios, "run" a scenario, "clear" to stop
- `deviceId` (string): Device (default: booted)
- `scenario` (string): Scenario name (e.g., "Freeway Drive", "City Run", "City Bicycle Ride", "Apple")

### `simulator_location_route` (~81 tokens)

Simulate movement along a custom route with waypoints. Specify GPS coordinates and speed for realistic location testing.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `speed` (number): Speed in meters/second (default: ~walking speed)
- `waypoints` (array, required): Array of {lat, lng} waypoints to traverse

### `simulator_verbose_logging` (~58 tokens)

Enable or disable verbose device logging for deep debugging. Requires device reboot to take effect.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `enabled` (boolean, required): Enable or disable verbose logging (device reboot may be required)

### `simulator_install_app_data` (~62 tokens)

Install an .xcappdata package to replace the current app container contents. Useful for restoring test data snapshots.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `path` (string, required): Path to .xcappdata package to install

### `simulator_get_env` (~68 tokens)

Read an environment variable from the running simulator device (e.g., HOME, TMPDIR, PATH).

Input parameters:

- `deviceId` (string): Device (default: booted)
- `variable` (string, required): Environment variable name to read (e.g., "HOME", "TMPDIR", "PATH")

### `simulator_memory_warning` (~45 tokens)

Trigger a simulated memory warning. Apps will receive didReceiveMemoryWarning and can be tested for proper memory cleanup.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_biometric` (~53 tokens)

Set Face ID / Touch ID enrollment state. Test biometric authentication flows.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `enrolled` (boolean, required): Whether Face ID / Touch ID is enrolled

### `simulator_network_status` (~40 tokens)

Get the current network configuration inside the simulator — interfaces, IP addresses, DNS config.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_defaults_read` (~83 tokens)

Read UserDefaults values from inside the simulator. Inspect app preferences, feature flags, and configuration.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `domain` (string, required): Defaults domain (bundle ID like "com.apple.mobilesafari" or "NSGlobalDomain")
- `key` (string): Specific key to read (omit for all keys)

### `simulator_defaults_write` (~89 tokens)

Write UserDefaults values inside the simulator. Set feature flags, change app configuration, or inject test data.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `domain` (string, required): Defaults domain (bundle ID)
- `key` (string, required): Key to write
- `type` (string): Value type (default: string)
- `value` (string, required): Value to set

### `simulator_snapshot` (~66 tokens)

Capture a structured accessibility snapshot of the current screen — like Playwright's browser_snapshot. Returns roles, labels, values, and positions. PREFERRED over screenshots for understanding UI structure and targeting interactions. No vision model needed.

Input parameters:

- `deviceId` (string): Device (default: booted)

### `simulator_wait_for_element` (~167 tokens)

Wait for an accessibility element to appear on screen. Polls until the element matching your criteria (label, role, or text) appears, or times out. Like Playwright's browser_wait_for.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `label` (string): Wait for element with this accessibility label (case-insensitive partial match)
- `pollIntervalMs` (number): How often to check in milliseconds (default: 500)
- `role` (string): Wait for element with this role (e.g., "Button", "TextField", "StaticText")
- `text` (string): Wait for element containing this text in label or value
- `timeoutMs` (number): Max wait time in milliseconds (default: 10000)

### `simulator_element_exists` (~94 tokens)

Quick check: does an element matching your criteria exist on screen right now? Returns true/false. Useful for conditional logic.

Input parameters:

- `deviceId` (string): Device (default: booted)
- `label` (string): Search for element with this accessibility label (case-insensitive partial match)
- `role` (string): Search for element with this role
- `text` (string): Search for element containing this text

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/ethanackerman-git-preflight-ios-mcp/preflight-ios-mcp#diagnostics

## Score history

- 2026-08-03: 68
- 2026-08-02: 64
- 2026-08-01: 21
- 2026-07-31: 5
- 2026-07-30: 24
- 2026-07-28: 46
- 2026-07-27: 46

## Links

- npm package: https://www.npmjs.com/package/preflight-ios-mcp
- Socket report: https://socket.dev/npm/package/preflight-ios-mcp
- Repository: https://github.com/EthanAckerman-git/Preflight
- Changelog RSS feed: https://verifymcp.io/servers/ethanackerman-git-preflight-ios-mcp/preflight-ios-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/ethanackerman-git-preflight-ios-mcp/preflight-ios-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/ethanackerman-git-preflight-ios-mcp/preflight-ios-mcp
