android-phone-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ANDROID_MCP_ALLOW_SHELL | No | Allow arbitrary adb shell commands. Default is off. | false |
| ANDROID_MCP_ALLOW_WRITE | No | Allow write operations (tap/input/install etc.). Default is off (read-only). | false |
| ANDROID_MCP_ACTION_TIMEOUT | No | Per-action timeout. Default is 30 seconds. | 30s |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_devicesA | List all adb-connected Android devices as {serial, connection_type}. Returns an empty list (never an error) when no device is connected. |
| get_device_infoA | Read device facts: model, manufacturer, Android version, resolution, density. |
| reset_sessionA | Reset the session: clear per-device snapshot caches and the execution budget counters (spec execution-budget). Call this after an EXECUTION_BUDGET_EXCEEDED error to continue, or whenever element ids from get_screen have gone stale (a fresh observer is created on the next screen access). Returns the reset budget state {action_count, elapsed_seconds, max_actions, max_seconds, exceeded}. |
| get_screenA | Capture a compact text-mode snapshot of the current screen. Returns elements as |
| get_screen_hashA | Return a cheap fingerprint of the current screen (hash of the snapshot). Call this before and after an action to detect whether the screen changed, without refetching the full snapshot. |
| tapA | Tap a semantic target and verify the result. Prefer semantic selectors — never compute coordinates yourself:
Returns verification evidence {executed, screen_changed, changed_elements[], screen_hash}, or SELECTOR_AMBIGUOUS with candidates[] when several elements match (retry with by=id). |
| swipeA | Swipe the screen by direction (up/down/left/right). Returns verification evidence {executed, screen_changed, changed_elements[], screen_hash}. |
| scroll_pageB | Scroll exactly one viewport page (native one-page scroll). |
| type_textA | Type text into an input field. With target, the field is located semantically first (must be an editable field). Without target, the currently focused field is used. The field is cleared before typing. |
| scroll_untilA | Scroll until a semantic target appears (or the scroll reaches its end). Uses one-viewport-page scrolling and stops as soon as the container boundary is reached (no useless swipes at the end). |
| open_appA | Launch an installed app by friendly name or package name. Unknown/not-installed apps return a structured APP_NOT_INSTALLED error (with a hint to pass the exact package name). |
| open_settingsA | Open a system settings panel via ACTION deep link. Supported panels: home, about_phone, wifi, bluetooth, display, sound, apps, storage, security, location, battery, network, date, accessibility, language, developer. |
| press_keyA | Press a system key: back, home, recent, menu, enter, power, volume_up, volume_down, clear. |
| wait_forA | Block until a semantic target appears or disappears on screen. Polls fresh snapshots every |
| verify_elementA | Assert whether a semantic target exists on the current screen. Structured boolean result — never raises for not-found or a text mismatch, so the model can branch on it directly. |
| diff_stateA | Diff the current screen against the last cached snapshot. Returns added/removed/text-changed element lists (stable-id diff) plus both screen hashes — the explicit counterpart of the automatic evidence returned by every action tool. |
| smart_scrollA | Scroll and AGGREGATE every matching element across the screens passed. Unlike scroll_until (first hit), smart_scroll visits each screen in the scroll budget and returns ALL matches with their positions. Reuses the one-viewport-page scrolling + end detection; on tree-failed screens the OCR layer is aggregated for free. |
| locateA | Locate a described element via the VLM grounding layer (read-only). The THIRD perception layer (tree -> OCR -> VLM): when the accessibility tree and OCR cannot resolve a target on a tree-failed screen (Flutter/ Unity/games), this asks a vision-language model for the element's bounding box on the current screenshot. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 18 tools
Most tools target distinct actions or resources, but the four scroll variants (swipe, scroll_page, scroll_until, smart_scroll) and multiple verification helpers (wait_for, verify_element, diff_state) occupy adjacent territory. The descriptions do enough to separate them, so only one or two selections could initially be confused.
Names are mostly snake_case imperative verb phrases like get_screen, open_app, and press_key, but a few like wait_for, scroll_until, and smart_scroll break the strict verb_noun pattern. The overall style is still consistent enough that an agent can predict tool names.
At 18 tools, the surface is on the heavy side; several scroll and screen-verification helpers could potentially be consolidated. Each tool has a purpose, but the sheer number makes selection harder and feels borderline for an agent.
Core UI automation is covered well: screen capture, actions, waiting, verification, and navigation. However, there are notable gaps around app lifecycle management (no install/uninstall/stop) and no explicit screenshot capture tool, which can create dead ends for some phone-control workflows.