1.5.1pypi · ghost-in-the-droid · latest release
Observed 2026-08-17T14:58:45.018Z using mcpSecurity-inventory. Protocol 2025-06-18.
| Tool | Category | Risk |
|---|---|---|
app_stateCheck whether an Android package or iOS bundle id is installed, running, or foreground.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"package": {
"title": "Package",
"type": "string"
}
},
"required": [
"device",
"package"
],
"title": "app_stateArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "app_stateOutput",
"type": "object"
} | — | — |
browser_backNavigate back in the current browser/app context.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "browser_backArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "browser_backOutput",
"type": "object"
} | — | — |
classify_screenClassify the current screen: what app, what type of screen (home, search, profile,
settings, dialog, error, loading), keyboard state. No LLM needed — uses XML heuristics.
Use this for quick state checks before deciding what action to take.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "classify_screenArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "classify_screenOutput",
"type": "object"
} | — | — |
clear_notificationsDismiss visible notifications when the platform exposes a clear control.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "clear_notificationsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "clear_notificationsOutput",
"type": "object"
} | — | — |
clipboard_getGet the current clipboard text from the device.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "clipboard_getArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "clipboard_getOutput",
"type": "object"
} | — | — |
clipboard_setSet clipboard text on the device. Use with press_key(PASTE) to paste into fields.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"device",
"text"
],
"title": "clipboard_setArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "clipboard_setOutput",
"type": "object"
} | — | — |
create_skillCreate a new reusable skill from a JSON list of recorded steps.
steps is a JSON array like:
[
{"action": "launch", "package": "com.example.app", "description": "Open app"},
{"action": "tap", "x": 540, "y": 1200, "description": "Tap button"},
{"action": "type", "text": "hello", "description": "Type greeting"},
{"action": "wait", "seconds": 2, "description": "Wait for load"}
]
Supported actions: launch, tap (x,y or element_idx), type, swipe, back, home, wait.
For iOS skills, pass platforms="ios" and either app_package or ios_bundle_id as the bundle id.
Optional elements_ios/elements_android are JSON selector maps written to elements_ios.yaml/elements.yaml.
After creating, use run_workflow(dev, name, "recorded", params) to replay it.Input schema{
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"app_package": {
"title": "App Package",
"type": "string"
},
"steps": {
"title": "Steps",
"type": "string"
},
"platforms": {
"default": "",
"title": "Platforms",
"type": "string"
},
"ios_bundle_id": {
"default": "",
"title": "Ios Bundle Id",
"type": "string"
},
"elements_ios": {
"default": "",
"title": "Elements Ios",
"type": "string"
},
"elements_android": {
"default": "",
"title": "Elements Android",
"type": "string"
}
},
"required": [
"name",
"app_package",
"steps"
],
"title": "create_skillArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "create_skillOutput",
"type": "object"
} | — | — |
crm_list_unread_messagesList local CRM contacts with unread messages, sorted by recency. Read-only.
Returns one row per unread conversation with the handle, unread count,
last message preview, and timestamp.
Input schema{
"properties": {},
"title": "crm_list_unread_messagesArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "crm_list_unread_messagesOutput",
"type": "object"
} | — | — |
crm_lookup_contactGet the stored fact sheet for one local CRM contact by handle. Read-only.
Returns the contact's profile fields, contact status/history, and the
latest conversation state (last message, unread count, timestamps).
Args:
handle: Contact handle, with or without @.
Input schema{
"properties": {
"handle": {
"title": "Handle",
"type": "string"
}
},
"required": [
"handle"
],
"title": "crm_lookup_contactArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "crm_lookup_contactOutput",
"type": "object"
} | — | — |
device_healthRun a comprehensive device health check.
iOS includes Appium/WDA status, active session details, and recovery steps.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "device_healthArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "device_healthOutput",
"type": "object"
} | — | — |
draft_skillDistil the device's most recent chat conversation into draft replayable steps for a HARD skill.
Returns the captured steps (with correct coords/args), a guessed app_package, and a summary.
Nothing is written — review/prune/rename the steps, then call save_skill(kind="hard", steps=...).Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "draft_skillArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "draft_skillOutput",
"type": "object"
} | — | — |
explore_appExplore an app's UI autonomously using BFS.
Launches the app, taps every interactive element, builds a state graph.
Returns JSON with discovered screens, elements, and transitions.
Use this to understand an unfamiliar app before writing automation for it.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"package": {
"title": "Package",
"type": "string"
},
"max_depth": {
"default": 2,
"title": "Max Depth",
"type": "integer"
},
"max_states": {
"default": 10,
"title": "Max States",
"type": "integer"
}
},
"required": [
"device",
"package"
],
"title": "explore_appArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "explore_appOutput",
"type": "object"
} | — | — |
extract_articlesExtract likely visible article/headline candidates from the current browser page.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"max_items": {
"default": 5,
"title": "Max Items",
"type": "integer"
}
},
"required": [
"device"
],
"title": "extract_articlesArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "extract_articlesOutput",
"type": "object"
} | — | — |
extract_visible_textExtract visible text from the current screen with browser chrome filtered by default.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"max_lines": {
"default": 200,
"title": "Max Lines",
"type": "integer"
},
"include_controls": {
"default": false,
"title": "Include Controls",
"type": "boolean"
}
},
"required": [
"device"
],
"title": "extract_visible_textArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "extract_visible_textOutput",
"type": "object"
} | — | — |
find_on_screenFind specific text on the screen and return its location.
Searches XML elements first (fast), falls back to OCR if not found.
Use this to check if a button, label, or message is visible.
Returns JSON with {text, x, y, w, h, method} or null if not found.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"device",
"text"
],
"title": "find_on_screenArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "find_on_screenOutput",
"type": "object"
} | — | — |
fix_device_healthApply a recovery action returned by device_health.recommended_fix.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"issue": {
"title": "Issue",
"type": "string"
}
},
"required": [
"device",
"issue"
],
"title": "fix_device_healthArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "fix_device_healthOutput",
"type": "object"
} | — | — |
force_stopForce-stop an Android package or terminate an iOS bundle id.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"package": {
"title": "Package",
"type": "string"
}
},
"required": [
"device",
"package"
],
"title": "force_stopArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "force_stopOutput",
"type": "object"
} | — | — |
get_crashReturn the full stack trace of the MOST RECENT crash (from the crash buffer).
Android-only: iOS crash logs need syslog/CrashReporter access, not exposed yet.
Optionally filter by package. Pair with list_crashes() to see what's there.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"package": {
"default": "",
"title": "Package",
"type": "string"
}
},
"required": [
"device"
],
"title": "get_crashArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_crashOutput",
"type": "object"
} | — | — |
get_current_urlGet the current browser URL when the platform exposes it.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "get_current_urlArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_current_urlOutput",
"type": "object"
} | — | — |
get_elementsGet all UI elements on the current screen as a JSON array.
Each element has: idx, text, content_desc, resource_id, class, bounds, center, clickable, scrollable.
Use element idx with tap_element(). Call this to understand the screen layout before acting.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"interactive_only": {
"default": true,
"title": "Interactive Only",
"type": "boolean"
}
},
"required": [
"device"
],
"title": "get_elementsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_elementsOutput",
"type": "object"
} | — | — |
get_notificationsGet active notifications. Returns JSON array of {package, title, text}.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "get_notificationsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_notificationsOutput",
"type": "object"
} | — | — |
get_phone_stateGet current app, activity, keyboard state, and focused element.
Quick way to check what app/screen the device is on without parsing full elements.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "get_phone_stateArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_phone_stateOutput",
"type": "object"
} | — | — |
get_screen_treeGet an LLM-friendly indented UI hierarchy of the current screen.
Each node shows: [idx] ClassName "label" [clickable] [x1,y1][x2,y2].
Use this to understand screen layout and pick which element to tap.
Much more readable than raw XML — prefer this over get_elements() for planning.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "get_screen_treeArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_screen_treeOutput",
"type": "object"
} | — | — |
get_screen_xmlGet the raw normalized UI XML dump from the device.
Android returns uiautomator XML; iOS returns normalized Appium/WDA XML.
Use get_screen_tree() instead for a readable summary.
Use this only when you need exact attribute values or the full hierarchy.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "get_screen_xmlArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_screen_xmlOutput",
"type": "object"
} | — | — |
get_stream_infoReturn effective stream metadata without opening the stream.
iOS reports WDA MJPEG URL/settings, screenshot fallback, and unsupported
Portal/WebRTC actions. Android reports Portal/H264/screencap metadata.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"mode": {
"default": "mjpeg",
"title": "Mode",
"type": "string"
},
"fps": {
"default": 5,
"title": "Fps",
"type": "integer"
},
"quality": {
"default": 8,
"title": "Quality",
"type": "integer"
}
},
"required": [
"device"
],
"title": "get_stream_infoArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "get_stream_infoOutput",
"type": "object"
} | — | — |
launch_appLaunch an app by Android package name or iOS bundle id. Use search_apps() to find it.
Args:
device: ADB serial or ios:<udid>.
package: App package name or iOS bundle id, e.g. "com.android.chrome" or "com.google.chrome.ios".
fresh: If True, force-stop the app first (cold start, clears in-memory
state — back stack, unsaved drafts, login flow position, etc.).
If False (default), reuses any existing background instance (warm
start — resumes wherever the user left off).
Use fresh=True for benchmarks, fresh start of a flow, or when the
current app state would interfere with the task.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"package": {
"title": "Package",
"type": "string"
},
"fresh": {
"default": false,
"title": "Fresh",
"type": "boolean"
}
},
"required": [
"device",
"package"
],
"title": "launch_appArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "launch_appOutput",
"type": "object"
} | — | — |
launch_intentLaunch a full Android intent. More powerful than launch_app().
Examples:
Open a URL: action="android.intent.action.VIEW" data="https://google.com"
Open Settings: package="com.android.settings"
Share text: action="android.intent.action.SEND" extras='{"android.intent.extra.TEXT": "hello"}'Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"action": {
"default": "",
"title": "Action",
"type": "string"
},
"data": {
"default": "",
"title": "Data",
"type": "string"
},
"package": {
"default": "",
"title": "Package",
"type": "string"
},
"extras": {
"default": "{}",
"title": "Extras",
"type": "string"
}
},
"required": [
"device"
],
"title": "launch_intentArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "launch_intentOutput",
"type": "object"
} | — | — |
list_appsList installed apps with human-readable names and package names or bundle ids.
iOS is limited to configured/common bundle ids verified through Appium.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "list_appsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "list_appsOutput",
"type": "object"
} | — | — |
list_crashesList recent app crashes and ANRs (from the logcat crash buffer, no root).
Android-only: iOS crash logs need syslog/CrashReporter access, not exposed yet.
Optionally filter by package (substring match on the crashing process).
Returns JSON: {count, crashes: [{type, timestamp, process, summary}]}.
Use get_crash() to pull a full stack for the most recent one.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"package": {
"default": "",
"title": "Package",
"type": "string"
},
"limit": {
"default": 10,
"title": "Limit",
"type": "integer"
}
},
"required": [
"device"
],
"title": "list_crashesArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "list_crashesOutput",
"type": "object"
} | — | — |
list_devicesList connected Android ADB devices and configured iOS Appium devices.
Call this first to get the device serial you need for other tools.Input schema{
"properties": {},
"title": "list_devicesArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "list_devicesOutput",
"type": "object"
} | — | — |
list_packagesList raw Android package names or iOS bundle ids. Prefer list_apps() for display names.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "list_packagesArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "list_packagesOutput",
"type": "object"
} | — | — |
list_skillsList all installed mobile automation skills with their actions, workflows, and platform support.
Use this to discover what high-level automations are available.
Prefer using run_workflow() over raw tap/swipe when a skill exists for the task.Input schema{
"properties": {
"device": {
"default": "",
"title": "Device",
"type": "string"
},
"supported_only": {
"default": false,
"title": "Supported Only",
"type": "boolean"
}
},
"title": "list_skillsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "list_skillsOutput",
"type": "object"
} | — | — |
list_unread_leadsList every influencer with an unread reply in the inbox, sorted by recency.
Returns one row per unread conversation with the handle, unread count,
last message preview, and timestamp. Useful for daily prioritisation:
'which leads should I respond to right now?'
Input schema{
"properties": {},
"title": "list_unread_leadsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "list_unread_leadsOutput",
"type": "object"
} | — | — |
long_pressLong press at coordinates. Use for context menus, drag initiation, etc.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"x": {
"title": "X",
"type": "integer"
},
"y": {
"title": "Y",
"type": "integer"
},
"duration_ms": {
"default": 1000,
"title": "Duration Ms",
"type": "integer"
}
},
"required": [
"device",
"x",
"y"
],
"title": "long_pressArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "long_pressOutput",
"type": "object"
} | — | — |
lookup_leadGet the full fact sheet for one influencer lead by handle.
Use this when you need to know everything about an influencer to draft
a personalised reply or decide next-step outreach: their follower count,
engagement, bio, niche, what hashtag we found them on, when we DMed them,
which account sent the DM, their latest reply, and unread state.
Args:
handle: TikTok username, with or without @ (e.g. 'creatorhandle' or '@creatorhandle')
Input schema{
"properties": {
"handle": {
"title": "Handle",
"type": "string"
}
},
"required": [
"handle"
],
"title": "lookup_leadArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "lookup_leadOutput",
"type": "object"
} | — | — |
ocr_regionOCR a specific region of the screen. Coordinates in device pixels.
More accurate than full-screen OCR for targeted text extraction.
Returns JSON array of {text, conf, x, y, w, h} relative to the crop region.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"x1": {
"title": "X1",
"type": "integer"
},
"y1": {
"title": "Y1",
"type": "integer"
},
"x2": {
"title": "X2",
"type": "integer"
},
"y2": {
"title": "Y2",
"type": "integer"
}
},
"required": [
"device",
"x1",
"y1",
"x2",
"y2"
],
"title": "ocr_regionArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "ocr_regionOutput",
"type": "object"
} | — | — |
ocr_screenOCR the entire device screen using RapidOCR. Returns all visible text with positions.
Use this when UI elements are rendered as images/canvas (e.g., analytics dashboards,
games, WebViews) where get_elements() returns no text.
Returns JSON array of {text, conf, x, y, w, h} sorted top-to-bottom.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "ocr_screenArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "ocr_screenOutput",
"type": "object"
} | — | — |
open_cameraOpen the platform camera app in a specific mode.
Android uses launcher/UI automation; iOS uses the Camera bundle and WDA UI
controls. No package or bundle id is required.
Args:
device: ADB serial or ios:<udid>.
mode: One of:
"photo" — rear camera, photo mode (default)
"video" — rear camera, video/record mode
"selfie" — front camera, photo mode
"selfie_video" — front camera, video mode
timer_s: Self-timer delay in seconds. Supported: 0 (off), 2, 3, 5, 10.
Uses UI automation — snaps to the closest value the device supports
(ASUS: 3s/10s, Samsung: 2s/5s/10s). 0 = no timer (default).
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"mode": {
"default": "photo",
"title": "Mode",
"type": "string"
},
"timer_s": {
"default": 0,
"title": "Timer S",
"type": "integer"
}
},
"required": [
"device"
],
"title": "open_cameraArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "open_cameraOutput",
"type": "object"
} | — | — |
open_notificationsPull down the notification shade or iOS Notification Center.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "open_notificationsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "open_notificationsOutput",
"type": "object"
} | — | — |
open_urlOpen a URL in the platform browser.
On iOS this uses Appium/WDA and defaults to the configured browser bundle
id, usually com.google.chrome.ios or com.apple.mobilesafari.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"url": {
"title": "Url",
"type": "string"
},
"bundle_id": {
"default": "",
"title": "Bundle Id",
"type": "string"
}
},
"required": [
"device",
"url"
],
"title": "open_urlArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "open_urlOutput",
"type": "object"
} | — | — |
paste_textSet clipboard text and immediately paste it into the currently focused field.
Equivalent to clipboard_set + press_key(PASTE) in one call.
Tap the target input field first to focus it, then call this.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"device",
"text"
],
"title": "paste_textArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "paste_textOutput",
"type": "object"
} | — | — |
press_backPress Back on Android or the best available iOS browser/navigation back action.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "press_backArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "press_backOutput",
"type": "object"
} | — | — |
press_homePress the platform Home button. Returns to the home screen.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "press_homeArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "press_homeOutput",
"type": "object"
} | — | — |
press_keySend a platform key event.
Android accepts KEYCODE_* names, with the KEYCODE_ prefix added automatically.
iOS supports WDA-backed HOME, ENTER/RETURN, and BACK/ESCAPE.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"key": {
"title": "Key",
"type": "string"
}
},
"required": [
"device",
"key"
],
"title": "press_keyArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "press_keyOutput",
"type": "object"
} | — | — |
read_newsOpen a news page and return structured headlines plus article snippets.
This is the iOS Chrome/WebDriver smoke workflow exposed as a single tool.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"url": {
"default": "https://text.npr.org/",
"title": "Url",
"type": "string"
},
"max_headlines": {
"default": 5,
"title": "Max Headlines",
"type": "integer"
},
"max_articles": {
"default": 3,
"title": "Max Articles",
"type": "integer"
},
"bundle_id": {
"default": "",
"title": "Bundle Id",
"type": "string"
},
"wait_s": {
"default": 2,
"title": "Wait S",
"type": "number"
},
"save_screenshots": {
"default": false,
"title": "Save Screenshots",
"type": "boolean"
}
},
"required": [
"device"
],
"title": "read_newsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "read_newsOutput",
"type": "object"
} | — | — |
run_actionRun a single skill action on the device.
Call list_skills() first to see available actions.
Examples:
run_action("SERIAL", "tiktok", "open_app", '{}')
run_action("SERIAL", "tiktok", "type_and_search", '{"query": "cats"}')Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"skill": {
"title": "Skill",
"type": "string"
},
"action": {
"title": "Action",
"type": "string"
},
"params": {
"default": "{}",
"title": "Params",
"type": "string"
}
},
"required": [
"device",
"skill",
"action"
],
"title": "run_actionArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "run_actionOutput",
"type": "object"
} | — | — |
run_flowRun an ordered batch of tool calls server-side in ONE round-trip.
`steps` is a JSON list of {"tool": "<name>", "args": {...}} — the same tool
names execute_tool exposes (tap, tap_element, type_text, launch_app, etc.).
Steps run in order and stop at the first error. Returns a JSON object with
per-step results and a SINGLE final screenshot (not one per step) — far
fewer tokens/round-trips than calling each tool separately. Steps do NOT
auto-settle between UI actions; if a step needs the screen to update before
the next one reads it, insert an explicit {"tool":"wait","args":{...}} step.
Example:
run_flow("SERIAL", '[{"tool":"launch_app","args":{"package":"com.android.settings"}},
{"tool":"find_on_screen","args":{"text":"Wi-Fi"}},
{"tool":"tap","args":{"x":540,"y":300}}]')
Security: fail-closed allow-list — only vetted read/UI tools may run inside
a flow. Anything else (raw `shell`, `run_skill`, or any unknown tool) makes
the whole flow be refused before any step runs, since a batch is exactly
where an injected instruction would smuggle a shell command. Max 50 steps.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"steps": {
"title": "Steps",
"type": "string"
}
},
"required": [
"device",
"steps"
],
"title": "run_flowArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "run_flowOutput",
"type": "object"
} | — | — |
run_workflowRun an installed skill workflow on the device.
Call list_skills() first to see available skills and workflows.
Examples:
run_workflow("SERIAL", "tiktok", "upload_video", '{"video_path": "/tmp/video.mp4"}')
run_workflow("SERIAL", "send_gmail_email", "recorded", '{"subject": "Hello", "body": "Test"}')
params is a JSON string of keyword arguments for the workflow.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"skill": {
"title": "Skill",
"type": "string"
},
"workflow": {
"title": "Workflow",
"type": "string"
},
"params": {
"default": "{}",
"title": "Params",
"type": "string"
}
},
"required": [
"device",
"skill",
"workflow"
],
"title": "run_workflowArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "run_workflowOutput",
"type": "object"
} | — | — |
save_skillSave the device's current chat conversation as a reusable skill.
kind="hard" replays concrete actions — pass revised `steps` (a JSON array from draft_skill), or
omit them to auto-distil the conversation. kind="soft" stores markdown `guidance` (what to watch
out for) surfaced to agents on demand via list_skills / run_workflow.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
},
"kind": {
"default": "hard",
"title": "Kind",
"type": "string"
},
"app_package": {
"default": "",
"title": "App Package",
"type": "string"
},
"description": {
"default": "",
"title": "Description",
"type": "string"
},
"steps": {
"default": "",
"title": "Steps",
"type": "string"
},
"guidance": {
"default": "",
"title": "Guidance",
"type": "string"
}
},
"required": [
"device",
"name"
],
"title": "save_skillArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "save_skillOutput",
"type": "object"
} | — | — |
screen_recording_statusReturn active screen recording status for a device.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "screen_recording_statusArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "screen_recording_statusOutput",
"type": "object"
} | — | — |
screenshotTake a screenshot of the device screen. Returns a base64-encoded JPEG.
Use this to SEE what's on screen before deciding what to tap.
Routes through the shared compressed screenshot path (half-resolution JPEG,
cross-platform) instead of a raw full-res PNG: a raw PNG base64 string
overflows the MCP tool-result token cap on content-heavy screens, so the
client falls back to text/OCR and never sees the pixels. The downscale cuts
the payload ~4-8x so most screens stay under the cap. (The lasting fix is
returning an MCP image-content block; tracked as feature #8.)Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "screenshotArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "screenshotOutput",
"type": "object"
} | — | — |
screenshot_annotatedTake a screenshot with numbered element labels overlaid on interactive elements.
The numbers correspond to element indices from get_elements().
Use this when you want to SEE the screen with elements visually labelled.
Returns base64-encoded PNG.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "screenshot_annotatedArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "screenshot_annotatedOutput",
"type": "object"
} | — | — |
screenshot_croppedTake a screenshot of a specific region of the screen.
Coordinates are in device pixels. Use this to zoom in on a specific area
(e.g., a form field, a notification, a chart). Returns base64-encoded JPEG.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"x1": {
"title": "X1",
"type": "integer"
},
"y1": {
"title": "Y1",
"type": "integer"
},
"x2": {
"title": "X2",
"type": "integer"
},
"y2": {
"title": "Y2",
"type": "integer"
}
},
"required": [
"device",
"x1",
"y1",
"x2",
"y2"
],
"title": "screenshot_croppedArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "screenshot_croppedOutput",
"type": "object"
} | — | — |
search_appsSearch installed apps by name. Case-insensitive. Returns Android packages or iOS bundle ids.
Example: search_apps('tiktok') → [{"name": "TikTok", "package": "com.zhiliaoapp.musically"}]Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"query": {
"title": "Query",
"type": "string"
}
},
"required": [
"device",
"query"
],
"title": "search_appsArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "search_appsOutput",
"type": "object"
} | — | — |
speak_textMake the phone speak text aloud using its built-in TTS engine.
Works whether the agent runs on the phone or on a PC — the call always
goes through the Ghost portal app running on the device.
Args:
device: ADB serial. This tool is Android-only.
text: Text to speak.
rate: Speech rate multiplier (0.5 = slow, 1.0 = normal, 1.5 = fast).
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
},
"rate": {
"default": 1,
"title": "Rate",
"type": "number"
}
},
"required": [
"device",
"text"
],
"title": "speak_textArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "speak_textOutput",
"type": "object"
} | — | — |
start_screen_recordingStart recording the device screen.
iOS uses WDA MJPEG captured through ffmpeg. Android uses adb screenrecord.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"filename": {
"default": "",
"title": "Filename",
"type": "string"
}
},
"required": [
"device"
],
"title": "start_screen_recordingArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "start_screen_recordingOutput",
"type": "object"
} | — | — |
stop_screen_recordingStop a running device screen recording and save the MP4.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
}
},
"required": [
"device"
],
"title": "stop_screen_recordingArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "stop_screen_recordingOutput",
"type": "object"
} | — | — |
swipeSwipe from (x1,y1) to (x2,y2). Use for scrolling, pulling down notifications, etc.
Common patterns: scroll down = swipe(dev, 540, 1400, 540, 600)
scroll up = swipe(dev, 540, 600, 540, 1400)Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"x1": {
"title": "X1",
"type": "integer"
},
"y1": {
"title": "Y1",
"type": "integer"
},
"x2": {
"title": "X2",
"type": "integer"
},
"y2": {
"title": "Y2",
"type": "integer"
},
"duration_ms": {
"default": 500,
"title": "Duration Ms",
"type": "integer"
}
},
"required": [
"device",
"x1",
"y1",
"x2",
"y2"
],
"title": "swipeArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "swipeOutput",
"type": "object"
} | — | — |
tapTap at exact pixel coordinates (x, y) on the device screen.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"x": {
"title": "X",
"type": "integer"
},
"y": {
"title": "Y",
"type": "integer"
}
},
"required": [
"device",
"x",
"y"
],
"title": "tapArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "tapOutput",
"type": "object"
} | — | — |
tap_elementTap a UI element by its index from get_elements().
Call get_elements() first to see what's on screen and get element indices.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"idx": {
"title": "Idx",
"type": "integer"
}
},
"required": [
"device",
"idx"
],
"title": "tap_elementArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "tap_elementOutput",
"type": "object"
} | — | — |
toggle_overlayToggle the numbered element overlay on the device screen.
When on, interactive elements get visible numbered labels that match get_elements() indices.
Useful for visual debugging or when sending screenshots to a vision model.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"visible": {
"default": true,
"title": "Visible",
"type": "boolean"
}
},
"required": [
"device"
],
"title": "toggle_overlayArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "toggle_overlayOutput",
"type": "object"
} | — | — |
type_textType text into the currently focused input field.
Tap an input field first to focus it. Spaces are supported.
Non-ASCII input is transliterated to the closest ASCII (adb input text is
ASCII-only); for full-fidelity emoji/CJK use type_unicode() instead.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"device",
"text"
],
"title": "type_textArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "type_textOutput",
"type": "object"
} | — | — |
type_unicodeType unicode text into the focused field.
Android uses ADBKeyboard when configured; iOS uses WDA text entry.
Use type_text() for plain ASCII.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
}
},
"required": [
"device",
"text"
],
"title": "type_unicodeArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "type_unicodeOutput",
"type": "object"
} | — | — |
waitPause execution for a fixed number of seconds.Input schema{
"properties": {
"seconds": {
"default": 2,
"title": "Seconds",
"type": "number"
}
},
"title": "waitArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "waitOutput",
"type": "object"
} | — | — |
wait_for_textWait until text appears on screen and return visible text context.Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"text": {
"title": "Text",
"type": "string"
},
"timeout": {
"default": 12,
"title": "Timeout",
"type": "number"
}
},
"required": [
"device",
"text"
],
"title": "wait_for_textArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "wait_for_textOutput",
"type": "object"
} | — | — |
web_searchOpen a web search in whatever browser is on the device.
Faster than: launch Chrome → tap address bar → type → submit. Useful when
the user asks "search for X" or you need to look up info that's not on the
current screen. Picks the first installed browser from a fallback chain
(Chrome → Firefox → Samsung Internet → Edge → Brave → Opera → Vivaldi →
DuckDuckGo Browser → system default), so it works even if Chrome is missing.
Args:
device: ADB serial or ios:<udid>.
query: Free-text search terms (don't pre-escape — handled here).
engine: "google" (default), "ddg" / "duckduckgo", "bing", or "brave".
bundle_id: Optional iOS browser bundle id override, e.g. com.google.chrome.ios.
Input schema{
"properties": {
"device": {
"title": "Device",
"type": "string"
},
"query": {
"title": "Query",
"type": "string"
},
"engine": {
"default": "google",
"title": "Engine",
"type": "string"
},
"bundle_id": {
"default": "",
"title": "Bundle Id",
"type": "string"
}
},
"required": [
"device",
"query"
],
"title": "web_searchArguments",
"type": "object"
}Output schema{
"properties": {
"result": {
"title": "Result",
"type": "string"
}
},
"required": [
"result"
],
"title": "web_searchOutput",
"type": "object"
} | — | — |
No completed comparison is available.
| Risk | Change | Subject |
|---|---|---|
| No material changes recorded. | ||
| Severity | Finding | Advisory |
|---|---|---|
| No confirmed vulnerability is published for this version. | ||
Artifact SHA-256: 8f7e12f626d471f29ad3198f3e1958ccc11188fcb02b90ab947f8cf749fab0fd
Scanner: mcp-proof-engine 0.1.0.