Introduction
Device automation for mobile apps, from a shell or an AI agent.
Karagöz drives an Android emulator, an Android phone, an iOS simulator or an iPhone, from your terminal or from an AI agent. Each command does one thing, like taking a screenshot or tapping a button, and answers with one line of JSON.
Early development. Not on npm yet: install it from source.
How it works
Section titled “How it works”You run a command and read one line back:
karagoz tap --text Chrome{"device":"emulator-5554","x":667.5,"y":2002.5,"element":{"class":"android.widget.TextView","text":"Chrome","contentDesc":"Chrome","clickable":true,"longClickable":true,"focusable":true,"bounds":[581,1905,754,2100]}} exit 0That line is the command’s result, and the exit code is 0. When a command fails, the line is {"error":{"code":"<CODE>","message":"<text>"}} and the exit code is 1. A program tells failures apart by error.code; the message is for people and can change.
The commands, their flags and their output are the same on all four targets. An AI agent gets them through karagoz mcp, an MCP server whose 15 tools return the line the CLI prints.
Why Karagöz
Section titled “Why Karagöz”adb, simctl and devicectl run the command; Karagöz tells you what the command actually did.
- What happened, as a code.
simctlanddevicectlreport success for uninstalling an app that is not there. Karagöz checks first and returnsAPP_NOT_FOUND. A refused install isINSTALL_FAILED, with the platform’s own code inreason. - The accessibility tree first. To see the screen, read
ui-treebefore taking a screenshot. The tree is text a program can search, costs a few hundred to a few thousand tokens, and gives the bounds needed to tap. A screenshot is saved to disk and returned as a path. - It installs only what you ask. Nothing goes on a device by itself:
installinstalls only the app you pass it, andinstall-runneronly Karagöz’s runner.
What it is not
Section titled “What it is not”- Not a test framework. No assertions, no test runner, no recorded flows, no retry policy, no reports.
tap --timeoutwaits for a node to appear; it never repeats an action. - Not a design comparison tool. Figma diffing, measurement and reporting belong a layer above. Karagöz produces the raw input and the metadata to measure it with, but does not interpret it.
What do you want to do?
Section titled “What do you want to do?”- Get startedInstall, check your setup, run your first commands
- Check what a target needsAndroid, iOS simulator, iPhone
- Install itFrom source, in 6 commands
- Connect an AI agentClaude Code, Codex, Cursor, VS Code, Claude Desktop
- Find a commandAll 15, one page each
- Look up an error codeWhat each code means and what returns it
Commands
Section titled “Commands”- devices
- List connected devices
- screenshot
- Save a full-resolution PNG and return its path with scale metadata
- ui-tree
- Return the accessibility tree of the focused window
- tap
- Tap or long-press a point, or a node found by text or id
- swipe
- Swipe between two points
- text
- Type text into the focused field
- key
- Press a key
- install
- Install or replace an app
- launch
- Start an app as its launcher icon does
- terminate
- Stop every process of an app
- uninstall
- Remove an app
- logs
- Read the device log
- doctor
- Report which adb and Xcode karagoz uses
- install-runner
- Build karagoz's runner and install it on an iPhone
- uninstall-runner
- Remove karagoz's runner from an iPhone
Every command except devices and doctor works on one device. When more than one is listed, pick it with --device <id or name> or KARAGOZ_DEVICE: Device selection. karagoz mcp starts the MCP server on stdio.