CLI & MCP Server
Give your agent a real iOS simulator.
grantiva builds your app, boots a device, taps, types, swipes, screenshots, reads the accessibility tree, and diffs the result against an approved baseline. Every one of those is also an MCP tool, so an AI agent can do it too.
No Appium server. No Maestro install. No Accessibility permission to grant. Headless on CI.
$ brew install grantiva/tap/grantiva $ grantiva doctor $ grantiva init
macOS 15+, Xcode 16+. MIT licensed. No Grantiva account required for local use.
One binary
The dependency list is empty.
Most iOS UI automation asks you to install a server, grant a permission, and hope CI agrees. This one is a Homebrew formula and an Xcode you already have.
UI automation runs through GrantivaAgent — a WebDriverAgent shipped inside the CLI binary and extracted by grantiva runner install. Nothing separate to install, version, or keep alive. Your existing Maestro flow files still run; the tool that ran them does not.
Nothing to approve in System Settings, nothing to re-approve after an OS update, and nothing that silently breaks a CI runner. It works the same on your Mac and on a fresh macOS-15 GitHub runner.
Capture, compare, and approve baselines locally in .grantiva/baselines/ with no account at all. Sign in only for grantiva ci run — shared baselines across machines and results posted to your PRs.
Commands
Everything supports --json.
Which is the whole point. A command that only prints for humans is a command an agent has to guess at.
Build and run
grantiva buildBuild the app for a simulator using xcodebuild.
grantiva build installBuild and install the app on a simulator, then optionally launch it. Use --no-launch to seed the data container first.
grantiva runRun Maestro-compatible flows against a simulator. Reports step pass/fail and screenshots the failure.
grantiva ci runThe full pipeline: capture screenshots, compare against baselines, upload results.
Visual regression
grantiva diff captureNavigate to every configured screen and capture screenshots.
grantiva diff compareDiff current captures against baselines — pixel plus CIE76 perceptual color distance.
grantiva diff approvePromote the current captures to baselines.
Agent-native
grantiva mcpStart the MCP server for AI agent integration. Speaks MCP over stdio.
grantiva hierarchyDump the UI hierarchy of a booted simulator without relaunching the app. XML or JSON.
grantiva runner startStart GrantivaAgent and keep it alive for interactive use.
grantiva recordRecord a simulator and extract PNG frames at exact requested timestamps.
Simulators and setup
grantiva simulator ensureCreate or idempotently reuse an exact named simulator.
grantiva simulator teardownShut down every simulator owned by a ticket or session.
grantiva doctorCheck environment and dependencies.
grantiva initGenerate grantiva.yml in the current directory.
18 tools. One grantiva mcp.
grantiva_a11y_tree and grantiva_a11y_check are the two that change what an agent can do. Every other UI tool is a way to act; these are the way to see. The tree is the same hierarchy VoiceOver walks — so an agent that lands on an unexpected screen can read what is actually in front of it and pick a different element, instead of retrying a label that was never there.
UI automation
Every UI-mutating tool returns the updated accessibility tree in its response — so the agent sees what changed after each tap without having to ask again.
grantiva_screenshotTake a screenshot of the iOS simulator. Returns a base64-encoded PNG image.
grantiva_tapTap a UI element by accessibility label or by coordinates.
grantiva_swipeSwipe on the simulator screen.
grantiva_typeType text into the currently focused field.
grantiva_a11y_treeGet the current accessibility tree — every element with its label, type, frame, and state, as JSON.
grantiva_a11y_checkAudit the current screen for missing labels on interactive elements and tap targets smaller than 44pt.
Build and test
grantiva_buildBuild via xcodebuild. Returns success status, duration, warnings, and errors.
grantiva_runBuild, install, and launch the app on the simulator.
grantiva_testRun the test suite via xcodebuild test. Returns pass/fail counts and output.
Simulators
grantiva_sim_listList available simulators with name, UDID, state, runtime, and availability.
grantiva_sim_bootBoot a simulator by name or UDID.
grantiva_sim_ensureCreate or idempotently reuse an exact named simulator, optionally booting it to readiness.
grantiva_sim_deleteDelete one simulator by its exact name or UDID.
Context and scripting
grantiva_contextReport the loaded grantiva.yml, the booted simulator, the Xcode version, and the runner session status. Call this first.
grantiva_scriptRun a batch of UI actions in sequence — tap, tap_xy, swipe, type, wait — and return the final accessibility tree.
Visual regression
grantiva_vrt_captureCapture screenshots for every configured screen.
grantiva_vrt_compareDiff current captures against baselines. Returns pixel and perceptual metrics per screen.
grantiva_vrt_approvePromote captures to baselines.
Two resources, with subscriptions
The server also publishes grantiva://hierarchy (the view hierarchy as JSON) and grantiva://screenshot (the current screen as a PNG). After a tap, swipe, type, or script call, the server emits a resource-updated notification for the hierarchy — a subscribed client refreshes its picture of the screen on its own.
Setup
Two minutes to a wired-up agent.
The server speaks MCP over stdio, so you normally never run it by hand — your MCP client launches it for you. It reads grantiva.yml from the working directory, which is how the build and VRT tools learn your scheme, simulator, and bundle ID.
Commit it for the whole team
A project-scoped .mcp.json at your repo root gives everyone the same tools.
UI tools need a live session
Run grantiva runner start --detach before the agent starts tapping. If no session is alive, the UI tools fail gracefully rather than taking the server down — the build, simulator, and context tools keep working.
Claude Desktop needs an absolute path
It does not inherit your shell PATH. which grantiva will tell you where Homebrew put the binary.
$ claude mcp add grantiva -- grantiva mcp{
"mcpServers": {
"grantiva": {
"command": "grantiva",
"args": ["mcp"]
}
}
}{
"mcpServers": {
"grantiva": {
"command": "/usr/local/bin/grantiva",
"args": ["mcp"],
"cwd": "/Users/you/Developer/MyApp"
}
}
}Screenshot every screen. Diff it. Block the PR.
Describe your screens in grantiva.yml, and the CLI boots the simulator, builds, installs, navigates to each one, captures it, and compares against the approved baseline — pixel difference plus CIE76 perceptual color distance, so an anti-aliasing shift does not read as a regression.
Maestro flows work as-is
Existing .maestro flows are auto-detected and parsed — tapOn, inputText, assertVisible, swipe, runFlow, takeScreenshot. No rewrite.
GitHub Check Runs
grantiva ci run posts before/after diffs to the pull request as a Check Run.
Split build and test
--app-file consumes a pre-built .app or .ipa from a CI artifact, so the build job and the visual job can be separate.
Local baselines, no account
diff capture, diff compare, diff approve all work against .grantiva/baselines/ on your machine.
scheme: MyApp simulator: iPhone 16 bundle_id: com.example.myapp screens: - name: Home path: launch - name: Settings path: - tap: "Profile" - tap: "Settings" diff: threshold: 0.02 perceptual_threshold: 5.0
Install it now. Decide about the rest later.
The CLI is free and needs no account. When you want shared baselines, PR checks, attestation, or feature flags, the rest of the platform is already wired to the same project.
macOS 15+, Xcode 16+. Source on GitHub.