Generated from the real MCP tools/list response by npm run docs:tools; do not hand-edit. See tool workflows for sessions, gestures, ad jobs and file transfers.
Release 0.19.0 · 66 tools · API 1 · catalog 9536208318cf0507.
| Tool | Access | Purpose |
|---|---|---|
phone_connection |
Read | Check the actual connection and current server/catalog version, including when the phone is offline. Includes recent content-free owner-scoped relay timings for end-to-end speed diagnosis; host/model time is not directly measured. |
phone_catalog |
Read | Live operation catalog. Request an operation for its current arguments schema. The stable gateways automatically use this catalog after server updates. |
phone_read |
Read | Read through the stable API. Discover operation and arguments with phone_catalog. New read operations are available automatically. |
phone_action |
Action | Execute an authorized write through the stable API. Discover its current arguments with phone_catalog. New actions are available automatically. |
phone_status |
Read | Session, permissions, displays, Android and installed app version. |
phone_diagnostics |
Read | On-demand battery, CPU, memory and Phone MCP wakelock counters. Does not read app contents. |
phone_diagnostic_probe |
Action | Run or retrieve a bounded two-sample battery observation without a wakelock. It can outlive a stopped Phone MCP service. |
phone_session_create |
Action | Create a separately routed app session. requestId is an idempotent UUID; keep the returned sessionId. Does not launch the app. The physical-screen policy is selected only in local Phone MCP settings. keepRendering=true preserves visual background work during pauses at a higher idle cost. After a successful user handoff, create a new requestId/session; the former session stays terminated. Explicit local Stop still requires local resumption. |
phone_start_app |
Action | Fast path: create one owned app session, open the app once and return its first observation plus screenshot in ONE tool call. Prefer this over separate create/open/snapshot/capture calls. A repeated requestId retains the existing session without reopening its app. Inspect launchUncertain and observationError; never replay an uncertain launch. Returns observation with a fresh snapshot after the action. |
phone_ui_flow |
Action | Execute 1-8 planned exact semantic clicks/waits with fresh native target guards and ONE final observation/screenshot. Use for already understood navigation; no model round trip between steps. Stops at the first missing/ambiguous/protected target, error or deadline. Inspect completedSteps/failedStep/uncertain; never replay a partial flow. App/session and local stop guards remain enforced. Use action_sequence for already observed Canvas/game gestures. Returns observation with a fresh snapshot after the action. |
phone_board_move |
Action | Play one already-decided chess move such as e2e4 using the boardId from observation.board. Prefer the observed board.piecePlacementFen over manually decoding coordinates. Freshly rechecks all 64 accessible squares and app/session/window geometry. If every square is a clickable accessible control, clicks named source/destination and rereads the complete board between them, allowing selection highlights without requiring raster pixels. Otherwise requires a fresh visible capture and uses one guarded two-tap sequence. Returns final observation/image; never switches input path after a partial action. Refuses changed/incomplete boards before any input. No engine or move selection; no full legality or turn inference. Promotion choices remain separate. Never replay partial/uncertain inputs. Returns observation with a fresh snapshot after the action. |
phone_plan_start |
Action | Prefer prepared conditional trees to avoid model round trips. Each case may contain then:[cases] for up to 6 levels / 32 total cases / 8 siblings. Android 0.19+ permits 4 independent armed plans per session; start with waitMs=0 before awaiting. Same-session inputs are serialized and conflicting ready plans yield before input. onUnexpected=wait keeps a standby plan armed without acting on unknown states, until its deadline; yield is default. A completed plan does NOT complete the user objective or end the app session. Prefer chess cases while the opponent thinks: provide observed boardId+anchorFen, own color and prepared opponent/reply pairs; optional initialMove is sent once. Catch-up accepts an already-present predicted opponent move, never replays the initial move. UI plans require exact semantic guards, one click/back and an explicit postcondition per case. Unknown/ambiguous state yields needs_model. Native stops, lease and capture/write permissions stay enforced. Trees/multiple plans require Android 0.19+; flat plans support 0.18+. No engine, arbitrary code or guessed response. New requestId for a revised plan. |
phone_plan_list |
Read | List all prepared plans for this owned app/session, active and retained terminal results. Read-only; does not start, resume, cancel, extend or clean anything. Use plan_status with a bounded wait for a selected plan. |
phone_plan_status |
Read | Read a local conditional plan. Prefer a bounded wait and reuse its final decision observation; no polling snapshot loop. Active jobs defer images. needs_model means no more local actions will run: analyze the unexpected state and prepare a new plan. Reaction timings exclude model plan-preparation time; measure both. Read-only, never starts or replays a plan. |
phone_plan_cancel |
Action | Cancel only this conditional plan, preserving the app/session. Stops later planned actions; an input already delivered may have taken effect. Inspect actions and observed state before continuing. |
phone_session_wake |
Action | Recover only the existing AI display under the screen policy selected locally in Phone MCP settings. This tool cannot enable the physical-screen-on mode or change the local setting. It does not relaunch the app or bypass keyguard. If off-screen recovery fails, report it instead of choosing a lit-screen fallback. |
phone_session_cleanup |
Action | Remove empty abandoned task records for an authorized app. Active and physical tasks are always preserved. Optional taskIds migrate identified legacy AI tasks; no live app is closed. |
phone_session_list |
Read | List this authorization’s active and ended app sessions, their displays, isolation and lease state. |
phone_session_keepalive |
Action | Extend a legitimate thinking pause for an active session. Does not restart an ended or locally stopped session. |
phone_session_end |
Action | Release this app session, its tasks/display/preview and pending plans after the user objective is verified complete, or on explicit user stop. Do not call merely because a plan finished, an action failed, the position is difficult, or a progress report is ready. Recover and continue an authorized unfinished objective; preserve its state across thinking pauses. If blocked, explain the unmet objective and keep the session only within its bounded lease. A different app session continues. |
phone_session_cancel |
Action | Interrupt only this app session and reject its queued commands. A locally stopped app requires local resumption. |
phone_notifications |
Read | Read current notifications for an authorized app without opening it. |
phone_reply_notification |
Action | Send the requested reply through a freshly observed notification. |
phone_snapshot |
Read | Read an authorized window. Reuse an action observation. For chess prefer detail=decision: complete board FEN/hash and relevant UI, without redundant square nodes; detail=full keeps all nodes. A cursor reads more nodes from the same unchanged snapshot. |
phone_screenshot |
Read | Capture the authorized window. For black or incomplete images try captureSource=surface: a fresh frame from the owned non-secure virtual display, without changing app state or physical-screen power. Optional labels map through coordinateSpace. |
phone_open_app |
Action | Open an authorized app on the active control display. Returns observation with a fresh snapshot after the action. |
phone_open_url |
Action | Open an HTTPS URL in the chosen authorized app on the active display. Returns observation with a fresh snapshot after the action. |
phone_click |
Action | Click an observed node. Legacy longPressNodeId and coordinateActions remain supported. Returns observation with a fresh snapshot after the action. |
phone_long_press |
Action | Long press an observed node, for example to open its context menu. Returns observation with a fresh snapshot after the action. |
phone_set_text |
Action | Replace an observed editable field, excluding protected fields. Returns observation with a fresh snapshot after the action. |
phone_scroll |
Action | Scroll an observed scrollable node. Returns observation with a fresh snapshot after the action. |
phone_back |
Action | Go back within the observed authorized window. Returns observation with a fresh snapshot after the action. |
phone_tap |
Action | Tap a freshly observed target. Canvas/game areas require a recent screenshot tied to the same snapshot; unrelated animation does not invalidate a stable target. Returns observation with a fresh snapshot after the action. |
phone_swipe |
Action | Swipe within the freshly observed window and stable geometry. For canvas/game areas, first capture the same snapshot. Returns observation with a fresh snapshot after the action. |
phone_action_sequence |
Action | Execute up to 8 already observed taps/swipes locally in one bounded command, with one final observation. Prefer one swipe for a drag or two taps for source/destination. Every step keeps the original session, app, window and target guards. Stops at the first failure; inspect executedCount and failedStep, never replay the whole sequence. Does not bypass app timers, protected content or reward conditions. Returns observation with a fresh snapshot after the action. |
phone_ad_start |
Action | Start one bounded local ad-closing job on an existing app session. The phone waits and closes available controls across successive ad windows without model round trips. Supply observed app returnTargets; for a graphical game, save its host windowId before the ad, then use by=windowId/exact only after another ad window opens. Available close/skip controls are preferred. Hidden ad controls can be revealed with bounded neutral taps; visual skip icons need positive pixel evidence beside an observed badge. It never skips observed timers or claims rewards; follow ad_status, or ad_cancel. Reuse requestId only for the same job. |
phone_ad_status |
Read | Read a local ad job with up to 20 seconds of server-side waiting, split into APK-compatible reads. Prefer waitMs=20000; observe=true and includeScreenshot=true return final UI evidence when terminal, avoiding extra model turns. completed confirms an observed returnTarget, not a reward. Keep the exact packageName, sessionId and jobId. Read-only: never clicks or starts another job. |
phone_ad_cancel |
Action | Cancel only this local ad job immediately. It does not end or resume its app session. Actions already delivered may have taken effect; inspect the returned state before continuing. |
phone_set_control_mode |
Action | Explicitly select foreground or parallel, preserving the existing session and permissions. |
phone_files_list |
Read | List Phone MCP transfers and recent installation jobs. Requires Shizuku. |
phone_send_file |
Action | Send a user-selected or generated chat file to the phone. Pass the host file object; no URL needs to be created, copied or published by the user. Follow file_job until completed. |
phone_upload_begin |
Action | Prepare a direct binary transfer from a local client, without hosting the file. Reuse requestId only for the same file. Return jobId, offset and an authenticated relative upload path. |
phone_upload_commit |
Action | Finish a fully received binary transfer; SHA-256 and exact size must match before the file becomes completed. Follow file_job; incomplete or mismatched bytes are never published as completed. |
phone_download_file |
Action | Download an HTTPS file, up to 512 MiB. Follow its job; reuse requestId after an uncertain result. |
phone_file_job |
Action | Inspect a transfer/install, or cancel a transfer. Only completed confirms success. |
phone_install_apk |
Action | Install the specified transferred APK via Shizuku, checking its SHA-256 and package. Follow the job. |
phone_stop |
Action | Stop the phone session. Restarting requires a local action. |
phone_find_nodes |
Read | Find matching accessible elements on the active display, including later pages. |
phone_wait_for |
Read | Wait for a matching element, returning found=false on timeout. Never repeats an action. |
phone_wait_and_click |
Action | Wait locally up to 8 seconds for one exact visible, enabled, unprotected accessible target, then click once and return its final observation. Timeout returns found=false and performed=false. Ambiguous matches are refused; no coordinate guessing, no timer skipping or action retries. Returns observation with a fresh snapshot after the action. |
phone_wait_for_idle |
Read | Wait until the observed accessibility content is stable; returns idle=false on timeout. |
phone_node_details |
Read | Read the full text and state of one freshly observed, unprotected node. |
phone_double_tap |
Action | Double tap inside the freshly observed window and stable target; canvas areas require a recent screenshot. Returns observation with a fresh snapshot after the action. |
phone_pinch |
Action | Pinch or zoom inside the freshly observed window and stable target; canvas areas require a recent screenshot. Returns observation with a fresh snapshot after the action. |
phone_edit_text |
Action | Append, insert, clear or replace an observed non-protected editable field. Returns observation with a fresh snapshot after the action. |
phone_press_key |
Action | Submit the observed editable field using its Android IME Enter action. Returns observation with a fresh snapshot after the action. |
phone_scroll_to_node |
Action | Ask Android to bring an observed node into view. Find with includeOffscreen first. Returns observation with a fresh snapshot after the action. |
phone_notification_dismiss |
Action | Dismiss a freshly observed clearable notification. |
phone_notification_snooze |
Action | Snooze a freshly observed notification. |
phone_storage_locations |
Read | List folders explicitly selected on the phone. Works without Shizuku. |
phone_list_files |
Read | List a path inside an explicitly selected folder. |
phone_read_file |
Read | Read a UTF-8 text file inside a selected folder, with line pagination. |
phone_write_file |
Action | Create or explicitly replace a UTF-8 file in a selected folder. Text is bounded to 16,000 JSON characters and 24,000 UTF-8 bytes. Overwrite requires overwrite=true. |
phone_delete_file |
Action | Delete the requested file inside a selected folder. Directories are refused. |
phone_shared_content |
Read | List content deliberately shared to Phone MCP through Android Share. |
phone_read_shared_file |
Read | Read a shared text file or image. Does not access other app files. |
phone_connection
Check the actual connection and current server/catalog version, including when the phone is offline. Includes recent content-free owner-scoped relay timings for end-to-end speed diagnosis; host/model time is not directly measured.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_catalog
Live operation catalog. Request an operation for its current arguments schema. The stable gateways automatically use this catalog after server updates.
| Parameter | Required | Schema |
|---|---|---|
operation |
No | {"type":"string","maxLength":80} |
knownVersion |
No | {"type":"string","maxLength":80} |
phone_read
Read through the stable API. Discover operation and arguments with phone_catalog. New read operations are available automatically.
| Parameter | Required | Schema |
|---|---|---|
operation |
Yes | {"type":"string","minLength":1,"maxLength":80} |
arguments |
No | {"type":"object","additionalProperties":{},"default":{}} |
phone_action
Execute an authorized write through the stable API. Discover its current arguments with phone_catalog. New actions are available automatically.
| Parameter | Required | Schema |
|---|---|---|
operation |
Yes | {"type":"string","minLength":1,"maxLength":80} |
arguments |
No | {"type":"object","additionalProperties":{},"default":{}} |
phone_status
Session, permissions, displays, Android and installed app version.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_diagnostics
On-demand battery, CPU, memory and Phone MCP wakelock counters. Does not read app contents.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_diagnostic_probe
Run or retrieve a bounded two-sample battery observation without a wakelock. It can outlive a stopped Phone MCP service.
| Parameter | Required | Schema |
|---|---|---|
probeId |
Yes | {"type":"string","format":"uuid"} |
action |
Yes | {"type":"string","enum":["start","result"]} |
seconds |
No | {"type":"integer","minimum":30,"maximum":900,"default":180} |
startDelaySeconds |
No | {"type":"integer","minimum":0,"maximum":60,"default":0} |
phone_session_create
Create a separately routed app session. requestId is an idempotent UUID; keep the returned sessionId. Does not launch the app. The physical-screen policy is selected only in local Phone MCP settings. keepRendering=true preserves visual background work during pauses at a higher idle cost. After a successful user handoff, create a new requestId/session; the former session stays terminated. Explicit local Stop still requires local resumption.
| Parameter | Required | Schema |
|---|---|---|
requestId |
Yes | {"type":"string","format":"uuid"} |
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
label |
No | {"type":"string","minLength":1,"maxLength":80} |
leaseSeconds |
No | {"type":"integer","minimum":30,"maximum":900,"default":300} |
keepRendering |
No | {"type":"boolean","default":false} |
sessionId |
No | {"$ref":"#/properties/requestId"} |
phone_start_app
Fast path: create one owned app session, open the app once and return its first observation plus screenshot in ONE tool call. Prefer this over separate create/open/snapshot/capture calls. A repeated requestId retains the existing session without reopening its app. Inspect launchUncertain and observationError; never replay an uncertain launch. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
requestId |
Yes | {"type":"string","format":"uuid"} |
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
label |
No | {"type":"string","minLength":1,"maxLength":80} |
leaseSeconds |
No | {"type":"integer","minimum":30,"maximum":900,"default":300} |
keepRendering |
No | {"type":"boolean","default":false} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":true} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_ui_flow
Execute 1-8 planned exact semantic clicks/waits with fresh native target guards and ONE final observation/screenshot. Use for already understood navigation; no model round trip between steps. Stops at the first missing/ambiguous/protected target, error or deadline. Inspect completedSteps/failedStep/uncertain; never replay a partial flow. App/session and local stop guards remain enforced. Use action_sequence for already observed Canvas/game gestures. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
steps |
Yes | {"type":"array","items":{"type":"object","properties":{"op":{"type":"string","enum":["wait_and_click","wait_for"]},"query":{"type":"string","minLength":1,"maxLength":250},"by":{"type":"string","enum":["text","description","viewId"],"default":"text"},"timeoutMs":{"type":"integer","minimum":100,"maximum":8000,"default":3000}},"required":["op","query"],"additionalProperties":false},"minItems":1,"maxItems":8} |
timeoutMs |
No | {"type":"integer","minimum":100,"maximum":8000,"default":8000} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":true} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_board_move
Play one already-decided chess move such as e2e4 using the boardId from observation.board. Prefer the observed board.piecePlacementFen over manually decoding coordinates. Freshly rechecks all 64 accessible squares and app/session/window geometry. If every square is a clickable accessible control, clicks named source/destination and rereads the complete board between them, allowing selection highlights without requiring raster pixels. Otherwise requires a fresh visible capture and uses one guarded two-tap sequence. Returns final observation/image; never switches input path after a partial action. Refuses changed/incomplete boards before any input. No engine or move selection; no full legality or turn inference. Promotion choices remain separate. Never replay partial/uncertain inputs. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
boardId |
Yes | {"type":"string","pattern":"^[a-fA-F0-9]{64}$"} |
uci |
Yes | {"type":"string","pattern":"^[a-h][1-8][a-h][1-8]$"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":true} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_plan_start
Prefer prepared conditional trees to avoid model round trips. Each case may contain then:[cases] for up to 6 levels / 32 total cases / 8 siblings. Android 0.19+ permits 4 independent armed plans per session; start with waitMs=0 before awaiting. Same-session inputs are serialized and conflicting ready plans yield before input. onUnexpected=wait keeps a standby plan armed without acting on unknown states, until its deadline; yield is default. A completed plan does NOT complete the user objective or end the app session. Prefer chess cases while the opponent thinks: provide observed boardId+anchorFen, own color and prepared opponent/reply pairs; optional initialMove is sent once. Catch-up accepts an already-present predicted opponent move, never replays the initial move. UI plans require exact semantic guards, one click/back and an explicit postcondition per case. Unknown/ambiguous state yields needs_model. Native stops, lease and capture/write permissions stay enforced. Trees/multiple plans require Android 0.19+; flat plans support 0.18+. No engine, arbitrary code or guessed response. New requestId for a revised plan.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
requestId |
Yes | {"$ref":"#/properties/sessionId"} |
plan |
Yes | {"anyOf":[{"type":"object","properties":{"kind":{"type":"string","const":"ui"},"anchor":{"type":"object","properties":{"all":{"type":"array","items":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":250},"by":{"type":"string","enum":["text","description","viewId"],"default":"text"}},"required":["query"],"additionalProperties":false},"minItems":1,"maxItems":6},"none":{"type":"array","items":{"$ref":"#/properties/plan/anyOf/0/properties/anchor/properties/all/items"},"maxItems":6,"default":[]}},"required":["all"],"additionalProperties":false},"allowWindowChange":{"type":"boolean","default":false},"onUnexpected":{"type":"string","enum":["yield","wait"],"default":"yield"},"cases":{"type":"array","items":{"type":"object","properties":{"when":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"action":{"anyOf":[{"type":"object","properties":{"op":{"type":"string","const":"click"},"query":{"$ref":"#/properties/plan/anyOf/0/properties/anchor/properties/all/items/properties/query"},"by":{"$ref":"#/properties/plan/anyOf/0/properties/anchor/properties/all/items/properties/by"}},"required":["op","query"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"back"}},"required":["op"],"additionalProperties":false}]},"after":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"terminal":{"type":"boolean","default":true},"then":{"type":"array","items":{"type":"object","properties":{"when":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"action":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/action"},"after":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"terminal":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/terminal"},"then":{"type":"array","items":{"type":"object","properties":{"when":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"action":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/action"},"after":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"terminal":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/terminal"},"then":{"type":"array","items":{"type":"object","properties":{"when":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"action":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/action"},"after":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"terminal":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/terminal"},"then":{"type":"array","items":{"type":"object","properties":{"when":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"action":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/action"},"after":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"terminal":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/terminal"},"then":{"type":"array","items":{"type":"object","properties":{"when":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"action":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/action"},"after":{"$ref":"#/properties/plan/anyOf/0/properties/anchor"},"terminal":{"$ref":"#/properties/plan/anyOf/0/properties/cases/items/properties/terminal"}},"required":["when","action","after"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["when","action","after"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["when","action","after"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["when","action","after"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["when","action","after"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["when","action","after"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["kind","anchor","cases"],"additionalProperties":false},{"type":"object","properties":{"kind":{"type":"string","const":"chess"},"boardId":{"type":"string","pattern":"^[a-fA-F0-9]{64}$"},"anchorFen":{"type":"string","minLength":15,"maxLength":90,"pattern":"^[1-8prnbqkPRNBQK/]+$"},"ourColor":{"type":"string","enum":["white","black"]},"initialMove":{"type":"string","pattern":"^[a-h][1-8][a-h][1-8]$"},"onUnexpected":{"type":"string","enum":["yield","wait"],"default":"yield"},"cases":{"type":"array","items":{"type":"object","properties":{"opponent":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"reply":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"then":{"type":"array","items":{"type":"object","properties":{"opponent":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"reply":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"then":{"type":"array","items":{"type":"object","properties":{"opponent":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"reply":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"then":{"type":"array","items":{"type":"object","properties":{"opponent":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"reply":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"then":{"type":"array","items":{"type":"object","properties":{"opponent":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"reply":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"then":{"type":"array","items":{"type":"object","properties":{"opponent":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"},"reply":{"$ref":"#/properties/plan/anyOf/1/properties/initialMove"}},"required":["opponent","reply"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["opponent","reply"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["opponent","reply"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["opponent","reply"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["opponent","reply"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["opponent","reply"],"additionalProperties":false},"minItems":1,"maxItems":8}},"required":["kind","boardId","anchorFen","ourColor","cases"],"additionalProperties":false}]} |
timeoutMs |
No | {"type":"integer","minimum":1000,"maximum":180000,"default":60000} |
waitMs |
No | {"type":"integer","minimum":0,"maximum":20000,"default":0} |
observe |
No | {"type":"boolean","default":true} |
includeScreenshot |
No | {"type":"boolean","default":false} |
detail |
No | {"type":"string","enum":["decision","full"],"default":"decision"} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_plan_list
List all prepared plans for this owned app/session, active and retained terminal results. Read-only; does not start, resume, cancel, extend or clean anything. Use plan_status with a bounded wait for a selected plan.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
phone_plan_status
Read a local conditional plan. Prefer a bounded wait and reuse its final decision observation; no polling snapshot loop. Active jobs defer images. needs_model means no more local actions will run: analyze the unexpected state and prepare a new plan. Reaction timings exclude model plan-preparation time; measure both. Read-only, never starts or replays a plan.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
planId |
Yes | {"$ref":"#/properties/sessionId"} |
waitMs |
No | {"type":"integer","minimum":0,"maximum":20000,"default":0} |
observe |
No | {"type":"boolean","default":true} |
includeScreenshot |
No | {"type":"boolean","default":false} |
detail |
No | {"type":"string","enum":["decision","full"],"default":"decision"} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_plan_cancel
Cancel only this conditional plan, preserving the app/session. Stops later planned actions; an input already delivered may have taken effect. Inspect actions and observed state before continuing.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
planId |
Yes | {"$ref":"#/properties/sessionId"} |
observe |
No | {"type":"boolean","default":true} |
includeScreenshot |
No | {"type":"boolean","default":false} |
detail |
No | {"type":"string","enum":["decision","full"],"default":"decision"} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_session_wake
Recover only the existing AI display under the screen policy selected locally in Phone MCP settings. This tool cannot enable the physical-screen-on mode or change the local setting. It does not relaunch the app or bypass keyguard. If off-screen recovery fails, report it instead of choosing a lit-screen fallback.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
reason |
No | {"type":"string","enum":["noninteractive","black_render","app_requires_screen"],"default":"app_requires_screen"} |
phone_session_cleanup
Remove empty abandoned task records for an authorized app. Active and physical tasks are always preserved. Optional taskIds migrate identified legacy AI tasks; no live app is closed.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
taskIds |
No | {"type":"array","items":{"type":"integer","minimum":1,"maximum":2147483647},"maxItems":64} |
sessionId |
No | {"type":"string","format":"uuid"} |
phone_session_list
List this authorization’s active and ended app sessions, their displays, isolation and lease state.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_session_keepalive
Extend a legitimate thinking pause for an active session. Does not restart an ended or locally stopped session.
| Parameter | Required | Schema |
|---|---|---|
sessionId |
Yes | {"type":"string","format":"uuid"} |
phone_session_end
Release this app session, its tasks/display/preview and pending plans after the user objective is verified complete, or on explicit user stop. Do not call merely because a plan finished, an action failed, the position is difficult, or a progress report is ready. Recover and continue an authorized unfinished objective; preserve its state across thinking pauses. If blocked, explain the unmet objective and keep the session only within its bounded lease. A different app session continues.
| Parameter | Required | Schema |
|---|---|---|
sessionId |
Yes | {"type":"string","format":"uuid"} |
phone_session_cancel
Interrupt only this app session and reject its queued commands. A locally stopped app requires local resumption.
| Parameter | Required | Schema |
|---|---|---|
sessionId |
Yes | {"type":"string","format":"uuid"} |
phone_notifications
Read current notifications for an authorized app without opening it.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
phone_reply_notification
Send the requested reply through a freshly observed notification.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
notificationId |
Yes | {"type":"string","format":"uuid"} |
text |
Yes | {"type":"string","minLength":1,"maxLength":4000} |
phone_snapshot
Read an authorized window. Reuse an action observation. For chess prefer detail=decision: complete board FEN/hash and relevant UI, without redundant square nodes; detail=full keeps all nodes. A cursor reads more nodes from the same unchanged snapshot.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
windowId |
No | {"type":"integer","minimum":0} |
cursor |
No | {"type":"string","maxLength":100} |
limit |
No | {"type":"integer","minimum":20,"maximum":350,"default":200} |
includeOffscreen |
No | {"type":"boolean","default":false} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
sessionId |
No | {"type":"string","format":"uuid"} |
phone_screenshot
Capture the authorized window. For black or incomplete images try captureSource=surface: a fresh frame from the owned non-secure virtual display, without changing app state or physical-screen power. Optional labels map through coordinateSpace.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
captureSource |
No | {"type":"string","enum":["auto","surface"],"default":"auto"} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
snapshotId |
No | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
phone_open_app
Open an authorized app on the active control display. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
No | {"type":"string","format":"uuid"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_open_url
Open an HTTPS URL in the chosen authorized app on the active display. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
url |
Yes | {"type":"string","maxLength":4096,"format":"uri"} |
sessionId |
No | {"type":"string","format":"uuid"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_click
Click an observed node. Legacy longPressNodeId and coordinateActions remain supported. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_long_press
Long press an observed node, for example to open its context menu. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_set_text
Replace an observed editable field, excluding protected fields. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
text |
Yes | {"type":"string","maxLength":4000} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_scroll
Scroll an observed scrollable node. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
direction |
Yes | {"type":"string","enum":["forward","backward"]} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_back
Go back within the observed authorized window. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_tap
Tap a freshly observed target. Canvas/game areas require a recent screenshot tied to the same snapshot; unrelated animation does not invalidate a stable target. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
x |
Yes | {"type":"integer","minimum":0,"maximum":16383} |
y |
Yes | {"$ref":"#/properties/x"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_swipe
Swipe within the freshly observed window and stable geometry. For canvas/game areas, first capture the same snapshot. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
fromX |
Yes | {"type":"integer","minimum":0,"maximum":16383} |
fromY |
Yes | {"$ref":"#/properties/fromX"} |
toX |
Yes | {"$ref":"#/properties/fromX"} |
toY |
Yes | {"$ref":"#/properties/fromX"} |
durationMs |
No | {"type":"integer","minimum":100,"maximum":1000,"default":350} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_action_sequence
Execute up to 8 already observed taps/swipes locally in one bounded command, with one final observation. Prefer one swipe for a drag or two taps for source/destination. Every step keeps the original session, app, window and target guards. Stops at the first failure; inspect executedCount and failedStep, never replay the whole sequence. Does not bypass app timers, protected content or reward conditions. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
steps |
Yes | {"type":"array","items":{"anyOf":[{"type":"object","properties":{"op":{"type":"string","const":"tap"},"x":{"type":"integer","minimum":0,"maximum":16383},"y":{"$ref":"#/properties/steps/items/anyOf/0/properties/x"}},"required":["op","x","y"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"swipe"},"fromX":{"$ref":"#/properties/steps/items/anyOf/0/properties/x"},"fromY":{"$ref":"#/properties/steps/items/anyOf/0/properties/x"},"toX":{"$ref":"#/properties/steps/items/anyOf/0/properties/x"},"toY":{"$ref":"#/properties/steps/items/anyOf/0/properties/x"},"durationMs":{"type":"integer","minimum":100,"maximum":1000,"default":150}},"required":["op","fromX","fromY","toX","toY"],"additionalProperties":false}]},"minItems":1,"maxItems":8} |
intervalMs |
No | {"type":"integer","minimum":0,"maximum":250,"default":0} |
timeoutMs |
No | {"type":"integer","minimum":500,"maximum":8000,"default":4000} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_ad_start
Start one bounded local ad-closing job on an existing app session. The phone waits and closes available controls across successive ad windows without model round trips. Supply observed app returnTargets; for a graphical game, save its host windowId before the ad, then use by=windowId/exact only after another ad window opens. Available close/skip controls are preferred. Hidden ad controls can be revealed with bounded neutral taps; visual skip icons need positive pixel evidence beside an observed badge. It never skips observed timers or claims rewards; follow ad_status, or ad_cancel. Reuse requestId only for the same job.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
requestId |
Yes | {"$ref":"#/properties/sessionId"} |
returnTargets |
Yes | {"type":"array","items":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":250},"by":{"type":"string","enum":["text","description","viewId","windowId"],"default":"text"},"match":{"type":"string","enum":["exact","contains"],"default":"exact"}},"required":["query"],"additionalProperties":false},"minItems":1,"maxItems":6} |
timeoutMs |
No | {"type":"integer","minimum":1000,"maximum":180000,"default":90000} |
maxActions |
No | {"type":"integer","minimum":1,"maximum":16,"default":8} |
visual |
No | {"type":"boolean","default":true} |
phone_ad_status
Read a local ad job with up to 20 seconds of server-side waiting, split into APK-compatible reads. Prefer waitMs=20000; observe=true and includeScreenshot=true return final UI evidence when terminal, avoiding extra model turns. completed confirms an observed returnTarget, not a reward. Keep the exact packageName, sessionId and jobId. Read-only: never clicks or starts another job.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
jobId |
Yes | {"$ref":"#/properties/sessionId"} |
waitMs |
No | {"type":"integer","minimum":0,"maximum":20000,"default":0} |
observe |
No | {"type":"boolean","default":false} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_ad_cancel
Cancel only this local ad job immediately. It does not end or resume its app session. Actions already delivered may have taken effect; inspect the returned state before continuing.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
sessionId |
Yes | {"type":"string","format":"uuid"} |
jobId |
Yes | {"$ref":"#/properties/sessionId"} |
phone_set_control_mode
Explicitly select foreground or parallel, preserving the existing session and permissions.
| Parameter | Required | Schema |
|---|---|---|
mode |
Yes | {"type":"string","enum":["foreground","parallel"]} |
panelOff |
No | {"type":"boolean","default":false} |
phone_files_list
List Phone MCP transfers and recent installation jobs. Requires Shizuku.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_send_file
Send a user-selected or generated chat file to the phone. Pass the host file object; no URL needs to be created, copied or published by the user. Follow file_job until completed.
| Parameter | Required | Schema |
|---|---|---|
requestId |
Yes | {"type":"string","format":"uuid"} |
file |
Yes | {"type":"object","properties":{"download_url":{"type":"string","maxLength":4096,"format":"uri"},"file_id":{"type":"string","minLength":1,"maxLength":512},"mime_type":{"type":"string","maxLength":200},"file_name":{"type":"string","maxLength":500}},"required":["download_url","file_id"],"additionalProperties":false} |
fileName |
No | {"type":"string","minLength":1,"maxLength":140} |
sha256 |
No | {"type":"string","pattern":"^[a-fA-F0-9]{64}$"} |
maxBytes |
No | {"type":"integer","minimum":1,"maximum":536870912,"default":536870912} |
MCP metadata: {"openai/fileParams":["file"]}
phone_upload_begin
Prepare a direct binary transfer from a local client, without hosting the file. Reuse requestId only for the same file. Return jobId, offset and an authenticated relative upload path.
| Parameter | Required | Schema |
|---|---|---|
requestId |
Yes | {"type":"string","format":"uuid"} |
fileName |
Yes | {"type":"string","minLength":1,"maxLength":140} |
sizeBytes |
Yes | {"type":"integer","minimum":1,"maximum":536870912} |
sha256 |
Yes | {"type":"string","pattern":"^[a-fA-F0-9]{64}$"} |
phone_upload_commit
Finish a fully received binary transfer; SHA-256 and exact size must match before the file becomes completed. Follow file_job; incomplete or mismatched bytes are never published as completed.
| Parameter | Required | Schema |
|---|---|---|
jobId |
Yes | {"type":"string","format":"uuid"} |
phone_download_file
Download an HTTPS file, up to 512 MiB. Follow its job; reuse requestId after an uncertain result.
| Parameter | Required | Schema |
|---|---|---|
requestId |
Yes | {"type":"string","format":"uuid"} |
url |
Yes | {"type":"string","maxLength":4096,"format":"uri"} |
fileName |
Yes | {"type":"string","minLength":1,"maxLength":140} |
sha256 |
No | {"type":"string","pattern":"^[a-fA-F0-9]{64}$"} |
maxBytes |
No | {"type":"integer","minimum":1,"maximum":536870912} |
phone_file_job
Inspect a transfer/install, or cancel a transfer. Only completed confirms success.
| Parameter | Required | Schema |
|---|---|---|
jobId |
Yes | {"type":"string","format":"uuid"} |
action |
No | {"type":"string","enum":["status","cancel"],"default":"status"} |
phone_install_apk
Install the specified transferred APK via Shizuku, checking its SHA-256 and package. Follow the job.
| Parameter | Required | Schema |
|---|---|---|
requestId |
Yes | {"type":"string","format":"uuid"} |
fileId |
Yes | {"$ref":"#/properties/requestId"} |
sha256 |
Yes | {"type":"string","pattern":"^[a-fA-F0-9]{64}$"} |
expectedPackage |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
phone_stop
Stop the phone session. Restarting requires a local action.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_find_nodes
Find matching accessible elements on the active display, including later pages.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
query |
Yes | {"type":"string","minLength":1,"maxLength":250} |
by |
No | {"type":"string","enum":["text","description","viewId","role","any"],"default":"any"} |
match |
No | {"type":"string","enum":["contains","exact"],"default":"contains"} |
includeOffscreen |
No | {"type":"boolean","default":false} |
sessionId |
No | {"type":"string","format":"uuid"} |
phone_wait_for
Wait for a matching element, returning found=false on timeout. Never repeats an action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
query |
Yes | {"type":"string","minLength":1,"maxLength":250} |
by |
No | {"type":"string","enum":["text","description","viewId","role","any"],"default":"any"} |
match |
No | {"type":"string","enum":["contains","exact"],"default":"contains"} |
includeOffscreen |
No | {"type":"boolean","default":false} |
timeoutMs |
No | {"type":"integer","minimum":100,"maximum":8000,"default":5000} |
sessionId |
No | {"type":"string","format":"uuid"} |
phone_wait_and_click
Wait locally up to 8 seconds for one exact visible, enabled, unprotected accessible target, then click once and return its final observation. Timeout returns found=false and performed=false. Ambiguous matches are refused; no coordinate guessing, no timer skipping or action retries. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
query |
Yes | {"type":"string","minLength":1,"maxLength":250} |
by |
No | {"type":"string","enum":["text","description","viewId"],"default":"text"} |
match |
No | {"type":"string","const":"exact","default":"exact"} |
timeoutMs |
No | {"type":"integer","minimum":100,"maximum":8000,"default":5000} |
sessionId |
No | {"type":"string","format":"uuid"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_wait_for_idle
Wait until the observed accessibility content is stable; returns idle=false on timeout.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
timeoutMs |
No | {"type":"integer","minimum":500,"maximum":8000,"default":5000} |
stableMs |
No | {"type":"integer","minimum":250,"maximum":1500,"default":600} |
sessionId |
No | {"type":"string","format":"uuid"} |
phone_node_details
Read the full text and state of one freshly observed, unprotected node.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
phone_double_tap
Double tap inside the freshly observed window and stable target; canvas areas require a recent screenshot. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
x |
Yes | {"type":"integer","minimum":0,"maximum":16383} |
y |
Yes | {"$ref":"#/properties/x"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_pinch
Pinch or zoom inside the freshly observed window and stable target; canvas areas require a recent screenshot. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
centerX |
Yes | {"type":"integer","minimum":0,"maximum":16383} |
centerY |
Yes | {"$ref":"#/properties/centerX"} |
startDistance |
Yes | {"type":"integer","minimum":20,"maximum":1500} |
endDistance |
Yes | {"type":"integer","minimum":20,"maximum":1500} |
durationMs |
No | {"type":"integer","minimum":150,"maximum":1000,"default":400} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_edit_text
Append, insert, clear or replace an observed non-protected editable field. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
mode |
Yes | {"type":"string","enum":["append","insert","clear","replace"]} |
text |
No | {"type":"string","maxLength":4000,"default":""} |
position |
No | {"type":"integer","minimum":0,"maximum":4000} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_press_key
Submit the observed editable field using its Android IME Enter action. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
key |
No | {"type":"string","const":"enter","default":"enter"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_scroll_to_node
Ask Android to bring an observed node into view. Find with includeOffscreen first. Returns observation with a fresh snapshot after the action.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
snapshotId |
Yes | {"type":"string","format":"uuid"} |
sessionId |
No | {"$ref":"#/properties/snapshotId"} |
nodeId |
Yes | {"type":"string","minLength":1,"maxLength":260,"pattern":"^0(?:\\.\\d+)*$"} |
observe |
No | {"type":"boolean","default":true} |
settleMs |
No | {"type":"integer","minimum":0,"maximum":800} |
detail |
No | {"type":"string","enum":["compact","decision","full"],"default":"compact"} |
includeScreenshot |
No | {"type":"boolean","default":false} |
maxDimension |
No | {"type":"integer","minimum":320,"maximum":1920,"default":1000} |
quality |
No | {"type":"integer","minimum":35,"maximum":95,"default":75} |
annotate |
No | {"type":"boolean","default":false} |
phone_notification_dismiss
Dismiss a freshly observed clearable notification.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
notificationId |
Yes | {"type":"string","format":"uuid"} |
phone_notification_snooze
Snooze a freshly observed notification.
| Parameter | Required | Schema |
|---|---|---|
packageName |
Yes | {"type":"string","minLength":3,"maxLength":240,"pattern":"^(?:android|[A-Za-z0-9_]+(?:\\.[A-Za-z0-9_]+)+)$"} |
notificationId |
Yes | {"type":"string","format":"uuid"} |
durationMs |
Yes | {"type":"integer","minimum":1000,"maximum":604800000} |
phone_storage_locations
List folders explicitly selected on the phone. Works without Shizuku.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_list_files
List a path inside an explicitly selected folder.
| Parameter | Required | Schema |
|---|---|---|
locationId |
Yes | {"type":"string","format":"uuid"} |
path |
No | {"type":"string","maxLength":500,"default":""} |
offset |
No | {"type":"integer","minimum":0,"maximum":10000,"default":0} |
limit |
No | {"type":"integer","minimum":1,"maximum":200,"default":100} |
phone_read_file
Read a UTF-8 text file inside a selected folder, with line pagination.
| Parameter | Required | Schema |
|---|---|---|
locationId |
Yes | {"type":"string","format":"uuid"} |
path |
Yes | {"type":"string","maxLength":500} |
offset |
No | {"type":"integer","minimum":1,"maximum":100000,"default":1} |
limit |
No | {"type":"integer","minimum":1,"maximum":200,"default":100} |
phone_write_file
Create or explicitly replace a UTF-8 file in a selected folder. Text is bounded to 16,000 JSON characters and 24,000 UTF-8 bytes. Overwrite requires overwrite=true.
| Parameter | Required | Schema |
|---|---|---|
locationId |
Yes | {"type":"string","format":"uuid"} |
path |
Yes | {"type":"string","maxLength":500} |
text |
Yes | {"type":"string","maxLength":16000} |
overwrite |
No | {"type":"boolean","default":false} |
phone_delete_file
Delete the requested file inside a selected folder. Directories are refused.
| Parameter | Required | Schema |
|---|---|---|
locationId |
Yes | {"type":"string","format":"uuid"} |
path |
Yes | {"type":"string","maxLength":500} |
phone_shared_content
List content deliberately shared to Phone MCP through Android Share.
| Parameter | Required | Schema |
|---|---|---|
| (none) | — | — |
phone_read_shared_file
Read a shared text file or image. Does not access other app files.
| Parameter | Required | Schema |
|---|---|---|
fileId |
Yes | {"type":"string","format":"uuid"} |
offset |
No | {"type":"integer","minimum":1,"maximum":100000,"default":1} |
limit |
No | {"type":"integer","minimum":1,"maximum":200,"default":100} |