Skip to content

๐Ÿงฐ Tools

Every tool works from the CLI (bunx @kaeawc/auto-mobile --cli <tool>), MCP, or the daemon HTTP endpoint โ€” same names, same arguments.

๐Ÿ“– Full arguments: the registered schema (schemas/tool-definitions.json) or automobile:tools. Availability varies by platform and feature gates.

๐Ÿท๏ธ Tool discovery metadata

  • ๐Ÿ“‹ tools/list entries carry a human-readable title and SDK ToolAnnotations.
  • ๐Ÿ›ก๏ธ Hints are untrusted client guidance, never authorization.
  • ๐Ÿ—‚๏ธ Classification lives in src/server/toolAnnotations.ts.
  • ๐Ÿ”€ Mixed-action tools take the conservative union of all supported actions.
  • ๐Ÿ“ฆ The wire omits default readOnlyHint: false, idempotentHint: false, and openWorldHint: true.
  • ๐Ÿ“– Read-only tools omit the meaningless destructive and idempotent hints.
  • ๐ŸŽ›๏ธ Controls always declare destructiveHint explicitly.
  • ๐Ÿ”‘ Metadata is independent of deviceReadOnly dispatch and ownership enforcement.
  • ๐Ÿงช readOnlyHint follows deviceReadOnly, except tools that also write host state (compareScreenshot record mode).

๐Ÿ” Shared options

  • ๐Ÿ”‘ sessionUuid โ€” run on a held device session (device tools)
  • ๐Ÿ’ก keepScreenAwake โ€” wake and keep a physical Android device awake (default on at session setup)
  • ๐Ÿชž raw / project (skeleton default, full) / includeExtras โ€” observation output on action tools
  • ๐Ÿ”— resourceLink โ€” getLogs, exportPlan, and videoRecording stop: return the complete result as an automobile:tool-output resource and a resource_link block, keeping only success, error, and the result’s required fields (a stop’s action, count, recordings, each bounded) inline (default off, inline)
  • ๐Ÿ“ฑ deviceId โ€” target a device explicitly on reads

Reading a device you do not own (deviceId)

A read never writes settings on a device another session holds. A sessionless read of an unheld running device may ready it (install CtrlProxy / runner) to answer. See which read tools ready an unheld device.

๐Ÿ‘€ Observe & navigate

Tool What it does
๐Ÿ“ธ snapshotOf Save a PNG crop of an element or screen rectangle
๐Ÿ†š compareScreenshot Record or compare a named screenshot baseline
๐Ÿ‘๏ธ observe Read the current screen, hierarchy, and screenshot
๐ŸŽฏ hitTest Preview what a tap at a point would hit, without tapping
๐Ÿงญ explore Automatically explore app to build navigation graph
๐Ÿ—บ๏ธ navigateTo Navigate to screen using navigation graph
๐Ÿ•ธ๏ธ getNavigationGraph Get navigation graph for debugging
๐Ÿ”Ž identifyInteractions Suggest likely interactions
๐Ÿงช prototype Show agent-authored UI on the device
๐Ÿ”ฆ highlight Draw a red hand-drawn circle around a UI element

๐Ÿ‘† Interact

Tool What it does
๐Ÿ“ tapAt Tap, long press, or double tap at screen coordinates in native, normalized, or percent units
๐Ÿ‘† tapOn Tap an element by text, id, or test tag
๐Ÿค tapAny Tap any clickable element; scope with container or scrollableContainer
๐Ÿ‘‰ swipeOn Swipe/scroll on screen or elements
โ†”๏ธ swipeAt Swipe between two screen points
๐Ÿซณ dragAndDrop Drag and drop element
ใ€ฐ๏ธ dragPath Drag a finger along a timed path
๐Ÿ–ฑ๏ธ hoverAt Hover a stylus or mouse over a path with no contact (Android)
๐ŸคŒ pinchOn Pinch to zoom
๐Ÿ–๏ธ multiTouch Simultaneous 2-5 finger tap, long press, or swipe at a screen point
โŒจ๏ธ sendKeys Execute ordered typing, clear, raw-key, and semantic IME commands
๐Ÿงญ focusNavigate Move D-pad focus to an element on Android TV; stops focused, max_steps or stuck
๐ŸŽ›๏ธ setUIState Set multiple form fields by desired state
๐Ÿ“ selectAllText Select all text in focused input
๐Ÿ”˜ pressButton Press a device or navigation button
โŒจ๏ธ keyboard Open, close, detect, or switch the keyboard / IME
๐Ÿ“‹ clipboard Clipboard operations (copy/paste/clear/get)
๐Ÿ—ฃ๏ธ siri iOS: activate Siri with a phrase (off by default: setToolEnabled; needs the siriAndAppIntents service) (e.g. an App Shortcut), returns the observation; Android returns unsupported

