adbmcp
This MCP server lets AI agents control Android devices/emulators through adb, covering discovery, debugging, app management, UI automation, files, ports, and wireless connections.
List connected devices and read model/Android/SDK/ABI/screen details.
Run guardrailed arbitrary shell commands on a selected device.
List, install, uninstall, launch, start, force-stop, and clear data for apps; grant/revoke runtime permissions.
Read logcat snapshots or start/read/stop live logcat streams.
Capture screenshots and dump UI hierarchy XML for element coordinates.
Drive the UI with taps, swipes, text input, and key events.
Pull files from and push files to the device, with overwrite/path guardrails.
Create, remove, and list adb forward/reverse port mappings.
Pair, connect, and disconnect devices over Wi-Fi/TCP-IP.
Query curated dumpsys services and restart the adb server for recovery.
Scope operations to one device with an optional
deviceserial, with typed errors and safety guardrails.
Provides tools for interacting with Android devices through the Android Debug Bridge (adb), including listing devices, running shell commands, installing and uninstalling apps, reading logcat, taking screenshots, driving the UI with taps/swipes/typing/key events, querying system services with dumpsys, transferring files, forwarding ports, managing app permissions, and pairing/connecting over Wi-Fi.
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., "@adbmcpscreenshot the screen of emulator-5554"
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.
adbmcp — Android Debug Bridge, as MCP tools
adbmcp is a Model Context Protocol server that exposes the
Android Debug Bridge (adb) to AI agents: list devices, run shell commands, install apps, read
logcat, take screenshots, drive the UI (tap/swipe/type/key events), query system services with
dumpsys, transfer files, forward ports, manage app permissions and pair/connect to devices over
Wi-Fi. It is a thin, predictable wrapper around the official
adb binary — no re-implemented adb protocol, no test framework, no extra state.
Multi-device first — every device-scoped tool takes an optional
deviceserial and every adb call is scoped withadb -s <serial>; ambiguity is an error listing the candidates.Failures an agent can act on — adb stderr/exit codes are mapped to typed causes (
NO_DEVICE,MULTIPLE_DEVICES,DEVICE_UNAUTHORIZED,DEVICE_OFFLINE,ADB_SERVER_CONFLICT,TIMEOUT,COMMAND_FAILED) with a hint for the next step.Safety by construction — full MCP annotations on every tool plus server-side guardrails that are enforced even if a host ignores annotations.
stdio by default, Streamable HTTP optional — the client launches
adbmcpas a subprocess;--httpserves the same tools over/mcpfor shared-device-host deployments.
Implements the MVP plus v2.0 items 1–7 in docs/design/product-design-v0.md.
Install
Requires Node.js >= 20 and Android platform-tools (adb) on PATH — or ADB_PATH pointing at the
binary.
# from npm
npx -y @yhuangsh/adbmcp
# from a checkout
git clone https://github.com/yhuangsh/adbmcp.git && cd adbmcp
npm install
npm run build
node dist/index.js # speaks MCP on stdin/stdoutClaude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"adb": {
"command": "npx",
"args": ["-y", "adbmcp"],
"env": {
"ADB_PATH": "/Users/me/Library/Android/sdk/platform-tools/adb"
}
}
}
}Cursor (.cursor/mcp.json)
{
"mcpServers": {
"adb": {
"command": "node",
"args": ["/absolute/path/to/adbmcp/dist/index.js"],
"env": {
"ADBMCP_ALLOWED_DEVICES": "emulator-5554"
}
}
}
}Other stdio clients work the same way: a command plus args, with ADB_PATH / ADBMCP_*
environment variables passed through. In stdio mode, stdout carries MCP protocol traffic only;
diagnostics go to stderr.
Streamable HTTP (shared device host)
Use HTTP when several agents or MCP clients should share one machine's adb server, devices and
allowlist — an emulator farm, a lab phone, or a remote desktop — instead of each client launching its
own subprocess. stdio stays the default: with no flags, adbmcp speaks MCP on stdin/stdout.
node dist/index.js --http # http://127.0.0.1:3331/mcp
ADBMCP_HTTP_TOKEN=secret node dist/index.js --http --host 0.0.0.0 --port 8080Flag / variable | Default | Meaning |
| off | Enable the Streamable HTTP transport. Without it the server is stdio-only. |
|
| Listen port ( |
|
| Bind address ( |
| unset | When set, every |
| derived | Comma-separated exact |
The endpoint is stateful: initialize creates a session, Mcp-Session-Id identifies it, and
DELETE /mcp closes it. All sessions share one device host, one ADBMCP_ALLOWED_DEVICES allowlist
and one logcat stream registry — streams started in one session can be read from another. Sessions
are the same trust domain, not isolation between agents.
Client config (Claude Desktop, Cursor, or any Streamable HTTP client):
{
"mcpServers": {
"adb": {
"type": "http",
"url": "http://localhost:3331/mcp"
}
}
}When ADBMCP_HTTP_TOKEN is set, add "headers": { "Authorization": "Bearer <token>" } to the
server entry (client support for header config varies).
Security notes:
Loopback by default. Binding a non-loopback host without
ADBMCP_HTTP_TOKENis refused at startup; the error explains the two ways forward (set a token, or bind127.0.0.1).Token auth is pre-MCP. With a token configured, missing/incorrect credentials get
401before any MCP session handling; comparison is constant-time (node:cryptotimingSafeEqual).DNS-rebinding protection. The SDK transport rejects requests whose
Hostheader is not the bound host or a loopback alias (localhost,127.0.0.1,::1) on the actual port. Override withADBMCP_HTTP_ALLOWED_HOSTSwhen a reverse proxy forwards a different hostname.One device host, many agents.
shellis available to every session; on a shared host preferADBMCP_ALLOWED_DEVICESandADBMCP_SHELL_ALLOWED_PREFIXES, and put the server behind the token.No in-process TLS. The server speaks plain HTTP; terminate TLS in a reverse proxy for non-loopback deployments and set
ADBMCP_HTTP_ALLOWED_HOSTSto the forwardedHostvalue.Only
/mcpis served; POST bodies are capped at 1 MiB (413above that), unsupported methods get405, and unknown paths get404.
Deploying over a VPN mesh (Tailscale example)
A common topology: your agent runs on a public server, and one or more device hosts (machines with USB-attached phones) are joined to a private mesh such as a Tailscale tailnet. Nothing needs to be exposed to the public internet — the agent reaches device hosts through the mesh.
Shape A — bind the mesh interface directly. On each device host, set the token, bind to the
mesh IP (or 0.0.0.0), and allow the hostname the agent will dial:
ADBMCP_HTTP_TOKEN=<token> ADBMCP_HTTP_ALLOWED_HOSTS='phonehost.tailnet-name.ts.net:3331,127.0.0.1:3331,localhost:3331' \
adbmcp --http --host 0.0.0.0 --port 3331WireGuard encrypts mesh traffic; the bearer token stays as the application-level gate so a
misconfigured ACL or a compromised mesh member still cannot touch your devices. ALLOWED_HOSTS must
contain the exact Host header the agent sends — MagicDNS name and port. Note the override
replaces the derived loopback defaults, so loopback entries are re-added for local health checks.
Shape B — loopback + tailscale serve (nice for always-on hosts). Keep adbmcp bound to
127.0.0.1 (optionally with a token still set), then let Tailscale expose it:
adbmcp --http --host 127.0.0.1 --port 3331 &
tailscale serve --bg --https=443 http://127.0.0.1:3331 # --https=443 is the default modeKeep the token set even in this shape — tailscale serve terminates TLS and limits reachability to
the tailnet, but adbmcp should still authenticate its clients. Point the agent at
https://phonehost.tailnet-name.ts.net/mcp (tailscale serve passes the original Host header
through, so the portless ADBMCP_HTTP_ALLOWED_HOSTS entry is correct here).
Caveats that apply to both shapes: one adbmcp node per device host (the agent configures one MCP server entry per host — there is no cross-host device registry); sessions live until the client deletes them or the process restarts, so a device host that suspends or redeploys drops its logcat streams and agents must re-initialize; and provision the token to the agent out-of-band (secret manager, not chat).
Related MCP server: android-mcp
Tools
device is optional on every device-scoped tool and required when more than one device is connected.
Annotation columns: RO = readOnlyHint, D = destructiveHint, I = idempotentHint,
O = openWorldHint.
Tool | What it does | RO | D | I | O |
|
| ✅ | — | ✅ | — |
| Curated build properties (model, Android version, SDK, ABI) + screen size/density | ✅ | — | ✅ | — |
| Curated | ✅ | — | ✅ | — |
| Arbitrary | — | — | — | ✅ |
|
| ✅ | — | ✅ | — |
|
| — | — | — | — |
|
| — | ✅ | ✅ | — |
|
| — | ✅ | ✅ | — |
|
| — | ✅ | ✅ | — |
|
| — | ✅ | ✅ | — |
| Bounded | ✅ | — | ✅ | — |
| Start a long-lived | ✅ | — | — | — |
| Drain buffered output since the last read | ✅ | — | — | — |
| Stop the stream, return unread output | ✅ | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| — | — | — | — |
|
| — | — | — | ✅ |
|
| — | — | ✅ | — |
|
| — | — | ✅ | — |
|
| — | — | ✅ | — |
|
| — | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| — | — | ✅ | ✅ |
|
| — | — | ✅ | ✅ |
|
| — | — | ✅ | ✅ |
|
| — | — | — | — |
| Resolve a package's LAUNCHER activity, then | — | — | — | — |
|
| — | — | ✅ | — |
|
| ✅ | — | ✅ | — |
|
| — | — | — | — |
|
| — | — | — | — |
|
| — | — | — | — |
|
| — | — | — | — |
|
| — | — | — | — |
Also shipped:
Resource
adb://devices— live device list as JSON (serial,state,model,allowed). State is never cached; re-read the resource to refresh.Prompts —
debug_crash,install_and_launch,capture_bug_report: step-by-step orchestrations of the tools above.
uninstall_package, grant_permission, revoke_permission and clear_app_data are the tools with
destructiveHint: true; shell, push_file, connect, disconnect and wireless_pair are the
openWorldHint: true tools. They are never merged with read-only tools, so hosts can auto-approve
reads and confirm writes.
Non-ASCII text input
Android's input text is ASCII-only: typing non-ASCII text (e.g. CJK) through it crashes on the
device with a NullPointerException instead of typing anything (issue #3). type_text therefore
has two paths:
ASCII text (default and unchanged) is sent as
input textwith%sspace encoding and device-shell quoting — one round trip, no extra device calls.Non-ASCII text is sent as
am broadcast -a ADB_INPUT_B64 --es msg <base64-utf8>to the active input method. This requires a broadcast-capable IME to be the active IME; the reference implementation is ADB Keyboard (com.android.adbkeyboard/.AdbIME). On every non-ASCII call adbmcp queriessettings get secure default_input_method(never cached) and broadcasts only when the active IME matches a configured capable component.
One-time setup, run from your own shell (adbmcp detects the IME but deliberately never installs or switches IMEs on its own):
adb install ADBKeyboard.apk # from the ADBKeyBoard releases
adb shell ime enable com.android.adbkeyboard/.AdbIME
adb shell ime set com.android.adbkeyboard/.AdbIME # must be the ACTIVE input methodFailure modes, both typed and actionable instead of leaking the device-side NPE:
[IME_UNAVAILABLE]— the text is non-ASCII but the active IME is not broadcast-capable (or no IME is selected). The message names the active IME and the hint gives theime enable/ime setcommands above.[TEXT_NOT_ASCII]—ADBMCP_TYPE_TEXT_NON_ASCII=rejectopts out of the broadcast path, so non-ASCII text is refused before any device call.
IMEs other than ADB Keyboard can be declared broadcast-capable with
ADBMCP_IME_BROADCAST_COMPONENTS (see the table below); both the short pkg/.Class form and the
flattened pkg/pkg.Class form match.
Configuration
Variable | Default | Meaning |
|
| Path to the adb binary. Must match the version of any running adb server. |
| unset (all allowed) | Comma-separated serial allowlist. Operations on other serials are refused. |
|
| Comma-separated JavaScript regex sources tested against the whole |
| unset (no prefix restriction) | When set, a |
|
| Remote roots |
| unset (refuse every clear) | Comma-separated package allowlist for |
|
| How |
|
| Comma-separated IME component ids accepted as broadcast-capable for the |
|
| Default subprocess timeout ( |
|
| Head+tail byte cap per call; the dropped middle is reported inline. |
|
| Ring-buffer cap per logcat stream; overflow is reported as |
|
| HTTP mode listen port (equivalent to |
|
| HTTP mode bind address (equivalent to |
| unset | Bearer token required on every |
| derived | Comma-separated exact |
Safety notes
Annotations are advisory, guardrails are authoritative. The host decides what to auto-approve;
adbmcpenforces its own limits regardless: blockedshellpatterns, the device allowlist, remote push roots, and the pull overwrite check.shellis arbitrary code execution on the device. It is annotated as not read-only and open-world, blocklisted by default, and documented as the escape hatch — keepshelldisabled or prefix-restricted (ADBMCP_SHELL_ALLOWED_PREFIXES) on shared or CI machines. The default blocklist covers reboot/power-state changes,su,mkfs,wipe,rmof/(including split/reordered flags and the/*glob), and pipelines intosh/bashsuch ascurl … | shor… | sudo bash. This is a guardrail, not a sandbox: a deliberately obfuscated command can still get through. A pattern-based guardrail: matching runs on the raw command text, including inside quotes, so even prose likeecho "use curl | sh to install"is refused — precision always yields to safety here. maintainer can replace the patterns withADBMCP_SHELL_BLOCKED_PATTERNS.uninstall_packagedeletes app data unlesskeep_data: true.clear_app_datadeletes app data permanently and is refused unless the package is listed inADBMCP_CLEAR_ALLOWED_PACKAGES(unset/empty refuses every clear).grant_permission/revoke_permissionchange an app's granted permissions. All four are markeddestructiveHint: true.Device scoping is explicit. With multiple devices connected, calls without
devicefail withMULTIPLE_DEVICESand the candidate serials instead of guessing.Filesystem writes are bounded.
pull_filenever overwrites silently;push_filerefuses writes outside the allowed remote roots and rejects..traversal and relative paths. Root containment is lexical: it does not resolve on-device symlinks, so a link pre-created inside an allowed root (e.g./data/local/tmp/x -> /data/system) can still redirect a push outside it.No privilege escalation.
adbmcpnever runsadb root/suitself and never retries a permission failure with elevation.The adb server is shared host state.
adbmcpnever kills or restarts it implicitly;adb_server_restartexists for the version-conflict case and says so in its description.Logcat streams are cleaned up. Streams are killed on
stop_logcat_stream, and all remaining streams are terminated on SIGINT/SIGTERM (server shutdown).
Development
npm install
npm run build # tsc -> dist/
npm test # vitest, no adb binary or device required
npm run typecheckTests drive a fake adb runner and a fake stream spawner, so the whole suite runs without platform-tools, a device or an emulator. Layout:
src/
index.ts entrypoint: stdio by default, --http for Streamable HTTP
http.ts HTTP sessions, bearer auth, loopback guard, DNS-rebinding allowlist
server.ts assembles config + runner + tools/resources/prompts
config.ts env config, shell/device/push/clear guardrails
devices.ts device parsing, resolution rule, list_devices tool
adb/runner.ts subprocess per call: -s scoping, timeouts, head+tail caps
adb/errors.ts typed causes mapped from adb stderr/exit codes
streams/registry.ts long-running logcat handles + ring buffer
tools/ one module per tool group (35 tools, MVP + v2.0 items 1–6 + v0.6.0 additions)
resources/devices.ts, prompts/index.ts
test/ vitest suites (fakes in test/helpers/)Status
Implements the MVP plus v2.0 items 1–7 from the design (§4.2): reverse port forwards and structured
forward/reverse listings, pm grant/revoke plus allowlist-gated clear_app_data, wireless
TCP/IP connect/disconnect/wireless_pair, first-class input injection (tap, swipe,
type_text, key_event — typed schemas that fix the input text quoting footgun, no DSL), the
curated dumpsys_query, and the pulled-forward Streamable HTTP transport. v0.4.0 was a
hardening/polish release (no new tools): shell guardrails now also block pipe-to-shell payloads and
split/globbed root-deleting rm, address-targeted disconnect failures are reported as typed
errors, and reverse_port rejects forward-only device-side specs pre-spawn. v0.5.0 adds Streamable
HTTP (/mcp, stateful sessions, one shared device/stream context, optional bearer auth, loopback
binding guard, DNS-rebinding protection). v0.6.0 adds launch_package (resolve a package's launcher
activity and start it, returning the component) and get_ui_hierarchy to_file (keep large dumps
on-device as {path, bytes} for pull_file instead of returning structurally truncated inline XML).
v0.6.1 teaches type_text non-ASCII (CJK) input: text rides the ADB_INPUT_B64 broadcast to a
capable IME (ADB Keyboard by default) when one is the active input method, with typed
IME_UNAVAILABLE/TEXT_NOT_ASCII errors otherwise (ADBMCP_TYPE_TEXT_NON_ASCII chooses the
posture). v0.7.0 moves onto the MCP TypeScript SDK v2 packages and serves both protocol revisions:
legacy clients keep stateful Streamable HTTP sessions while 2026-07-28 clients get stateless
serving (server/discover, resultType, per-request _meta), same guardrails on both paths.
Not implemented: screenrecord, bugreport, iOS, emulator lifecycle management. Windows is
best-effort (POSIX-first, like most of the ecosystem).
Contributing
Bug reports and use-case-driven feature requests are welcome — see CONTRIBUTING.md for what makes a good issue, how triage works, and the development setup.
Available Tools
35 toolsadb_server_restartRestart the adb serverA
Recover from adb server version conflicts by running adb kill-server followed by adb start-server, then report the device list. Affects the shared adb server on this host (Android Studio and other tools use it too), so call it only when adb reports a server/version problem or a device is stuck.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the generic safety flags (readOnlyHint=false, destructiveHint=false, idempotentHint=false). The description goes well beyond them by disclosing the actual command sequence, the fact that the adb server is shared with Android Studio and other host tools, and that it returns the device list.
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 earning their place: the first gives mechanism and outcome, the second gives the blast radius and the call condition. The critical constraint is front-loaded in the second sentence rather than 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 no-parameter, no-output-schema action tool, the description covers mechanism, side effects on other processes, the precondition for calling, and the returned device list. An agent has everything it needs to decide and invoke 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 takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless schema is 4. The description does not waste words inventing 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 states a specific mechanism (running `adb kill-server` then `adb start-server`) and the goal (recovering from adb server version conflicts), plus the side effect of reporting the device list. No sibling tool does anything similar, so it is trivially distinguishable from the list_* / port-forwarding 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?
It states exactly when to call it ('only when adb reports a server/version problem or a device is stuck') and implicitly when not to, by naming the cost of misuse. This is explicit trigger-condition guidance rather than vague context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_app_dataClear app dataADestructiveIdempotent
Delete all data stored by an app (pm clear <package>). Destructive and allowlist-gated: the server refuses unless the package is listed in ADBMCP_CLEAR_ALLOWED_PACKAGES (comma-separated); an unset or empty value refuses every clear.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| package | Yes | Package name to clear, e.g. "com.example.app". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, yet the description still adds substantial non-redundant detail: exactly what is destroyed ('all data stored by an app'), that it is allowlist-gated via a named env var, and that the failure mode is fail-closed on unset/empty values. This is exactly the extra behavioral context the annotations cannot 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?
Two dense sentences, front-loading the destructive action before the gating condition. No filler, no repetition of the title or schema.
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 destructive mutation with no output schema, the description covers the action, the destruction scope, and the authorization gate, while annotations cover the safety profile and the schema covers both parameters. Nothing an agent needs to call this 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 both the device and package parameters are already documented with examples in the schema. The description only echoes the package parameter via the `pm clear <package>` form and adds no syntax or format detail beyond it, so the baseline of 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+resource ('Delete all data stored by an app') and anchors it to the underlying mechanism (`pm clear <package>`), which cleanly separates it from siblings like force_stop_app and uninstall_package.
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 clear precondition for invocation (package must be present in ADBMCP_CLEAR_ALLOWED_PACKAGES, empty/unset refuses everything), which tells the agent when the call will succeed. It does not, however, name alternative tools such as uninstall_package for when full removal is intended, so routing guidance is incomplete but context is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connectConnect to a device over TCP/IPAIdempotent
Connect adb to a device over TCP/IP (adb connect <host>:<port>), e.g. "192.168.1.42:5555"; a successful connect adds the device to list_devices. Not device-scoped: the address selects the device, and no serial exists until the connection is established. IPv6 literals (e.g. "[::1]:5555") and a bare host without :port are not accepted; specify host:port explicitly. On Android 10+ enable Wireless debugging on the device first; on Android 11+ that also needs a one-time pairing first — call wireless_pair with the code from the Wireless debugging screen, then connect to the port shown there (the pairing port and this connect port are different).
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | Device TCP address as "host:port", e.g. "192.168.1.42:5555" (the port is shown in the Wireless debugging settings). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, idempotentHint=true, openWorldHint=true, but the description adds effects the annotations cannot convey: a successful connect mutates the device list visible to list_devices, and no serial exists until the connection is established. It also discloses platform preconditions and the pairing-port/connect-port distinction.
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 operation, the command form, and a concrete example, then the constraints and prerequisites. It is dense and single-paragraph, and the Android 10/11 prerequisite sentence is long, but every clause carries actionable 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 single-parameter connect tool with no output schema, the description covers the effect of success/invocation target, valid and invalid address forms, and the full prerequisite chain. Nothing needed to call it correctly is missing, and return-format detail is unnecessary.
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 schema already documents the host:port format with an example, so the baseline is 3. The description goes further by describing rejection rules (no IPv6 literals, no bare host) and clarifying that the address, not a serial, identifies the target, adding real 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?
States a specific verb+resource ('Connect adb to a device over TCP/IP') and immediately maps it to the underlying command. It also distinguishes itself from siblings by noting it is not device-scoped and that the address selects the device, contrasting with the serial-based tools in the sibling list.
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 the alternative wireless_pair and the exact conditions that select it (Android 11+ one-time pairing, then connect to the port shown in Wireless debugging). It also states exclusions directly: IPv6 literals and bare hosts are not accepted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
disconnectDisconnect TCP/IP devicesAIdempotent
Disconnect one TCP/IP-connected device (adb disconnect <host>:<port>) or, when address is omitted, every TCP/IP-connected device (adb disconnect). USB connections are unaffected. Not device-scoped: for a TCP/IP device the address itself is the serial.
| Name | Required | Description | Default |
|---|---|---|---|
| address | No | TCP address "host:port" to disconnect; omit to disconnect every TCP/IP device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint=false, idempotentHint=true, destructiveHint=false), and the description adds genuinely useful non-obvious context: USB is unaffected and the tool is not device-scoped because the address is the serial. It does not describe failure modes (e.g., address not connected), 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?
Three tight sentences with no filler; the primary single-device behavior is front-loaded, followed by the omission case and the scoping caveat.
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 covers both modes, the scope boundary, and the addressing model. Only error/edge-case behavior on a nonexistent address is absent, a minor 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 description coverage is 100% and the single `address` parameter already documents the 'host:port, omit to disconnect all' semantics, which the description largely restates. The added nuance that the address serves as the serial is mild extra value; 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 (disconnect) and resource (TCP/IP-connected device) with both the single-device and all-devices forms, plus the underlying `adb disconnect` command. An agent can distinguish it from siblings like `connect` and `wireless_pair` 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?
Clearly states the two invocation modes (address supplied vs. omitted) and scopes the tool by noting USB connections are unaffected. It does not explicitly name `connect` as the counterpart operation or state error behavior when no matching device exists, so it falls short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dumpsys_queryQuery a dumpsys serviceARead-onlyIdempotent
Read a curated Android system service dump (dumpsys <service> [args...]): "battery" for charge/level, "activity" for tasks and activities, "window" for windows and display state, "connectivity" for network state. Output can be huge — "activity" especially — so it is capped (64 KB maximum) with a head+tail truncation marker where bytes were dropped; pass extra_args to narrow it (e.g. "activities" or "windows"). Other dumpsys services are intentionally not exposed; use shell for those.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| service | Yes | Curated service to dump: "battery", "activity", "window" or "connectivity". | |
| extra_args | No | Optional arguments appended after the service, e.g. "activities com.example.app" or "windows"; token-split on whitespace and quoted for the device shell. | |
| timeout_ms | No | Timeout in milliseconds (default 30000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, and the description adds materially new behavior: output is capped at 64 KB with a head+tail truncation marker where bytes were dropped, and 'activity' output is especially large. This tells the agent results may be partial, which the annotations do not 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?
Front-loads the core action and the service enumeration, then layers the truncation caveat and the narrowing hint. Dense but every clause carries information; only the parenthetical examples are slightly redundant with the schema.
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 usefully covers the output contract (64 KB cap, truncation marker) and routes unsupported services to shell. Parameters are fully covered by the schema, leaving little missing for correct 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 description coverage is 100%, so all four parameters are already documented in the schema. The description reinforces extra_args with the same examples found in the schema but adds no syntax or format detail beyond it, 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 ('Read a curated Android system service dump') and enumerates exactly which services are exposed with a one-line meaning for each. It also distinguishes itself from the sibling 'shell' tool by scoping what is intentionally not available.
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 (the four curated services), a concrete narrowing technique (pass extra_args like 'activities' or 'windows'), and an explicit exclusion with the alternative named ('Other dumpsys services are intentionally not exposed; use shell for those').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
force_stop_appForce-stop an appAIdempotent
Stop all processes of a package on one device (am force-stop). Idempotent; safe to call when the app is not running.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| package | Yes | Package name to stop, e.g. "com.example.app". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true, destructiveHint=false, and readOnlyHint=false, so the safety profile is covered. The description largely repeats idempotency but adds that it is safe to invoke when the app is not running, a modest behavioral detail. No contradiction with 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?
Two short sentences, front-loaded with the action and implementation hint. The idempotency clause borders on redundancy with the annotation but is concise enough to warrant 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 two-parameter tool whose annotations carry the safety profile and whose schema documents all parameters, the description covers what is needed. It does not restate device-selection behavior, but the schema already handles that.
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 parameters are documented in the schema itself. The description only adds 'on one device' as loose context and does not explain parameter syntax or format 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 gives a specific verb and resource ('Stop all processes of a package on one device') with an implementation hint (`am force-stop`). It naturally distinguishes from siblings like clear_app_data and uninstall_package by action, though it does not name them explicitly, so it falls just 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?
'Safe to call when the app is not running' gives one usage condition, which is useful context. However, it offers no guidance on when to prefer this over alternatives such as uninstall_package or clear_app_data, leaving selection to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forward_portForward a host port to the deviceAIdempotent
Create a port forward from the host to the device (adb forward), e.g. local "tcp:8080" to remote "tcp:8080". Use it to reach a device-side server (app HTTP server, debug port) from host-only test tooling.
| Name | Required | Description | Default |
|---|---|---|---|
| local | Yes | Host-side spec, e.g. "tcp:8080". | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| remote | Yes | Device-side spec, e.g. "tcp:8080" or "localabstract:webview_devtools_remote". | |
| no_rebind | No | Pass --no-rebind to fail instead of replacing an existing forward (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the operation is a non-read, non-destructive, idempotent, closed-world mutation, so the safety profile is covered. The description adds directional context and an example, but says nothing about lifecycle (the forward persists until remove_forward) or the rebind behavior, which are the traits an agent most needs. Adds modest value beyond 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?
Two sentences, front-loaded with the verb+resource, then the use case. No filler, and the `adb forward` reference plus usage rationale both earn their 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?
No output schema exists, so return values need no explanation, and annotations cover the mutation profile. The one meaningful omission is that a created forward is persistent and must be cleaned up with remove_forward, which an agent setting up host-only test tooling would benefit from knowing.
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 all four parameters including the `tcp:8080` and `localabstract:...` forms. The description's example echoes what the schema provides and adds no new syntax or constraint detail, so 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+resource ("Create a port forward from the host to the device") and anchors it to the underlying `adb forward` command. The host-to-device direction implicitly separates it from reverse_port, but no sibling is named explicitly, so an agent must infer the contrast.
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?
"Use it to reach a device-side server (app HTTP server, debug port) from host-only test tooling" gives a concrete when-to-use condition. It does not name when-not-to-use or point to reverse_port/remove_forward as alternatives, so routing guidance is clear but not complete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_device_infoGet device informationARead-onlyIdempotent
Read a curated set of build properties (model, Android version, SDK level, ABI) plus screen size and density for one device. Use it instead of shell getprop when you only need identity/build details.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_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 and openWorldHint=false, so the safety profile is covered. The description adds the useful scoping fact that the property set is curated rather than a full getprop dump, though it says nothing about behavior when no device is connected or how the device is auto-selected.
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, zero filler, with the return contents and the sibling-routing rule front-loaded. 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?
With no output schema, the description helpfully enumerates what is returned, which compensates well. Only minor gaps remain (no mention of error behavior or defaults when multiple devices match), which keeps it just below full 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 coverage is 100% and the single optional 'device' parameter is fully documented in the schema (serial from list_devices, optional with one connected device). The description adds no syntax or format detail beyond that, so the baseline of 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 precise verb and resource ('Read a curated set of build properties') and enumerates the returned data (model, Android version, SDK level, ABI, screen size, density). It is clearly distinguishable from siblings like shell or get_ui_hierarchy.
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 the alternative ('instead of shell getprop') and the condition that selects this tool ('when you only need identity/build details'). This gives the agent a direct routing rule, not just implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ui_hierarchyGet the UI hierarchyARead-onlyIdempotent
Dump the current view hierarchy of one device as uiautomator XML (uiautomator dump), including bounds, resource ids, text and clickability. Use it to find stable selectors before driving the UI through shell (input tap/text). With to_file: true the XML is kept on the device at /data/local/tmp/adbmcp-ui-.xml and returned as {path, bytes} instead of inline text, so large dumps stay structurally valid; retrieve it with pull_file. Dumps accumulate at that prefix by design — remove them with the shell tool (rm ) after pulling.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| to_file | No | Write the dump to /data/local/tmp/adbmcp-ui-<timestamp>.xml and return {path, bytes} instead of inline XML (default false). | |
| timeout_ms | No | Timeout in milliseconds for the dump (default 30000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so safety is covered. The description adds substantive side-effect context beyond that: to_file:true persists XML on the device, dumps accumulate by design, and cleanup requires a manual rm — not inferable from the schema or 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?
The scoping and usage guidance is front-loaded, and each sentence carries distinct information (purpose, when-to-use, to_file behavior, cleanup). It is dense across three sentences 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?
With no output schema, the description compensates by describing both return shapes (inline XML vs {path, bytes}) and the on-device artifact lifecycle. Everything an agent needs to call it correctly and handle the result 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 100%, so the baseline is 3. The description still adds value by explaining the to_file branch in depth (on-device path pattern, returned shape {path, bytes} instead of inline text), going beyond the terse schema wording for that 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?
States a specific verb and resource ('Dump the current view hierarchy of one device as uiautomator XML') and enumerates the payload it captures (bounds, resource ids, text, clickability). An agent can distinguish this inspection tool from tap/type_text/shell 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?
Explicitly prescribes the use case ('find stable selectors before driving the UI through shell (input tap/text)') and names the alternatives. It also lays out the downstream workflow with pull_file for retrieval and the shell rm for cleanup, so when-to-use and follow-on actions are fully covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grant_permissionGrant a runtime permissionADestructiveIdempotent
Grant a runtime permission to an app (pm grant <package> <permission>). Destructive: it changes the permissions the app holds; revoke_permission reverses it. Only changeable runtime permissions work; on stock Android these can be granted to non-debuggable apps too, though some restricted permissions still reject the shell.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| package | Yes | Package name, e.g. "com.example.app". | |
| permission | Yes | Permission name, e.g. "android.permission.CAMERA". |
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 covered. The description adds real value beyond that: what changes (the permissions the app holds), that revoke reverses it, and that restricted permissions still reject the shell even on stock Android.
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 action and CLI form, then the destructive/reversal note, then the edge-case constraint. 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?
Covers the mutation, its inverse, and the main failure condition for a tool with no output schema. Return behavior is unspecified but not essential here; the description is otherwise complete for correct 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 100%, so the baseline is 3. The description adds the `pm grant <package> <permission>` invocation, which maps the two required params to their CLI positions, plus the constraint that the permission must be a changeable runtime permission — meaningful semantics for the permission argument.
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 ('Grant a runtime permission to an app') and immediately names the reversing sibling, revoke_permission. An agent can distinguish it from the other adb tools 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?
Explicitly names revoke_permission as the inverse operation and states the precondition that only changeable runtime permissions work. It doesn't spell out a when-not-to-use case (e.g., when to prefer shell), but the routing context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
install_apkInstall an APKA
Install a local APK on one device via adb install. Fails with INSTALL_FAILED_* details from the device when the package cannot be installed.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| replace | No | Pass -r to replace an already installed package (default false). | |
| apk_path | Yes | Path to the APK on the host machine (not on the device). | |
| timeout_ms | No | Install timeout in milliseconds (default 120000; large APKs are slow). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safety profile (not read-only, not idempotent, not destructive), so the bar is lower. The description still adds real behavioral value by disclosing the failure mode: issues surface as INSTALL_FAILED_* codes from the device. It does not cover whether `replace` preserves or wipes existing app data, which is the main 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?
Two tight sentences with zero filler; the core action is front-loaded and the failure behavior follows immediately. Nothing here could be cut without losing 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?
For a single-device install tool with full parameter coverage and annotations carrying the safety profile, the description covers purpose and the notable failure path. Since there is no output schema, the agent would benefit from a note on what a successful return looks like, but the INSTALL_FAILED_* disclosure covers the most important return behavior.
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 four parameters (device, replace, apk_path, timeout_ms) are already documented, including defaults and the host-vs-device path distinction. The description adds no parameter-level detail beyond the schema, 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+resource: installs a local APK via `adb install`, and clarifies it operates on one device. This distinguishes it well from adjacent tools like push_file (which moves bytes without installing) or launch_package (which runs an already-installed app). It stops short of explicitly naming a sibling, so a 4 rather than 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?
There is no when-to-use guidance, no prerequisites (e.g., device connected, output of list_devices needed), and no routing to alternatives such as push_file. The phrase 'Install a local APK on one device' implies context but does not instruct the agent 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.
key_eventSend a key eventA
Send one key event to the device (input keyevent <code>). Pass a named key (HOME, BACK, ENTER, DEL, MENU, POWER, VOLUME_UP, VOLUME_DOWN, TAB, ESCAPE, APP_SWITCH, WAKEUP, SLEEP) or a raw Android keycode 0-300. Use WAKEUP (or POWER) before driving a screen that may be off, and BACK/HOME to navigate.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | Android keycode 0-300, or a named key: HOME, BACK, ENTER, DEL, MENU, POWER, VOLUME_UP, VOLUME_DOWN, TAB, ESCAPE, APP_SWITCH, WAKEUP, SLEEP. | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare the mutation profile (readOnly=false, non-idempotent, non-destructive), so those are covered. The description adds useful behavior the annotations cannot: the exact adb mechanism, the difference between named keys and raw keycodes, and the practical caveat that the screen may be off. Error/return behavior is not disclosed, but for a fire-and-forget input injection this is minor.
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 and command, followed by the key-format explanation and practical hints. Two sentences, no filler, though the enumerated key list duplicates the schema and could be trimmed.
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 single-purpose with no output schema needed; the description covers input format, mechanism, and the main usage caveat. Only the absence of any note about failure modes or return behavior keeps it from a 5.
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 largely restates the schema (named keys plus raw keycode 0-300) and adds only the framing "raw Android keycode" and the wake/navigation hints rather than new parameter-level detail such as what happens with an out-of-range code.
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 one key event to the device") and even names the underlying command (`input keyevent <code>`). This clearly distinguishes it from siblings like tap, swipe, and type_text, which also inject input but at a different level.
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 actionable when-to-use guidance: WAKEUP/POWER before driving a possibly-off screen, BACK/HOME to navigate. It does not explicitly say when to prefer tap/type_text instead of a keycode, so it falls short of full alternative routing but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch_packageLaunch an app by package idA
Launch an installed app by package id: resolve its LAUNCHER activity (cmd package resolve-activity --brief) and start it (am start -n, with -W when wait is true). Returns the resolved component so later calls can use start_activity without re-resolving. The monkey -p <package> 1 one-liner exists, but this keeps everyday launches off the shell escape hatch.
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | Pass -W and wait for the launch to be reported as displayed (default false). | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| package | Yes | Package name to launch, e.g. "com.android.settings". | |
| timeout_ms | No | Timeout in milliseconds (default 30000; raise it when wait is true). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations establish the safety profile (not read-only, not idempotent, not destructive), and the description adds real behavioral context beyond that: the underlying resolve-activity/am start -n flow, the -W wait semantics, and the fact that it returns the resolved component for reuse. It does not cover auth or rate constraints, but none are implied here.
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 the core action, and each sentence carries routing or mechanism value. The 'monkey' aside earns its place as a justification against the shell path.
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 disclosing the return value (the resolved component) and the reuse path via start_activity. For a 4-parameter launch tool, this is nearly complete, missing only edge-case behavior on unresolvable packages.
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 four parameters including wait, device, and timeout_ms. The description's '-W when wait is true' restates the schema's own semantics rather than extending them, so 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+resource (launch an installed app by package id) and reveals the mechanism. It explicitly distinguishes itself from siblings start_activity and shell, so an agent can select it 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?
Clear routing context: it returns the resolved component so later calls can use start_activity, and it argues for itself over the 'monkey -p' shell one-liner. It lacks an explicit 'when not to use' statement but the alternative relationship is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesList connected Android devicesARead-onlyIdempotent
List Android devices and emulators known to adb with their serial, connection state and model. Call this first to discover serials for the "device" parameter of other tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so safety is covered. The description adds genuinely useful behavior beyond that: it covers emulators as well as physical devices and enumerates the returned attributes, which matters since no output schema exists.
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, front-loaded with what is listed and followed by the workflow instruction. Every clause earns its place, with no restatement of the title 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?
With no parameters, rich annotations, and no output schema, the description supplies precisely the missing piece — what the returned records contain — and how to use the result downstream. Nothing an agent needs to call it correctly is absent.
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 takes zero parameters, so the baseline is 4. The description correctly adds no parameter information and instead uses the space for output and workflow 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?
Specific verb and resource ('List Android devices and emulators known to adb') plus the exact fields returned (serial, connection state, model). It is clearly distinguishable from siblings like get_device_info because it enumerates rather than details a single 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?
Explicit sequencing guidance: 'Call this first to discover serials for the "device" parameter of other tools' tells the agent exactly when this tool belongs in a workflow. It does not name a when-not condition or an alternative, but for a discovery tool none is really needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_forwardsList port forwardsARead-onlyIdempotent
List the forward socket connections of one device (adb forward --list) as a JSON array of {serial, local, remote} objects (empty array when there are none).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_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, and openWorldHint=false, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the exact return shape ({serial, local, remote} JSON array) and the empty-array edge case, which matters because no output schema exists.
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, front-loaded with the action and resource, with the return format appended as a compact clause. Nothing is redundant or padded.
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 single-optional-param read tool, the description covers purpose, the CLI equivalent, and the return value shape and empty case. With annotations handling safety and no output schema present, nothing an agent needs 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% for the single `device` parameter, including the 'optional when exactly one device is connected' nuance. The description adds nothing about the parameter, so the baseline 3 for schema-does-the-work 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 and resource ('List the forward socket connections of one device') and pins it to the underlying operation (`adb forward --list`), which cleanly distinguishes it from siblings like list_reverses, forward_port, and remove_forward.
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?
Usage is implied by the name and the read-only listing nature of the tool, but there is no explicit when-to-use guidance and no mention of the obvious alternative (list_reverses for reverse forwards). The agent can infer intent, but nothing routes it deliberately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_packagesList installed packagesARead-onlyIdempotent
List package names installed on one device (optionally filtered by a substring of the package name), e.g. filter "com.example" to find only the app you care about.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| filter | No | Substring filter passed to `pm list packages`, e.g. "example" or "com.android.chrome". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds the output type (package names) and filter behavior, but does not mention permissions, performance, or other runtime traits beyond what the annotations provide.
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?
A single front-loaded sentence with a concrete example, no filler. Every clause contributes to understanding what the tool returns and how filtering works.
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 list tool with no output schema, the description states the return content (package names) and filter behavior. It leaves device optionality to the schema, which already documents it, so it is largely complete for the tool's complexity.
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 the device and filter parameters are already documented in the schema. The description repeats the filter concept and gives an example, but adds no meaning beyond the schema's own examples and 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 and resource: list package names installed on one device. It also clarifies the optional substring filtering and gives an example, making it easily distinguishable from mutation siblings like install_apk or uninstall_package.
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?
Implies when to use it by mentioning filtering to find an app of interest, but does not explicitly compare against alternatives such as list_devices, get_device_info, or dumpsys_query. No when-not guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_reversesList reverse port forwardsARead-onlyIdempotent
List the reverse socket connections of one device (adb reverse --list) as a JSON array of {serial, remote, local} objects (empty array when there are none). remote is the device-side listen spec, local the host-side target.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_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 this as read-only, idempotent, non-destructive, and not open-world, so the safety profile is covered. The description adds valuable behavioral context beyond those annotations: it returns a JSON array of `{serial, remote, local}` objects, returns an empty array when none exist, and explains that remote is the device-side listen spec and local is the host-side target.
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 tight sentences with the action front-loaded, and every clause earns its place by adding command mapping, return format, or field semantics. There is no filler 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 read-only list tool with one optional parameter and no output schema, the description supplies the essential missing return-shape information and empty-result behavior. Annotations cover the safety profile, and the schema covers the device parameter, leaving no significant 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 description coverage is 100%, and the sole optional `device` parameter is already documented in the schema as coming from list_devices and being optional when exactly one device is connected. The description adds no additional parameter syntax or format details, 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 gives a specific verb and resource ('List the reverse socket connections of one device') and maps it to the exact underlying command (`adb reverse --list`). It clearly distinguishes reverse connections from the sibling list_forwards tool by name and concept.
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?
Usage is implied by the direct action and the `--list` comparison, so an agent can infer it is for inspecting existing reverse mappings. However, there is no explicit when-to-use, when-not-to-use, or sibling alternative guidance (e.g., versus list_forwards or remove_reverse).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
logcat_snapshotRead a logcat snapshotARead-onlyIdempotent
Dump the current logcat buffer (adb logcat -d) from one device, optionally filtered to a log tag. Bounded output; use the stream tools when you need to watch logs over time.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| max_lines | No | Maximum lines to return, most recent kept (default 200, max 5000). | |
| timeout_ms | No | Timeout in milliseconds (default 30000). | |
| filter_spec | No | logcat filter spec, e.g. "AndroidRuntime:E *:S" or "ActivityManager:I *:S". Space separated, passed to adb logcat as-is. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/destructiveHint, so safety is covered. The description adds real behavioral context beyond that: it captures a bounded snapshot (not a follow), is scoped to one device, and the output is bounded — the key trait separating it from the stream tools.
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, zero waste: behavior and scope first, then the routing constraint. Everything 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?
For a read-only snapshot tool with 100% schema coverage and full annotations and no output schema, the description covers the essential decision (snapshot vs stream) and the bounded nature of output. It need not enumerate return format, though a note on truncation behavior would close the remaining 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 description coverage is 100%, so all four parameters (device, max_lines, timeout_ms, filter_spec) are already documented in the schema; baseline 3 applies. The description's phrase 'optionally filtered to a log tag' is slightly narrower than the schema's full logcat filter spec, adding little and potentially under-selling filter_spec.
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 ('Dump the current logcat buffer') plus the underlying command and scope ('from one device'), and explicitly sets itself apart from the streaming siblings. An agent can tell it apart from start_logcat_stream/read_logcat_stream 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?
'use the stream tools when you need to watch logs over time' gives a clear selection condition and points to the alternative family. It stops short of naming the exact sibling (start_logcat_stream vs read_logcat_stream) or stating the reverse condition, so it is clear but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pull_filePull a file from the deviceA
Copy a file from the device to the host machine (adb pull). Refuses to overwrite an existing host file unless overwrite is true. This writes to the host filesystem, so it is not a read-only tool.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| overwrite | No | Allow replacing an existing host file (default false). | |
| local_path | Yes | Destination path on the host machine (relative paths resolve against the server cwd). | |
| remote_path | Yes | Absolute path on the device, e.g. "/sdcard/Download/crash.log". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false and destructiveHint=false, and the description adds genuinely new context: it refuses to overwrite an existing host file unless overwrite is true, and it explicitly confirms it writes to the host filesystem rather than being read-only. It does not describe failure modes or whether parent directories are created, but the overwrite guard-rail is real added value.
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, each carrying distinct information: what it does, its overwrite guard, and its filesystem-write nature. No filler 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?
With no output schema and full parameter documentation, the description covers the essential behavior (direction, overwrite refusal, host-side writes) for a 4-parameter copy tool. Remaining gaps such as error handling and directory creation are minor for a tool whose annotations and schema carry the rest.
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%, with every parameter documented including the overwrite default and the relative-path resolution rule, so the baseline is 3. The description's mention of overwrite largely restates what the schema already says, adding little syntax or format detail beyond it.
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), resource (a file), and direction (from the device to the host machine), plus the underlying adb command. The direction alone distinguishes it from the sibling push_file without either schema being opened.
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 explicit device-to-host direction gives clear context for when this tool applies and implicitly excludes push_file's opposite direction. However, it never names the alternative or states a when-not condition, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
push_filePush a file to the deviceA
Copy a file from the host machine to the device (adb push). For safety the remote path must be inside the configured allowed roots (default /sdcard, /storage/emulated/0, /data/local/tmp).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| local_path | Yes | Source path on the host machine (relative paths resolve against the server cwd). | |
| remote_path | Yes | Destination path on the device, e.g. "/sdcard/Download/app.apk". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, non-idempotent, open-world mutation. The description adds genuinely new behavioral context beyond that: the safety restriction that the remote path must fall inside configured allowed roots, with default roots listed. It does not describe failure behavior when a path is rejected, but the added constraint is substantive.
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, zero filler, with the core operation front-loaded and the safety constraint second. 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?
With no output schema, the description plus annotations plus fully-described parameters cover what an agent needs to invoke the tool: operation, direction, and path safety. It omits what happens on a disallowed path or a failed copy, a minor gap for a straightforward file-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 (device, local_path, remote_path) are already documented in the schema. The description reinforces the remote_path constraint with allowed-root detail, but this is supplemental rather than compensating for a gap. 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 and resource ('Copy a file from the host machine to the device') and names the underlying adb operation, which cleanly distinguishes it from the sibling pull_file. An agent can select it 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?
The description gives a clear operating context (host-to-device copy) and a precondition on the remote path, which implies when the tool applies. It does not explicitly name pull_file as the reverse-direction alternative or state when-not-to-use, so it stops short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_logcat_streamRead a logcat streamARead-only
Return buffered logcat output accumulated since the previous read of this stream. Output is capped per call; anything not returned stays buffered for the next read. Dropped bytes are reported when the ring buffer overflowed.
| Name | Required | Description | Default |
|---|---|---|---|
| max_bytes | No | Maximum bytes to return in this call (default 65536). | |
| stream_id | Yes | stream_id returned by start_logcat_stream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already covering the safety profile, the description adds real behavioral context beyond annotations: per-call output capping, that unreturned data stays buffered for the next read, and that dropped bytes are reported on ring-buffer overflow. It stops short of covering error behavior (e.g., invalid or stopped stream) or whether the read blocks.
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, each earning its place, with the core incremental-read semantics front-loaded ahead of the buffering and overflow caveats.
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 read tool with no output schema, the description adequately explains return semantics (incremental buffer, cap, remainder carried over, dropped-byte reporting). Minor gaps remain around failure modes and blocking behavior, but nothing essential to calling 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 both parameters are already documented, including max_bytes' default of 65536 and stream_id's origin. The description's mention of a per-call cap reinforces max_bytes but adds no syntax or format detail beyond the schema, so 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+resource ('Return buffered logcat output') and pins down the scope with 'accumulated since the previous read of this stream', which implicitly distinguishes it from logcat_snapshot and the start/stop stream siblings. It does not explicitly name the alternative tools, so an agent must infer the split.
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?
Usage is implied rather than stated: the phrase 'since the previous read of this stream' and the schema's 'stream_id returned by start_logcat_stream' tell the agent this is a follow-up to start_logcat_stream, but there is no explicit when-to-use guidance or contrast with logcat_snapshot.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_forwardRemove a port forwardAIdempotent
Remove a port forward created with forward_port (adb forward --remove <local>).
| Name | Required | Description | Default |
|---|---|---|---|
| local | Yes | Host-side spec previously forwarded, e.g. "tcp:8080". | |
| device | No | Device serial from list_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=false, destructiveHint=false, and idempotentHint=true, so the safety profile is largely covered. The description adds the inverse relationship to forward_port and the underlying adb command, but says nothing about what happens if the forward does not exist or what the response is.
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?
A single front-loaded sentence with no waste; the verb, the resource, and the creating sibling all appear immediately.
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, non-destructive removal tool with full schema coverage, annotations covering the safety profile, and no output schema, the definition supplies the key inverse relationship. Only edge-case behavior (missing forward) is left unspecified.
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 both parameters (local, device) are documented in the schema itself, so the baseline of 3 applies; the description adds no format or syntax detail 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?
States a specific verb+resource ("Remove a port forward") and names the sibling that creates it (forward_port), letting an agent distinguish it from remove_reverse and other removal tools 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?
The clause "created with forward_port" establishes the prerequisite and implicitly routes the agent to the create/remove pair. It does not explicitly exclude or contrast with remove_reverse, but the intended usage is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_reverseRemove a reverse port forwardAIdempotent
Remove a reverse socket connection created with reverse_port (adb reverse --remove <remote>).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| remote | Yes | Device-side spec previously passed to reverse_port, e.g. "tcp:8080". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and destructiveHint=false, so safety and repeat-call behavior are covered. The description adds the underlying `adb reverse --remove <remote>` semantics, which confirms the mapping is deleted rather than modified, but says nothing about permissions or failure modes beyond what idempotency implies.
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?
A single front-loaded sentence with the verb+resource first and the ADB equivalence as supporting detail. Nothing is padded or repeated from the schema.
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-required-parameter removal tool with annotations covering the safety profile, this is close to complete. It could mention behavior when the remote spec was never created, but the idempotentHint annotation largely covers that gap, and no output schema exists to explain.
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 `device` and `remote` are already documented in the schema, including the example format. The description only echoes `<remote>` as a placeholder, adding no syntax or validation detail beyond the structured fields.
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 (Remove) and resource (a reverse socket connection created with reverse_port), and pairs itself with the sibling that created the mapping. An agent can distinguish this from remove_forward and reverse_port 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?
The phrase 'created with reverse_port' makes the lifecycle pairing explicit, implying the user should have an existing mapping from reverse_port before calling this. It stops short of stating exclusions (e.g. 'use remove_forward for forward mappings') or failure conditions, but the context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reverse_portReverse a device port to the hostAIdempotent
Create a reverse socket connection (adb reverse): the device listens on the remote spec and connections are forwarded to the local spec on the host machine. Use it to let device-side code (app under test, on-device scripts) reach a server running on your machine.
| Name | Required | Description | Default |
|---|---|---|---|
| local | Yes | Host-side target spec, e.g. "tcp:8080". | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| remote | Yes | Device-side listen spec, e.g. "tcp:8080". | |
| no_rebind | No | Pass --no-rebind to fail instead of replacing an existing reverse (default false). |
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=true), so the description only needs to add context beyond them. It does add the forwarding direction semantics, but says nothing about lifecycle: whether the reverse persists beyond the session, or that the default behavior replaces an existing reverse when the spec differs (the no_rebind parameter implies rebinding, which is left to the schema).
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, zero waste, with the directionality semantics front-loaded before the use case. Nothing repeats the title or 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?
For a 4-param mutation tool with full schema coverage, annotations, and no output schema, this covers what an agent needs to call it correctly. The only omissions are peripheral: the rebind/replace default and the existence of remove_reverse as the teardown counterpart.
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. The description still earns above baseline by explaining that 'remote' is the device-side listening spec and 'local' is the host-side target, which resolves the naming ambiguity that the terse schema descriptions ('Device-side listen spec') only partly cover.
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?
Names a specific verb+resource ('Create a reverse socket connection (`adb reverse`)') and disambiguates the exact point that confuses agents versus forward_port: which side listens and which side connects. An agent can distinguish it from 'forward_port' 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 a concrete when-to-use ('let device-side code ... reach a server running on your machine'), which is the canonical scenario. It stops short of naming the sibling alternative forward_port for the opposite direction or pointing at remove_reverse for teardown, so it doesn't reach explicit when-not/alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
revoke_permissionRevoke a runtime permissionADestructiveIdempotent
Revoke a runtime permission from an app (pm revoke <package> <permission>). Destructive: the app loses the permission immediately and may fail until it is granted again.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| package | Yes | Package name, e.g. "com.example.app". | |
| permission | Yes | Permission name, e.g. "android.permission.CAMERA". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false; the description goes beyond them by spelling out the concrete consequence ('the app loses the permission immediately and may fail until it is granted again'). It does not mention the actual command output or whether a device must be targeted, but the added failure-mode context is genuine value.
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: the first states the action and its CLI equivalent, the second front-loads the 'Destructive:' warning and the user-visible effect. No filler, nothing that could be cut.
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 3-parameter mutation with no output schema, the description covers action, command form, and destructive consequence, which is enough to call it safely. It omits any note on idempotency or on the optional device parameter, but those are minor for this tool's complexity.
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 three parameters carry descriptions with concrete examples ('com.example.app', 'android.permission.CAMERA') and the optional-device rule. The description only mirrors the `<package> <permission>` ordering already implied by required params, adding essentially nothing new, 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 uses a specific verb+resource ('Revoke a runtime permission from an app') and even quotes the underlying `pm revoke <package> <permission>` invocation, so there is no ambiguity about the operation. It does not name its inverse sibling grant_permission, so it stops short of full sibling 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?
Usage is implied rather than stated: an agent can infer this is the inverse of grant_permission from the sibling list, but the description never says when to revoke versus when to use grant_permission, nor any prerequisite (e.g. that the permission must currently be granted).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshotCapture a screenshotARead-onlyIdempotent
Capture the current screen of one device (exec-out screencap -p) and return it as a PNG image. Follow up with get_ui_hierarchy when you need element coordinates instead of pixels.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_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, and destructiveHint=false, so safety is covered without description help. The description still adds real context the annotations don't: the underlying command (`exec-out screencap -p`) and the return format (PNG image). It does not cover behavior with multiple devices connected, but the schema does.
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, zero padding, with the core action and return type front-loaded and the sibling routing held for the second sentence. 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?
For a single-optional-parameter read tool with full schema coverage and safety annotations, nothing an agent needs is missing: the action, the output format, and the alternative tool are all stated, and no output schema exists that the description would need to compensate for.
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 `device` parameter is fully documented in the schema, so the baseline of 3 applies. The description only implies single-device scoping ('one device') and adds no syntax or format detail 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?
States a specific verb and resource ('Capture the current screen') plus the exact output artifact ('return it as a PNG image'), and distinguishes itself from the sibling get_ui_hierarchy by contrasting pixels vs. element coordinates. 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?
Explicitly names the alternative and the condition that selects it ('Follow up with get_ui_hierarchy when you need element coordinates instead of pixels'), which is genuine routing guidance. It doesn't state the inverse case (prefer screenshot when visual appearance matters) or note when-not to use it, so it falls just short of fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shellRun a device shell commandA
Escape hatch: run an arbitrary command through adb shell on one device and return stdout/stderr. Powerful but not read-only — destructive commands are refused by default (reboot, su, mkfs, wipe, rm of / including split/reordered flags and the /* glob, and pipelines into sh/bash such as curl … | sh or … | sudo bash). This is a guardrail, not a sandbox: a deliberately obfuscated command can still get through. Prefer the dedicated tools (list_packages, install_apk, get_ui_hierarchy, …) when they cover the job. A non-zero remote exit code is reported as exit_code: N in the output. If the call times out, only the host-side adb client is killed; the command keeps running on the device (inherent to adb).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| command | Yes | Device shell command, e.g. "dumpsys battery" or "ls /sdcard/Download". | |
| timeout_ms | No | Command timeout in milliseconds (default 30000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly=false, destructive=false, openWorld=true, idempotent=false; the description goes far beyond by enumerating the refused-command guardrail, warning that it is 'a guardrail, not a sandbox' and can be obfuscated past, and disclosing that a timeout kills only the host-side adb client while the device command keeps running. It also documents that non-zero remote exits surface as `exit_code: N`. No contradiction with annotations — destructive=false is consistent with the stated refusal of destructive commands.
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 'Escape hatch' framing and then layers guardrail, routing, and timeout behavior with no filler. Dense but every sentence carries operational information an agent needs.
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 still explains the return surface (stdout/stderr, `exit_code: N` on non-zero) and the timeout side effect. For a high-risk arbitrary-execution tool, the safety caveats and routing guidance make it complete enough to invoke 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?
Schema coverage is 100%, so the baseline is 3; however the description adds real meaning beyond the schema for `timeout_ms` by explaining that on timeout only the host-side adb client is killed and the remote command continues. Device/command semantics are already fully covered by the schema, so this is a modest but genuine addition.
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 an arbitrary command through `adb shell` on one device') plus the return surface (stdout/stderr). It also distinguishes itself from the many dedicated siblings by framing itself as the 'escape hatch' and naming the preferred alternatives (list_packages, install_apk, get_ui_hierarchy).
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 routing guidance: 'Prefer the dedicated tools … when they cover the job', with concrete sibling names. It also states the when-not condition — destructive commands (reboot, su, mkfs, wipe, rm of /, pipelines into sh/bash) are refused by default — so the agent knows the boundaries before invoking.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_activityStart an activityA
Launch an activity on one device (am start) either by component ("com.example/.MainActivity") or by intent action ("android.intent.action.VIEW" with optional data/extras). Use wait: true to block until the activity is reported as displayed.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | Intent data URI (-d), e.g. "https://example.com/item/1". | |
| wait | No | Pass -W and wait for launch to complete (default false). | |
| action | No | Intent action, e.g. "android.intent.action.VIEW". Mutually exclusive with component. | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| extras | No | Raw `am start` arguments appended as-is and shell-quoted, e.g. ["--es", "message", "hello world", "--ez", "debug", "true"]. | |
| package | No | Restrict the intent to a package (-p), e.g. "com.example.app". | |
| component | No | Explicit component "package/activity". Mutually exclusive with action. | |
| timeout_ms | No | Timeout in milliseconds (default 30000; raise it when wait is true). | |
| force_stop_first | No | Pass -S to force-stop the target app before starting it (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare this is a non-readOnly, non-idempotent, non-destructive operation, so the mutate-but-not-destroy profile is already covered. The description adds genuinely useful behavior beyond that: the wait: true flag blocks until the activity is *reported as displayed*, and the launch targets a single device. It omits what happens on failure or when the component doesn't exist.
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, front-loaded with the core action and mechanism, then the blocking caveat. No filler, and the most important disambiguation (component vs action) comes first.
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 and a fully documented schema, the description covers what an agent needs to call the tool, including the blocking semantics of wait. It leaves gaps on error behavior and on when device must be specified versus inferred, but nothing that would cause a wrong 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 description coverage is 100%, so the schema already documents all nine parameters in detail, including the data/extras syntax and mutual exclusivity. The description reinforces component-vs-action exclusivity but adds no format or constraint detail the schema lacks, 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 names a specific verb (Launch), the resource (an activity), the underlying mechanism (`am start`), and the two mutually exclusive invocation modes. It is clearly distinguishable from the nearby launch_package sibling.
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 tells the agent how to choose between component and action modes and when to set wait: true, which is real usage guidance. It stops short of naming alternatives such as launch_package or explaining when to prefer one over the other, and gives no exclusions or failure conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
start_logcat_streamStart a logcat streamARead-only
Start a long-lived adb logcat process on one device and return a stream_id. Poll it with read_logcat_stream and release it with stop_logcat_stream. Streams are killed when the server shuts down.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| filter_spec | No | logcat filter spec, e.g. "AndroidRuntime:E *:S" or "ActivityManager:I *:S". Space separated, passed to adb logcat as-is. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds lifecycle context the annotations don't carry: the stream is long-lived and is torn down when the server shuts down, which matters for resource management. readOnlyHint=true is not contradicted, since the tool observes logs rather than mutating device state, though holding a persistent process is a resource trait the description handles well.
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 with zero filler; the core action and return value come first, followed by the follow-up calls and the lifetime caveat in priority order.
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 usefully names the return value (stream_id) and the lifecycle that governs it. For a 2-param tool with full schema coverage, that is nearly complete; only the snapshot-vs-stream choice is 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 both parameters (device, filter_spec) are already fully documented in the schema with examples. The description adds no syntax or format detail beyond that, so 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 ('Start a long-lived `adb logcat` process on one device') plus the return value (stream_id). It is clearly distinguishable from logcat_snapshot (one-shot) and read_logcat_stream/stop_logcat_stream (lifecycle stages), all of which are named or implied.
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 routes the agent through the lifecycle: poll with read_logcat_stream, release with stop_logcat_stream. It does not, however, state when to prefer this long-lived stream over the sibling logcat_snapshot for a one-time capture, so the main alternative is left implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop_logcat_streamStop a logcat streamARead-onlyIdempotent
Terminate a logcat stream and forget its stream_id. Up to max_bytes of output buffered but not yet read is returned in this result; any excess is discarded and reported.
| Name | Required | Description | Default |
|---|---|---|---|
| max_bytes | No | Maximum buffered bytes to return (default 65536). | |
| stream_id | Yes | stream_id returned by start_logcat_stream. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover readOnly/idempotent/non-destructive, and the description adds real behavioral value beyond them: it discloses that buffered-but-unread output up to max_bytes is returned here and that excess is discarded and reported. Note a mild tension between a 'terminate/forget' operation and readOnlyHint=true, but for an ephemeral session-scoped stream this is defensible rather than a hard contradiction.
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 primary action (terminate + forget) followed by the return/discard behavior. Every clause carries information; 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?
With no output schema, the description carries the burden of explaining returns and does so (buffered output up to max_bytes, overflow discarded and reported). It omits error behavior for an unknown/already-stopped stream_id, though idempotentHint partially covers that.
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% (baseline 3), and the description adds meaning beyond the schema by explaining how max_bytes governs the returned buffered output and that overflow is discarded and reported. It also implicitly clarifies that stream_id is consumed and invalidated after the call.
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: 'Terminate a logcat stream and forget its stream_id.' This clearly separates it from start_logcat_stream and read_logcat_stream, though the differentiation with read_logcat_stream (read without terminating) is only implied rather than named.
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?
Usage is implied by 'forget its stream_id' (call this as final cleanup), but there is no explicit when-to-use or when-not-to-use guidance relative to read_logcat_stream, which is the natural alternative for retrieving buffered output without terminating.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
swipeSwipe the screenA
Swipe from (x1, y1) to (x2, y2) (input swipe X1 Y1 X2 Y2 [duration_ms]), e.g. to scroll a list or dismiss a card. duration_ms is the gesture time in milliseconds (device default 300 when omitted); a longer duration drags more slowly. Coordinates are device pixels; screenshot afterwards to verify the result.
| Name | Required | Description | Default |
|---|---|---|---|
| x1 | Yes | Start X in device pixels (non-negative integer). | |
| x2 | Yes | End X in device pixels (non-negative integer). | |
| y1 | Yes | Start Y in device pixels (non-negative integer). | |
| y2 | Yes | End Y in device pixels (non-negative integer). | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| duration_ms | No | Gesture duration in milliseconds; omit for the device default (300 ms). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=false); the description adds that the default duration is 300 ms on omission, that longer durations drag more slowly, and that the agent should screenshot afterwards to verify. It does not discuss failure modes or permission needs, which is a minor gap for a gesture 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?
One dense, front-loaded sentence: the signature comes first, followed by use examples, duration semantics, units, and a verification tip. Every clause adds operative information and nothing is padding.
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?
There is no output schema, and the description handles this by pointing to screenshot for verification, while units, defaults, and the optional device parameter are covered in the schema. What is missing is any statement of what a failed or out-of-bounds swipe does, a small gap for a 6-parameter gesture 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 coverage is 100%, so the baseline is 3, but the description adds genuine semantics beyond the schema: duration as a speed control ('a longer duration drags more slowly') and the default-300 behaviour in context. It reiterates pixel units rather than expanding on them, keeping it out of 5 territory.
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 ('Swipe from (x1, y1) to (x2, y2)') and even shows the underlying adb form, so the agent knows exactly which gesture is performed. It is trivially distinguishable from siblings like tap, key_event, or shell.
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 usage context ('to scroll a list or dismiss a card'), which tells the agent when this gesture is appropriate. It does not state exclusions or explicitly contrast with tap/key_event for other navigation cases, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tapTap the screenA
Tap a point on the device screen (input tap X Y). Coordinates are device pixels: read them from get_ui_hierarchy bounds or get_device_info screen_size, and screenshot after the tap to verify the result (screenshot → decide → act loop). If the display is off, wake it first with key_event WAKEUP — input events are dropped while the screen is off.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | X in device pixels (non-negative integer). | |
| y | Yes | Y in device pixels (non-negative integer). | |
| device | No | Device serial from list_devices; optional when exactly one device is connected. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare the safety profile (readOnly=false, idempotent=false, destructive=false, openWorld=false), and the description adds a genuinely useful runtime behavior: input events are silently dropped while the display is off, so key_event WAKEUP must precede the tap. It also prescribes a screenshot-verify loop, though it does not discuss failure modes such as taps landing outside the visible area.
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 action and its raw equivalent are front-loaded in the first clause, followed by coordinate sourcing, verification, and the wake precondition in descending order of importance. Every clause carries information; 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?
With no output schema and annotations already covering the safety profile, the description supplies the remaining essentials: exact command semantics, coordinate provenance, the screen-off precondition, and the verification loop. An agent can call this correctly without opening any sibling tool definition.
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 goes further by telling the agent where valid x/y values come from (get_ui_hierarchy bounds vs. get_device_info screen_size), which is actionable provenance not present in the schema. It does not add anything new for the optional `device` 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 names a specific verb+resource and pins the exact underlying operation (`input tap X Y`), so the agent knows precisely what will happen on the device. It is clearly distinguishable from siblings like swipe, type_text, and key_event.
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 routes the agent to get_ui_hierarchy bounds and get_device_info screen_size for coordinates, and to screenshot for post-tap verification, which is strong contextual guidance. It does not, however, state when to prefer swipe or type_text over tap, so the alternative selection is only partly covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
type_textType textA
Type text into the focused input field (input text <text>). Spaces are encoded as %s (adb's space form) and shell metacharacters are quoted, so the text reaches the device intact; note that a literal "%s" in text still becomes a space on the device. Focus the field first (tap it), and screenshot to confirm what was typed.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to type, e.g. "hello world" or "user@example.com". | |
| device | No | Device serial from list_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 a non-readonly, non-destructive write. The description adds significant behavioral detail beyond that: spaces are encoded as %s, shell metacharacters are quoted, and a literal '%s' still becomes a space on the device. It also states the focus prerequisite and suggests verification.
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 front-loads the core action, then adds encoding caveats, then prerequisites/verification. Every sentence earns its place, with no wasted phrasing.
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 write tool with full schema coverage, annotations, and no output schema, the description covers the essential context: what it does, how to prepare (focus), how to verify (screenshot), and encoding pitfalls. Device selection is delegated appropriately to the schema.
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 would be 3. The description adds meaningful value for the `text` parameter by explaining encoding rules and the %s caveat, though it says nothing additional about the `device` parameter 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?
States a specific verb ('Type text') and target ('focused input field'), and even gives the underlying adb command. It clearly distinguishes itself from siblings like tap, key_event, and shell by focusing on text entry into an already-focused field.
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 a clear prerequisite ('Focus the field first (tap it)') and a verification step ('screenshot to confirm what was typed'). It does not name explicit alternatives such as key_event for special keys or shell for arbitrary input, so it falls short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
uninstall_packageUninstall a packageADestructiveIdempotent
Remove an application from one device via adb uninstall. Destructive: the app is deleted from the device (use keep_data to keep its data directory).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device serial from list_devices; optional when exactly one device is connected. | |
| package | Yes | Package name to uninstall, e.g. "com.example.app". | |
| keep_data | No | Pass -k to keep the app data and cache directories (default false). | |
| timeout_ms | No | Uninstall timeout in milliseconds (default 60000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, idempotentHint=true, so the 'Destructive: the app is deleted' line largely restates structured data. The description does add a concrete consequence (app is deleted from the device) and clarifies keep_data behavior, which is modest value beyond 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?
Two tight sentences with the verb and mechanism front-loaded, followed by the destructive consequence and the mitigating option. 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 simple single-purpose tool with full schema coverage and annotations covering the safety profile, the description is essentially complete. No output schema exists, but the uninstall result is trivial; the only mild gap is lack of explicit routing versus sibling app-state tools.
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 device, package, keep_data, and timeout_ms in detail. The description's note about keep_data ('keep its data directory') merely echoes the schema's own description, adding nothing new; 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+resource ('Remove an application') and the underlying mechanism (`adb uninstall`), scoping to 'one device'. It is clearly distinct from neighboring tools, though it never explicitly names a sibling it differs from (e.g. 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?
Usage is only implied by the action verb; there is no explicit when-to-use versus alternatives, and notably no guidance distinguishing this from the nearby clear_app_data or force_stop_app tools. The keep_data mention is a parameter hint rather than routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
wireless_pairPair a device for wireless debuggingAIdempotent
Pair with an Android 11+ device for wireless debugging (adb pair <host>:<pair_port> <code>), using the pairing code from Settings > Developer options > Wireless debugging > "Pair device with pairing code". This is step one of a two-step flow: after "Successfully paired", call connect with the same host and the port shown on the main Wireless debugging screen — the temporary pairing port above is not that connect port. Pairing codes expire after a couple of minutes, so ask the user for a fresh code if this fails.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | Six-digit pairing code from the pairing dialog; an optional single hyphen is accepted, e.g. "123-456". | |
| host | Yes | Hostname or IP shown in the Wireless debugging settings, e.g. "192.168.1.42" (no port). | |
| pair_port | Yes | Pairing port shown on the Wireless debugging pairing dialog — different from the port used by connect. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly=false, destructive=false, openWorld=true), so the bar is lower. The description still adds real behavioral context the annotations don't carry: pairing codes expire after a couple of minutes, the expected 'Successfully paired' signal, and what to do on failure. It does not contradict the structured hints.
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 and the adb command, then layers the flow, port caveat, and expiry warning. Dense but every sentence carries operational value; slightly long, though nothing 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?
For a stateful, time-sensitive pairing step with no output schema, the description supplies the prerequisite (code from Settings), the expected success signal, the sequencing into `connect`, and the expiry/failure path. An agent has everything needed to call it correctly and recover from failure.
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 with format, range, and the pairing-vs-connect port distinction. The description reinforces the port distinction and shows the `<host>:<pair_port> <code>` invocation shape, but adds little beyond the schema — 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+resource ('Pair with an Android 11+ device for wireless debugging') and even names the underlying adb command. It clearly distinguishes itself from the sibling `connect` by calling itself 'step one of a two-step flow' and warning that the pairing port is not the connect port.
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 describes when to use it (step one of pairing), what to do next ('after Successfully paired, call connect with the same host'), a concrete exclusion (the pairing port is NOT the connect port), and failure recovery ('ask the user for a fresh code if this fails'). Nothing is left to inference.
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.
35 tool updates
v0.6.0- First observed
adb_server_restart - First observed
clear_app_data - First observed
connect - First observed
disconnect - First observed
dumpsys_query - First observed
force_stop_app - First observed
forward_port - First observed
get_device_info - First observed
get_ui_hierarchy - First observed
grant_permission - First observed
install_apk - First observed
key_event - First observed
launch_package - First observed
list_devices - First observed
list_forwards - First observed
list_packages - First observed
list_reverses - First observed
logcat_snapshot - First observed
pull_file - First observed
push_file - First observed
read_logcat_stream - First observed
remove_forward - First observed
remove_reverse - First observed
reverse_port - First observed
revoke_permission - First observed
screenshot - First observed
shell - First observed
start_activity - First observed
start_logcat_stream - First observed
stop_logcat_stream - First observed
swipe - First observed
tap - First observed
type_text - First observed
uninstall_package - First observed
wireless_pair
TDQS
Scored across 35 tools
Most tools have clearly distinct purposes, and the forward/reverse and logcat streaming tool groups are well differentiated by their descriptions. Minor ambiguity exists between start_activity and launch_package, and shell intentionally overlaps with many dedicated tools, but the descriptions explicitly guide correct selection.
All names use snake_case, and most follow a verb_noun pattern (list_devices, install_apk, grant_permission, pull_file). A few deviate with noun-first or single-word names (logcat_snapshot, dumpsys_query, screenshot, shell), but the convention remains readable and consistent.
35 tools is heavy for a single server. Each tool maps to a distinct adb operation, which justifies breadth, but some groups could be consolidated (e.g., forward/reverse families, logcat stream lifecycle), making the set borderline overloaded.
The surface covers device connection, app lifecycle, file transfer, logging, UI automation, shell, and dumpsys querying well. Minor gaps exist around device reboot, system settings, and screen recording, but most workflows can be completed with the available tools.
Maintenance
Related MCP Connectors
Give your AI agent a real cloud Android phone: push APKs, drive it, get screenshots and logs.
Cloud Android phones for AI agents: create a phone, read the screen, tap, type, install APKs, park.
Cloud Android phones for AI agents: read the screen, tap, type, install APKs, park and resume.
Let AI agents control Android and iOS devices on Mobilerun Cloud: screen, input, apps, workflows.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables LLMs to control and manage Android devices via ADB, including app installation, UI interaction, and device monitoring.3512GPL 3.0
- AlicenseAqualityCmaintenanceEnables AI agents to control, inspect, and automate Android devices, Waydroid containers, and AVD emulators over ADB. Provides tools for screenshots, UI-hierarchy text-based tapping, gestures, key presses, text input, app management, and raw shell commands.12MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to visually perceive and directly control Android devices via ADB and screen-control tooling, including screenshots, taps, swipes, typing, app management, UI inspection, file transfer, shell commands, and audio/video streaming.365 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to see and control Android devices through ADB and screen mirroring, supporting screen capture, touch input, app management, UI element finding, file transfer, shell commands, clipboard access, and audio/video streaming.365 npmMIT