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.0a3.tar.gz (210.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.0a3-py3-none-any.whl (157.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: simdrive-1.0.0a3.tar.gz
  • Upload date:
  • Size: 210.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.0a3.tar.gz
Algorithm Hash digest
SHA256 cda54906578bdbce3a2094108e5f4706f56d493b9e0cd74dc3ebda088893a08d
MD5 1614495acf2ac7893840724b3037fb66
BLAKE2b-256 cfe20b288c552dd7574a2be066af362d9a6cc6a22130326475ab2c3f3614ff24

See more details on using hashes here.

File details

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

File metadata

  • Download URL: simdrive-1.0.0a3-py3-none-any.whl
  • Upload date:
  • Size: 157.7 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.0a3-py3-none-any.whl
Algorithm Hash digest
SHA256 f1f785a0a270fffb2ad4d25c2303023bb7c6c12aaaf394afbe66767f36044844
MD5 0284bb41c37aa5d7a2847afb99f3151d
BLAKE2b-256 94176eb43db615760ec2f09ba7a21fa9d8cc6bf1de1d60c7ead36b912b0dd0cd

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