๐Ÿ“ฆ Apps, files & data

Tool What it does
๐Ÿ—‚๏ธ listApps List installed apps
๐Ÿš€ launchApp Launch app by package name
๐Ÿ›‘ terminateApp Terminate app by package name
๐Ÿ’ฅ crashApp Intentionally crash a running app through the platform crash path
๐Ÿ”„ appLifecycle Background-kill an app to test state restoration (Android; iOS background and SIGKILL)
โฌ‡๏ธ installApp Install app on device (.apk, split APKs, .apks, .aab, .app, or .ipa)
๐Ÿ—‘๏ธ uninstallApp Uninstall app by package name or bundle identifier
๐Ÿ” inspectPackageSigning Fresh read of one app’s presence (installed/absent/unknown) and signing
๐Ÿ”— getDeepLinks Query app deep links
๐Ÿ“ฅ putAppFile Write files into a bounded logical storage target
๐Ÿงน resetAppLogs Reset named app log files
โš™๏ธ getPreference Read an Android system property, Android SharedPreferences key, or iOS UserDefaults key
โš™๏ธ setPreference Write a system property, SharedPreferences, or UserDefaults key
๐Ÿ—๏ธ deleteKeychainItem Delete one allowlisted app-owned iOS Keychain item (SDK opt-in, requires confirm)
๐Ÿ”‘ setKeyValue Set app key-value storage entry
โŒ removeKeyValue Remove app key-value storage entry
๐Ÿงผ clearKeyValueFile Clear app key-value storage file
๐Ÿ—„๏ธ listDataStores List app Jetpack DataStore instances (Android, requires AutoMobile SDK adapter)
๐Ÿ—„๏ธ getDataStore Read entries from an app Jetpack DataStore instance (Android, requires AutoMobile SDK adapter)
๐Ÿงฎ sqlQuery Execute SQL on app SQLite database
๐Ÿ” resetKeychain Reset an app’s Keychain/Keystore state (scoped by appId)
๐Ÿ”— setAppLinks Android 12+: change an app’s App Links state so https links open the app directly (or not)
โฑ๏ธ measureStartup Measure cold/warm/hot app startup
๐Ÿ“œ getLogs Read device logs with filters
๐Ÿ“ก sendBroadcast Send an Android broadcast to the app under test
๐Ÿ› ๏ธ backgroundWork Android: read and trigger an app’s background work without waiting hours

๐Ÿ“ฑ Devices & system

