A self-hosted bridge and stdio MCP for one Android phone
18 tools with complete schemas and descriptions. Naming is verb-noun consistent (phone_*). Descriptions are adequate (50-150 chars) but lack LLM-optimized guidance on WHEN to use each tool and dependencies between them. All parameters have types and descriptions. Output schemas are implicit (JSON responses) but not formally documented. Error handling is minimal, no recovery guidance or actionable error messages. Security is a major gap: phone_shell defaults root=true and accepts arbitrary commands with no validation or rate limiting. No tool annotations (readOnlyHint/destructiveHint) despite clear risk stratification.
Capture the current screen and return JPEG plus display/package metadata.
Set the phone clipboard exactly; an empty string clears it.
Cancel pending work or abandon a delivered command. Delivery may mean its side effect happened.
Read one command receipt. Use this after an uncertain timeout; do not resubmit the action.
Run Back, Home, or Recents using a fresh screenshot basis.
Launch an Android package and return a screenshot.
phone_shell accepts arbitrary commands with root=true default and no input validation. No rate limiting, timeout enforcement, or command whitelisting. Agents can execute destructive commands (rm -rf /) without confirmation.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk stratification. phone_shell, phone_write_file, phone_tap, phone_swipe are DESTRUCTIVE/WRITE but unmarked. LLMs cannot distinguish safe from unsafe tools.
Descriptions lack LLM-optimized guidance on WHEN to use each tool and dependencies. E.g., phone_tap says 'Tap display coordinates' but does not explain that it requires a prior screenshot (basis_command_id) or that coordinates must match display_width/display_height. Agents must infer from parameter names.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
List installed packages with bounded output.
List an absolute phone path with bounded output.
Long-press display coordinates using a fresh screenshot basis.
Read a bounded byte range; use next_offset/eof for another chunk.
Execute a bounded phone shell command. Timeouts do not undo side effects.
Show pairing, online state, phone status, and the active/latest command without secrets.
Swipe between display coordinates using a fresh screenshot basis.
Tap display coordinates using a fresh, unused screenshot basis.
Replace the focused editable field exactly; an empty string clears it.
Read the current accessibility node tree without consuming a screenshot basis.
Wake the phone and capture a screen. A secure keyguard still needs the person.
Write at most 49152 decoded bytes; content may be UTF-8 text or Base64.
Output schemas are implicit (JSON responses) but not formally documented. Agents do not know what fields to expect (e.g., does phone_status return 'pairing_status' or 'pairing'?). No pagination guidance for list_* tools despite max_bytes limits.
Error handling is absent. No recovery guidance, actionable error messages, or error classification (retryable vs fatal). If phone_tap fails due to stale basis_command_id, the agent has no guidance on what to do next.