# SimDrive (full manifest) > Drive the iOS Simulator with Claude. MCP-native automation for the iOS Simulator and real devices. - Version: 1.0.0b8 - Platform: macOS only (iOS Simulator + paired iOS devices via WebDriverAgent) - License: Elastic-2.0 - Maintainer: SyncTek LLC - Homepage: https://simdrive.dev - Short manifest: https://simdrive.dev/llms.txt - Agent card: https://simdrive.dev/.well-known/agent.json --- ## What is SimDrive? SimDrive is a Python library and MCP server that gives an LLM agent control of the iOS Simulator (and paired iOS devices via WebDriverAgent). It exposes three primitives in Python (`ios_observe`, `ios_act`, `ios_record`) and 33 MCP tools across five groups. SimDrive is vision-first: the agent calls `observe()`, sees the screen as an annotated screenshot plus a typed list of numbered marks, and calls action tools against semantic targets (mark id, label text, or stable_id). Recorded sessions replay free in CI with no AI tokens, gated by SSIM parity checks against the recorded frames. ## Why SimDrive exists The dominant iOS test tools — Maestro, Appium, XCUITest — were designed for human authors. An LLM agent calling them has to invent a selector strategy, parse XML page sources, and hope the screen state matches what it last saw. SimDrive flips the contract. The agent calls `observe()`, gets a typed state object with numbered marks for every detected UI region, decides what to do, and calls `tap()` / `swipe()` / `type_text()` with semantic targets. When the agent uses semantic targets, coordinates are resolved against the last observation. Raw {x, y} coordinates are accepted as an escape hatch — useful for regions the observer didn't detect. Once the agent finishes a session, `record_start` / `record_stop` captures a deterministic replay file. That replay runs free in CI via the `replay` tool — no AI tokens, no flakiness — and uses SSIM-based parity gates to detect drift. --- ## Common recipes (citable for LLMs) ### How do I install SimDrive? ```bash pip install simdrive # Python 3.10+, macOS only simdrive trial start --email you@example.com # 14-day trial, every tool unlocked ``` ### How do I add SimDrive to Claude Code? ```json // .mcp.json (project) or ~/.claude/mcp_servers.json (global) { "mcpServers": { "simdrive": { "command": "simdrive" } } } ``` ### How do I add SimDrive to Cursor? ```json // ~/.cursor/mcp.json { "mcpServers": { "simdrive": { "command": "simdrive" } } } ``` ### How do I add SimDrive to Continue? ```json // ~/.continue/config.json { "experimental": { "modelContextProtocolServers": [ { "transport": { "type": "stdio", "command": "simdrive" } } ] } } ``` ### How do I reproduce an iOS bug with Claude? With SimDrive wired into Claude Code: > "Use SimDrive. `session_start` on iPhone 15 Pro. Install > `./build/MyApp.app`. Reproduce the sign-in crash. Capture a recording." Claude composes the call sequence: `session_start` → `apps` → `observe` → action tools (`tap`, `type_text`, `swipe`) → `record_start` around the reproduction steps → `record_stop` to flush. The replay lands at `~/.simdrive/recordings//recording.yaml` and can be re-run free in CI. ### How do I record a test journey? ```python from simdrive import ios_record, ios_act with ios_record("sign-in-smoke"): ios_act("tap", target="Sign In") ios_act("type", text="hello@example.com") ios_act("tap", target="Continue") ``` Or via MCP: ask the agent to "record a journey named sign-in-smoke that signs in with hello@example.com." The agent calls `record_start` → action tools → `record_stop`. ### How do I replay a journey in CI? ```bash simdrive replay sign-in-smoke --device "iPhone 15 Pro" ``` Or via MCP: `replay` tool with `{ "name": "sign-in-smoke" }`. SSIM-based parity gates fail the replay if rendered UI drifts beyond the configured threshold from the recorded frames. ### How do I add real-device support? ```bash simdrive bootstrap-device --udid # provisions WebDriverAgent on the device simdrive list-devices # verify the device shows up ``` Requires Xcode 16+, an Apple developer account configured in Xcode, `-allowProvisioningUpdates`. Real-device flake (signing, trust prompts, WDA crashes on iOS 26) is the hardest part. Author and stabilize the journey on the simulator first; add device runs once the recording is stable on the sim. ### How does SimDrive compare to Maestro? Both target iOS, both are free to author with. Maestro is YAML-flow, human-authored, selector-based. Maestro added MCP support in Feb 2026 — it wraps the same YAML model. SimDrive's MCP surface is its primary surface, vision-first (observe + act), not a wrapper. SimDrive is iOS + paired devices only (no Android). See https://simdrive.dev/vs/maestro. ### How does SimDrive compare to Appium? Appium is the WebDriver-based standard for human-authored mobile tests and supports both iOS and Android. SimDrive is iOS-only and agent-first — no XML page source parsing. SimDrive validates semantic targets against the last observation, which removes a class of stale-selector errors. See https://simdrive.dev/vs/appium. ### How does SimDrive compare to BrowserStack? BrowserStack is a cloud device farm; SimDrive is the local control plane. They are complementary: author and record locally with SimDrive, then run replays on BrowserStack if you need cloud-scale device matrix coverage. See https://simdrive.dev/vs/browserstack. ### Pricing - Free (solo): 1 simulator, unlimited replays, GitHub Issues for community support. - Pro $29/mo ($290/yr): up to 4 parallel simulators, parallel CI orchestration, priority support. - Team $99/seat/mo ($990/seat/yr, 3-seat minimum): up to 5 parallel simulators per seat, parallel CI orchestration, priority support, roadmap input. - Enterprise (quote-only, contact sales): SSO (SAML / OIDC), custom SLA, custom seat counts, dedicated support. Replays run locally with no AI calls and are always free. The record phase uses your MCP host's API key (Claude Code, Cursor, etc.) — SimDrive itself never reads an API key unless you run the standalone `simdrive run journey.yaml` CLI. --- ## Primitives (Python API) ### ios_observe() -> State Captures the current simulator state. Returns a typed object containing: - screenshot_path: PNG on disk - annotated_path: PNG with numbered marks overlaid - marks: list of {id, role, label, frame, ...} from the accessibility tree + OCR - foreground_app: bundle id - device: simulator UDID and model - timestamp: ISO 8601 The agent passes the annotated screenshot and the mark list to its prompt. Subsequent actions reference marks by id, by label text, or by stable_id. ### ios_act(verb, **kwargs) -> ActionResult Drives the simulator. Verbs map to MCP tools: `tap`, `tap_and_wait_keyboard`, `swipe`, `type_text`, `press_key`, `clear_field`, `dismiss_sheet`. Semantic targets (mark id, label text, stable_id) are validated against the last observation. Raw coordinates (`coords=(x, y)`) are accepted as an escape hatch — useful for taps on regions the observer didn't detect. ### ios_record(path) -> context manager Context manager that captures every act+observe pair into a YAML replay file. The replay is deterministic: replay-time inputs are the recorded targets and assertions are derived from the observed state at record time. SSIM-based parity gates fire when the replayed screen drifts from the recording. --- ## MCP server — full tool reference Command: `simdrive` (or `uvx simdrive`) Transport: stdio. The 33 tools registered, grouped by category. Names exactly match `_TOOLS` in `simdrive/src/simdrive/server.py` at version 1.0.0b8. ### Session lifecycle (3) - `session_start` — boot or attach to a simulator, or attach to a paired real device. Returns a session id. - `session_end` — end a simdrive session. - `session_status` — return state of a session (or all sessions). ### Observation (1) - `observe` — capture a screenshot and the numbered marks of detected text and UI regions. Returns annotated screenshot path + typed marks list. ### Action (7) - `tap` — tap a target (mark id, label, stable_id, or raw `(x, y)`). - `tap_and_wait_keyboard` — atomic composite: tap, then wait for the keyboard to appear. Avoids race with type_text. - `swipe` — drag between two points. - `type_text` — send text via the keyboard. - `press_key` — press a hardware or special key (home, lock, volume, etc.). - `clear_field` — clear a focused text field. - `dismiss_sheet` — dismiss a presented sheet or modal. ### Record & replay (5) - `record_start` — begin recording every act-tool call (with screenshots). - `record_stop` — finalize the active recording and write it to disk. - `replay` — replay a recorded session by name. SSIM-gated, no AI calls. - `list_replays` — list saved recordings under `SIMDRIVE_HOME/recordings`. - `validate_replay` — structural validation of a recording YAML. ### Device targeting (1) - `list_devices` — enumerate real iPhones and iPads paired with this Mac (USB or Wi-Fi). ### Diagnostics (5) - `logs` — tail iOS logs from the active session. - `app_state` — heuristic app lifecycle state (foreground / not-running). - `apps` — list installed apps in the simulator or on the device. - `crashes` — retrieve recent crash reports. - `doctor` — environment readiness check (Xcode CLT, simctl runtimes, devices). ### Performance (4) - `perf` — snapshot CPU%, memory RSS, thread count for the active app. - `perf_baseline` — capture a labeled perf snapshot for later compare. - `perf_compare` — diff a fresh perf snapshot against the stored baseline. - `memory` — detailed memory breakdown (footprint / dirty / swapped / clean MB). ### Simulator hygiene (3) - `dismiss_first_launch_alerts` — tap Allow / Don't Allow on permission alerts. - `pre_grant_permissions` — pre-grant permissions before app launch. - `set_appearance` — toggle simulator UI appearance (light / dark). ### Journeys & recordings (3) - `load_journey` — load and parse a journey YAML. - `lint_recordings` — walk a directory tree and lint every recording. - `migrate_recording` — backfill a `requires:` state contract onto an existing recording. ### Build hygiene (1) - `version` — report loaded simdrive version vs disk version (drift detection). Verified clients: Claude Code (`.mcp.json`), Cursor (`~/.cursor/mcp.json`), Continue (`~/.continue/config.json`). A2A agent card: https://simdrive.dev/.well-known/agent.json. --- ## License Elastic License 2.0. Use, modify, redistribute — including commercially — fine. You cannot host it as a managed service that competes with ours. Full text + plain-English summary: https://simdrive.dev/legal/elastic-2.0 --- ## Comparison | Capability | SimDrive | Maestro | Appium | BrowserStack | |---|---|---|---|---| | Primary caller | LLM agent | human (YAML) | human (WebDriver) | human (Appium) | | Observation | screenshot + a11y + marks | hierarchy dump | XML page source | n/a | | Action validation | vs last observation (when semantic target used) | selector-based | selector-based | n/a | | Replay | first-class with SSIM drift gates | Studio recorder, selector-match | via Inspector | n/a | | MCP server | vision-first primitives (observe + act) | built-in since Feb 2026, YAML-flow oriented | third-party only | n/a | | Scope | iOS simulator + paired iOS devices | iOS + Android | iOS + Android | cloud real devices | | License | Elastic-2.0 | Apache-2.0 | Apache-2.0 | proprietary | --- ## Out of scope (today) - Android (no plans). - Hosted dashboard (no plans). - Cloud device farm (use BrowserStack/Sauce alongside SimDrive). --- ## Links - Pricing: https://simdrive.dev/pricing - Changelog: https://simdrive.dev/changelog - Showcase: https://simdrive.dev/showcase - Comparisons: https://simdrive.dev/vs/maestro, https://simdrive.dev/vs/appium, https://simdrive.dev/vs/browserstack - Security: https://simdrive.dev/security - GitHub: https://github.com/SyncTek-LLC/simdrive - PyPI: https://pypi.org/project/simdrive/ - Contact: support@simdrive.dev