Tool What it does
๐Ÿ“ƒ listDevices List booted devices
๐Ÿ’ฟ listDeviceImages List device images
๐Ÿค– getAndroid Find or recover an Android AVD and prepare it for automation
๐ŸŽ getApple Find or recover an iOS Simulator and prepare it for automation
๐Ÿ—๏ธ provisionDevice Provision exact virtual device
๐Ÿงฐ setDeviceResources Set selected device resources and verify native state
โš–๏ธ reconcileDeviceResources Compare a simulator to a requested resource map
โœ… setActiveDevice Pick the active device for this connection
๐Ÿ”Œ killDevice Kill device
๐Ÿ—‘๏ธ deleteDevice Stop and permanently delete a device, with verified platform-inventory absence
๐Ÿ’พ deviceSnapshot Capture or restore device snapshot
๐Ÿ”ƒ rotate Rotate device orientation
๐Ÿ“ setPosture Set foldable / Duo posture
๐Ÿ“ถ statusBar Pin status-bar time, battery, and signal for clean screenshots
๐ŸชŸ windowMode Fullscreen, PiP, or split-screen an Android task
๐ŸŽ›๏ธ rotaryScroll Wear OS crown scroll with read-back; reports every attempted method
โŒš rotateCrown watchOS: rotate the Digital Crown by a signed delta with optional velocity
๐ŸŒ openLink Open URL in browser
๐Ÿ  homeScreen Go to home screen
๐Ÿ•˜ recentApps Open recent apps
๐Ÿ”” systemTray System tray actions for notifications (open/close/list/find/tap/dismiss/clearAll)
๐Ÿ”“ wakeAndUnlock Wake a device and unlock its keyguard
๐ŸŒ changeLocalization Change locale, time zone, text direction, time format, and calendar system
๐Ÿฉบ getDeviceState Read clock, DND, connectivity, and other device state
๐Ÿ”ง setDeviceState Set DND, airplane mode, and other device state
๐Ÿ–ฅ๏ธ displayConfig Read or set font scale, density, and display size
๐ŸŽจ displayProfile Apply an OEM-style display profile (Android)
๐Ÿ getIosSimulatorCapabilities Discover biometric capabilities for a selected iOS Simulator device type and runtime
๐Ÿชช biometricAuth Simulate biometric success or failure
๐Ÿ“ณ shake Shake the device (simulator/emulator)
๐Ÿงฒ setSensor Set an emulator sensor (accelerometer, gyro, โ€ฆ)
๐ŸŽ™๏ธ injectAudioInput Emulator or simulator: play a WAV file or tone into the microphone. Off by default
โน๏ธ stopAudioInput Stop an audio injection. Off by default
๐Ÿ”Š captureAudio Emulator or simulator: record audio output and report its level. Off by default
๐Ÿ“ž phoneCall Simulate an incoming phone call
๐Ÿ’ฌ sendSms Simulate an incoming SMS
๐ŸŽต mediaSession Read or control Android media sessions
๐Ÿ“ฃ postNotification Post notification via Android SDK hooks or iOS Simulator simctl push
๐Ÿ”• getNotificationPolicy Read app notification/DND policy state
๐Ÿ”• setNotificationPolicy Set app notification/DND policy state
๐Ÿ›‚ getAppPermissions Read app permission state
๐Ÿ›‚ setAppPermissions userId grant/revoke; device-wide reset [‘all’]; Android notification state
โ˜ ๏ธ killProfile Simulate an OEM background-kill policy (Android)
๐Ÿญ manufacturerProfile Approximate an OEM device (Android)
โš ๏ธ systemAlerts Auto-answer OS permission and system alerts

๐ŸŒ Network, plans & recording

Tool What it does
๐Ÿ“ถ network Control network capture and error simulation
๐ŸŽญ mockNetwork Add mock network response rule
๐Ÿงฝ clearMockNetwork Clear mock network response rules
๐Ÿ•ธ๏ธ getNetworkGraph Get aggregate captured network graph
โ–ถ๏ธ executePlan Execute YAML plan steps; stops on first failed step
๐Ÿ”’ criticalSection Synchronize multiple devices at a barrier, then run steps serially
๐Ÿšง barrier Sync multiple devices at a point in a plan
โบ๏ธ recordToolCalls Record MCP tool calls to YAML
๐ŸŽฌ recordDeviceGestures Start recording on-device user input (not tool calls) for exportPlan
๐Ÿ“ค exportPlan Stop active recording and export a YAML plan
๐ŸŽฅ videoRecording Start or stop device video recording
๐Ÿ“ˆ performanceTrace Record an xctrace / Perfetto trace; read it back at automobile:device-session/{sessionUuid}/performance-traces/{traceId}{?offset,maxBytes}
๐Ÿ”ฌ captureTrace Android: record a Perfetto trace from typed categories (sched, gfx, view, am, wm, binder_driver, memory, app); stop pulls the .perfetto-trace. Off by default
๐Ÿง  heapDump Android: dump a debuggable or profileable app’s heap to a host .hprof (heap_dump_not_debuggable otherwise). Off by default

