Skip to main content

Hand your iOS simulator to your agent. Claude-native MCP driver for iOS simulator testing — vision, taps, recordings.

Project description

simdrive

Hand your iOS simulator to your agent.

Claude-native 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 simdrive 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

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

Install

pip install simdrive

Requirements:

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

simdrive 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": {
    "simdrive": { "command": "simdrive" }
  }
}

Restart Claude Code. The 12 simdrive tools are now available.

Quickstart

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

Claude (using simdrive):
  → 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 (12 tools)

Tool Purpose
session_start Boot/find a sim, optionally launch an app
session_end End session (sim stays booted)
session_status Inspect active session(s)
observe Capture screenshot (returns file path), optional log tail
tap Click at screenshot pixel coordinate
swipe Drag from (x1,y1)→(x2,y2)
type_text Send keyboard input
press_key Hardware buttons (home, lock, siri, shake, return, etc.)
record_start Begin recording every action
record_stop Finalize recording.yaml
replay Re-execute a recording with SSIM drift detection
logs Tail simulator logs (NSPredicate filterable)

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 simdrive[dev]
pytest                          # 22 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-0.3.0a1.tar.gz (71.2 kB view details)

Uploaded Source

Built Distribution

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

simdrive-0.3.0a1-py3-none-any.whl (57.6 kB view details)

Uploaded Python 3

File details

Details for the file simdrive-0.3.0a1.tar.gz.

File metadata

  • Download URL: simdrive-0.3.0a1.tar.gz
  • Upload date:
  • Size: 71.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for simdrive-0.3.0a1.tar.gz
Algorithm Hash digest
SHA256 b4edf4f690b5768000484025ac3052dec76db4a597c461aaf593be4081e3bef5
MD5 7d07e7ac9ed8ec624428c586baa84f6d
BLAKE2b-256 a0781fd9ce522f7a3c60765ddd8fc00903afe7c2510d2abbfbc32ef6c92033a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for simdrive-0.3.0a1.tar.gz:

Publisher: simdrive-publish.yml on SyncTek-LLC/specterqa-ios

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simdrive-0.3.0a1-py3-none-any.whl.

File metadata

  • Download URL: simdrive-0.3.0a1-py3-none-any.whl
  • Upload date:
  • Size: 57.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for simdrive-0.3.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 16e6e61bb9fc4084a31814ff922076975cfe9a4a5781a0083b5fe55e426181c2
MD5 26930fa474730126582b8232976d7dad
BLAKE2b-256 1eae40d38cd75c485be251edcba8875b09975105555a1f46c78057b72d4c827a

See more details on using hashes here.

Provenance

The following attestation bundles were made for simdrive-0.3.0a1-py3-none-any.whl:

Publisher: simdrive-publish.yml on SyncTek-LLC/specterqa-ios

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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