brickproof-adb
Controls Android devices (TV boxes, phones, tablets) over ADB: discovers and connects devices on the network, takes screenshots and dumps UI elements, taps/swipes/types and presses remote keys, finds and activates on-screen labels, installs APKs and split bundles, pushes/pulls files, and manages packages with dry runs, protected-package refusal, snapshots and one-call rollback.
brickproof-adb
Let an AI assistant look after your own Android devices — TV boxes first, phones and tablets too — over ADB, without bricking them.
brickproof-adb is an MCP server. It gives Claude (or any MCP client) the screen, the input and the package manager of your devices, and puts guard rails where a careless call would hurt: every package change is a dry run first, the packages a device cannot live without are read off the device and refused, a package that serves something on your network right now is not touched, and everything applied goes into a snapshot that one call rolls back.
It runs on Windows, macOS and Linux, in Docker, and as a Home Assistant app; devices connect over USB or the network.
What it looks like
Finding the TV.
You: Find my TV.
Claude calls
adb_devices discover=true. Nothing is connected yet; the search looks for devices that announce debugging and for port 5555 on the home network:Found: 192.0.2.50:5555 (port 5555 open, network debugging) - adb_connect host=192.0.2.50:5555; if this computer is new to the device, it asks on its screen to allow debuggingClaude: I found one device at 192.0.2.50. Shall I connect? The TV will ask whether to allow debugging.
You: Yes.
Claude calls
adb_connect host=192.0.2.50:5555; you confirm the prompt to allow debugging on the TV screen, with "Always allow" checked. The address is remembered and connected again whenever the server starts.
Installing what you just downloaded.
You: Install on the TV the app I just downloaded.
Claude calls
adb_installwithout a path and gets the newest installable files of your Downloads folder, thenadb_installwith the first one: a report of what would be installed on which device. After your yes, the same call withdry_run=falseinstalls it.
Cleaning up a TV box.
You: The box is slow. Turn off the preinstalled junk, but nothing it needs.
Claude calls
adb_app action=list filter=system, picks five packages and callsadb_app action=disablewith them. That is a dry run by default: the plan comes back with the rollback path of each package — and one package refused, because the box uses it as its launcher:REFUSED: the list contains protected packages - com.example.launcher. com.example.launcher — launcher, roles (HOME) The full set with every source: adb_app action=protected Nothing was applied. Remove them from the list by hand; the tool has no override.Claude drops it, runs the plan for the other four, then repeats it with
dry_run=false. The account count and the launcher are checked after the batch, and the four packages are recorded in the snapshot.You: The voice remote stopped working.
Claude calls
adb_app action=restore, reads the plan and repeats it withdry_run=false: the four packages are enabled again in one call.
Seeing the screen and tapping.
You: Open the network settings on the phone.
Claude calls
adb_screenshot, gets the picture and the line under it:screen 1080x2340 -> image 473x1024 · scale 2.283/2.285 · pass coords="screenshot" to adb_tap/adb_swipeand taps the "Network & internet" row it sees, with
adb_tap coords="screenshot", in the image's own coordinates. On a TV box without a touchscreen it usesadb_find_and_tap text="Network", which walks the focus there with the remote's keys.
Related MCP server: adb-tv-mcp
Install it where your AI is
Details, other setups and checks: docs/installation.md. An AI app without MCP support cannot use this server.
Home Assistant — install the ha-adb-mcp app. It is reachable from a browser chat through your Home Assistant's external address.
Claude Desktop (Windows, macOS) — download the
.mcpbfile from the latest release and drag it into the Claude Desktop window, or choose it in Settings → Extensions → Advanced settings → Install Extension… (a double click works too, unless an archiver opens the file instead); Claude Desktop shows a short form and installs it. No Node.js needed. A JSON configuration instead: docs/installation.md.Claude Code:
claude mcp add brickproof-adb -- npx -y brickproof-adbOther MCP clients on your computer — the server command is
npx -y brickproof-adb.A chat in the browser without Home Assistant — needs a computer at home that stays on, running
brickproof-adb serve, behind a public HTTPS address: docs/installation.md.Docker —
ghcr.io/st412m/brickproof-adb: docs/installation.md.
First run
Turn on debugging on the device. Android TV, Google TV, Fire TV and phones hide it under Developer options, which appear after tapping the build number seven times in the About screen of the settings. There: USB debugging for a cable; Network debugging or ADB debugging on many TV boxes; Wireless debugging on a phone with Android 11 or newer.
Tell the assistant "find my TV" (or phone). It searches the network and suggests what to connect; a phone on a cable shows up by itself.
Confirm the prompt to allow debugging on the device screen, with "Always allow" checked. A phone over Wi-Fi asks for the pairing code shown on its screen instead.
Defaults that need no setting: files go to and from your Downloads folder, connected devices are remembered, and adb is found by itself (or brickproof-adb get-adb downloads it).
Requirements
Node.js 22.17 or newer — for every setup except the Claude Desktop extension, Home Assistant and Docker.
adb (Android SDK Platform-Tools): found by itself where Android Studio, WinGet, Homebrew or your system put it, or downloaded with
brickproof-adb get-adb. Docker and Home Assistant bring their own.A device with debugging on, over USB or the network.
Connecting
Over stdio (Claude Desktop, Claude Code) there is nothing to connect: the client starts the server. Over HTTP (brickproof-adb serve) the token goes either in the path or in a header:
https://<your-host>/private_<token>/mcp
Authorization: Bearer <token>The token is generated on the first start; brickproof-adb token shows it again, brickproof-adb token --new replaces it. See docs/security.md.
Tools
18 tools. Semantics, refusals and time limits: docs/tools.md; screen geometry and input: docs/screen-and-input.md.
adb_devices— connected and remembered devices;discover=truesearches the networkadb_connect— connect a network device,iporip:port; remembered for the next startadb_disconnect— drop one network device (and forget it), or alladb_pair— pair an Android 11+ device over Wireless debuggingadb_shell— any shell command; off unlessallow_shellis setadb_logcat— recent log lines, filtered on the deviceadb_screenshot— the screen as JPEG, with the scale to tap byadb_ui_dump— on-screen elements with tap coordinatesadb_tap— tap a point, in screen or screenshot coordinatesadb_swipe— swipe or long-pressadb_key— a key press (HOME, BACK, DPAD_CENTER…)adb_text— type into the focused field, Unicode through ADBKeyBoardadb_find_and_tap— find an element by its label and activate itadb_install— install an APK, a split set or an.apks/.xapk/.apkmbundle; dry run by default; without a path, lists what can be installedadb_uninstall— remove an app by package nameadb_app— package operations with guard rails, snapshot and rollbackadb_push— copy a file to the deviceadb_pull— copy a file from the device
Safety
What protects your devices, and what does not: docs/safety.md. In short: dry runs by default, a protected set read off the device, a network guard on live services, an account canary between batches, a snapshot with one-call rollback, and adb_shell and uninstalling off until you turn them on. No tool changes these switches; you do, with brickproof-adb set or in the settings of your app.
Limitations
ADB is not a sandbox. With
allow_shellon,adb_shellcan do anything the device's shell user can, past every guard.The search finds devices on the same network only: a guest network, Wi-Fi client isolation or separate VLANs hide them. In Docker and Home Assistant only TV boxes on port 5555 are found; phones connect by the address on their screen.
The tool list is cached per chat; after an update start a new chat.
A screenshot of a sleeping device is a dark frame, and the answer says
screen: Asleep;adb_key key=WAKEUPwakes it, and HDMI-CEC may then switch on the television.Content protected with FLAG_SECURE (streaming players, banking apps) shows as a black frame.
Snapshots live on the machine that made them: a rollback has to run where the change was made.
USB devices in Docker work only on a Linux host.
License
Available Tools
18 toolsadb_appManage packagesADestructive
Package operations with guard rails: inspect, launch, stop, clear, disable, uninstall, back up and restore packages. Use it rather than adb_shell or adb_uninstall for package changes. Every action that changes packages defaults to dry_run=true. A protected set derived from the device (launcher, active IME, installer, WebView provider, role holders, account packages) aborts the whole call on any overlap, and has no override. A network guard refuses disable, uninstall, stop and clear while the package is serving an off-device client, naming the port and the peer. Only force_network=true lifts it; force covers a failed APK backup and nothing else. An account canary between batches rolls a batch back and stops on a drop. Everything applied goes into a snapshot, so action=restore undoes it. mode=uninstall also needs the server option allow_uninstall and a successful APK backup. action=launch also accepts uri and/or intent_action for an intent or deep link; CALL, CALL_PRIVILEGED and CALL_EMERGENCY are refused while allow_shell is false.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | action=list only: case-insensitive substring filter | |
| uri | No | action=launch only: deep-link / intent data URI (am start -d). Its presence, together with intent_action, selects the intent-based launch instead of resolving the package's main activity. | |
| mode | No | How to remove: disable (default) is undone by action=enable or restore; uninstall needs allow_uninstall. | |
| force | No | Proceed even if the APK backup failed. Off by default. It does not affect the network guard; see force_network. | |
| scope | No | action=backup only: what to back up when packages is omitted (default user) | |
| store | No | Where snapshots and APK backups live: by default the snapshot store (setting store). Another path must be inside file_roots. | |
| action | Yes | list/info/protected/state only read. launch/stop/clear act at once (clear defaults to dry_run), stop/clear under the network guard. disable/uninstall/enable/restore default to dry_run. | |
| backup | No | Pull APKs before removing. Default true for uninstall, false for disable. | |
| canary | No | Check the account count and the launcher between batches, default true. Turning it off removes the only automatic check for a latent breakage. | |
| extras | No | action=launch only: intent extras. string -> --es, boolean -> --ez, int32 integer -> --ei, larger integer -> --el; anything else is refused by key name. A JSON-stringified object is accepted too. | |
| filter | No | action=list only, default user | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| dry_run | No | Default true for state-changing actions. Set false to actually apply. | |
| packages | No | Package name or array of package names. For action=launch with uri/intent_action, at most one package is accepted (used as -p to narrow the resolver); it is otherwise optional there. | |
| batch_size | No | Packages per batch between canary checks, default 5, max 25 | |
| force_network | No | Override the network guard for disable, uninstall, stop and clear: act on a package that is currently serving an off-device client. It does NOT override the protected set. Off by default. | |
| intent_action | No | action=launch only: intent action, default android.intent.action.VIEW when uri is set. Must match [A-Za-z0-9_.]+. See the CALL refusal note above. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the destructiveHint=true annotation: it names the protected set and that overlap aborts the whole call with no override, describes the network guard's refusal message (port and peer), the account canary rollback, snapshot-backed restore, and the allow_uninstall prerequisite. This is exactly the operational risk context an agent needs before a destructive call.
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?
Front-loaded with a one-line scope statement and then dense, non-redundant sentences about guards and preconditions. The unbroken paragraph of seven dense sentences makes it harder to scan than a short bulleted list would be, but no sentence is 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 17-parameter destructive tool with no output schema, it covers the safety model thoroughly (guards, canary, snapshot, uninstall prerequisites). The gap is the read-side actions: list/info/protected/state are only summarized as 'only read', so an agent gets no sense of what state or protected report or what a batch result looks like.
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 per-property descriptions are already detailed, so the baseline is 3; the description earns an extra point by disambiguating cross-parameter semantics the schema documents only locally — force covers a failed APK backup 'and nothing else' while force_network lifts only the network guard and never the protected set. It still restates some defaults (dry_run, backup) that the schema already carries.
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?
Opens with a specific verb set and resource ('Package operations ... inspect, launch, stop, clear, disable, uninstall, back up and restore') and explicitly distinguishes itself from adb_shell and adb_uninstall. An agent can route package-management calls here without opening a 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?
States the routing decision outright ('Use it rather than adb_shell or adb_uninstall for package changes') and layers per-action guidance (which actions are instant vs dry_run, which fall under the network guard). Alternatives are named and the condition selecting them is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_connectConnect deviceAIdempotent
Connect to a device over network ADB. host is ip or ip:port (default port 5555). An Android 11+ phone with Wireless debugging is paired once with adb_pair first; after that adb_connect is enough. The reverse is adb_disconnect.
| Name | Required | Description | Default |
|---|---|---|---|
| host | Yes | Device address: ip (port 5555 implied) or ip:port, e.g. 192.0.2.50 or 192.0.2.50:5555. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-readonly, non-destructive, idempotent, non-open-world semantics, and the description adds real behavioral context on top: network transport, default port 5555, and the one-time pairing prerequisite on Android 11+. It does not cover failure modes (same-network requirement, refused/timeout behavior) or what happens when re-connecting an already-connected host, so it stops short of a 5.
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?
Four short sentences, purpose front-loaded, with the prerequisite and inverse tool in the position an agent reads last. The host/port sentence duplicates the schema's own description and is the one mildly redundant element, keeping this just under a 5.
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 tool with no output schema and adequate annotations, the description covers purpose, prerequisite, addressing format, and the inverse operation, which is enough to invoke it correctly. The remaining gap is runtime behavior on failure or on already-connected devices, which an agent would have to discover empirically.
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% and the single host parameter is fully documented in the schema, including the implied default port and an example address. The description largely restates that format, adding no syntax or edge-case meaning beyond what the schema already carries, 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?
States a specific verb and resource ('Connect to a device over network ADB') and immediately disambiguates against siblings by naming adb_pair as the prerequisite and adb_disconnect as the inverse operation. An agent can distinguish this tool from the rest of the adb_* family without opening any 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?
Explicitly states the condition for use: an Android 11+ phone must be paired once with adb_pair, 'after that adb_connect is enough.' It also names the inverse tool, adb_disconnect, giving the agent both the entry condition and the exit path.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_devicesList devicesARead-onlyIdempotent
List connected Android devices with serial, state and description (adb devices -l), and remembered addresses that are not connected now. Start here: the other tools take serial from this list. If the device the user means is not in the list, call again with discover=true: it searches the local network for devices to connect (mDNS and port 5555), any time and as often as needed, and connects none of them.
| Name | Required | Description | Default |
|---|---|---|---|
| discover | No | Search the local network (about 10 s) for devices with network or Wireless debugging on; returns candidates and the next step for each. Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is largely covered; the description still adds real value by disclosing that discovery performs a local-network scan and 'connects none of them', i.e. the call is a candidate-producing probe, not a mutation. Minor tension: a LAN scan (mDNS/port 5555) sits awkwardly beside openWorldHint=false, though the description's explicit no-connect guarantee keeps the agent from misreading it as an external write.
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?
Front-loaded with the core purpose and the 'Start here' routing cue, with the discover fallback second. The final sentence is long and stacks three clauses ('any time and as often as needed, and connects none of them'), which could be trimmed, but every sentence carries 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?
No output schema exists, so the description carries the return-format burden and does so: device serial/state/description, remembered-but-disconnected addresses, and candidate lists from discovery. Combined with 100% parameter coverage and complete annotations, an agent has everything needed to call it and to interpret the 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?
Schema description coverage is 100%, so the baseline is 3, but the description goes beyond the schema by supplying the trigger condition for discover=true (the target device is absent from the list) and the repetition allowance ('any time and as often as needed'). It doesn't restate the ~10 s timing, which lives in the schema, but the added decision context is genuine.
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 a specific verb and resource ('List connected Android devices') plus the exact fields returned (serial, state, description) and mirrors the underlying command (adb devices -l). It also covers the secondary result set (remembered but disconnected addresses), so an agent can distinguish it from adb_connect/adb_pair without reading a 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?
Explicitly positions itself as the entry point ('Start here: the other tools take serial from this list') and gives a concrete escalation rule ('If the device the user means is not in the list, call again with discover=true'). It also bounds the discover call: 'any time and as often as needed, and connects none of them.' This is when-to-use, when-to-escalate, and a stated non-side-effect in three sentences.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_disconnectDisconnect deviceAIdempotent
Disconnect a network ADB device, the reverse of adb_connect. Omit host to disconnect every network device. adb_disconnect then adb_connect recovers a device that adb_devices lists as offline. With host the address is also forgotten and not reconnected at start.
| Name | Required | Description | Default |
|---|---|---|---|
| host | No | ip:port as listed by adb_devices. Omit to disconnect all network devices. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (idempotent, non-destructive, not open-world), so the bar is lower. The description goes beyond them by disclosing a persistent side effect not derivable from annotations: "With host the address is also forgotten and not reconnected at start." It does not describe the response/error surface, but the key state consequence is surfaced.
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?
Four short sentences, the primary purpose and its sibling relationship front-loaded, then omit-host behavior, then the recovery workflow, then the host-persistence caveat. No filler and nothing repeated from the schema verbatim.
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?
With one optional parameter, full schema coverage, annotations covering the safety profile, and no output schema to explain, the description supplies nearly everything an agent needs. The only minor gap is the absence of any statement about failure modes (e.g. disconnecting a host that is not connected).
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 single parameter is already documented, so the baseline is 3. The description adds meaning beyond the schema by explaining the persistence consequence of passing host (address forgotten, not reconnected at start) rather than only the omit-all behavior the schema states.
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?
Starts with a specific verb+resource ("Disconnect a network ADB device") and immediately differentiates itself from the sibling adb_connect by calling itself "the reverse of adb_connect." An agent can distinguish it from the other 17 adb_* siblings 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?
Provides concrete usage context: "adb_disconnect then adb_connect recovers a device that adb_devices lists as offline" tells the agent exactly when this tool is the right first step. It also states the omit-host case. However, it gives no explicit when-not-to-use or alternative for other disconnect scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_find_and_tapFind and tap elementA
Find an on-screen element by text, resource-id or content-desc and activate it. The method is derived from the device: with a touchscreen the element centre is tapped; on leanback without one the focus is walked there with DPAD keys, since a coordinate tap activates whatever has focus. If the focus stalls, cycles, or the target is not reached in max_steps or the time budget, nothing is pressed and the tool reports where it stopped. Prefer it over adb_ui_dump plus adb_tap when the label is known; use adb_tap for a point that has no label.
| Name | Required | Description | Default |
|---|---|---|---|
| desc | No | content-desc to match | |
| text | No | Visible label to match, checked against both the text attribute and content-desc (substring by default, case-insensitive). Some TV launchers put every label in content-desc and leave text empty. | |
| exact | No | Require an exact match instead of substring. Default false. | |
| index | No | Which match to use when several elements match. Without it, several matches are an error listing the candidates. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| max_steps | No | Max DPAD steps on leanback devices, default 12, max 40. Each step re-dumps the UI (~1.5-2s) and the walk also stops after an internal ~25s budget, returning a report instead of timing out. | |
| resource_id | No | resource-id; the part after "/" is enough |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare non-read-only, non-idempotent, non-destructive, closed-world, and the description adds real behavioral context: the tap-vs-DPAD strategy is derived from the device, and on a stalled/cycling walk nothing is pressed and a report of where it stopped is returned rather than a timeout. It stops short of describing auth/device prerequisites, which are covered only implicitly.
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?
Four sentences, well front-loaded: purpose first, then method, then failure behavior, then alternative routing. Dense but each sentence carries information; only the device-strategy sentence overlaps somewhat with the parameter docs.
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 mutating, device-dependent tool with no output schema and zero required parameters, the description covers the calling modes, fallback behavior, and failure reporting. It leaves the shape of the returned failure report unspecified, which is a minor gap given no output schema exists to document it.
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 documents all seven parameters including matching defaults and max_steps limits. The description restates the matching keys and the DPAD/time-budget behavior but adds no syntax or format beyond the structured fields, 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?
States a specific verb (find and activate) plus the exact matching keys (text, resource-id, content-desc), and explicitly names the sibling combination it replaces. An agent can tell it apart from adb_tap and adb_ui_dump without reading either 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?
Gives an explicit selection rule: prefer this over adb_ui_dump + adb_tap when the label is known, and use adb_tap for a point that has no label. Also warns about the focus-walk failure mode, so the agent knows when falling back is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_installInstall appADestructive
Installs only with dry_run=false; by default it reports what would be installed and installs nothing. Installs an APK from the server's file roots (file_roots). apk_path takes a single .apk, an array of split-APK paths, or one .apks/.xapk/.apkm bundle. Without apk_path it installs nothing and lists the installable files in file_roots, newest first, with the full path to pass as apk_path: start there when the user says "install what I downloaded". Bundle splits are chosen from the device ABI list, density and locale. No matching ABI split is a refusal; a density mismatch is not. Flags -r, -t and -g are applied by default. The reverse is adb_uninstall, or adb_app for a removal with a backup and a rollback.
| Name | Required | Description | Default |
|---|---|---|---|
| abi | No | Bundle only: force an ABI instead of the device default (e.g. armeabi-v7a) | |
| dir | No | Only without apk_path: the list shows the top level and one level of subfolders; for a deeper folder pass it here, listed the same way. Ignored when apk_path is given. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| density | No | Bundle only: force a screen density in dpi instead of the device value | |
| dry_run | No | Default true: report the files, the command and the device (for a bundle, also the chosen splits) and install nothing. Only false installs. | |
| locales | No | Bundle only: extra language splits to include alongside the device language (e.g. ["ru"] on an en-US device) | |
| apk_path | No | Single APK path, array of split-APK paths, or one .apks/.xapk/.apkm bundle. Without it: a list of the installable files in file_roots, newest first; nothing is installed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructive=true, non-idempotent, non-read-only, but the description adds substantive behavior they do not: the default dry_run=true means nothing is installed, ABI mismatch is a refusal while a density mismatch is not, and -r/-t/-g flags are applied by default. These are exactly the side-effect details an agent needs before invoking a destructive 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 most consequential fact, the dry_run=true default, is front-loaded in the first clause, and every subsequent sentence carries a distinct rule (input forms, listing mode, split selection, default flags, alternatives). No filler or restatement of the title.
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?
With no output schema, the description compensates by describing what each mode returns (a list of installable files newest-first with the full path to pass as apk_path) and what a dry run reports (files, command, device, chosen splits). For a 7-parameter destructive tool with zero required parameters, nothing an agent needs to call it correctly is missing.
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 baseline is 3 and the schema already documents each parameter's role. The description still adds cross-parameter semantics the schema only implies, notably that dir is ignored when apk_path is given and how bundle splits are selected from ABI/density/locale with a refusal rule for ABI.
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 a specific verb and resource (installs an APK from the server's file roots) and immediately scopes the operation by naming the accepted inputs (single APK, split array, bundle). It also distinguishes itself from siblings by naming adb_uninstall and adb_app as the removal paths, so an agent can route without opening another 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?
Explicitly says when to use it versus alternatives: 'start there when the user says "install what I downloaded"' for the no-apk_path listing mode, and 'The reverse is adb_uninstall, or adb_app for a removal with a backup and a rollback.' It also states the precondition that only dry_run=false actually installs, which is the single most important routing fact.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_keySend keyA
Send a keyevent. Accepts names (HOME, BACK, ENTER, DPAD_UP, POWER, VOLUME_UP, MENU, TAB...) or numeric codes. On TV boxes DPAD_UP/DOWN/LEFT/RIGHT move the focus and DPAD_CENTER presses it. verify="activity"|"ui" reports whether the key changed anything; see adb_tap for the same parameter. For text use adb_text; for a labelled element, adb_find_and_tap.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Key name (HOME, BACK, ENTER, DPAD_CENTER, WAKEUP...; the KEYCODE_ prefix is optional) or a numeric keycode. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| verify | No | Default "none". See adb_tap. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false), so the bar is lower. The description adds real non-annotation context: DPAD_UP/DOWN/LEFT/RIGHT move focus and DPAD_CENTER activates, and verify="activity"|"ui" reports whether the key changed anything. It stops short of stating failure behavior for invalid keycodes or any blocking/timeout characteristics.
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?
Front-loads the core action in three words, then layers input format, device behavior, verification, and sibling routing in short clauses. No sentence is redundant and nothing is buried.
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 3-parameter, no-output-schema tool with annotations already covering safety, the description supplies the essential context: accepted key forms, verify semantics, and alternative tools. Minor gaps (whether calls block until the key is processed, handling of invalid keycodes) remain, but nothing needed to invoke it correctly is missing.
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 three parameters are already documented, establishing a baseline of 3. The description adds some semantic value beyond the schema (expanded key name examples, numeric-code acceptance, DPAD navigation behavior), but defers verify entirely to adb_tap rather than explaining it here.
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 a specific verb+resource ("Send a keyevent") and immediately bounds the input domain (named keys or numeric codes). It explicitly distinguishes itself from siblings by naming adb_text and adb_find_and_tap as the right tools for those alternate tasks, so an agent can route correctly without opening any 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?
Gives explicit routing rules: use adb_text for text input and adb_find_and_tap for a labelled element, i.e. when-not-to-use-this is covered. It also explains the verify parameter's role in confirming effect, matching the sibling adb_tap convention.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_logcatRead logcatARead-onlyIdempotent
Read recent logcat lines without waiting for new ones, e.g. to see why an app crashed; unlike adb_shell it works with allow_shell off. filter: either a logcat filterspec like "ActivityManager:I :S" (contains ":" or ""; *:S is auto-appended if missing so unmatched tags are silenced) or a plain substring grepped case-insensitively across the whole line. lines limits the result (default 200). Filtering runs on the device.
| Name | Required | Description | Default |
|---|---|---|---|
| lines | No | How many lines to return, default 200, at most 2000. | |
| filter | No | A filterspec such as "ActivityManager:I *:S" (has ":" or "*"), or a plain substring matched case-insensitively. Omit for the last lines unfiltered. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, so the safety profile is covered. The description goes further by disclosing that it does not wait for new lines, that filtering runs on the device, and that *:S is auto-appended to silence unmatched tags — genuinely useful behavioral context. It stops short of describing return/pagination behavior, so not a 5.
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?
Front-loaded with the purpose before elaborating on filtering, and nearly every clause adds information (wait behavior, shell-off compatibility, filterspec rules, on-device filtering). It is dense and slightly run-on with stacked parentheticals, but there is no 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 zero-required-parameter, read-only tool with a fully described schema, rich annotations, and no output schema, the description supplies everything needed: purpose, alternative routing, and filter semantics. No output-format explanation is owed since no output schema exists.
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 earns above-baseline credit by explaining the dual semantics of filter (filterspec when it contains ':' or '*', otherwise case-insensitive whole-line substring) and the auto-append rationale that the schema alone does not fully motivate.
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?
Specific verb+resource ("Read recent logcat lines") with an explicit scope qualifier ("without waiting for new ones"). It actively distinguishes itself from the sibling adb_shell ("unlike adb_shell it works with allow_shell off"), so an agent can route correctly without opening a 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?
Gives a concrete use case ("e.g. to see why an app crashed") and names the alternative (adb_shell) with the condition that selects this tool (works when allow_shell is off). Clear context, but no explicit statement of when this tool should NOT be used in favor of a sibling beyond the single adb_shell comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_pairPair deviceA
Pair with an Android 11+ device over Wireless Debugging, once per device and computer; afterwards adb_connect alone reconnects. On the device: Developer options -> Wireless debugging -> "Pair device with pairing code" shows ip:port and a 6-digit code. The pairing port is random and differs from the connect port; after pairing succeeds, call adb_connect with the ip:port shown on the main Wireless debugging screen.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | 6-digit pairing code from the dialog | |
| host | Yes | ip:port from the pairing dialog (random port, NOT 5555) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false), and the description adds real operational context on top: the pairing is a one-time-per-machine operation and the pairing port differs from the connect port. What it does not cover is failure behavior (wrong code, timeout) or what a successful pair returns, which is the remaining 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?
Front-loaded with purpose and the once-per-device constraint, then the on-device steps and the follow-up call. Four sentences all carry usable information, though the UI navigation path could be compressed without loss.
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 two-parameter, no-output-schema tool, the description covers prerequisites, sequencing, port semantics, and the next tool to call. It is close to complete; only error/retry behavior is absent, and no output schema exists that would need explaining.
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 baseline is 3, but the description goes beyond the schema by explaining that the pairing port is random and distinct from the connect port used later — a semantic point the schema's '(random port, NOT 5555)' only partially conveys. It reinforces rather than merely repeats the field 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?
States a specific verb and resource ('Pair with an Android 11+ device over Wireless Debugging') and immediately distinguishes itself from the sibling adb_connect by explaining that pairing happens once and adb_connect alone handles reconnection. An agent can route between adb_pair and adb_connect without opening either 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?
Explicit when-to-use ('once per device and computer'), explicit sequencing ('afterwards adb_connect alone reconnects'), and an explicit follow-up instruction ('after pairing succeeds, call adb_connect with the ip:port shown on the main Wireless debugging screen'). Prerequisites (Android 11+, Developer options path) are also given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_pullPull file from deviceADestructiveIdempotent
Copy a file from the device into the server's file roots (file_roots), overwriting a file of the same name and creating missing directories. The reverse is adb_push.
| Name | Required | Description | Default |
|---|---|---|---|
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| host_path | Yes | Absolute destination path on the server, inside file_roots. | |
| device_path | Yes | File on the device, e.g. /sdcard/Download/report.pdf. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is known. The description adds real value beyond that by disclosing the overwrite-on-same-name behavior and automatic creation of missing directories, which explains the destructive flag concretely. It does not cover error cases such as a missing source file.
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, both front-loaded and waste-free: the first carries the operation and its side effects, the second handles sibling disambiguation. Nothing redundant with the title.
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?
With no output schema, the description needn't explain return values, and it adequately covers direction, destination constraint, overwrite semantics, and directory creation. The only gap is failure behavior (source not found, path outside file_roots), which is minor for a simple transfer 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 all three parameters (serial, host_path, device_path) are fully documented in the schema, including the file_roots containment constraint. The description adds nothing parameter-specific beyond the file_roots phrase, so the 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?
States a specific verb (copy) and direction (device into server's file_roots), and explicitly names the reverse operation adb_push, so the agent can distinguish it from adb_push without opening either schema. No ambiguity about which direction data flows.
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 closing sentence 'The reverse is adb_push' effectively routes the agent between the two transfer tools, giving clear directional context. It stops short of explicit when-not guidance (e.g., what to do if the destination is outside file_roots), so it is a strong 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_pushPush file to deviceADestructiveIdempotent
Copy a file from the server's file roots (file_roots) to the device, overwriting a file of the same name there. To install an APK use adb_install instead. The reverse is adb_pull.
| Name | Required | Description | Default |
|---|---|---|---|
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| host_path | Yes | Absolute path of the file on the server, inside file_roots. | |
| device_path | Yes | Destination on the device, e.g. /sdcard/Download/file.apk or /data/local/tmp/. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so safety profile is covered. The description adds the concrete consequence — overwriting a same-named file on device — which reinforces the destructive hint rather than contradicting it. It does not cover failure modes (missing path, insufficient permission, disk space), keeping it short of a 5.
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 tight sentences, front-loaded with the action and overwrite semantics, followed by sibling routing. Zero 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 3-param, non-nested tool with full schema coverage, full annotations and no output schema, the description supplies the routing and overwrite behavior an agent needs. Missing only edge-case behavior (nonexistent host path, permission failure), which slightly limits it.
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 the file_roots restriction on host_path, which is already stated in the schema property description, and no extra syntax or format detail beyond that.
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 a specific verb and resource (copy a file from server to device), scopes the source to file_roots, and explicitly names the two most confusable siblings, adb_install and adb_pull. An agent can distinguish this from every other adb_* tool without opening a 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?
Gives explicit routing rules: use adb_install for APKs, adb_pull for the reverse direction. That is precisely the when-to-use-this-vs-alternatives guidance the dimension asks for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_screenshotTake screenshotARead-onlyIdempotent
Take a screenshot of the device screen. Returns a JPEG image, then a text line with the logical screen size, the image size and the scale between them, e.g. "screen 1080x2340 -> image 473x1024 · scale 2.283/2.285". Pass coords="screenshot" to adb_tap/adb_swipe to tap coordinates read off that image. A near-uniformly dark frame is a warning after the image, not a refusal. To read labels and exact tap points, adb_ui_dump is cheaper and precise; the screenshot shows what the dump cannot (images, video, games).
| Name | Required | Description | Default |
|---|---|---|---|
| max_px | No | Max dimension 320-1920, default 1024 | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| quality | No | JPEG quality 30-95, default 70 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly/idempotent/no-destruction, and the description adds genuinely new behavioral context: the two-part return payload (JPEG then size/scale text line), the near-uniformly-dark-frame warning being advisory rather than a refusal, and the scale factor tying image pixels to logical coordinates.
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?
Four tight sentences, front-loaded with what it does and what it returns, then usage routing and the caveat. No sentence is filler and the example output line is compact and illustrative.
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 exists, yet the description fully specifies the return shape (image plus size/scale line) including a concrete example. Combined with the sibling routing and the coords="screenshot" handoff, an agent has everything needed to call it and consume the 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?
Schema description coverage is 100%, so max_px, serial, and quality are already documented with ranges and defaults. The description adds no parameter-level detail beyond the cross-tool coords convention, which is baseline territory when the schema does the work.
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 a specific verb+resource ("Take a screenshot of the device screen") and explicitly contrasts its role with adb_ui_dump, so an agent can separate it from siblings without opening any 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?
Gives explicit when-to-use routing: use ui_dump for labels/exact tap points, use the screenshot for what the dump cannot (images, video, games). It also names the downstream convention (coords="screenshot" on adb_tap/adb_swipe) that makes the output actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_shellRun shell commandADestructive
Run a shell command on the device (settings, pm, am, dumpsys, getprop, wm, cmd, svc...) and return stdout. It bypasses every guard rail, so it works only while the server option allow_shell is on. For package changes use adb_app instead: dry runs, a protected set, a network guard and a rollback snapshot.
| Name | Required | Description | Default |
|---|---|---|---|
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| command | Yes | Command line for the device shell, e.g. "getprop ro.build.version.release". Logged verbatim with log_requests: type secrets with adb_text instead. | |
| timeout_sec | No | Time limit in seconds, default 30, at most 120. Past it the call fails with "timed out". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already flag this as destructive and non-idempotent, but the description adds material context the annotations cannot: it bypasses every guard rail, it is gated behind the allow_shell server option, and the command is logged verbatim (so secrets should go through adb_text instead). The timeout failure mode ('timed out') is also disclosed. This is well beyond what structured fields convey.
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 sentences, front-loaded with what the tool does and its return value, then the precondition, then the sibling routing. Every sentence carries a distinct, load-bearing piece of information with no 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 raw-shell escape hatch, the description covers the safety posture (guard-rail bypass, allow_shell gate), the logging/secret-handling caveat, the failure mode, and the correct sibling for package operations. With annotations supplying the destructive/idempotent profile and the schema complete at 100% coverage, nothing an agent needs before invoking it is missing; return values are summarized as stdout, so no output schema is required.
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 serial, command, and timeout_sec are already fully documented in the schema, setting the baseline at 3. The description's command-family list and the secrets/log_requests warning echo rather than extend the schema's own parameter descriptions, so no upward adjustment 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?
States a specific verb and resource ('Run a shell command on the device') and enumerates concrete command families (settings, pm, am, dumpsys, getprop, wm, cmd, svc) with the return value ('stdout'). It also distinguishes itself from adb_app by name, so the agent can separate the two without opening either 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?
Explicitly states the precondition ('works only while the server option allow_shell is on') and names the alternative for a whole category of work: 'For package changes use adb_app instead', including the reasons (dry runs, protected set, network guard, rollback snapshot). This is exactly the when-to-use/when-to-use-something-else guidance the dimension asks for.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_swipeSwipeA
Swipe from (x1,y1) to (x2,y2) over duration_ms (default 300). The same point at both ends with duration_ms >= 800 is a long-press. coords and verify work as in adb_tap and both endpoints share one coordinate space; with verify="ui", an "unchanged" result on a swipe usually means the end of a scrollable list. On a TV box without a touchscreen, move the focus with adb_key DPAD_* instead.
| Name | Required | Description | Default |
|---|---|---|---|
| x1 | Yes | Start X in pixels, in the space chosen by coords. | |
| x2 | Yes | End X in pixels. | |
| y1 | Yes | Start Y in pixels. | |
| y2 | Yes | End Y in pixels. | |
| coords | No | Coordinate space for BOTH endpoints, default "screen". See adb_tap for the "screenshot" semantics and its 120s TTL. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| verify | No | See adb_tap. For a swipe, "ui" reporting "unchanged" usually means you hit the end of a scrollable list rather than that nothing happened. | |
| duration_ms | No | Duration in ms, default 300. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the write/idempotency profile (readOnlyHint=false, idempotentHint=false), so the description's job is to add context, which it does: it explains that verify="ui" returning "unchanged" typically signals the end of a scrollable list rather than a no-op. That result-interpretation guidance is genuinely useful and not derivable from annotations or schema. It stops short of covering failure modes or return shape.
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 dense sentences, front-loaded with the core geometry and timing before the long-press and TV caveats. Slightly reliant on cross-references to adb_tap for coords/verify semantics, which costs a little, but there is no 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 an 8-parameter input-injection tool with no output schema and annotations that only cover the safety profile, the description covers the non-obvious cases an agent would otherwise get wrong: the long-press threshold, shared coordinate space, and the interpretation of a verify="ui" unchanged result. Only the failure/return behavior remains unaddressed.
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, but the description adds real semantic content beyond the schema: the default 300 ms duration, the >= 800 ms long-press threshold rule, and the fact that both endpoints share a single coordinate space. Those are behavioral constraints the schema does not encode.
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?
Opens with a specific verb plus explicit geometry and timing ('Swipe from (x1,y1) to (x2,y2) over duration_ms'), which is unambiguous and clearly distinct from adb_tap, adb_key, and adb_find_and_tap. It also defines the long-press variant, so the agent understands the tool covers more than literal swipes.
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?
Gives concrete when-to-use routing: use adb_key DPAD_* on a TV box without a touchscreen, and use the same-point + duration_ms >= 800 form for a long-press. It also names the sibling whose conventions it inherits (adb_tap for coords and verify), so the agent knows where to look for the shared semantics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_tapTapA
Tap at (x, y). coords="screen" (default): coordinates from adb_ui_dump, the logical space input tap uses. coords="screenshot": coordinates off the last adb_screenshot for the SAME serial, rescaled; missing or older than 120s is refused. Rotation between screenshot and tap is not checked. verify="activity"|"ui" reports whether the tap changed anything; a failed verify never turns a performed tap into an error. To activate an element by its label, adb_find_and_tap does it in one call and also works on TV boxes without a touchscreen.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X in pixels, in the space chosen by coords. | |
| y | Yes | Y in pixels, same space. | |
| coords | No | Coordinate space, default "screen". "screenshot" = pixels read off the last adb_screenshot image for this serial, rescaled automatically; refused if that screenshot is missing or older than 120s. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| verify | No | Default "none". "activity" compares the resumed activity before/after. "ui" also hashes the UI dump (~2-4s); a clock or timer ticking on its own can make it report "changed". "unchanged" is reliable. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that rotation is not checked, that a stale screenshot (>120s) is refused, and that a failed verify never converts a performed tap into an error. These are non-obvious behavioral traits an agent needs, and nothing contradicts the annotations.
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?
Front-loaded with the core action, then dense but purposeful sentences covering each mode and the alternative. Slightly packed, but no wasted sentences.
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 tap mutation with no output schema, the description covers coordinate spaces, staleness limits, verification semantics, and the sibling alternative. Complete enough for correct invocation, with only minor gaps around which other alternatives to prefer.
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 baseline is 3, but the description adds real meaning: it clarifies that 'screen' is the logical space input tap uses (vs screenshot rescaling) and explains what each verify mode compares. This meaningfully augments the enum descriptions.
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 a specific verb (tap) and resource (x, y coordinates) with clear scope, and explicitly contrasts itself with the sibling adb_find_and_tap. An agent can distinguish it from the label-based alternative without opening any 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?
Gives explicit conditions for the two coord modes and routes label-based activation to adb_find_and_tap. Clear context for when to use it, though it doesn't address other alternatives like adb_swipe or adb_key.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_textType textA
Type text into the focused input field. Focus the field first; on a TV box, DPAD_CENTER on the field opens the keyboard. For single keys (ENTER, BACK) use adb_key. ASCII goes through input text; non-ASCII (Cyrillic, emoji, CJK) is sent via the ADBKeyBoard IME, which must be installed on the device (github.com/senzhk/ADBKeyBoard): the current keyboard is switched to it and restored afterwards. The response reports only the character count, never the text itself. Never retry a wrong password or PIN: repeated failures can lock the account or device. Stop and ask the user.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to type into the focused field. Only its length appears in the response and the log. | |
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only say it is a non-read-only, non-idempotent, non-destructive write; the description adds substantial context beyond that: the ADBKeyBoard IME dependency for non-ASCII, the keyboard switch-and-restore side effect, and the fact that the response/log never contain the text itself. The account/device lockout warning is real operational risk information not present in structured fields.
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?
Purpose and the focus prerequisite are front-loaded, and the encoding path plus safety warning follow in a logical order. It is denser than strictly necessary and the password/PIN warning, while valuable, sits slightly apart from the core typing behavior.
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?
With no output schema, the description takes responsibility for the return value ('reports only the character count, never the text itself') and also covers the IME prerequisite and post-condition. An agent has everything needed to invoke it correctly or to know when it cannot.
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 both parameters are already documented. The description reinforces that only the length of 'text' is echoed back, but adds no syntax, encoding, or format detail beyond the schema. Baseline 3 applies when the 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?
States a specific verb and resource ('Type text into the focused input field') and explicitly distinguishes itself from the sibling adb_key ('For single keys (ENTER, BACK) use adb_key'). An agent can route between the two without opening either 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?
Gives the precondition ('Focus the field first; on a TV box, DPAD_CENTER on the field opens the keyboard'), names the alternative tool for a different use case, and adds an explicit when-not with a stop condition ('Never retry a wrong password or PIN... Stop and ask the user').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_ui_dumpDump UI hierarchyARead-onlyIdempotent
Dump the current UI hierarchy (uiautomator) as a compact list of interactive/labeled elements with tap coordinates @(x,y). Password fields are marked [PASSWORD] and listed even with no visible text. Use together with adb_tap. Prefer it over adb_screenshot for labels and tap targets; use adb_screenshot for content the dump does not see (images, video, some WebViews and games).
| Name | Required | Description | Default |
|---|---|---|---|
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the description's added value is the uiautomator source, the coordinate annotation format, and the notable behavior that password fields are marked [PASSWORD] and listed even with no visible text. That last detail is real behavioral disclosure an agent could not infer from structured fields. It doesn't mention output size limits or pagination, so not a 5.
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 tight sentences, zero filler. Capability and output format come first, then the pairing with adb_tap, then the routing rule against adb_screenshot — properly front-loaded.
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 read-only, single-optional-param tool with full annotation coverage, the description supplies everything needed: what it returns, how coordinates are encoded, and how it differs from the screenshot sibling. No output schema is needed because the return format is described in prose.
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 single 'serial' parameter is fully documented there, including the 'optional when exactly one device is connected' rule. The description adds nothing about serial, so the baseline 3 is correct.
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 a specific verb (Dump) and resource (current UI hierarchy via uiautomator) plus the exact output shape: a compact list of interactive/labeled elements with tap coordinates @(x,y). It explicitly distinguishes itself from adb_screenshot, so an agent can choose between them without opening either 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?
Gives explicit when-to-use ('Use together with adb_tap', 'Prefer it over adb_screenshot for labels and tap targets') and when-not ('use adb_screenshot for content the dump does not see — images, video, some WebViews and games'). Both the alternative tool and the selecting condition are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
adb_uninstallUninstall appADestructiveIdempotent
Uninstall an app by package name, at once and without a backup. keep_data=true keeps app data (-k). The reverse is adb_install. For system packages, reversible bulk operations and backups, use adb_app.
| Name | Required | Description | Default |
|---|---|---|---|
| serial | No | Device serial from adb_devices. Optional when exactly one device is connected. | |
| package | Yes | Package name, e.g. com.example.app (adb_app action=list lists them). | |
| keep_data | No | Keep the app data and cache (-k). Default false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so the safety profile is largely covered. The description still adds meaningful context beyond that: the operation is 'at once and without a backup' (no recoverable path) and keep_data=true preserves data via -k, which clarifies the destructive footprint of each variant.
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-loaded with the destructive action and its irreversibility, followed by the inversion and the alternative routing. No sentence is wasted.
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?
Complete for a simple 3-param destructive tool with full schema coverage and no output schema; it does not mention serial-selection prerequisites or any return/failure signal, but annotations and schema carry those details adequately.
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 three parameters are already documented; the description only restates the keep_data/-k behavior already present in the schema and adds no new syntax or format detail. 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?
States a specific verb and resource ('Uninstall an app by package name') and immediately qualifies the scope ('at once and without a backup'), which an agent can distinguish from adb_install and adb_app without opening any 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?
Explicitly names both the inverse ('The reverse is adb_install') and the routing condition for the alternative ('For system packages, reversible bulk operations and backups, use adb_app'), so when-to-use and when-not-to-use are both stated.
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.
18 tool updates
v0.1.0- First observed
adb_app - First observed
adb_connect - First observed
adb_devices - First observed
adb_disconnect - First observed
adb_find_and_tap - First observed
adb_install - First observed
adb_key - First observed
adb_logcat - First observed
adb_pair - First observed
adb_pull - First observed
adb_push - First observed
adb_screenshot - First observed
adb_shell - First observed
adb_swipe - First observed
adb_tap - First observed
adb_text - First observed
adb_ui_dump - First observed
adb_uninstall
TDQS
Scored across 18 tools
Most tools target a distinct action+resource, and descriptions explicitly steer selection (e.g. adb_ui_dump vs adb_screenshot, adb_tap vs adb_find_and_tap). There is deliberate overlap in package operations (adb_app, adb_install, adb_uninstall) and UI tapping (adb_tap vs adb_find_and_tap), but the guidance on when to prefer each largely resolves it.
Every tool follows the same adb_verb_noun snake_case pattern (adb_ui_dump, adb_install, adb_pull, adb_logcat). No mixed conventions or stray naming styles.
18 tools is slightly on the heavy side but each covers a genuine sub-domain: connection (devices/connect/pair/disconnect), UI interaction, package management, file transfer, shell and logs. Nothing is redundant enough to feel padded.
The surface covers the ADB lifecycle well: discovery/connection, UI automation, package management with rollback, file transfer, shell and logcat. Minor gaps exist (e.g. port forwarding, reboot, app data inspection) but they are workarounds rather than blocking omissions.
Maintenance
Related MCP Connectors
Control Android TV from any AI. 38 MCP tools: playback, recap, recommend, smart-home, schedules.
Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.
Turns a phone into a camera+Bluetooth remote so AI assistants can see and control any PC.
Melaya is a remote MCP server. It gives an assistant hands on your own Android phone and browser: it reads the screen through the accessibility tree, then taps, types and navigates inside the apps and sites you allow-list, with no per-app API. It also builds, schedules and runs agent pipelines across 6k+ connected tools. OAuth 2.1, nothing to install.
Related MCP Servers
- AlicenseBqualityCmaintenanceEnables AI assistants to interact with Android devices and emulators via ADB, providing tools for screenshots, UI inspection, touch and text input, app management, and device control.4259 npm20MIT
- AlicenseBqualityCmaintenanceEnables AI agents to control Android TV/Android devices through ADB, including screen capture, remote control, app management, and more.242 npm1MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to drive an Android TV or Google TV box end to end through named tools — discover, pair, connect, check, install, provision, link, test, screenshot, report and a gated shell — with usage instructions embedded in the tool descriptions so the agent never improvises adb. Every command passes the same safety gate that refuses destructive actions.1Apache 2.0
- AlicenseNot gradedqualityNot gradedmaintenanceSet up Android TV, Google TV and Fire TV boxes over ADB on the local network: discover and pair boxes, set any launcher as the HOME app, install apps, take screenshots and run checks. No raw shell tool; the tools that change the box ask before they run.Apache 2.0