Skip to main content

SimDrive — MCP-native iOS simulator driver. Vision-first, agent-driven.

Project description

SpecterQA for iOS

Hand your iOS simulator to your agent.

SpecterQA for iOS (simdrive internally) is an MCP server for driving iOS simulators. Vision-first. No XCTest, no accessibility-tree query, no daemons. Your agent looks at a screenshot, picks a pixel, and SpecterQA taps it.

Why

You stay in your editor. Your agent drives the sim in the background. Taps don't steal focus, your keyboard doesn't get hijacked.

Automating an iOS simulator from inside an LLM session has historically required:

  • A Swift XCTest runner that breaks every Xcode release
  • An accessibility tree your agent has to mentally reconstruct from JSON dumps
  • Bespoke selectors (label:"Sign in") that drift with every UI change
  • Watchdogs killing your runner mid-test

SpecterQA for iOS replaces all of that with: screenshot in, click out. Your agent already understands screenshots — the LLM is the selector engine.

Install

pip install specterqa-ios

Requirements:

  • macOS with Xcode + iOS Simulator (for native HID input)
  • A booted simulator. SpecterQA will use a running one or boot one for you.

SpecterQA runs in the background by default — taps and keystrokes go straight to the simulator without raising its window or stealing your keyboard focus. Verify via session_status (mode: "background").

Wire into Claude

Add to your .mcp.json:

{
  "mcpServers": {
    "specterqa-ios": { "command": "specterqa-ios" }
  }
}

Restart Claude Code. The 29 SpecterQA MCP tools are now available.

Existing .mcp.json configs with command: simdrive keep working — both console scripts (specterqa-ios and simdrive) point at the same server.

Quickstart

You: open Settings on iPhone 17 Pro and turn on Airplane Mode.

Claude (using SpecterQA):
  → session_start({device: "iPhone 17 Pro", app_bundle_id: "com.apple.Preferences"})
  → observe()                              # screenshot + annotated copy with numbered marks
  → tap({text: "Airplane Mode"})           # by visible text
  → observe()                              # sees the toggle
  → tap({mark: 12})                        # by mark number from the annotation
  → observe()                              # confirms it's green

You can also tap({x, y}) if you have specific pixel coords (great for replay). Pick whichever is lowest-friction per call:

Form Use it for
{text: "..."} Buttons, labels, anything with visible text
{mark: N} When the agent has just looked at the annotated screenshot
{x, y} Replays, deterministic UI tests, icons without text

That's the whole loop. No selectors. No waits. No XCTest.

Tool surface (29 MCP tools)

Group Tools
Lifecycle (3) session_start, session_end, session_status
Observe (1) observe
Act (5) tap, swipe, type_text, press_key, clear_field
Record/Replay (5) record_start, record_stop, replay, list_replays, validate_replay
Logs (1) logs
Performance (4) perf, perf_baseline, perf_compare, memory
Diagnostics (5) doctor, app_state, apps, crashes, list_devices
Robustness (4) dismiss_first_launch_alerts, pre_grant_permissions, set_appearance, dismiss_sheet
Version (1) version

Coordinates are always in screenshot pixel space — same pixels the agent sees in the most recent observe.

Recording + replay

record_start({name: "checkout-flow"})
  ... agent does the flow naturally, calling tap/swipe/type_text ...
record_stop()  # writes ~/.simdrive/recordings/checkout-flow/recording.yaml

Later:

replay({name: "checkout-flow", on_drift: "halt"})

Each step is gated on visual similarity: if the live screen has drifted from the recorded pre-screenshot, the replay halts (halt), warns and continues (warn), or proceeds blind (force). The recording is a self-contained YAML+PNG bundle you can commit to your repo.

Testing

pip install specterqa-ios[dev]
pytest                          # 91 unit tests, no sim required
pytest -m live                  # 26 live tests against TestKitApp

Live tests boot a fresh TestKitApp session per test and exercise every tool: tap by text/mark/coords, type into focused fields, swipe-to-scroll, alert-while-focused dismissal (the iOS 26 case that defeated v15), record + replay with drift detection.

What this isn't

  • Not a real-device tool. v0.1 is simulator-only. Real device support via idb/devicectl is on the roadmap.
  • Not a CI replacement (yet). Designed for interactive Claude sessions; CI integration is a follow-up.
  • Not a fork of XCTest. We deliberately avoid Apple's testing stack to stay durable across Xcode releases.

License

MIT. Built by SyncTek.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simdrive-1.0.0a4.tar.gz (222.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simdrive-1.0.0a4-py3-none-any.whl (161.5 kB view details)

Uploaded Python 3

File details

Details for the file simdrive-1.0.0a4.tar.gz.

File metadata

  • Download URL: simdrive-1.0.0a4.tar.gz
  • Upload date:
  • Size: 222.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for simdrive-1.0.0a4.tar.gz
Algorithm Hash digest
SHA256 2c731a8314b9eb0c6c20d56b2c06d8175cc2cc909fc3dfb724adcdbe3d87455c
MD5 146a12e8f93b19161526921b67498fa6
BLAKE2b-256 51aa7c844ae4406f3866d1246e321501561b3ccfccce0f1deaf40b8669c9d82b

See more details on using hashes here.

File details

Details for the file simdrive-1.0.0a4-py3-none-any.whl.

File metadata

  • Download URL: simdrive-1.0.0a4-py3-none-any.whl
  • Upload date:
  • Size: 161.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for simdrive-1.0.0a4-py3-none-any.whl
Algorithm Hash digest
SHA256 c255201ffe42d5993455d703c11c2b7a15f0d60109c5d378e26c6a6dc3753096
MD5 a3913076a28cb2d0f697b16e213ff05d
BLAKE2b-256 fdb5d18b7960533cd296a595775a8d09c36dd0bc93257fbe7064bddacdc9ef33

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page