ai-mobile-tester
Enables automated UI testing of Android native and WebView apps on devices/emulators via ADB, including UI observation, deterministic YAML flow replay, and self-healing locators.
Enables automated UI testing of iOS native and WKWebView apps on simulators via xcrun simctl and WebDriverAgent.
Provides Compose testTag coverage checks to help make Jetpack Compose UI elements addressable for automated testing.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ai-mobile-testerWrite a UI test that logs in and verifies the welcome screen"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ai-mobile-tester
An MCP server that lets AI assistants (Claude Code, Cursor, Windsurf, …) write and run mobile UI tests by natural language — Android and iOS simulators, native and WebView/hybrid — with no Appium and no Chromedriver. Android drives over ADB; iOS simulators over xcrun simctl + WebDriverAgent, and their WKWebViews over Apple's Web Inspector protocol. You describe a test in plain English; the assistant captures the screen, authors a durable YAML flow, then replays it deterministically with self-healing locators (native) and an HTML report.
One flow can target both platforms: leave platform: out and it runs on Android by default, or on iOS when given a simulator UDID (device_id for run_flow, --device for the CLI), with when: { platform } for the steps that genuinely differ. A flow that only ever runs on iOS declares platform: ios instead, and then uses the only booted simulator on its own. iOS is simulators only — no physical-device support.
How it works
Observe — the assistant captures a compact, token-frugal snapshot of the screen —
observe_ui(native) orobserve_webview(WebView) — with stable selectors and[ref]handles.Author — it writes a YAML flow (tap / input / assert / scroll steps) from those selectors. You keep the flow file.
Validate —
validate_flowlints the flow offline (schema, fragile selectors, undefined variables) — no device needed.Run —
run_flowexecutes it deterministically on the device (no AI per run), self-heals drifted native locators, and writes an HTML report.
The YAML flow is the durable artifact: author once with the assistant, then replay forever (CI, daily, …) at zero AI cost and with no drift.
Related MCP server: MCP Appium
Prerequisites
Node.js 18+
For Android: the Android SDK Platform Tools —
adbin your PATH (download) — and a device with USB debugging enabled, or a running emulatorFor iOS: a Mac with the full Xcode and an iOS simulator runtime — see ios-testing.md. Running an iOS flow needs no Android SDK, but
list_devicesfails withoutadb(find a simulator's UDID withxcrun simctl list devicesinstead), andinitwarns thatadbis missing.For WebView / hybrid apps: the app's WebView must opt in to remote debugging — on Android
WebView.setWebContentsDebuggingEnabled(true)(debug builds usually have it), on iOSWKWebView.isInspectable = true(iOS 16.4+; Safari needs no opt-in). iOS also needs the optionalappium-remote-debuggerclient — see ios-testing.md
Install & set up
npm install -g ai-mobile-tester
npx ai-mobile-tester initThe wizard checks adb, registers the MCP server with Claude Code (via claude mcp add, writing ~/.claude.json) and Claude Desktop (its claude_desktop_config.json, if installed), and installs the /run-test slash command. Restart Claude Code / Claude Desktop and the tools are available.
Manual / advanced MCP configuration
init is the easy path, but you can register the server by hand for any MCP client. The server runs on stdio via the serve subcommand:
{
"mcpServers": {
"ai-mobile-tester": { "command": "npx", "args": ["-y", "ai-mobile-tester", "serve"] },
},
}For Claude Code you can also run claude mcp add --scope user ai-mobile-tester -- ai-mobile-tester serve. For the most stable setup, install globally (npm i -g ai-mobile-tester) and point at ai-mobile-tester serve (or the absolute node <prefix>/dist/index.js that init writes) — the npx form re-resolves from a cache that npm can garbage-collect.
Example — a native flow
appId: com.example.app
env:
TEST_USER: "you@example.com"
TEST_PASSWORD: "" # keep the secret out of the file; pass it at run time (--env TEST_PASSWORD=…)
---
- launchApp
- tapOn: { id: login_button }
- inputText: { into: { id: email }, text: "${TEST_USER}" }
- inputText: { into: { id: password }, text: "${TEST_PASSWORD}" }
- tapOn: "Sign in"
- assertVisible: "Welcome"Example — a WebView flow
appId: com.example.shop
env:
TEST_USER: "you@example.com"
TEST_PASSWORD: "" # keep the secret out of the file; pass it at run time (--env TEST_PASSWORD=…)
---
- launchApp
- switchContext: "WEBVIEW_com.example.shop@shop.example.com"
- assertVisible: { css: "#email" }
- inputText: { into: { css: "#email" }, text: "${TEST_USER}" }
- tapOn: { css: '[data-testid="signin"]' }
- assertVisible: { css: ".order-summary" }
- switchContext: NATIVE_APPValidate offline, then run it:
/run-test path/to/flow.yaml…or just ask the assistant to run it.
Run in CI (no AI)
Once a flow exists, run it headlessly — no Claude, no MCP, just a device (Android through adb, or a booted iOS simulator):
ai-mobile-tester run flow.yaml --junit results.xml # exit 0 pass · 1 fail · 2 could-not-run
ai-mobile-tester validate flow.yaml # offline pre-checkPortable to any CI (GitHub Actions, MacStadium, GitLab, …). See docs/ci-runner.md.
Documentation
Authoring UI tests — the full workflow — start here.
YAML flow format reference — every command and selector.
Waits, timeouts and
dismiss:— which commands poll, whatoptionalandtimeoutMsreally cost, and thedismiss:rules.When the screen never idles —
ERROR: could not get idle state: what it means, how to confirm it, and the escape hatches.Testing WebView / hybrid apps — drive WebViews by CSS selector, on both platforms.
Testing iOS apps (simulators) — prerequisites, WebDriverAgent, divergences from Android, and the WebView setup.
Compose testability — make Jetpack Compose elements addressable with
testTags.Running flows in CI — exit codes, secrets, JUnit, a portable recipe.
MCP tools
Flow engine:
Tool | Description |
| Compact, token-frugal snapshot of the native screen (actionable elements get a |
| Every attribute of the element(s) a selector matches — the state flags |
| Lists the app's WebView pages and returns a compact DOM snapshot of the richest, by CSS selector |
| Tap a WebView element by css/text, then return the updated DOM (interactive observe→act→observe) |
| Type into a WebView field by css/text, then return the updated DOM |
| Type into a field (optionally focus it by selector first) |
| Statically validate a YAML flow (schema + lints), no device needed |
| Run a validated YAML flow deterministically; self-heals native locators; writes an HTML report |
| Report Compose |
Device & app: list_devices, device_info, connect_device, launch_app, install_apk, uninstall_app, clear_app_data, force_stop.
Interaction: tap, tap_xy, tap_element, long_press, swipe, scroll_down, scroll_up, type_text, press_key.
Observation & assertions: take_screenshot, dump_ui, describe_element, find_element, get_current_activity, is_element_visible, assert_visible, assert_not_visible, assert_text, wait_for_element, wait_for_text, wait_for_activity.
Development
git clone <your-fork> ai-mobile-tester && cd ai-mobile-tester
npm install
npm run build
npm test # the test suite
npm run lint && npm run format:checkWhat's new in 3.0.0
Cross-platform flows: write one YAML flow that runs on Android or iOS. Neutral
pressKeynames (ENTER,TAB,DELETE,HOME, …) and friendly permission names (camera,microphone,location, …) resolve to the right platform-native key automatically, and awhen: { platform }clause onrunFlowlets a shared flow branch for a platform-specific step. See yaml-flow-format.md and ios-testing.md.
What's new in 3.1.0
WebView taps dispatch real touches:
tapOnin a WebView now sends a real trusted CDP touch event instead of a syntheticclick(). Elements must be unoccluded to actuate. After a WebView tap that should launch a native screen, use the newassertActivitycommand (Android-only) to verify the Activity transition happened — a content-onlyassertVisiblecan pass even if the native transition failed.
What's new in 3.2.0
dismiss:auto-dismisses async dialogs. A config-level list of selectors was checked at every step boundary (native only, skipped inside a WebView context) and the first visible match tapped — for permission prompts, rating nags, or promo interstitials that appear unpredictably. Dismissals show up as a run-level annotation in the report header, not as numbered steps, so step indices stay diffable. (Since 3.5.0 the watcher also fires during a wait, not only between steps — see below.)Conditional branching:
runFlow'swhen:now also accepts{ visible: <selector> }/{ notVisible: <selector> }alongside the existing{ platform }, plus anelse:for the other side. Useelse, not two adjacentwhens — see yaml-flow-format.md. Note: steps inside avisible/notVisible-guarded branch don't self-heal (a{ platform }guard still does for an inlinecommands:branch — afile:subflow is always strict-only).observe_uino longer hands back a bare empty tree on a continuously animating screen — it retries briefly, then returns an actionable diagnostic naming the likely cause instead of silence.
What's new in 3.3.0
tapandinput_textwait for the screen to settle before returning their snapshot. Previously they captured immediately after acting, so the tree you got back could still be the screen you just left, or a half-drawn one mid-transition. They now re-capture until the tree has both changed and stopped changing. When it never settles you get the newest snapshot plus a note saying which test failed — either the screen kept moving (a live animation), or it never changed at all, in which case the note says plainly that the snapshot is the screen from before your action. Costs one extra UI dump per action, two when it never settles;observe_uiis unchanged.
What's new in 3.4.0
WebView tools now work on iOS simulators.
observe_webview,webview_tap,webview_input, andswitchContext: "WEBVIEW_<bundle-id>@<url-match>"drive WKWebViews over Apple's Web Inspector protocol, with the same YAML grammar as Android. Needs the optionalappium-remote-debuggerclient (npm install --no-save appium-remote-debugger) and the target app to setWKWebView.isInspectable = true(iOS 16.4+; Safari needs no opt-in) — see ios-testing.md for the full setup and its honest limits (one simulator at a time, taps need exactly one on-screen WebView, the page must not be pinch-zoomed).
What's new in 3.5.0
The runner no longer reports green for a run that never happened.
uiautomator dumpprintsERROR: could not get idle state.and exits 0, and the dump file was never deleted first — so the follow-up read silently returned the previous dump. A 19-minute-old tree of a different screen was measured being served as the current UI, and selector resolution,assertVisible,assertNotVisible,tapOnand the self-healing locator store all consumed it. That produces false passes as readily as false failures. A refused dump now fails with a named cause instead of returning a tree, andrun_flowreports it asscreen never idlerather than asnot visible: #your_selector— a misattribution that cost one reporter most of a session. See When the screen never idles.⚠ Runs will fail more often after upgrading, and that is the fix working — not a regression. Two shapes of flow change colour, and both were passing on something untrue:
A screen whose UI tree could never be read used to be tested against a stale tree from an earlier screen. Those steps passed or failed at random; they now fail honestly, with the cause named and the escape hatches listed in the error itself.
A flow whose
assertNotVisiblepassed at 300ms because the element had not rendered yet will now wait for it, find it, and fail. That assertion was winning a race, not checking the screen. If the step means "this never appears at all", give it a short explicit budget (assertNotVisible: { id: error_banner, timeoutMs: 1000 }); if it was standing in for "wait for the spinner to go away", it now does what it always read like.A selector that named nothing native — a
cssoutside a WebView,{ index: 0 }, anid/textthat a${VAR}expanded to nothing — used to match every node and be answered with the first one.assertVisiblepassed without looking,tapOntapped the root node's centre, andscrollUntilVisiblewith acsselement inside aWEBVIEW_context returnedpassedin 1ms having never scrolled. Every native lookup now fails withmatches any node on the native path — needs id or text, before it takes a dump. Give the step anidortext, or move it into the WebView context wherecssbelongs.
Waiting for something to go away is a real wait.
assertNotVisiblepolls until the element is gone instead of answering off one snapshot in ~300ms while every other lookup polled ~11s. NewwaitFor: { element, state: visible | notVisible, timeoutMs? }states a synchronisation point explicitly (and never self-heals, so the locator is taken literally). New per-step and flow-leveltimeoutMs— the hard-coded 10s fitted no real app. Precedence is step → flow default → 10000, and an explicit value beatsoptional's short cap in both directions. The flow default reaches every polling wait,assertActivityincluded;scrollUntilVisibleis the one deliberate exception, because its budget funds scroll gestures rather than one lookup. The full table, with harness-measured costs, is in Waits, timeouts anddismiss:.dismiss:now fires during waits, not only between steps.tapOn/assertVisiblespend up to 10s polling inside a single step, so a dialog that rendered mid-poll was never dismissed and the step failed with the dialog correctly declared. The watcher now runs on every poll tick, reusing that tick's snapshot — zero extra UI dumps — capped at 3 dismissals per wait so a mis-aimed entry cannot become a tap storm. The rule that goes with it: never pointdismiss:at an element an explicit step also touches.Escape hatches for screens that cannot be read.
tapXY: { x, y }/{ xPct, yPct }taps a raw coordinate from YAML (percentages survive a change of device);stopAppandlaunchApp: { forceStop: true }give a cold start withoutclearState's data wipe, on both platforms; andget_current_activity/assertActivity— the only assertion that never reads the UI tree — now falls back throughmResumedActivity→mCurrentFocus→mFocusedApp→topResumedActivityinstead of returning null on Android 16.
What's new in 3.6.0
Three authoring diagnostics. Nothing about how a flow runs changes — this release is about what you are told while writing one.
A failed lookup now says what WAS on screen.
not visible: #navigation_rebrand_explore, after twelve seconds of silent polling, names the one thing that is not there and nothing that is — so a wrong selector, a modal covering the screen, and the wrong screen entirely all read identically. Every native miss now appends a second line listing the screen's addressable nodes:not visible: #ghost on screen (3): #email_field, #login_button, #titleYou see it wherever the failure surfaces: inline in
run_flow's and the CLI's summary — 3.6.0 inlines the failing step's error for any failure, not only a refused dump — as well as inreport.htmland the JUnit XML. The interactivewait_for_element/assert_visibleMCP tools do not carry it yet.It reuses the snapshot the poll loop already captured, so it costs zero extra UI dumps — and on a screen that will not dump at all, taking another one is exactly what would fail while trying to explain the failure. Ids first, text where there is no id, both clamped to 40 characters, capped at 12 entries with identical handles collapsed (
#row_item ×30) so a whole list screen cannot turn one failure into a token bomb (~600 characters worst case). Read the(N)in the header to tell an overlay from a whole screen — it is the true node count. A dialog or bottom sheet has few addressable nodes, fits inside the cap and is listed in full; a large(N)is a whole screen. Do not read the+N moretail that way: the collapse means a 48-node list screen shows 9 entries and no tail at all. Applies totapOn,assertVisible,inputText,waitFor: { state: visible },scrollUntilVisibleand — since 3.7.0 —capture; not toassertNotVisible, whose failure already means the element is on screen. A WebView miss keeps its own text — with one exception,scrollUntilVisible, which has no WebView branch and so reports the native tree it actually searched even inside aswitchContext.New
describe_elementtool: "is this state even assertable?" in one call.observe_uirenders a compact view and hides most attributes, so the only way to find out whether a control exposes its state was to drop to rawuiautomator dumpXML. An entire test was once authored around "the heart turns red" before anyone discovered the app never reported that state at all. One call would have shown it:"Favorite" — 1 match. match index: 0 ... contentDesc: "Favorite" checkable: false checked: false selected: false ...(Abridged — the real block lists all 17 attributes plus bounds;
...marks the 13 elided here.)Nothing flips between the two states, so no assertion can be written on it — a fact worth five seconds rather than a session.
describe_elementreturns every attribute the dump carries, plus exact bounds, and one block per match with theindex:a flow selector would use — so an ambiguous selector shows all its candidates instead of silently picking the first. Read-only and native. It matches onid/text, and accepts the sameenabled/checked/focused/selectedqualifiers a flow selector does — so theindex:it reports is the one that selector will get. See authoring-tests.md.validate_flowcatches a password committed inenv:. Flow files get committed, and so do the credentials in them — this repository's own example flow carries a plaintext password, which is how the rule earned its place.validate_flownow warns when anenv:default is a non-empty literal under a credential-shaped key (password,passwd,passphrase,passcode,pwd,secret,token,credential, pluskeyonly in compound form likeapi_key/apiKey), and tells you to blank the default and pass the real value at run time. Barekeyand barepassare deliberately excluded —KEY_CODE,SORT_KEYandBOARDING_PASSare ordinary flow variables, and a false positive has no remedy but renaming yours. It never warns on a${VAR}reference or on the empty default ci-runner.md tells you to commit — warning on the recommended pattern is how a validator teaches people to ignore it. A non-empty placeholder is not exempt: nothing about the value is inspected, so"changeme"warns too. Key names only: no entropy scoring, no guessing from the value's shape, and the value is never echoed into the warning. It is a warning, not an error; by the time you read it the value is already in your history, and the follow-up is to rotate it.
What's new in 3.7.0
capture: assert on the value that was actually on the screen. A test that favourites the first vehicle in a re-ranking list and then checks the Favorites tab could previously express nothing stronger thanassertVisible: 'View \d{4} .*'— and on any account that already has favourites, that is already true before the test runs. It passed with the feature completely broken.capturebinds a string read off the screen to a flow variable that every later step can use:- capture: { from: { id: toolbar_split_title }, as: VEHICLE } - tapOn: { id: favorite_button } - tapOn: { id: favorites_tab } - assertVisible: { text: "View .*${VEHICLE}.*" } # the car you actually favouritedThe full form is
{ from: <selector>, as: NAME, attr?: text | contentDesc, redact?: true }.fromis an ordinary selector with the same polling,timeoutMsbudget and self-healing asassertVisible.asmust match^[A-Z][A-Z0-9_]*$, and that is enforced, not advised. Omitattrand it readstext, falling back tocontentDescwhentextis empty; writeattrout and it reads only the attribute you named — naming one and being answered with a different one is the quiet substitution this command exists to remove, so an explicitattr: texton an icon whose label lives incontentDescfails where omitting it would have worked. Scope is flow-wide and forward-only, and it crossesrunFlowboundaries in both directions: a parent's capture is visible inside a sub-flow, and a sub-flow's is still bound after it returns. See yaml-flow-format.md.An empty read fails the step rather than binding nothing.
""would turntext: "View .*${VEHICLE}.*"intoView .*.*— a pattern matching any card on the screen, so the run goes green while the assertion has quietly become the tautology this feature exists to remove. A capture whose element is on screen but whose attribute is empty fails, and the report row says(element found, value empty)so it does not read as a missing element.optional: trueis refused at parse time for the same reason: a skipped capture leaves the name unbound and every later step then fails on an unresolved variable — correct, but bewildering.captureis native only; inside aswitchContext: "WEBVIEW_…"it fails instead of quietly reading the native tree behind the page, which would bind a real-looking wrong value.⚠ Behaviour change: an interpolated value is now matched literally in a native
id/text.idandtextare regex full-match, so a${VAR}used to be spliced in as a pattern. A real UI string —$29,499,2020 or newer (19,125)— compiles to a perfectly valid regex that matches nothing, and the step fails as though the element were absent, with nothing in the message saying the value was read as a pattern. Since 3.7.0 the substituted value is escaped so it matches itself and nothing else.The rule is by field, not by origin, so
${VAR}means the same thing wherever its value came from — anenv:default,--env,process.envor a capture:escaped: a native
id, a nativetext.never escaped:
css(a CSS selector, not a regex — a backslash corrupts it), atextselector inside a WEBVIEW context (the DOM path compares with===, exact equality),inputText'stext:(this is the string typed into the app), and everything that is not a regex-matched selector field (appId,tapXY,switchContext).
The pattern you wrote around the reference is untouched, so
{ text: "View .*${VEHICLE}.*" }keeps its own.*live and only the value goes in literal.${VAR:raw}is the opt-out, applied per reference, for a variable whose value really is meant as a pattern. What can change colour: a flow whoseenv:default was deliberately written as a regex and used in a nativeid/text—validate_flownow warns on exactly that combination, so those flows name themselves offline rather than on a device. It also fixes a latent bug in the other direction: an email address in atext:selector had its dots matching any character, and now matches itself.validate_flowrefuses a${VAR}used above thecapturethat binds it. No execution order resolves it, so it is an error — caught offline, before a device, an app install and eleven steps have been spent. The line between error and warning is drawn on how many runs the flow is wrong on: wrong on every path is an error, wrong on some paths is a warning, wrong on no path is silence. So a capture inside arunFlow when:branch (or arepeatwhosetimesmay be0) still defines the name and only warns — that branch may well run, and a fatal false positive stops a working flow dead. Awhen:/else:pair where both sides capture the same name is bound on every path and stays silent. Capturing the same name twice warns, naming both steps; so does acaptureinside a WebView context.optional:and a malformedas:are hard parse errors.An empty
env:default does not buy silence, and that is the subtle one.NAME: ""is the shapedocs/ci-runner.md#secretsteaches for a value injected at run time, so it is the idiom most flows carry — and treating a declared-but-blank key as "defined" would make every check above inert on exactly the flows they were written for. If the branch holding the capture never runs,VEHICLEstays"",text: "View .*${VEHICLE}.*"collapses toView .*.*, and the step passes against any card on the screen. It warns rather than errors, because--env VEHICLE=…legitimately fills a declared key and a fatal error would block that run. A flow that declaresNAME: ""and captures nothing is untouched.One gap, stated rather than papered over: a
dismiss:entry that references a captured name is not covered by the ordering checks — they walk the step list, anddismiss:is config. At run time such an entry stands itself down and warns at every step boundary until the capture lands, so it is noisy rather than silent, butvalidate_flowwill not tell you offline.A "selector without an id is fragile" warning no longer fires on a
textthat interpolates a${VAR}. Asserting on a captured value requires a text selector by definition — the value is only knowable at run time — so the warning was unsatisfiable on the pattern this release recommends. It still fires on a plain text-only or index-only selector, where an id genuinely is the better choice.Captured values are reported — and two of the three places are new machine-readable output you may already be parsing. The capture's own row in
report.htmlgainsVEHICLE = 2021 Honda Civic (read from text). The JUnit XML (--junit) gainscaptured NAME=valuein that step's<system-out>, next to the existinghealednote. Andrun_flow's summary text gains acaptured: NAME=value, …line on a failed run only —report.htmlis a path a model cannot open, and that string is returned on every single call, so a passing run stays quiet.redact: truestores***in the record itself, so no renderer can leak a redacted value by forgetting a flag; the real value still reaches later steps. There is noreport.json— the machine-readablerun_flowpayload remains deferred work, and this release deliberately did not invent a partial one, so--junitis still the machine-readable artifact that exists.
What's new in 3.7.1
iOS runs no longer abort when their WebDriverAgent session is replaced. WDA holds one session at a time, and a session that has been replaced answers
404with the error codeinvalid session idand the messageSession does not exist. The client already had a retry for exactly that case — but it looked for the code's wording inside the message, which never contains it, so the retry never ran and the run died withWDA GET /session/<id>/window/size failed: Session does not exist. It shipped behind a green unit test whose fake WDA copied the code into the message field, which a real WDA never does. Recovery now reads the structured error code, and still retries only once. That is safe because WDA rejects a command sent on a dead session before running it (measured: a tap sent on a dead session left an on-screen counter untouched).Tool calls made during a run share its WDA session instead of ending it. The server builds a fresh driver for every tool call, and each one used to create a session of its own — so an
observe_uiortapissued while a backgroundedrun_flowwas still running ended that run's session. Every call and run in the server process now shares one session per WDA, and clients that hit a dead session at the same moment create one replacement between them, not one each. Measured against a simulator: 201 interleaved calls from several clients ran on a single session with no failures, where the same kind of loop with a session per client created a new session on every one of its 80 calls. A second process driving the same simulator — another MCP server, Appium, a script — can still replace the session; that is recovered from, not prevented. See ios-testing.md.WDA is never reinstalled because it was slow to answer. A
/statuscheck that timed out used to be read as "WDA is not running" and answered with a reinstall, which ends every session and sends the app under test to the background — after which later steps silently read the home screen. But/statuswaits behind a UI dump already in progress: on a 1,500-element page the dump took 3.8s, and a/statussent meanwhile missed its 2-second budget against a perfectly healthy WDA. A timed-out check is now checked again, so WDA gets up to 32s in all (the 2s check, then a 30s wait); a WDA that still does not answer is an error naming the command that restarts it; and only a WDA that is actually down — a refused or reset connection, or an error answer from/status— is reinstalled. WDA is also confirmed once per tool call or run, instead of before every one of the hundreds of commands a long flow sends. ⚠ Behaviour change: if WDA genuinely dies partway through a run, the run fails at the step that met the dead WDA — withdismiss:configured too — and nothing in that run brings WDA back, because a relaunch would send the app under test to the background and later steps would read the home screen. Depending on where the crash lands, the step's error is a connection failure (fetch failed) or an error containingWebDriverAgent stopped responding partway through this run or tool call(inside a WebView context, awhen:check or the WebView tap bridge, it arrives wrapped in their own prefix). The next run or tool call relaunches WDA.A run says when its session was recreated. Recovery is silent by design, so a run whose WDA session was replaced now carries one warning — in the
run_flowsummary, the CLI output andreport.html— saying how many times, without failing a flow that recovered. Relatedly, adismiss:watcher whose screen capture fails for any reason now warns that it could not look. It used to warn only for a screen that never idles, so a watcher blinded by a WDA error said nothing at all. This second change is in the platform-neutral runner, so Android runs can show that warning too.
What's new in 3.7.2
ai-mobile-tester runruns an iOS flow without--device. The CLI used to pick its device through adb before it looked at the flow'splatform:, so aplatform: iosflow could only run with an explicit--device <udid>. Without one it failed in one of four ways, depending on the machine: with one Android device attached, the adb serial was handed to the iOS driver (No iOS simulator with UDID <serial>); with several, it asked you to pick one with--device <serial>; with none, it said to start an Android emulator; and on a Mac with no Android SDK, it asked whether the Android SDK platform-tools were on your PATH. The CLI now takes the platform from the flow — or, for a flow that declares none, from--device— and an iOS run uses the only booted simulator, exactly as therun_flowMCP tool always has. Android runs keep the same default device and every adb message.A
--devicethat contradicts the flow's declaredplatform:now says so, in either direction —--device <id> is not an iOS simulator UDID, but <flow> declares platform: ios, or--device <udid> looks like an iOS simulator UDID, but <flow> declares platform: android— instead of failing later on a missing simulator or device. A flow that declares no platform is never refused: that is how one shared flow runs on iOS, by being given a simulator UDID.A flow without
platform:keeps separate self-heal memory per platform. Its iOS runs used to read and write the Android file,<flow>.fingerprints.json, where awhen: { platform }branch that runs on only one platform shifts which stored locator each later step is paired with — so an iOS step could heal onto a different element and pass. Heal memory now follows the device a run actually got: iOS runs use<flow>.fingerprints.ios.json, fromrun_flowand the CLI alike. If you ran such a flow on iOS before: when it only ever ran on iOS, rename its<flow>.fingerprints.jsonto<flow>.fingerprints.ios.jsonto keep that memory; when it ran on both platforms, delete the file once, so each platform re-learns from its own runs (a step that was passing only by healing then fails until its selector is updated).The HTML report names the simulator an iOS run used when no device id was passed, instead of
default.
What's new in 3.8.0
A run's report now says what happened in a way that cannot be misread — a green test used to render red, and one did get filed as a bug. Three outputs change shape; see "What changes for you" below.
A verdict.
report.htmlopens with✓ PASSEDor✗ FAILED. It used to state no verdict at all.A real tally.
66 passed · 10 skipped · 0 failedreplaces the report's66 of 76 steps passedand the CLI's andrun_flow's66/76 steps passed. A deliberate skip — anoptional:miss, awhen:that did not apply — is not a shortfall, and the old wording read as ten failures.Warnings look like warnings. They render amber with
⚠, and dismissed dialogs render neutral; red and orange are kept for step results. A warning raised more than once says how often, e.g.(17×).Steps after a failure are
not run, each with the reason —not run — the run stopped at step 4— instead ofskippedwith an empty detail. Inside arunFloworrepeat, the rest of the block is listed too, and a loop's unstarted iterations are counted on the loop's own row.Every block has a row. A
runFlowthat ran, and everyrepeat, gets a row with its file, its condition,times:, or — lacking both — a command count as the target, and what ran as the detail (when: visible #promo — ran else). Its steps are indented beneath it and numbered by position:4.2is the second step inside the block at step 4, and6.3.1is the first step of iteration 3 of therepeatat step 6.Time is in the row that spent it. With
dismiss:, the dialog check before each step reads the screen, and that read is the step's first look — but it was timed outside every row, so a run's steps could add up to a small fraction of its duration. Each row now includes it; the header shows what is left over (298.5 s (0.4 s outside steps)), how many dialog checks ran, how long they took and how many could not read the screen.
What changes for you:
JUnit testcase names are unchanged for flows without
runFloworrepeat. Flows that use them now number steps by position (4.2), so CI shows those testcases as renamed once — and from then on the names stop changing when awhen:branch runs on one run and not the next.The summary line reads
✓ login — 7 passed · 0 skipped · 0 failedinstead of✓ login — 7/7 steps passed. Anything that parsessteps passedneeds updating.Steps after a failure are
not run, notskipped. JUnit reports them as skipped, now with a message.Per-step times in a flow with
dismiss:go up by the dialog check before each step. The run's total time does not change.
Roadmap
Phase 1 (current): Android (native + WebView) via ADB, distributed as an npm package. Also: iOS simulator support (native + WebView), via
xcrun simctl+ WebDriverAgent + Apple's Web Inspector.Phase 2: web (Playwright).
Phase 3: cloud device farms (Firebase Test Lab, BrowserStack), CI/CD integration.
Phase 4: SaaS — web dashboard, team collaboration, history & analytics.
License
MIT
Available Tools
38 toolsassert_not_visibleA
Assert that an element is NOT currently visible on screen. Returns an error if the element IS found.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text or content-desc; regex full-match — use .* for partial, e.g. 'Sign.*' | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| resource_id | No | Bare resource-id, e.g. login_button; regex full-match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the burden of behavioral disclosure. It does state that it returns an error if the element is found, which is a key behavior. However, it does not mention the type of error, the return value on success (e.g., a pass message), or the timeout behavior. For a simple assertion tool, this is reasonably transparent but incomplete for an agent expecting to handle outcomes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, each earning its place. The core purpose is stated first, and the key behavioral consequence (returns an error if found) is immediately captured. No filler or redundant phrasing, making it highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with optional parameters and no output schema, so the description covers the essential purpose and key behavioral effect. The parameters are fully documented in the schema, so the agent can invoke it correctly. However, it doesn't specify the return type on success (e.g., a boolean true or a pass message), which is a minor gap for an agent that needs to interpret the result. But given the simplicity, the description is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all three parameters with examples and regex guidance, and with 100% coverage, the description adds nothing extra about parameter meaning. The description does not describe which combination of text and resource_id is required (e.g., AND/OR logic) or whether both can be used together. However, the schema alone is sufficient for basic parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool asserts an element is NOT visible, which is distinct from its sibling assert_visible. It uses a specific verb ('Assert') and resource (element visibility), and the note about returning an error if found adds clarity. This is sufficient to distinguish it from assert_visible and other assertion tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it: when you expect an element to be absent, and it contrasts with assert_visible, but it doesn't explicitly state 'use assert_visible when you expect the element to be present' or list other alternatives. Sibling tools like is_element_visible and find_element exist, but no explicit routing guidance is given. This is clear context but no exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assert_textC
Assert that an element with a given resource ID contains the expected text
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. | |
| resource_id | Yes | Bare resource-id, e.g. login_button; regex full-match | |
| expected_text | Yes | The expected text content of the element |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of explaining behavior, but it does not disclose whether the assertion waits, fails the test, returns a boolean, or throws an error. The word 'Assert' implies a check, but the observable effects and failure semantics are left unspecified.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, tightly worded sentence that immediately conveys the tool's purpose. There is no filler or redundant information; every word contributes to understanding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an assertion tool with no output schema and no annotations, the description lacks critical context about success/failure behavior, waiting semantics, and how it differs from wait_for_text. An agent cannot fully predict the tool's runtime behavior from this definition alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description essentially restates the relationship between resource_id and expected_text without adding new meaning beyond the schema, so no higher score is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Assert') and resource ('an element with a given resource ID contains the expected text'), making the tool's core function evident. It does not explicitly distinguish it from siblings like wait_for_text or assert_visible, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided about when to use this tool versus alternatives such as wait_for_text, is_element_visible, or assert_visible. The description only states what the tool does, not under what conditions it should be chosen or avoided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assert_visibleC
Assert that an element is currently visible on screen. Returns an error if the element is NOT found.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text or content-desc; regex full-match — use .* for partial, e.g. 'Sign.*' | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| resource_id | No | Bare resource-id, e.g. login_button; regex full-match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the full behavioral burden. It discloses an error when the element is not found, but leaves undefined what happens when the element exists but is not visible, despite 'visible' being the core concept. It also does not state whether the check is immediate or has a timeout, which matters given the wait_for_element sibling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with no filler. The primary assertion is front-loadedтное and the error condition is stated immediately, making the tool's purpose easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema and no annotations mean the description should clarify success returns and ambiguous invocation cases. It does not say what a successful assertion returns, and because all parameters are optional in the schema, it does not warn that some locator is still needed. The distinction between 'not found' and 'not visible' is also unresolved, leaving an agent without enough information to confidently invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains text, resource_id, and device_id including regex semantics. The description adds no parameter-level meaning beyond referring to 'an element', so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Assert') and the target condition ('element is currently visible on screen'), and it identifies the failure mode (returns an error if not found). It does not explicitly contrast with siblings like assert_not_visible or is_element_visible, so it stops short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives such as is_element_visible, wait_for_element, or assert_not_visible. No conditions, exclusions, or when-not-to-use guidance is provided; only the word 'assert' weakly implies a validation context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_testabilityA
Audit the current screen for locator stability: how many actionable elements have a stable id, which don't, and the Compose testTag fix. (Android; on iOS, id-coverage is not meaningful — see docs/ios-testing.md)
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. The verb 'Audit' strongly implies a read-only operation, and the mention of 'Compose testTag fix' suggests it provides advice rather than applying changes. However, the description does not explicitly state that it never modifies anything, nor does it describe the output or return value. It also doesn't clarify any prerequisites (e.g., a connected device) or side effects. Given the absence of annotations, this is a moderate gap; the description gives some context but not full transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the core purpose and then details the counts and the Compose fix. It includes the platform caveat and documentation reference without fluff. Every clause earns its place: the main action, the specific metrics, and the platform-specific note. It is concise (~50 words) and immediately usable, earning a top score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is relatively simple (one optional parameter, no output schema), but the description omits important context: it does not describe the output format (does it return a report? JSON? a count?), the meaning of 'device_id', or any prerequisites like a connected device or active screen. It does provide platform guidance, but the missing parameter semantics and return-value information leave the description incomplete for a thorough understanding. Given the simplicity, it could easily have been more complete, so a 3 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, meaning the input schema provides no descriptions for the single parameter 'device_id'. The tool description does not mention 'device_id' at all, so it adds no meaning beyond the schema's bare name. Since the description must compensate for low schema coverage, its failure to explain what 'device_id' refers to (e.g., an Android device identifier) leaves the agent guessing. This is a significant gap for even one parameter, so a score of 2 is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Audit'), a clear resource ('the current screen'), and a specific goal ('locator stability'). It breaks down exactly what it does: counts how many actionable elements have a stable id, which don't, and mentions the Compose testTag fix. This clearly distinguishes it from all sibling tools, which are actions (tap, swipe, etc.) or queries (dump_ui, find_element). No ambiguity about its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear platform context: 'Android; on iOS, id-coverage is not meaningful — see docs/ios-testing.md'. This serves as an explicit exclusion for iOS and directs to documentation. However, it does not explicitly compare this tool to any alternative tools (like dump_ui or describe_element) or state when to use it vs. them. It implies usage (when you need to audit stability) but lacks explicit 'use this instead of X when...' guidance. Overall, it provides solid context without enumerating alternatives, earning a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_app_dataA
Clear all data for an app (cache, databases, shared preferences)
| Name | Required | Description | Default |
|---|---|---|---|
| package | Yes | The app package name | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does disclose the key behavioral trait: this is a destructive operation that wipes app data, explicitly naming cache, databases, and shared preferences. It does not cover irreversibility or side effects on a running app, but the core destructive scope is clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one concise, front-loaded sentence with a parenthetical clarifying exactly what data is cleared. Every word earns its place, and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is sufficient for a simple two-parameter destructive action, and the schema covers inputs. However, given the large set of sibling tools, it does not provide any guidance on choosing this over uninstall_app or force_stop, nor does it indicate what return or confirmation the caller should expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both package and device_id are already documented in the schema. The description adds no extra parameter semantics, but none are needed beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Clear all data') and a specific resource ('for an app'), with explicit examples of what is affected: cache, databases, and shared preferences. However, it does not explicitly differentiate itself from sibling tools like uninstall_app or force_stop, which also operate on app state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given for when to use this tool versus alternatives such as force_stop or uninstall_app. The description does not mention prerequisites, destructive consequences, or when a less invasive operation would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connect_deviceC
(Android) Connect to a device over TCP/IP (wireless debugging)
| Name | Required | Description | Default |
|---|---|---|---|
| ip | Yes | IP address of the device | |
| port | No | Port number (default: 5555) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full behavioral burden. It states the connection mechanism but does not disclose side effects, success/failure behavior, prerequisites such as the device already listening on the port, or whether the connection persists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence with no filler, and the Android and wireless-debugging qualifiers add useful context. It is appropriately concise, though it has no structured detail beyond the core statement.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low parameter complexity and complete schema coverage, an agent can likely invoke the tool correctly. However, the description omits when the connection should be established, what a successful connection looks like, and what errors might occur, which are meaningful gaps for a stateful connection action.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters and the default port. The description adds only the TCP/IP/wireless debugging context, which is helpful but does not materially extend the parameter definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific action ('Connect'), a resource ('a device over TCP/IP (wireless debugging)'), and scopes the tool to Android. It is clear and not tautological, though it does not explicitly contrast with siblings such as list_devices or device_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance about when to use connect_device versus alternatives, when not to use it, or what setup is required first. The wireless-debugging context implies a use case, but the description never states it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_elementA
Read-only: dump EVERY attribute of the element(s) a selector matches — the state flags observe_ui hides (checkable, checked, selected, focused, enabled, password, scrollable), the full resource-id and class, and exact bounds. Returns one block per match with the index: a flow selector would use, so an ambiguous selector shows all its candidates instead of silently picking the first. Accepts the same enabled/checked/focused/selected qualifiers a flow selector does, so the index it reports is the index that selector will get. Use it while authoring to answer 'does this control expose its state at all?' before writing an assertion around it. For a single match with fewer attributes, find_element is the smaller answer.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Bare resource-id (Compose testTag), regex full-match | |
| text | No | Visible text or content-desc, regex full-match | |
| checked | No | Only match nodes with this checked state | |
| enabled | No | Only match nodes with this enabled state | |
| focused | No | Only match nodes with this focused state | |
| selected | No | Only match nodes with this selected state | |
| device_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the disclosure burden. It clearly declares 'Read-only' upfront, explains that it returns one block per match including the flow-selector `index`, and how ambiguity is handled (shows all candidates instead of picking the first). It also notes the link to flow selector qualifiers. Minor omissions like behavior on no match or the exact output format are the only gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose ('Read-only: dump EVERY attribute...') and then proceeds logically: return format, qualifiers, use case, and alternative. Every sentence adds value, and the length is justified given the tool's complexity. There is no wasted text or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema and annotations, the description covers most essential details: what is returned, how ambiguity is handled, the relationship to flow selectors, and a usage example. It doesn't specify the output format for `bounds` or the behavior when no elements match, which would be helpful for an agent to interpret results correctly. Overall, it is nearly complete but has small gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 86%, so most parameters already have semantic descriptions. The description adds meaningful context beyond the schema: it explains that the qualifiers (enabled/checked/focused/selected) are the same as a flow selector's, and that the reported index corresponds to the one that selector will use. This clarifies how the parameters interact and what the output will be. It doesn't describe each parameter individually, but the schema already does that, so the added value is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action (dump every attribute) on a specific resource (matched elements), enumerating exactly what is returned (state flags, resource-id, class, bounds). It also distinguishes itself from find_element by noting it is the larger, more exhaustive alternative for ambiguous selectors, making it easy for an agent to tell apart from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly specifies when to use: 'Use it while authoring to answer
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
device_infoB
(Android) Get detailed information about a connected Android device
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the disclosure burden. The verb 'Get' implies a non-mutating read and 'connected Android device' names a precondition, but the description does not disclose return contents, error behavior, or what happens when no device_id is provided. It is not misleading, but it is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no filler, and it front-loads the verb and object. It is appropriately compact for a one-parameter getter, though a brief clarification of what 'detailed information' includes would make it more useful while still remaining concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and has one optional parameter, but there is no output schema and no annotations to describe the return contract. 'Detailed information' is too generic to tell an agent exactly what it will receive, and no caveats are mentioned beyond the device being connected. This is a minimum-viable definition with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the device_id parameter is already fully documented in the schema, including fallback to the default device. The description adds no meaningful parameter semantics beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Get') and a concrete resource ('detailed information about a connected Android device'), with an explicit '(Android)' platform prefix. It is clearly distinguishable from the UI-action siblings, though it does not specify what 'detailed information' includes or explicitly contrast itself with list_devices/connect_device.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as list_devices, connect_device, or get_current_activity. It states only the operation, leaving the agent to infer the appropriate context and no exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dump_uiC
(Android) Dump the current UI hierarchy and return a structured representation of all visible elements
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, but it only restates the core function and the visible-element scope. It does not disclose whether the tool is read-only, whether it requires an accessibility or instrumentation setup, or what performance/impact it may have.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one focused sentence with no filler, and the platform and primary action are front-loaded. Every phrase ('current', 'structured representation', 'visible elements') contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple tool with one optional parameter, but the absence of an output schema and annotations means the description should explain more about the returned structure and how to use the result. It also does not address the closely related observe_ui sibling, leaving selection and output interpretation under-specified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents device_id at 100% coverage, including the default-device behavior. The description adds no extra parameter semantics, so the schema-baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('dump'), the resource ('current UI hierarchy'), and the output ('structured representation of all visible elements'), so an agent can tell what the tool does. It does not differentiate itself from the overlapping sibling observe_ui, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use dump_ui instead of alternatives like observe_ui, find_element, or describe_element. The '(Android)' prefix is useful context but not a selection rule, and there are no exclusions or conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_elementA
Find a UI element by text, resource ID, or class name and return its attributes and bounds. Returns the FIRST match with 8 of the node's attributes; describe_element returns every match with all 17 plus the index: a flow selector would use, and is the one to reach for when a selector may be ambiguous or when a state flag is in question.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text or content-desc; regex full-match — use .* for partial, e.g. 'Sign.*' | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| class_name | No | Ignored in M1; reserved for a future class selector | |
| resource_id | No | Bare resource-id, e.g. login_button; regex full-match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It does disclose key behaviors: returns the first match, returns 8 attributes, and includes bounds. However, it does not specify what happens on no match (e.g., null, error), the exact return structure, or whether the operation is read-only (implied but not stated). These gaps leave some uncertainty for an agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero waste. The first sentence states the purpose and output, and the second immediately pivots to the sibling comparison and usage guidance. It is front-loaded and every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema, so the description must compensate by explaining the return value. It mentions 'attributes and bounds' and '8 attributes' but does not enumerate which attributes or describe the return format in detail. It also omits error behavior and the default device behavior (though schema covers device_id default). For a read-only find operation, this is adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so each parameter already has a meaningful description (e.g., text is visible text or content-desc with regex full-match). The tool description adds no extra parameter semantics beyond what the schema provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('find'), a resource ('UI element'), and the search methods ('text, resource ID, or class name') along with the output ('attributes and bounds'). It explicitly contrasts with describe_element by noting it returns the FIRST match with 8 attributes, clearly distinguishing the two tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly names the alternative tool (describe_element) and the conditions that should trigger its use: when a selector may be ambiguous or when a state flag is in question. This gives the agent clear when-to-use and when-not-to-use guidance without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow_referenceA
Return the compact YAML-flow grammar reference (commands, selectors, env, switchContext, examples). Call this before authoring a flow — no file lookup needed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden of behavioral disclosure. It clarifies that this is a reference retrieval with no side effects and is local (no file lookup), which is useful. However, it doesn't describe the return format details or performance characteristics, but since it's a static reference, the key behavioral traits are covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no redundancy. The purpose is front-loaded and actionable, with the usage hint appended efficiently. Every word contributes value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter reference tool, the description is complete. It specifies the content of the returned reference, when to call it, and that no additional setup is needed. Nothing is missing that an agent would need to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema coverage is 100% (empty object). The description adds semantic value by indicating what the returned reference contains, which helps the agent understand what to expect. With no parameters, a baseline of 4 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool returns: a compact YAML-flow grammar reference, listing specific components (commands, selectors, env, switchContext, examples). This is distinct from sibling tools, which are action or query tools rather than reference tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear guidance on when to use this tool: 'Call this before authoring a flow' and notes that no file lookup is needed. This is explicit usage context, though it doesn't mention alternatives or when not to use it, which is acceptable given the tool's unique reference nature.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
force_stopB
Force stop a running app
| Name | Required | Description | Default |
|---|---|---|---|
| package | Yes | The app package name to stop | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavior. It states the action but does not mention consequences like forced termination losing unsaved data, or that the app must be running. The description is minimal and omits critical side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that is front-loaded with the core action. It is appropriately brief for a simple tool, though it could include more context without becoming verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple mutation tool with no output schema, the description is minimally sufficient but lacks key behavioral details such as data-loss implications or whether the action is reversible. Given the tool's simplicity and schema coverage, this is adequate but not thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% – both 'package' and 'device_id' are already documented in the input schema. The description adds no extra meaning beyond what the schema provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Force stop a running app' uses a specific verb ('force stop') and resource ('a running app'), clearly distinguishing it from siblings like launch_app or clear_app_data. The purpose is immediately obvious and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives such as clear_app_data or uninstall_app. It does not mention prerequisites, exclusions, or typical use cases, leaving the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_current_activityA
Get the name of the currently resumed activity (foreground screen)
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. 'Get' implies a read-only action and the description makes the target state clear, but it does not mention behavior when no activity is resumed, device connection requirements, or any error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence containing only the essential information: the action, the target, and a clarifying synonym. No padding or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool with full schema coverage, the description plus schema is nearly complete. It could state the return type explicitly since no output schema exists, but 'name' already signals the expected string result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter, device_id, is already fully documented in the schema ('Target device ID. If omitted, uses the default device'). The description adds no parameter-level meaning, so it stays at the baseline for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Get') and a clear resource ('name of the currently resumed activity'), further clarified by the parenthetical '(foreground screen)'. This distinguishes it from related siblings like wait_for_activity, which waits rather than retrieves.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool instead of related alternatives such as wait_for_activity, dump_ui, or observe_ui. The description states what the tool returns but does not describe the calling context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
input_textA
Type text into a field (optionally focus it first by selector). Uses ADBKeyboard for reliability. Waits for the screen to settle, then returns a fresh snapshot — annotated if it never settled.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Bare resource-id (Compose testTag), regex full-match | |
| text | No | Visible text or content-desc, regex full-match | |
| index | No | Pick the Nth match (0-based) | |
| value | Yes | Text to type | |
| optional | No | If true, a miss does not error | |
| device_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It adds valuable behavior beyond 'type': using ADBKeyboard, waiting for the screen to settle, and returning a fresh snapshot with annotation if never settled. This is meaningful context, though it omits details about failure modes or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary action ('Type text into a field'), and every sentence adds useful behavioral information. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description explains the return behavior (fresh snapshot, optionally annotated), which is important. It also covers the typing method and settling behavior. It could be more complete by explaining what happens on failure, but the essential context for calling the tool correctly is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 83%, so the schema already documents most parameters. The description's mention of 'optionally focus it first by selector' adds context for the selector parameters (id, text, index) but does not explain value, optional, or device_id beyond what the schema provides. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool types text into a field and can optionally focus it first by selector, which is a specific verb and resource. However, a sibling tool named 'type_text' exists and the description does not differentiate input_text from it, so the agent cannot tell them apart from the description alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives like 'type_text' or other input methods. It does not state typical use cases, exclusions, or prerequisites, leaving the agent to infer when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
install_apkA
Install an APK file on a connected Android device
| Name | Required | Description | Default |
|---|---|---|---|
| apk_path | Yes | Path to the APK file on the host machine | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of disclosing behavior. It does not mention side effects like overwriting an existing app, prerequisites such as device connectivity and permissions, or possible failure modes. The description only states the core action without additional behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, direct sentence with no filler or redundant wording. It front-loads the action and object, making it immediately scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the schema fully documents the required and optional inputs, making basic invocation possible. However, with no output schema and no annotations, the description does not clarify success/error reporting, installation side effects, or device prerequisites, leaving gaps for an agent deciding how to handle failures.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of the parameters with descriptions for both apk_path and device_id, so the baseline is 3. The tool description adds no extra semantic detail beyond what the schema already provides, such as path format or how the default device is selected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Install') with a clear resource ('APK file') and target ('connected Android device'). This clearly differentiates it from sibling tools like launch_app, uninstall_app, and clear_app_data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied by the name and description, but there is no explicit guidance about when to prefer this tool over alternatives, or any exclusions such as needing the device to be unlocked or having an existing installation. No when-not-to-use conditions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_element_visibleB
Check if an element with the given text or resource ID is currently visible on screen
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text or content-desc; regex full-match — use .* for partial, e.g. 'Sign.*' | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| resource_id | No | Bare resource-id, e.g. login_button; regex full-match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It does convey that the check is of the current screen state and identifies elements by text or resource ID, which adds some meaning beyond the tool name. However, it does not state the return contract, behavior when no element matches, or whether this can throw.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one tight, front-loaded sentence with no filler. It states exactly what the tool checks and the element-identification criteria, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The core use is clear, but the description does not specify the return value or behavior when the element is not present, and it does not clarify what happens if neither text nor resource_id is provided. Given no output schema and no annotations, this is minimally adequate rather than complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents text, resource_id, and device_id including regex and default-device semantics. The description only restates that text or resource ID can be used, adding no extra parameter meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a specific operation ('check if ... currently visible') and a clear resource (element identified by text or resource ID). It is unambiguous, but it does not explicitly differentiate itself from siblings like assert_visible or wait_for_element.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus assert_visible, wait_for_element, or find_element. The 'currently visible' wording implies a direct, non-waiting check, but the agent is left to infer the right context and there are no explicit exclusions or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch_appB
Launch an Android app by package name, optionally specifying an activity
| Name | Required | Description | Default |
|---|---|---|---|
| package | Yes | The app package name (e.g., com.example.app) | |
| activity | No | The activity to launch (e.g., .MainActivity). If omitted, launches the default/launcher activity. | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only says 'Launch an Android app' but does not describe side effects, failure conditions (e.g., app not installed), whether an existing task is resumed, or what the tool returns. This is a minimal statement of the operation, not a disclosure of behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler or redundant wording. Every word contributes to the core purpose and parameter usage, making it efficiently scannable for an agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the schema covers all parameters, but there are no annotations and no output schema. The description does not mention return behavior, error cases, or any side effects of launching an app, so it is minimally adequate but not fully complete for an agent that needs to predict the tool's full effect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% descriptive coverage, so the schema already explains each parameter, including the default launcher activity behavior. The description adds no additional semantic value beyond restating that an activity may optionally be specified, which keeps this at the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Launch') and resource ('Android app') and includes the key parameters (package name, optional activity). It clearly distinguishes launch_app from siblings like install_apk, uninstall_app, and force_stop by naming the core operation directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus alternatives, and does not mention any exclusions or prerequisites. The intended usage is only implied by the tool's name and the nature of the operation, not explicitly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesB
List all connected Android devices/emulators and iOS simulators
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. The description says it lists devices, but does not reveal whether it returns only connected devices, whether it needs adb/emulator tools initialized, whether it can block/wait for devices, what happens when no devices are present, or whether the list is ordered or filtered. For a zero-parameter discover command this is a moderate gap, so it merits a 2 rather than a 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that conveys the action, the resource, and the platform scope in 9 words. There is no redundancy, and the key scope delimiter (Android/iOS, devices/emulators/simulators) is included without bloat.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (0 params, no output schema, no annotations), the description captures the primary purpose. However, it does not mention the command's value as a prerequisite for other operations (e.g., connect_device), nor hints at the output shape (device IDs, names, states). For a list command, knowing what gets returned matters to an agent, but the absence of an output schema raises the need for at least a short comment on output format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, and schema description coverage is effectively 100% (empty schema with no required properties). The baseline for a 0-parameter tool is 4. The description does not need to explain parameters; it correctly implies the tool requires no input.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('List') and resource ('connected Android devices/emulators and iOS simulators'). This clearly distinguishes it from siblings, most of which act on the current device rather than enumerating available ones. It lacks an explicit head-to-head differentiation clause with a sibling, but the verb+resource scope is clear enough on its own.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit 'use this when...' guidance or mention of alternatives such as connect_device or device_info. However, from the sibling names, listing devices is a natural precursor to connecting or acting on a device, and the zero-parameter design implies it is a discovery operation. No exclusions or when-not-to-use conditions are stated, so guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
long_pressB
Long press at specific screen coordinates
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X coordinate | |
| y | Yes | Y coordinate | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| duration_ms | No | Duration of the long press in milliseconds (default: 1000) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden for behavioral disclosure. It only states the action, not effects like whether it blocks until the press completes, if it requires a visible element, or if it could fail. The agent has no information about side effects, system behavior, or postconditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler. It states the verb and object concisely, and each word earns its place. It could not be meaningfully shorter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple action with fully described parameters and no output schema, the description is minimally adequate. However, it omits any context about when to choose this over sibling gestures, and the lack of annotations leaves safety and side-effect behavior entirely unaddressed. Given the many sibling tools, a bit more context would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all parameters are already documented with descriptions. The tool description adds no additional meaning beyond emphasizing 'specific screen coordinates,' which is already clear from the parameter names. Baseline of 3 applies because the structured schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Long press at specific screen coordinates' uses a specific verb and resource, clearly stating the gesture and where it applies. It distinguishes from siblings like tap_xy and swipe because 'long press' implies a different duration and behavior, though it does not explicitly name alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool instead of alternatives such as tap_xy, swipe, or press_key. The description does not mention context, prerequisites, or exclusions, leaving the agent to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
observe_uiB
Capture a compact, token-frugal snapshot of the current screen (actionable elements get a [ref=eN]).
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral disclosure burden. It does reveal that the snapshot is compact, token-frugal, current-screen-based, and that actionable elements include refs. However, it does not mention side effects, failure conditions, or whether it relies on the accessibility hierarchy, though 'snapshot' suggests a read-only operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One compact sentence that front-loads the key behavior and adds a useful detail about refs. There is no filler or repetition of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema and no annotations, so the description should explain enough about return values and the optional device_id parameter to allow correct invocation. It leaves device_id undocumented and does not describe what the snapshot contains beyond refs, which is incomplete for a tool in a large sibling family.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter device_id has no schema description and the tool description does not mention it at all. Since schema description coverage is 0%, the description was required to compensate and failed to explain what device_id means or how it affects the snapshot.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action (Capture) and resource (a compact, token-frugal snapshot of the current screen), and the parenthetical about actionable elements receiving [ref=eN] distinguishes it from siblings like take_screenshot and dump_ui. An agent can identify what this tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance about when to use observe_ui versus alternatives such as dump_ui, take_screenshot, or find_element. The phrase 'token-frugal' implies a use case, but no when-to-use or when-not-to-use conditions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
observe_webviewA
List the app's debuggable WebView pages and return a compact DOM snapshot of the one with the most content (css-selectored). The app must opt in to WebView debugging: on Android WebView.setWebContentsDebuggingEnabled(true), on iOS WKWebView.isInspectable = true (16.4+; Safari needs no opt-in). Pass match (a URL substring/regex) to target a specific page; pin a page in a flow with switchContext "WEBVIEW_@".
| Name | Required | Description | Default |
|---|---|---|---|
| match | No | URL substring/regex selecting a specific page | |
| package | Yes | The app package (Android) or bundle id (iOS) hosting the WebView | |
| device_id | No | Target device. An adb serial selects an Android device; a UUID-shaped simulator UDID (from list_devices) selects an iOS simulator and is REQUIRED for iOS — omit it and this call runs against Android. Optional on Android when only one device is attached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the platform-specific opt-in requirements, the selection behavior (most content), and the targeting behavior via `match`. It does not describe the exact shape of the DOM snapshot or failure modes when no debuggable WebView exists, but the core behavioral traits are well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: it front-loads the main action, then gives prerequisites, then parameter guidance, then the alternative. Every sentence earns its place and no filler is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description covers the main action, prerequisites, parameter semantics, and the sibling alternative. It could mention what happens when no debuggable WebView is found or how the DOM snapshot is returned, but the essential information for selecting and invoking the tool is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining that `match` is a URL substring/regex and that `package` is the host app, and it clarifies the device_id behavior (iOS simulator UDID required, Android optional). This is meaningful added context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List' and 'return'), a clear resource (debuggable WebView pages / DOM snapshot), and a distinctive selection criterion (the page with the most content, css-selectored). It also names the sibling alternative (switchContext) for pinning a page, which helps distinguish it from other webview tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly explains when to use this tool: to list debuggable WebView pages and get a compact DOM snapshot, and it gives the opt-in prerequisites per platform. It also tells the agent to pass `match` to target a specific page and to use switchContext for pinning a page in a flow, which is a clear alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
press_keyB
Press a hardware/software key (BACK, HOME, ENTER, MENU, etc.)
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Key name: BACK, HOME, ENTER, MENU, POWER, VOLUME_UP, VOLUME_DOWN, TAB, DELETE, DPAD_UP, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT, DPAD_CENTER, etc. | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It transparently states the core action (pressing a hardware/software key), but it does not disclose side effects, whether the press targets the foreground app, or how it behaves with device_id omitted. Still, it is not misleading and gives the basic behavioral intent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words, front-loads the action, and uses examples efficiently. It is appropriately sized for a simple input tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity, the schema fully documents both parameters, and there is no output schema requiring return-value explanation, this description is largely complete. The main gap is the lack of sibling differentiation for when to use this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema already documents the key and device_id parameters. The description adds only the generic 'hardware/software key' framing and examples, which adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Press') and a clear resource ('hardware/software key') with concrete examples like BACK and HOME. It is not a tautology and is clearly separable from coordinate or element-based sibling tools, though it does not explicitly name those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use press_key versus alternatives such as long_press, tap_xy, or tap_element. The description implies key-based input but provides no exclusions, prerequisites, or context for selecting this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_flowA
Run a validated YAML test flow on a device (deterministic, no AI). Writes an HTML report and returns a pass/fail summary + report path. Call flow_reference for the YAML grammar.
| Name | Required | Description | Default |
|---|---|---|---|
| env | No | Runtime variables, override the flow's env | |
| heal | No | Self-heal drifted selectors via fingerprints (default true; false = strict) | |
| path | Yes | Path to the .yaml flow file | |
| device_id | No | Target device: an adb serial or an iOS simulator UDID (a UDID runs a flow without platform: on iOS). If omitted: the only booted simulator for a platform: ios flow, otherwise the default adb device. | |
| output_dir | No | Run-artifact directory (default .mobile-runs/<timestamp>) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden, and it does disclose determinism, no AI, report generation, and pass/fail return. However, it does not mention the flow's side effects on the device, prerequisites like a connected/booted device, or error/failure behavior, so coverage is partial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences front-load the core purpose, then the output, then the reference to flow_reference. No redundant phrases or filler; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has five parameters, no annotations, no output schema, and a clear sibling validate_flow, yet the description omits the validation/execution workflow and failure behavior. It is adequate for basic invocation but not complete for safe, correct end-to-end use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already explains all five parameters; the description adds no parameter-level detail beyond restating 'YAML flow' and 'device.' Baseline 3 applies because the schema does the semantic heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb-resource pair: 'Run a validated YAML test flow on a device,' immediately distinguishing execution from sibling validation/reference tools. The added 'deterministic, no AI' and the output statement (HTML report, pass/fail summary) make the tool's job unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells the agent to call flow_reference for YAML grammar, which is useful routing for one sibling. It does not explicitly address when to use run_flow versus validate_flow or state exclusions/prerequisites, leaving much of the decision to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scroll_downB
Scroll down on the screen (swipe from bottom to top)
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It only states the mechanical action without mentioning any side effects, scroll extent, speed, or whether it operates on the whole screen or a focused element. This is minimal disclosure for a UI control tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with no filler. It is front-loaded with the primary action and adds the gesture detail efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple scrolling action, the description provides the essential information. However, with no annotations and no output schema, an agent might benefit from knowing whether this scrolls the entire screen, whether it waits for scrolling to finish, or how far it scrolls. These gaps make it adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter device_id is fully described in the schema (covers 100%), and the description adds no extra meaning. Since schema coverage is high, the baseline of 3 is appropriate; the description does not compensate further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (scroll down) and the specific gesture (swipe from bottom to top). This distinguishes it from the sibling scroll_up, which would imply the opposite direction, so an agent can immediately infer the tool's purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like swipe or scroll_up. It doesn't state any context, prerequisites, or conditions that would help an agent decide between this and other scrolling-related tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scroll_upA
Scroll up on the screen (swipe from top to bottom)
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of explaining behavior. It does disclose the physical gesture direction ('swipe from top to bottom'), which is useful, but it omits details like scroll distance, duration, or edge behavior. For a simple gesture tool, this is adequate but not fully transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with the core action front-loaded and the clarifying gesture in parentheses. Every word earns its place; there is no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, no-output-schema tool, the description plus schema are mostly sufficient to invoke the tool. However, it does not mention the scroll amount or how it relates to the more general swipe tool, leaving a minor but real completeness gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers the only parameter, device_id, including the default-device behavior. The description adds no parameter-specific detail, and with 100% schema description coverage, the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Scroll up on the screen.' The parenthetical 'swipe from top to bottom' disambiguates the gesture and distinguishes this from scroll_down or generic swipe usage.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus alternatives like scroll_down or swipe. The tool's name and direction imply its use, but the description does not state conditions, exclusions, or alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
swipeC
Swipe from one point to another on the screen
| Name | Required | Description | Default |
|---|---|---|---|
| x1 | Yes | Start X coordinate | |
| x2 | Yes | End X coordinate | |
| y1 | Yes | Start Y coordinate | |
| y2 | Yes | End Y coordinate | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| duration_ms | No | Duration of the swipe in milliseconds (default: 300) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. The description only says 'swipe from one point to another' and fails to disclose that this is a user-like gesture that may trigger animations, scroll actions, or require screen stability. It does not explain potential side effects or prerequisites (e.g., device must be unlocked). This is a significant gap for a UI interaction tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, which is efficient and front-loaded with the core action. It is not verbose, but it is also under-specified, which is why it scores 4 rather than 5. Every word earns its place, but there is no extra context to help the agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 6 parameters, no output schema, and no annotations, yet the description is extremely brief. Critical missing context includes coordinate system specifics, duration meaning, device targeting, and potential side effects. For a gesture tool, the description is incomplete for an agent to invoke it correctly without additional knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema describes each parameter's meaning (e.g., x1 is start X coordinate). However, the description adds no additional semantics, such as coordinate system origin (e.g., pixels from top-left), how duration affects behavior, or that device_id can target a specific device. Baseline 3 is appropriate since the schema covers the basics, but the description does not compensate for missing context like coordinate origin.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (swipe) and the resource (screen), but it is generic and does not distinguish from sibling tools like scroll_down or scroll_up, which are specific types of swipes. An agent might confuse 'swipe' with scroll gestures without additional context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives such as scroll_down, scroll_up, or tap_xy. There is no mention of use cases like swiping for navigation, dismissing elements, or scrolling through lists. The agent is left to infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
take_screenshotA
Take a screenshot of the device screen and return it as an image (returns a large image; prefer observe_ui / observe_webview text — use only when those cannot answer).
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavior. It discloses that the output is a large image, which is a meaningful trait, but it does not mention any other potential side effects or caveats (e.g., speed, resolution, or capture scope). For a read-only screenshot tool, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two short sentences, with the core action front-loaded and the usage caveat following. Every clause serves a purpose, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description covers the action, the output type, and when to use it. The only minor gap is that it doesn't specify the exact format or size beyond 'large image', but that is not critical for invocation. Overall, it is sufficiently complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage for the single optional device_id parameter, so the description does not need to add parameter details. It does not add any extra meaning beyond the schema, which is acceptable given the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Take a screenshot') and the subject ('device screen'), and clearly indicates the output is an image. It also differentiates from siblings by naming observe_ui / observe_webview as preferred alternatives, so an agent can distinguish this from text-extraction tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to use: 'prefer observe_ui / observe_webview text — use only when those cannot answer.' This gives clear conditional guidance and names the alternatives, leaving no ambiguity about selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tapA
Find an element by selector and tap its center. Waits for the screen to settle, then returns a fresh snapshot — annotated if it never settled.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Bare resource-id (Compose testTag), regex full-match | |
| text | No | Visible text or content-desc, regex full-match | |
| index | No | Pick the Nth match (0-based) | |
| optional | No | If true, a miss does not error | |
| device_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
There are no annotations, so the description carries the behavioral burden. It usefully discloses that the tool waits for the screen to settle, returns a fresh snapshot, and annotates the snapshot if it never settled. It does not cover error behavior or edge cases, but the optional parameter partially signals miss handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence with the primary action front-loaded. Every phrase adds value, and there is no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with optional parameters and no output schema, the description adequately explains core behavior and return value. It is missing explicit sibling differentiation and failure-mode details, but it is sufficient for basic invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high at 80%, and parameter descriptions already explain id, text, index, and optional. The description adds only general selector context and does not clarify the undocumented device_id parameter or add meaningful semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description identifies a specific verb and resource: find an element by selector and tap its center. It also communicates a clear postcondition (returning a fresh snapshot). However, it does not explicitly distinguish itself from the similarly named sibling tap_element.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does but gives no guidance about when to use it versus alternatives like tap_xy, tap_element, or long_press. An agent is left to infer selection from tool names rather than from explicit usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tap_elementC
Find a UI element by text, resource ID, or class name and tap its center
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text or content-desc; regex full-match — use .* for partial, e.g. 'Sign.*' | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| class_name | No | Ignored in M1; reserved for a future class selector | |
| resource_id | No | Bare resource-id, e.g. login_button; regex full-match |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, but it only discloses that the tap lands at the element's center. It does not mention what happens when multiple elements match, what occurs if no element is found, or that class_name is ignored in M1. The mention of class_name as a lookup method is potentially misleading given the schema says it is ignored.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence that conveys the core action, target, and selector types without wasted words. Every phrase contributes to understanding what the tool does.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a UI action with no output schema and no annotations, the description is too thin to be fully actionable. It lacks guidance on alternative tool selection, behavior on multiple/no matches, and the fact that class_name is not currently functional in M1. The rich parameter schema helps, but the surrounding context is still incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so each parameter is already documented. The description adds a useful summary of the selector parameters but no new meaning beyond what the schema provides, and it omits parameter-specific notes like regex matching and the deprecated/ignored nature of class_name.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear verb-target relationship: find a UI element by text, resource ID, or class name, then tap its center. This is specific enough to distinguish it from coordinate-based taps, though it does not explicitly name sibling tools or explain how it differs from them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given for when to prefer tap_element over alternatives like tap_xy, long_press, or find_element. The description implies useful selection criteria (text/resource-ID/class-name) but provides no exclusions, prerequisites, or conditions for when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tap_xyA
Tap at raw screen coordinates (x, y). To tap an element by selector, use the 'tap' tool.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X coordinate to tap | |
| y | Yes | Y coordinate to tap | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries behavioral disclosure on its own. It clearly indicates the tap is at raw screen coordinates and does not involve element lookup, but it omits details like coordinate origin/units and out-of-bounds behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences deliver the core purpose first and the alternative second, with no redundant wording.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple and the schema documents all parameters, but there is no output schema or behavior notes about coordinate system or failure cases. The description is adequate for basic invocation but leaves a few operational details implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description doesn't need to repeat parameter definitions. It adds the useful clarification that x/y are raw screen coordinates rather than element-relative, though it does not specify units or origin.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('Tap') and a specific resource ('raw screen coordinates'), distinguishing this tool from selector-based tapping. The explicit contrast with the 'tap' tool makes its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly tells the agent when not to use this tool: to tap an element by selector, use the 'tap' tool instead. This gives a direct routing rule from raw-coordinate tapping to selector-based tapping.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
type_textA
Type text into the currently focused input field. Unicode is supported when ADBKeyboard is installed on the device.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to type | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavior. It mentions Unicode support with ADBKeyboard, which is useful, but it does not disclose what happens if no field is focused, whether it clears existing text, or if it performs a tap first. This is a moderate disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence, front-loading the primary action and including a useful caveat about Unicode support. No filler words; every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 2-param tool with full schema coverage, the description is adequate. However, there is no guidance on the focused field requirement or fallback behavior, and no output schema, so an agent might be uncertain about success conditions. It is not missing critical info but could be richer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with descriptions for both parameters. The description adds the Unicode detail and the focused input context, but these are not parameter-specific. The schema already explains text and device_id, so the description adds minimal extra param meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it types text into the currently focused input field, which is specific and distinguishes it from tap, swipe, and other input tools. It could be improved by noting that it requires a focused field, but overall it is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it (when typing text is needed) but does not explicitly contrast with sibling tools like input_text or webview_input, nor does it provide exclusion conditions (e.g., when text field is not focused). It gives no guidance on when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
uninstall_appA
Uninstall an app from a connected Android device
| Name | Required | Description | Default |
|---|---|---|---|
| package | Yes | The app package name to uninstall | |
| device_id | No | Target device ID. If omitted, uses the default device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the safety burden. 'Uninstall' clearly signals destructive removal, but the description does not explicitly mention that app data is deleted or that the operation is irreversible, which would strengthen transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no filler. Every word contributes to identifying the action, the target, and the environment.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with a fully documented schema, the description plus schema is sufficient for correct invocation. It could add a note about return values or data-loss side effects, but those are refinements rather than missing essentials.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents both package and device_id with 100% coverage. The description adds no parameter-level meaning beyond what the schema provides, so it earns the baseline score for fully covered schemas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific action 'Uninstall' and the resource 'app', scoped to 'a connected Android device'. This is clearly distinct from sibling tools like install_apk, clear_app_data, and force_stop.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use it when you need to remove an app from an attached Android device. It does not name alternatives or exclusions, such as using clear_app_data when the app should remain installed, so it stops short of explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
validate_flowA
Statically validate a YAML test flow file (schema, fragile-selector + undefined-env lint, and subflow resolution). No device needed. Call flow_reference for the YAML grammar.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Path to the .yaml flow file |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that validation is static and lists the checks performed, but it does not state whether the operation is read-only, what it returns on success/failure, or any error behavior. For a validation tool, this is a meaningful gap, though the word 'statically' hints at no side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The primary purpose is front-loaded, and the pointer to flow_reference is a useful one-line addition. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the tool's core validation scope but omits the return format (e.g., error list, exit code) and does not explicitly confirm it is read-only. Given there is no output schema, the description should have explained what the agent can expect as a result. The absence of that detail leaves a notable gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the parameter description already states 'Path to the .yaml flow file.' The tool description does not add further meaning about path syntax, file naming conventions, or required permissions. The baseline of 3 applies because the schema fully documents the parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Statically validate a YAML test flow file.' It lists concrete validation aspects (schema, lint, subflow resolution) and explicitly contrasts with sibling flow_reference by directing the agent there for grammar. The 'No device needed' qualifier further separates it from device-dependent siblings like run_flow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: static validation without a device, and points to flow_reference as the alternative for grammar. Although it doesn't explicitly state 'use this instead of run_flow when you only need to check validity,' the 'No device needed' phrase strongly implies that distinction. This is enough for an agent to infer when to choose this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_for_activityC
Wait until a specific activity becomes the foreground (resumed) activity
| Name | Required | Description | Default |
|---|---|---|---|
| activity | Yes | Activity name or partial match (e.g., '.MainActivity' or 'com.example/.MainActivity') | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| timeout_ms | No | Maximum time to wait in milliseconds (default: 10000) | |
| poll_interval_ms | No | Polling interval in milliseconds (default: 500) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure. It states the core behavior (wait until foreground) but omits critical details: it does not mention that the tool blocks until the timeout, what happens on timeout (error vs return), whether it returns any value, or how it interacts with device_id. For a blocking wait operation, this is a significant transparency gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence that front-loads the essential purpose. There is no wasted wording, and it is appropriately concise for a simple wait operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of annotations and output schema, the description is too thin. An agent needs to know whether the tool raises an exception on timeout, what it returns upon success, and whether it targets a specific device. The current description does not address these, leaving an agent uncertain about failure modes and postconditions. For a tool with 4 parameters and no other documentation, this is incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all four parameters have descriptions in the schema), so the baseline is 3. The description adds minimal value beyond the schema: it confirms the 'activity' parameter is the target of the wait, but it does not explain semantics of timeout_ms or poll_interval_ms beyond what the schema already states. No additional guidance on partial matching or device targeting is provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: wait until a specific activity becomes the foreground (resumed) activity. It names the resource (activity) and the condition, and it is distinct from sibling tools like wait_for_element or wait_for_text which wait for UI elements/text. However, it does not explicitly differentiate from get_current_activity which polls the current activity, so a small gap remains.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives. The description only states what it does, with no exclusions, no mention of alternative tools, and no context about prerequisites or typical scenarios. An agent would have to infer that this is for waiting on activity state changes, but no explicit direction is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_for_elementB
Wait until a UI element matching the query appears on screen, polling at regular intervals
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Visible text or content-desc; regex full-match — use .* for partial, e.g. 'Sign.*' | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| timeout_ms | No | Maximum time to wait in milliseconds (default: 10000) | |
| resource_id | No | Bare resource-id, e.g. login_button; regex full-match | |
| poll_interval_ms | No | Polling interval in milliseconds (default: 500) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden of behavioral disclosure. It does add 'polling at regular intervals,' but it does not say what happens on timeout, whether the element must be visible or merely present in the hierarchy, or whether the tool returns a boolean or raises an error. This is a significant gap for a blocking wait operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words. It front-loads the core action and then adds the polling detail. Every clause contributes meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple wait tool with no output schema and no annotations, the description is incomplete. Schema covers parameters, but the description lacks timeout failure behavior, return/error semantics, and any comparison to sibling wait or visibility tools. An agent cannot fully predict how the tool behaves in edge cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema fully documents text, resource_id, timeout_ms, poll_interval_ms, and device_id. The description's generic 'matching the query' adds no parameter detail beyond the schema, which is acceptable at the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Wait until a UI element matching the query appears on screen' with explicit polling behavior. It distinguishes this from sibling wait_for_text, wait_for_activity, find_element, and assertion tools without requiring schema inspection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance about when to prefer this tool over wait_for_text, assert_visible, find_element, or is_element_visible. It also does not state exclusions or mention that wait_for_text is a specialized alternative. An agent must infer the intended use from the name and sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wait_for_textB
Wait until specific text appears anywhere on the screen
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | The text to wait for | |
| device_id | No | Target device ID. If omitted, uses the default device. | |
| timeout_ms | No | Maximum time to wait in milliseconds (default: 10000) | |
| poll_interval_ms | No | Polling interval in milliseconds (default: 500) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations and no output schema, the description carries the burden of explaining behavior. It only states that the tool waits for text; it does not disclose what happens on timeout (exception vs false return), whether the text is searched in visible/rendered content only, or whether it might throw if text is not found. Schema parameters hint at polling and timeout, but the outcome behavior remains undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no filler or redundancy. It efficiently conveys the essential operation and scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations and no output schema, the description leaves meaningful gaps: return/termination behavior on timeout, how 'text' is matched, and when to choose this over wait_for_element or assert_text. The schema covers parameters well, but the operational contract is incomplete for an agent deciding whether to call it and what to expect.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents text, device_id, timeout_ms, and poll_interval_ms. The description adds no new parameter-level meaning beyond implying the text is the target condition, so a baseline score is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Wait until') and resource ('specific text appears anywhere on the screen'), so an agent can understand the core function. It does not explicitly differentiate from siblings like wait_for_element or assert_text, but the 'text appears anywhere' phrasing provides enough distinction to be more than simply restating the name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the usage context: use when you need to block until text appears on screen. However, it offers no explicit when-to-use versus alternatives such as wait_for_element, assert_text, or wait_for_activity, and no exclusions or conditions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
webview_inputA
Type text into a WebView field by css (or text) selector, then return the updated WebView DOM (focuses + sets the value so framework inputs accept it).
| Name | Required | Description | Default |
|---|---|---|---|
| css | No | ||
| text | No | ||
| match | No | ||
| value | Yes | Text to type | |
| package | Yes | ||
| device_id | No | Target device. An adb serial selects an Android device; a UUID-shaped simulator UDID (from list_devices) selects an iOS simulator and is REQUIRED for iOS — omit it and this call runs against Android. Optional on Android when only one device is attached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description is the only source of behavioral disclosure. It reveals that the tool focuses the field and sets the value rather than merely sending keystrokes, and that it returns the updated WebView DOM. This exceeds a bare action statement, though it does not cover side effects or failures.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence that front-loads the core action and the distinctive return behavior; no filler or repeated schema information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description gives the essential action, return behavior, and focus/value mechanism, but with no annotations and no output schema it leaves the selector requirement and remaining parameters (match, package) implicit. Adequate for basic use but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is only 33%, so the description must compensate. It clarifies that css or text is a selector mechanism and value is typed text, but it does not explain match or package semantics, leaving several parameters under-specified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description opens with a specific verb and resource ('Type text into a WebView field') and names the selector mechanism and return value. This cleanly distinguishes it from generic siblings like type_text/input_text by targeting WebView fields.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear context for when to use: interacting with WebView fields using a css/text selector, returning updated DOM. It does not explicitly state when not to use or name alternatives, but the WebView scoping is enough to route an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
webview_tapB
Tap an element inside the app's WebView by css (or text) selector, then return the updated WebView DOM (auto-waits + scrolls into view). Use the css from observe_webview; pass match= to target a specific page.
| Name | Required | Description | Default |
|---|---|---|---|
| css | No | ||
| text | No | Visible-text selector for the element (alternative to css) | |
| match | No | ||
| package | Yes | ||
| device_id | No | Target device. An adb serial selects an Android device; a UUID-shaped simulator UDID (from list_devices) selects an iOS simulator and is REQUIRED for iOS — omit it and this call runs against Android. Optional on Android when only one device is attached. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description mentions auto-waits and scrolls into view, which are useful behavioral details beyond what the schema provides. Since annotations are absent, this is a positive addition, but it doesn't cover potential failure modes or side effects of tapping.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with the core action and key usage context. It's concise and front-loads the primary verb and resource, but it could be clearer about parameter specifics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 5 parameters, moderate complexity, and no output schema. The description covers main use cases and return value, but lacks details on error handling, edge cases, or the exact structure of the returned DOM. It's adequate but not exhaustive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 40% coverage, with descriptions for text and device_id. The description adds meaning for css (from observe_webview) and match (target specific page), but package and device_id are not fully elaborated. It partially compensates for the schema gap, but not completely.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool taps an element in a WebView using a css or text selector, distinguishing it from generic tap tools. It mentions returning the updated DOM and references observe_webview for context, which helps differentiate from siblings like tap_element.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It instructs to use css from observe_webview and to pass match for a specific page, which gives some usage context. However, it does not explicitly state when to use this over tap_element or other tapping tools, nor mention any alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
38 tool updates
v3.8.0- First observed
assert_not_visible - First observed
assert_text - First observed
assert_visible - First observed
check_testability - First observed
clear_app_data - First observed
connect_device - First observed
describe_element - First observed
device_info - First observed
dump_ui - First observed
find_element - First observed
flow_reference - First observed
force_stop - First observed
get_current_activity - First observed
input_text - First observed
install_apk - First observed
is_element_visible - First observed
launch_app - First observed
list_devices - First observed
long_press - First observed
observe_ui - First observed
observe_webview - First observed
press_key - First observed
run_flow - First observed
scroll_down - First observed
scroll_up - First observed
swipe - First observed
take_screenshot - First observed
tap - First observed
tap_element - First observed
tap_xy - First observed
type_text - First observed
uninstall_app - First observed
validate_flow - First observed
wait_for_activity - First observed
wait_for_element - First observed
wait_for_text - First observed
webview_input - First observed
webview_tap
TDQS
Scored across 38 tools
Multiple tools overlap heavily: tap_element and tap both tap by selector; type_text and input_text both type into fields; find_element, describe_element, dump_ui, and observe_ui all provide UI hierarchy/element querying. An agent would need to read detailed descriptions to avoid misselecting the wrong tool.
Most tools use a readable verb_noun snake_case pattern, but there are notable inconsistencies: tap_element and tap are near-synonyms, type_text and input_text are duplicate concepts, and webview_tap/webview_input invert the expected verb-object order. The general pattern is still recognizable.
38 tools is a heavy surface for a mobile testing server, and several tools are near-duplicates rather than genuinely distinct capabilities. The count would be more reasonable if tap_element/tap and type_text/input_text were merged.
The core mobile testing lifecycle is well covered: discovery, interaction, waiting, assertions, screenshots, app lifecycle, device management, WebView automation, and YAML flow validation. Minor gaps exist, such as clearing text fields, element-level swipes, and waiting for an element to disappear, but these are workaroundable.
Maintenance
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Drive real Android & iOS devices and web browsers from natural language for mobile + web QA. 290+ tools across device control, app management, automation sessions, browser automation, and flow recording / replay. Bearer-auth — get a token at robotactions.com → Profile → API Tokens.
- LimrunOAuthcom.limrun
Cloud iOS simulators and Android emulators your agent can create, drive, and throw away.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceEnables AI-powered mobile app testing and automation through Appium, using Azure OpenAI to intelligently navigate mobile applications and generate test cases.-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to automate Android mobile device testing through Appium, with automatic device detection, screen element inspection, and natural language test scenario execution.3MIT

MCP Appiumofficial
AlicenseBqualityAmaintenanceEnables AI assistants to automate mobile app testing and development for iOS and Android through natural language interactions. Supports intelligent element identification, session management, automated test generation, and comprehensive device interactions including clicks, swipes, screenshots, and app management.316,084 npm471Apache 2.0
Argentofficial
AlicenseAqualityAmaintenanceEnables AI assistants to interact with iOS Simulators and Android Emulators, allowing autonomous app development, UI interaction, profiling, and debugging through natural language.762,841Apache 2.0