โ™ฟ Accessibility & tooling

Tool What it does
๐Ÿฆฎ accessibility Check or control accessibility services
๐ŸŽฏ accessibilityFocus Set or clear Android TalkBack focus by resourceId, text, or contentDesc
๐Ÿซถ accessibilityAction Perform a TalkBack-style accessibility action (Android)
โœ… accessibilityAudit Run the platform’s own accessibility audit engine on the current screen
๐Ÿงพ audit Audit the current screen on demand
๐Ÿงฉ setToolEnabled Show or hide tools in discovery

๐Ÿ“บ Android TV focus navigation

focusNavigate({ until, direction?, maxSteps?, settleMs? }) (#14947) drives focus-based UIs. It observes, and while the input-focused element (focusedElement) does not match until (text, contentDesc and/or resourceId) it presses the D-pad arrow toward the nearest match, or direction when given, then observes again. With no focused element or no match on screen it presses down. It returns the path of focused elements and a status: focused, max_steps (default 30, at most 100) or stuck (every direction toward the nearest match is blocked on the current element; an explicit direction stops after two unchanged presses). A direction that leaves focus unchanged is skipped for that element for the rest of the call, so steering tries the next-best axis. Activate the focused item afterwards with sendKeys key enter; Android treats KEYCODE_ENTER and KEYCODE_DPAD_CENTER both as select, so no separate select key exists. Android only; not yet verified on a TV image (see docs/design-docs/plat/android/form-factors.md).

๐Ÿ“ Notes

  • โŒจ๏ธ Compact observations fold soft-keyboard keys into one keyboard: { visible: true, package: "โ€ฆ" } summary plus at most one skeleton row (<ime> | Keyboard (โ€ฆ) | input). The row appears only with at least one bounded accessible descendant.
  • ๐Ÿ“ธ Screenshot paths are kept for at least 10 minutes after return unless evicted early under capacity pressure; each path has a screenshotExpiresAt/expiresAt (host epoch ms, not a promise). Retention starts at 128 MiB and scales by 64 MiB per active device up to 1 GiB, within a limit of 4096 files. Each deviceโ€™s newest 3 screenshots (counting its incoming frame) are evicted only as a last resort, and a capture is admitted even if nothing fits. The byte limits and per-device allowance are configurable. After a restart, existing files get a process-start grace of ten minutes.
  • ๐Ÿงน holdSessionOnFailure keeps plan sessions instead of auto-releasing them.

No audio input (audio_input_unavailable)

When a device cannot record audio, observe returns diagnostics: [{ code: "audio_input_unavailable", message, retryable: false }], and a setAppPermissions grant of microphone (iOS) or RECORD_AUDIO (Android) still succeeds but carries the same diagnostics entry. This applies to an iOS simulator on a host with no audio input device, and to an Android emulator launched with -no-audio (AUTOMOBILE_EMULATOR_AUDIO=false) or with hw.audioInput=no. Recordings on that device contain no audio. Treat this as an environment limitation: do not retry, and do not report it as an app failure. Fix the host (for example, make a virtual loopback device the default input) or the AVD audio settings. The message names the cause.

Stylus pointer on tapAt, swipeAt and dragPath

pointer: { toolType: "stylus" } injects a stylus instead of a finger (Android only; never falls back to a finger).

pointer shape Route Needs
{ toolType: "stylus" }, pressure omitted or 1 (tapAt, swipeAt) adb shell input stylus Android 12+ (API 31)
pressure other than 1, tilt (radians, 0 to PI/2), orientation (radians), or buttons (primary, secondary) CtrlProxy instrumentation stylus_input_v1 (Android 12+)
dragPath with any pointer CtrlProxy instrumentation stylus_input_v1 (Android 12+)

On an emulator or userdebug build whose adb shell already runs as root (after adb root) and has the uinput tool, a stylus stroke with pressure and a dragPath also work without stylus_input_v1, through a virtual pen; tilt, orientation and buttons still need the runner, and each stroke starts about 4 seconds later while the pen attaches.

pointer: { toolType: "eraser" } touches with the pen’s eraser end (apps see TOOL_TYPE_ERASER) on tapAt, swipeAt and dragPath, with optional pressure. It needs that same root adb shell with the uinput tool, and is refused before any input everywhere else; tilt, orientation and buttons are refused with an eraser.

dragPath points also take pressure and tilt (they need pointer), interpolated between points; holdMs and releaseHoldMs become holds at the first and last point. A device or runner that cannot honour the request is refused before anything is sent, naming the missing capability. tilt, orientation and buttons are Android only; doubleTap and a panel display are not supported with a stylus yet. Details and the unverified parts are in the stylus design note.

hoverAt

Hover enter, move and exit over points with no contact (Android only; the reasons iOS is refused are in the stylus design note). It takes the dragPath point shape (x, y, per-point durationMs) plus an optional per-point distance (stylus only), and the same coordinateSpace, display, snapshotId and layer.

toolType chooses who hovers, and apps see the difference:

toolType What the app receives
stylus (default) ACTION_HOVER_* with TOOL_TYPE_STYLUS, SOURCE_STYLUS and an AXIS_DISTANCE value
mouse ACTION_HOVER_* with TOOL_TYPE_MOUSE and SOURCE_MOUSE; no distance; desktop-style UI

It needs the hover_input_v1 runner capability, or, for a stylus hover, an adb shell that already runs as root with a writable /dev/uinput (after adb root on an emulator or userdebug build). A device or runner without either, and iOS, are refused before anything is sent with the missing capability named, and a hover is never turned into a touch. CtrlProxy advertises the capability and injects the hover through its UiAutomation instrumentation (see the stylus design note); the semantics above are the documented intent and still need on-device confirmation (#13082).

prototype

Show agent-authored UI on a device: show, patch, inspect, dismiss {id} / {all: true}, status. Android can hold up to four prototypes (replaceOthers: false); iOS shows one at a time. Features (data model, gestures, checks) require the matching device capability and are refused before upload otherwise. Spec: prototype UX. Camera and media support per runtime: camera and media guide.

Watch-sized mockups

Prototypes cannot run on watchOS, but a watch-sized spec gives a quick visual mockup of a watch screen on an iPhone simulator or Android emulator. Float the window in the centre and give the root box the watch screen’s size, a large corner radius (which also clips its content) and a black background:

Case width ร— height (dp/pt) cornerRadius
41 mm 176 ร— 215 36
45 mm 198 ร— 242 40
49 mm Ultra 205 ร— 251 44
{
  "id": "watch-41mm",
  "window": {
    "placement": { "type": "floating", "gravity": "center", "offset": { "x": 0, "y": 0 } }
  },
  "components": {
    "watchRow": {
      "root": {
        "type": "row",
        "style": {
          "width": "fill",
          "background": "#222222",
          "cornerRadius": 16,
          "padding": { "start": 10, "end": 10, "top": 8, "bottom": 8 }
        },
        "children": [{ "type": "text", "text": "{props.title}", "style": { "color": "#FFFFFF" } }]
      }
    }
  },
  "root": {
    "type": "box",
    "style": {
      "width": { "dp": 176 },
      "height": { "dp": 215 },
      "cornerRadius": 36,
      "background": "#000000"
    },
    "children": [
      {
        "type": "scroll",
        "child": {
          "type": "column",
          "style": { "spacing": 6, "padding": { "start": 8, "end": 8, "top": 12 } },
          "children": [
            { "type": "use", "component": "watchRow", "props": { "title": "Drink water" } },
            { "type": "use", "component": "watchRow", "props": { "title": "Stand up" } }
          ]
        }
      }
    ]
  }
}

Put each common watch pattern in components and reuse it with use: a vertically scrolling list of rows, a full-screen metric (one large number with a label and unit), a two-button confirmation (two buttons with weight: 1 in a row, swapped in with visibleWhen), and a now-playing card (title, artist, previous / play-pause / next iconButtons and a linear progress).

The mockup is a phone overlay sized like a watch. It does not simulate the Digital Crown, Always-On or wrist-down dimming, real watchOS or Wear OS fonts and controls, or the round Wear OS screen, and nothing runs on a watch. Check the final design on a real watch.