Stream, drive and inspect iOS Simulators from a browser, a terminal or an AI agent.
SimTool runs a local server beside a simulator and gives you:
- A browser viewer — the live screen with touch, keyboard, rotation, screenshots and recordings, and an inspector beside it: Network, Logs, State, Accessibility, Device, Tests and Activity.
- A CLI for agents and scripts — every action with
--json: taps and gestures, the accessibility tree, logs, network, device settings, app build and launch — and a bad network (3G, Edge, 100% loss, …) for the app on one simulator, without touching the Mac's. - YAML tests — steps that wait for the accessibility tree instead of sleeping, each run recorded with its video, network, logs and state per step.
- Libraries for your app —
SimToolNetworkLoggerreports calls and streams of any protocol (HTTP, gRPC, WebSocket, …), andSimToolStateLoggerstreams@Observablemodel state. Both are for debug builds. - An HTTP API — what the viewer and the CLI use, open to your own tools.
Apple silicon (arm64), macOS 14 or newer, Xcode with simulator runtimes.
brew tap platacard/simtool
brew trust platacard/simtool
brew install simtool
simtool doctorOr pin the version per project with mise:
mise use github:platacard/SimTool@1.0.0. Manual downloads, checksums and
prerequisites: docs/install.md.
In an app's repository:
simtool init # .simtool/config.yml: simulator, app and build; offers the agent skills
simtool run --web # build, install and launch the app, then open the viewerAny simulator, without a project:
simtool devices --json
simtool serve --device "iPhone 17 Pro" --webThen drive it from a terminal, a script or an agent:
simtool input tap --label Continue --json
simtool ax tree --flat --labeled
simtool logs tail --app com.example.MyApp --lines 20 --json
simtool test run .simtool/tests/login.ymlLink the libraries in debug builds, pinned to the release of your CLI:
.package(url: "https://github.com/platacard/SimTool.git", exact: "1.0.0"),import SimToolNetworkLogger
let logger = SimToolNetworkLogger.resolved() // nil unless SimTool armed the app
logger?.instrument(URLSessionConfiguration.default) // URLSession traffic
let chat = logger?.startStream(.websocket, url: socketURL)
chat?.received(.text(json), channel: "chat:1") // and any other protocol, call or streamsimtool run arms the loggers for the app it launches. See
the network logger SDK and
the model state inspector.
- The viewer and the server — the viewer, its tabs, the processes and simulators SimTool holds
- Automation from the CLI — input, accessibility, logs, network, settings
- Tests and sessions — YAML tests, verdicts, evidence, sharing
- Building and launching apps — builds, caching, Xcode over MCP, launch arguments
- The network logger SDK
- Model state inspector
- Project config,
runandopen - HTTP API
- Install and releasing
Two SwiftPM packages: the root vends the app libraries, Tool/ builds the CLI.
swift build --package-path Tool
swift run --package-path Tool simtool doctor
swift test && swift test --package-path Tool