// real WebKit · native touch · 46 agent tools
Playwright can’t render real iOS WebKit, and Apple’s simctl can’t tap. ios-sim-driver closes both gaps: full control of a real iOS device, Simulator or physical iPhone, for an AI agent or any script.
The problem
iPhone-only bugs never show up in CI. Headless Chromium can’t reproduce Safari’s -webkit-fill-available, 100dvh, the disappearing toolbar, or MSE/HLS playback; simctl, Apple’s own CLI, has no gesture API at all. Real iOS testing meant a person at a Mac, tapping a screen.
What it does
One engine, three surfaces: a CLI (bin/ios), an MCP server exposing 46 ios_* tools, and Claude Code skills with an /ios command. Tools and CLI verbs map 1:1 onto the same code path. An agent can tap, swipe, type, and pinch by accessibility label; dump the live accessibility tree; eval JavaScript inside genuine WebKit; spoof GPS; simulate push notifications; enroll Face ID; flip dark mode and Dynamic Type; and shoot App Store-ready screenshots behind the clean 9:41 status bar. Input verbs reuse one persistent Appium session; everything else goes straight through simctl.
- Node.js
- Appium 3
- XCUITest
- simctl
- devicectl
- MCP
Physical iPhones
v0.4.0 added --target device: app management through devicectl with no signing needed, plus input, accessibility, and screenshots through an auto-signed WebDriverAgent. Verified live on an iPhone 15 Pro running iOS 26.5, including a 1.78 MB accessibility-tree dump. Simulator-only features refuse cleanly on hardware.
Receipts
- ~1,250 lines of pure JavaScript, zero npm dependencies: no package.json, no node_modules. It shells out to Appium/XCUITest, simctl, and devicectl; the host needs only macOS, Xcode, and one global Appium install.
- 4 releases in 2 days (v0.1.0 through v0.4.0, June 2026); the MCP tool surface grew from 23 to 46; all 4 roadmap phases complete.
- In daily production: all 46 tools are registered globally in every Claude Code session on my build machine, defaulting to iPhone 17 Pro / iOS 26.5.
- The honest limit: the Simulator has no camera or mic. Camera flows use photo-library injection; live camera needs the physical-device path.
Outcome
It started as a ~140-line Safari-driving script built while hardening RanSynTV, an IPTV web app, then graduated into a standalone platform. Build once, prove cheaply, graduate what works. The source is on GitHub, private while it stabilizes; the rest of the shelf is public at github.com/RandomSynergy17 →.
