mobile-debug-mcp
This MCP server lets an agent build, install, launch, inspect, interact with, and verify Android/iOS apps on local devices or simulators, with optional debugging and performance tracing.
Build, install, launch, restart, terminate, and reset app data.
List devices, check system/toolchain status, and inspect app readiness.
Capture screenshots, UI trees, screen fingerprints, current screens, and debug snapshots.
Tap, swipe, scroll, type text, press back, find elements, adjust controls, and wait for UI/screen changes.
Verify screens, element visibility, and UI state with deterministic assertions.
Run bounded multi-step journeys with assertions and optional capture-on-failure.
Collect logs, stream logs, read network activity, and retrieve retained interaction diagnostics.
Attach to Android JDI or iOS simulator LLDB debuggers; inspect state, set/remove breakpoints, wait for events, read stacks/locals, step, resume, and detach.
Probe and capture Android Perfetto or iOS simulator Instruments system traces, then retrieve or cancel them.
Allows building, installing, and inspecting Android apps via ADB, enabling AI-assisted mobile development and debugging.
Provides support for Flutter mobile development, though not fully tested, enabling AI-assisted development and debugging.
Allows building, installing, and inspecting iOS apps via Xcode and idb, enabling AI-assisted mobile development and debugging.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mobile-debug-mcp Diagnose the latest crash from the app"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Mobile Debug Tools
Build, install, control, and inspect Android and iOS apps from an MCP-compatible client. Mobile Debug Tools connects your client to local device toolchains and provides UI actions, screenshots, logs, state assertions, and optional Android performance capture and runtime debugging.
Android, iOS, and Kotlin Multiplatform projects are supported. Flutter and React Native have not been tested. Platform and device limitations are described in the tool reference.
Use responseMode: "compact" for bounded interaction and journey summaries.
Retrieve retained details without replaying input with
get_interaction_diagnostics; debug output
remains available.
What you can use it for
Mobile Debug Tools gives a coding agent access to a running app, so development can include feedback from the device as well as the source code. For example:
Build and test a feature. After adding a settings screen, build and install the app, navigate to it, and check that its controls display and behave as expected. See app management and UI interactions and assertions.
Check a bug fix or regression. Reproduce a sequence such as opening a form, entering text and submitting it, then verify the resulting screen or control state. Repeat the journey after a code change to check the outcome.
Review the UI on a device. Capture screenshots to inspect layout and visual changes, or inspect the UI hierarchy for exposed labels and control state. See observations.
Investigate an app failure. Collect logs, screenshots and a debug snapshot around a failing action to understand what happened. Evidence correlation links observations to the action.
Investigate mobile performance or runtime behaviour. Capture a Perfetto or iOS simulator Instruments trace during a slow flow, or attach the runtime debugger to a debuggable app to inspect breakpoints, call stacks and locals on Android or an iOS simulator.
Related MCP server: xcforge
How it works
Your agent client launches a local MCP server and communicates with it over stdio. The server translates tool calls into operations through Android's ADB or Apple's Xcode tools and idb, then returns device observations and action results to the client. It connects to emulators, simulators and supported physical devices through those toolchains.
The agent plugin bundles the server configuration and usage skill. The same server can also be configured directly in an MCP client or run from a source checkout. See code structure for the implementation's module boundaries.
Start here
Choose how to connect:
Agent plugin — Recommended. Installs the server configuration and usage skill together for supported agent clients.
Direct MCP configuration. Connect the published server to another MCP-compatible client.
Manual setup. Build and run a local source checkout.
Check the requirements for your platform before installing.
Requirements
Node.js >= 22
Android SDK (adb) for Android support
Xcode and its command-line tools on macOS for iOS support
idb for iOS UI inspection and interaction
JDK 17+ for optional Android runtime debugging; Xcode’s Swift-enabled LLDB/Python for optional iOS simulator debugging
Agent plugin
The plugin installs the MCP server configuration and the mobile-debug-mcp usage
skill together. These are GitHub/local installation routes; they do not require
approval from a client's public curated marketplace.
In a terminal with a current Codex CLI:
codex plugin marketplace add clivejefferies/mobile-debug-tools --ref main
codex plugin add mobile-debug-tools@mobile-debug-tools
codex plugin listStart a new chat/session and confirm the plugin is enabled and its skill and MCP
tools are available. These commands use the repository's marketplace, named
mobile-debug-tools, not a public directory listing. See the
official packaging instructions.
Run these shell commands (not slash commands inside a chat):
claude plugin marketplace add clivejefferies/mobile-debug-tools --scope user
claude plugin install mobile-debug-tools@mobile-debug-tools --scope user
claude plugin listRestart the session after installation. In an interactive Claude Code chat, the
corresponding commands start with /plugin instead of claude plugin. See
Claude Code's installation guide.
For local installation, clone this repository and run these commands from its root in a macOS/Linux shell:
git clone https://github.com/clivejefferies/mobile-debug-tools.git
cd mobile-debug-tools
cursor_plugin_dir="$HOME/.cursor/plugins/local/mobile-debug-tools"
if [ -e "$cursor_plugin_dir" ]; then
echo "Move the existing plugin directory aside before copying the new package."
else
mkdir -p "$(dirname "$cursor_plugin_dir")"
cp -R agent-plugin/cursor "$cursor_plugin_dir"
fiOn Windows, copy the contents of agent-plugin/cursor into a new
~/.cursor/plugins/local/mobile-debug-tools folder, including .cursor-plugin.
Use this generated Cursor-native package, not the portable parent: Cursor does
not expand ${PLUGIN_DATA} in portable mcp.json. Do not symlink to the checkout.
Run Developer: Reload Window, open Customize, and confirm the skill and MCP server are loaded. For Teams/Enterprise distribution, import this repository under Dashboard → Plugins & MCPs → Team Marketplaces; its Cursor catalog selects the native package. Members install from Customize. See Cursor's plugin guide.
Install the Antigravity CLI, then clone this GitHub repository and export its plugin:
git clone https://github.com/clivejefferies/mobile-debug-tools.git
cd mobile-debug-tools
npm run package:antigravity -- "$PWD/antigravity-dist"
agy plugin validate --strict "$PWD/antigravity-dist"
agy plugin install "$PWD/antigravity-dist"
agy plugin list --jsonNo npm install is needed for the export script. Choose a new output directory;
the exporter refuses to overwrite an existing one. Check the installed entry has
one skill (mobile-debug-mcp) and one MCP server (mobile-debug-mcp), then start
a new session and approve the specific MCP calls you intend to use.
The Antigravity-only export avoids strict-validation warnings from the other
clients' compatibility files. It uses mcp_config.json and the same pinned npm
server and shared skill. GitHub/local installation does not require the
Antigravity Marketplace interest form. See Google's plugin guide.
Each client needs Node.js 22 or newer, npx on its PATH, npm registry access on
first launch, and the platform toolchains for your device. After installation,
ask the agent to list devices, select an explicit emulator/device, and inspect
its screen. An installed component list alone does not prove a working device
connection. Disable any separate manual registration of this MCP server in the
same client to avoid duplicate tools. If a plugin command is unavailable, update
the client; the direct MCP configuration works independently.
MCP configuration
For a standard installation, add this stdio server to your client's MCP settings:
{
"mcpServers": {
"mobile-debug": {
"command": "npx",
"args": ["--yes", "mobile-debug-mcp"]
}
}
}If your client uses separate fields, choose stdio, set the command to npx, and
supply --yes and mobile-debug-mcp as arguments. The examples below add optional
path overrides; replace the placeholder paths before using them.
Recommended when you want Android only, or when you want to make the Android toolchain explicit.
{
"mcpServers": {
"mobile-debug": {
"command": "npx",
"args": ["--yes", "mobile-debug-mcp"],
"env": {
"ADB_PATH": "/path/to/adb",
"ANDROID_SDK_ROOT": "/path/to/android/sdk",
"GRADLE_JAVA_HOME": "/path/to/jdk"
}
}
}
}For Android-only setups, XCRUN_PATH and IDB_PATH are not required unless you want to pin them explicitly.
Recommended when you want iOS simulator or device support, or when idb lives in a non-standard location.
{
"mcpServers": {
"mobile-debug": {
"command": "npx",
"args": ["--yes", "mobile-debug-mcp"],
"env": {
"XCRUN_PATH": "/usr/bin/xcrun",
"MCP_IDB_PATH": "/path/to/idb",
"IDB_PATH": "/path/to/idb"
}
}
}
}For iOS-only setups, ADB_PATH and ANDROID_SDK_ROOT are not required unless you want to pin them explicitly.
Manual setup
For a local source checkout, follow the development setup to install dependencies and build the server. Then configure your MCP client to launch that build over stdio:
{
"mcpServers": {
"mobile-debug": {
"command": "node",
"args": ["/absolute/path/to/mobile-debug-mcp/dist/server.js"]
}
}
}Replace the path with your checkout location. Rebuild after source changes.
Environment setup
The server discovers platform tools from standard locations and PATH. Leave
path overrides unset for a standard installation. Use them for non-standard
locations, multiple toolchains, or a pinned development environment.
Variable | Purpose |
| Path to |
| Android SDK root. |
| Path to |
| Path to |
| Java home for Gradle-backed operations. |
After connecting the client, call get_system_status to check discovery and
prerequisites. See environment diagnostics if a toolchain
or device is unavailable.
Android debugger errors include bounded, sanitized failure classifications and recovery guidance; see the debugger guide.
Documentation
Documentation guide — find the guide for your task.
Tool reference — inputs, responses, examples, and shared principles.
Contributing — develop the server and run its checks.
Changelog — release history.
License
Launch and interaction results distinguish dispatch from timestamped device readiness evidence. Readiness waits account for observed sleeping/locked device blockers. Unknown or unsupported signals are explicit, and no automatic unlock is performed.
Available Tools
53 toolsadjust_controlA
Purpose: Adjust a numeric control value with verification.
This is the initial adjustable-control surface for slider-like controls and other controls that expose a numeric value or value_range.
Inputs:
exactly one of selector or element_id
property (defaults to "value")
targetValue
tolerance (optional; discrete default is 0, continuous default is max(step / 2, 1% of range) when omitted)
maxAttempts (optional; defaults to 5)
platform/deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target_state / actual_state / within_tolerance / converged / attempts / adjustment_mode
target.selector = original selector or element handle
success = true when the control converges within tolerance
Verification Guidance:
Prefer direct platform adjustment when the runtime exposes it; then verified increment/decrement actions; use coordinate fallback only as degraded mode
Use expect_state for the control value readback
Do not use derived semantic metadata as proof of success
Failure Handling:
ELEMENT_NOT_FOUND → re-resolve the control
ELEMENT_NOT_INTERACTABLE → the control cannot be adjusted through the current runtime
CONTROL_CONVERGENCE_FAILED → the control did not converge within bounded retries or the requested value is out of range
UNKNOWN → capture a snapshot and stop Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: targetValue (required), deviceId, platform, property, +4 more.
attach_debuggerA
Attach an owned Android JDI or iOS simulator LLDB session. Requires an explicit device and debuggable app; choose processId when ambiguous. Stops suspend all app threads. Auto-detach: 60s paused, 5m idle, 30m total.
Inputs: appId (required), deviceId (required), platform (required), processId, +2 more.
build_appA
Build a project for Android or iOS and return the built artifact path. Does not install. platform and projectType are required.
Inputs: platform (required), projectPath (required), projectType (required), variant.
cancel_system_traceC
Stop owned capture and discard partial files. Already completed local artifacts are retained.
Inputs: traceId (required).
capture_debug_snapshotA
Capture a complete debug snapshot (raw observation layer plus optional derived semantic layer). Returns structured JSON with snapshot_revision, captured_at_ms, snapshot_delta, and loading_state when detectable. Returns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.
Inputs: appId, reason, deviceId, logLines, +5 more.
capture_screenshotB
Capture a screenshot from an Android device or iOS simulator. Returns device metadata and the screenshot image. Returns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.
Inputs: platform (required), deviceId, actionRef.
classify_action_outcomeA
Classify the outcome of the most recent action into exactly one of: success, no_op, backend_failure, ui_failure, unknown.
Use the runtime action result's action_type as actionType so the classifier can distinguish local-state actions from side-effect actions.
Use this when the intended outcome is not already fully verified by the UI signal alone.
For backend/API activity, compare get_screen_fingerprint before and after the action and call get_network_activity immediately after the action if the outcome is still ambiguous.
HOW TO GATHER INPUTS before calling:
Call wait_for_screen_change or compare get_screen_fingerprint before/after — set uiChanged accordingly.
If you checked for a specific element with wait_for_ui, set expectedElementVisible.
Pass actionType from the action response when available.
Only provide networkRequests if you already collected them or want to classify a side-effect action with backend evidence.
RULES (applied in order — stop at first match):
If uiChanged=true OR expectedElementVisible=true → outcome=success
If actionType is missing → outcome=unknown
If any request has status=failure or retryable → outcome=backend_failure
If actionType maps to a local-state action → outcome=no_op; prefer state-based verification and avoid default network fallback
If actionType maps to a side-effect action and no networkRequests were supplied → outcome=unknown
If no requests returned → outcome=no_op
If all requests succeeded → outcome=ui_failure
Otherwise → outcome=unknown
BEHAVIOUR after outcome:
success → continue
no_op → retry with richer state verification or re-resolve the element
backend_failure → stop and report the failing endpoint
ui_failure → stop and report failure
unknown → take one recovery step (e.g. capture_debug_snapshot), then stop
Inputs: uiChanged (required), actionType, hasLogErrors, networkRequests, +1 more.
detach_debuggerB
Dispose the owned debugger connection, release owned suspension and remove its owned transport. Idempotent; retries incomplete cleanup.
Inputs: debugSessionId (required), timeoutMs, responseMode.
expect_element_visibleA
Purpose: Deterministically verify that the intended UI outcome of an action has occurred by confirming a target element is visible.
Inputs:
selector: required selector used to resolve the target element
element_id: optional previously resolved element identifier used only as context
Output Structure:
success: true when the element is visible
selector: selector used for verification
element_id: resolved element identifier when available
element: minimal resolved element info when visible
failure_code: TIMEOUT or UNKNOWN when verification fails
retryable: true when failure_code=TIMEOUT
Recommended Usage:
Define the expected element state before executing the action
Resolve the target element or triggering control
Call an action tool such as tap_element
If needed, wait for UI availability using wait_for_*
Call expect_element_visible as the final verification step
If success=false, follow the action tool retry guidance
Verification Guidance:
Primary and authoritative verification tool for expected element appearance or visibility
Use this when the screen should stay the same but the UI should reveal or update a specific element
selector is the primary input; element_id is an optional optimization only
The tool resolves the selector internally when needed
Constraints:
Returns structured binary success/failure only
Must not rely on natural-language interpretation or reasoning
Failure Handling:
TIMEOUT → retry verification once or retry the action after re-resolving
UNKNOWN → capture a snapshot and stop
Inputs: selector (required), deviceId, platform, element_id, +2 more.
expect_screenA
Purpose: Deterministically verify that the intended navigation outcome of an action has occurred.
Inputs:
fingerprint: preferred exact-match screen fingerprint
screen: exact semantic screen identifier when a fingerprint is not available
Output Structure:
success: true when the expected screen matches the observed screen
observed_screen: current fingerprint and screen identifier
expected_screen: the expected fingerprint and/or screen identifier
confidence: 1 for an exact match, otherwise 0
Recommended Usage:
Define the expected screen before executing the action
Resolve the target element or screen state
Call an action tool such as tap_element
If needed, wait for transition using wait_for_*
Call expect_screen as the final verification step
If success=false, treat the outcome as unverified and follow the action tool retry guidance
Verification Guidance:
Primary and authoritative verification tool for navigation outcomes
Prefer fingerprint whenever you have one
Use screen only as a fallback exact match against known identifiers
Works best when the expected screen identifier is known ahead of time
If the expected screen is not already known, capture or define it before executing the action
Constraints:
Returns structured binary success/failure only
Must not rely on natural-language interpretation or reasoning
Failure Handling:
success=false means the expected screen was not reached; retry or recover using the action tool's failure strategy
Inputs: screen, deviceId, platform, fingerprint.
expect_stateA
Purpose: Verify a readable UI state property on the currently visible element.
Inputs:
selector or element_id
property
expected
platform/deviceId (optional)
Supported properties:
checked, selected, focused, expanded, enabled, text_value, value, raw_value
Verification Guidance:
Use this when the UI element is visible but its state must also be confirmed
Prefer the canonical property names above
The tool compares the normalized readable state and returns the observed value when available
Constraints:
Returns structured success/failure only
Does not infer a state when the property is unavailable
Failure Handling:
ELEMENT_NOT_FOUND → re-resolve the element or wait for UI stabilization
UNKNOWN → capture a snapshot and stop
Inputs: expected (required), property (required), deviceId, platform, +2 more.
find_elementA
Find a UI element by semantic query (text, content-desc, resource-id, class).
Returns the best match plus resolution metadata when available, including confidence, selection reason, and fallback alternates.
Inputs: query (required), exact, deviceId, platform, +1 more.
get_app_readinessB
Observe readiness with at most two fresh UI-tree samples. Reports loading, transitioning, settled or unknown with evidence and limitations. Managed Android and supported iOS simulator debugger pauses are reported from debugger evidence; unresponsive detection remains unsupported. Settled normalized foreground UI is not proof of app identity, responsiveness or backend completion. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: platform (required), deviceId, timeoutMs, stabilityMs.
get_current_screenA
Get the currently visible activity on an Android device. Returns package and activity name.
Inputs: deviceId.
get_debugger_capabilitiesB
Probe optional platform debugger prerequisites and matching running debuggable processes; does not attach.
Inputs: appId (required), deviceId (required), platform (required), processId, +2 more.
get_debugger_localsB
Read at most 100 shallow locals. Sensitive values returned only on request; strings truncate at 256 characters; iOS aggregates return type summaries. No evaluation or field traversal.
Inputs: stopId (required), frameId (required), debugSessionId (required), timeoutMs, +1 more.
get_debugger_stackB
Read bounded stack frames for a stopped thread; IDs expire on resume.
Inputs: stopId (required), threadId (required), debugSessionId (required), limit, +3 more.
get_debugger_stateC
Read debugger state, current stop and breakpoint/cleanup status.
Inputs: debugSessionId (required), timeoutMs, responseMode.
get_interaction_diagnosticsA
Read the retained original interaction or journey result without replaying input or observing the device. Pass diagnostics.session_id/result_id as sessionId/resultId. Session-local memory: ten minutes, 100 results, 16 MiB total, 1 MiB per result. Expired, evicted or restarted results are unavailable. May contain private UI text and errors; compact output is not redaction.
Inputs: resultId (required), sessionId (required).
get_logsA
Get recent logs from Android or iOS simulator. Returns device metadata and structured logs suitable for AI consumption. Returns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.
Inputs: platform (required), pid, tag, appId, +7 more.
get_network_activityA
Returns structured network events captured from platform logs since the last action.
Call this immediately after an action when you want backend evidence for a side-effect flow, only if the result is still ambiguous. Do not call more than once per action.
Events are filtered to significant (non-background) requests only. Each event includes endpoint, method, statusCode, networkError, status, and durationMs.
status values:
success: HTTP 2xx or request detected with no error signal
failure: HTTP 4xx
retryable: HTTP 5xx, network error (timeout, dns_error, tls_error, etc.)
Returns { requests: [], count: 0 } when no credible network signals are found.
Inputs: platform (required), deviceId.
get_screen_fingerprintB
Generate a stable fingerprint representing the current visible screen (activity + visible UI elements). Returns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.
Inputs: deviceId, platform, actionRef.
get_system_statusA
Quick healthcheck of local mobile debugging environment (adb, devices, logs, env, iOS).
Inputs: no named parameters.
get_system_trace_capabilitiesA
Probe Android Perfetto or iOS Instruments prerequisites without recording. iOS requires explicit booted simulator deviceId; reports template matrix and unknown profiling permissions.
Inputs: platform (required), appId, deviceId, template.
get_system_trace_statusC
Reconcile an owned trace and retrieve its state; finalise duration-completed capture.
Inputs: traceId (required).
get_ui_treeB
Get the current UI hierarchy from an Android device or iOS simulator. Returns a structured JSON representation of the screen content with snapshot metadata and incremental delta signals when available. Successful observations include snapshot_session_id and snapshot_revision for same-device conditional input. Compact errors preserve the error and cannot authorize an expectation. Returns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.
Inputs: platform (required), deviceId, actionRef, responseMode, +1 more.
install_appA
Install an app on Android or iOS. Accepts a built binary (apk/.ipa/.app) or a project directory to build then install. platform and projectType are required.
Inputs: appPath (required), platform (required), projectType (required), deviceId.
list_devicesA
List Android devices and iOS simulators. Supply appId for device-specific installation status; unknown checks do not imply absence.
Inputs: appId, platform.
press_backA
Purpose: Dispatch the Android Back action.
Inputs:
platform/deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = { key: "back" }
success = true when the back action was dispatched
failure_code/retryable when dispatch fails
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Call press_back
If needed, wait for transition using wait_for_*
Verify with expect_screen when a known destination is expected
If verification fails, retry once or recover explicitly
Verification Guidance:
Back outcomes can vary by screen, so verify against the intended destination when possible
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
Failure Handling:
TIMEOUT → retry once
UNKNOWN → capture a snapshot and stop
Conditional input: optionally supply expectedState { snapshotSessionId, snapshotRevision, timeoutMs? } from a successful get_ui_tree on the same explicit platform/deviceId. A fresh normalized UI-tree check runs immediately before input, even with verification disabled. PRECONDITION_FAILED or PRECONDITION_UNAVAILABLE means no input was dispatched; inspect condition evidence and re-observe before deciding what to do next. Compact failures summarize the fresh condition evidence; use get_interaction_diagnostics with the returned diagnostics reference for the retained UI tree. This is not atomic with OS input delivery. Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: deviceId, platform, responseMode, expectedState, +3 more.
read_log_streamB
Read accumulated log stream entries for the active session. Returns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.
Inputs: actionRef, sessionId.
remove_debugger_breakpointC
Remove an owned breakpoint; repeated removal succeeds.
Inputs: breakpointId (required), debugSessionId (required), timeoutMs, responseMode.
reset_app_dataA
Reset app data (clear storage) for a mobile app on Android or iOS simulator
Inputs: appId (required), platform (required), deviceId.
restart_appA
Purpose: Restart a mobile app on Android or iOS.
Inputs:
platform
appId
deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = { appId }
success = true when the restart command completed
failure_code/retryable when restart dispatch fails
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Define the expected landing screen when it is known
Call restart_app
If needed, wait for transition using wait_for_*
Verify with expect_screen
If verification fails, retry once or capture a snapshot
Verification Guidance:
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
expect_screen is the authoritative verification step when the reopened screen is known
Do not treat timing or screen change alone as final verification
Failure Handling:
TIMEOUT → retry once
UNKNOWN → inspect snapshot/logs before retrying Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: appId (required), platform (required), deviceId, responseMode, +3 more.
resume_debuggerC
Resume owned debugger suspension and immediately expire stopped references.
Inputs: stopId (required), debugSessionId (required), timeoutMs, responseMode.
run_journeyA
Run an ordered, bounded sequence of start_app, tap, wait, and deterministic assertion steps against one device. Stops after the first failed step. Tap steps may include expectedState from a successful same-device get_ui_tree. A failed condition blocks that input, retains fresh condition evidence through a diagnostics reference in compact mode, and stops subsequent steps. Conditions are not journey defaults or supported on other step types.
Inputs: steps (required), platform (required), defaults, deviceId, +3 more.
scroll_to_elementA
Purpose: Scroll until a target element becomes visible.
Inputs:
platform
selector
direction, maxScrolls, scrollAmount, deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = original selector
target.resolved = minimal resolved element info when found
success = true when scrolling produced a visible target element
failure_code/retryable when the target was not reached
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Resolve the target selector
Call scroll_to_element
If needed, wait for UI stabilization using wait_for_*
Verify with expect_element_visible when the expected element visibility is known
If success=false, follow failure handling before retrying
Verification Guidance:
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
Use expect_element_visible when you need an explicit post-scroll confirmation
Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
Failure Handling:
NAVIGATION_NO_CHANGE → adjust scroll direction or stop
TIMEOUT → retry with refined selector or larger scroll budget
UNKNOWN → capture a snapshot and stop Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: platform (required), selector (required), deviceId, direction, +6 more.
set_debugger_breakpointA
Set an exact source breakpoint: Android className or iOS absolute sourceFile (exactly one), plus line; unloaded classes/images remain pending. No silent line relocation.
Inputs: line (required), debugSessionId (required), className, timeoutMs, +2 more.
start_appA
Purpose: Launch a mobile app on Android or iOS.
Inputs:
platform
appId
deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = { appId }
success = true when launch was dispatched successfully
failure_code/retryable when launch dispatch fails
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Define the expected landing screen when it is known
Call start_app
If needed, wait for transition using wait_for_*
Verify with expect_screen
If verification fails, retry once or capture a snapshot
Verification Guidance:
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
expect_screen is the authoritative verification step when the landing screen is known
Do not treat timing or screen change alone as final verification
Failure Handling:
TIMEOUT → retry once
UNKNOWN → inspect snapshot/logs before retrying Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: appId (required), platform (required), deviceId, responseMode, +3 more.
start_log_streamB
Start streaming logs for a target application on Android or iOS. For Android this uses adb logcat --pid=; for iOS it streams xcrun simctl spawn <device> log stream with a predicate.
Inputs: packageName (required), level, deviceId, platform, +1 more.
start_system_traceA
Start bounded Android Perfetto or iOS simulator Time Profiler recording, returning an owned trace_id after readiness. iOS requires explicit deviceId and running appId. Run an existing journey with systemTraceId, then stop to retrieve a local artifact or cancel to discard. Traces can contain sensitive system metadata, logs and paths; local user-managed retention, no upload.
Inputs: platform (required), appId, deviceId, template, +1 more.
step_debuggerC
Acknowledge one-shot line stepping and resume. Wait for a subsequent stop event separately.
Inputs: kind (required), stopId (required), threadId (required), debugSessionId (required), +2 more.
stop_log_streamC
Stop an active log stream for the session.
Inputs: sessionId.
stop_system_traceB
Stop owned capture gracefully and retrieve a local Perfetto file or validated Instruments .trace bundle. Retry after a transfer/cleanup failure.
Inputs: traceId (required).
swipeA
Purpose: Dispatch a swipe gesture on Android or iOS.
Inputs:
start and end coordinates
duration
platform/deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = { x1, y1, x2, y2, duration }
success = true when the swipe was dispatched
failure_code/retryable when dispatch fails
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Determine swipe coordinates
Call swipe
If needed, wait for transition using wait_for_*
Verify with expect_screen or expect_element_visible when a deterministic outcome is expected
Verification Guidance:
Swipe outcomes are less predictable; choose the most specific verifier available for the intended effect
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
Failure Handling:
TIMEOUT → retry once
UNKNOWN → capture a snapshot and stop
Conditional input: optionally supply expectedState { snapshotSessionId, snapshotRevision, timeoutMs? } from a successful get_ui_tree on the same explicit platform/deviceId. A fresh normalized UI-tree check runs immediately before input, even with verification disabled. PRECONDITION_FAILED or PRECONDITION_UNAVAILABLE means no input was dispatched; inspect condition evidence and re-observe before deciding what to do next. Compact failures summarize the fresh condition evidence; use get_interaction_diagnostics with the returned diagnostics reference for the retained UI tree. This is not atomic with OS input delivery. Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: x1 (required), x2 (required), y1 (required), y2 (required), +8 more.
tapA
Purpose: Dispatch a tap at specific screen coordinates.
Inputs:
x, y coordinates
platform (optional)
deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = { x, y }
success = true when the tap was dispatched
failure_code/retryable when dispatch fails
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Resolve coordinates deterministically
Call tap
If needed, wait for transition using wait_for_*
Verify with expect_screen or expect_element_visible depending on the intended outcome
Verification Guidance:
Prefer tap_element over tap when an element can be resolved
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
Use expect_screen for navigation and expect_element_visible for local UI changes
Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
Failure Handling:
TIMEOUT → retry once
UNKNOWN → capture a snapshot and stop
Conditional input: optionally supply expectedState { snapshotSessionId, snapshotRevision, timeoutMs? } from a successful get_ui_tree on the same explicit platform/deviceId. A fresh normalized UI-tree check runs immediately before input, even with verification disabled. PRECONDITION_FAILED or PRECONDITION_UNAVAILABLE means no input was dispatched; inspect condition evidence and re-observe before deciding what to do next. Compact failures summarize the fresh condition evidence; use get_interaction_diagnostics with the returned diagnostics reference for the retained UI tree. This is not atomic with OS input delivery. Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: x (required), y (required), deviceId, platform, +5 more.
tap_elementA
Purpose: Tap a previously resolved UI element using its elementId.
Inputs:
elementId: a resolved UI element identifier returned by wait_for_ui
Output Structure:
action_id: unique timestamp-based action identifier
timestamp: ISO 8601 timestamp for the action attempt
action_type: "tap_element"
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector: original target handle ({ elementId })
target.resolved: minimal resolved element info used for the tap
success: true when the tap was dispatched
failure_code: present when success=false
retryable: present when failure_code exists
ui_fingerprint_before/ui_fingerprint_after: optional fingerprints captured around the action
Recommended Usage:
Resolve the target with wait_for_ui or another deterministic resolver
Call tap_element
If needed, wait for transition using wait_for_*
Verify outcome using expect_*
use expect_screen when navigation is expected
use expect_element_visible when the UI change is local
If verification fails, inspect failure_code and follow the retry strategy below
Verification Guidance:
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
Prefer expect_screen for navigation or modal transitions
Prefer expect_element_visible when the tap should reveal or update a specific element
wait_for_* may be used for resolution and synchronization, but not as the final verification step when an applicable expect_* tool exists
Do not treat tap_element.success as outcome success; it only means the tap was executed
Failure Handling:
STALE_REFERENCE → re-resolve the element, then retry
ELEMENT_NOT_INTERACTABLE → wait or refine the target, then retry
UNKNOWN → capture a snapshot and stop
This tool reports execution success only. Verification must be done with a separate expect_* tool.
Conditional input: optionally supply expectedState { snapshotSessionId, snapshotRevision, timeoutMs? } from a successful get_ui_tree on the same explicit platform/deviceId. A fresh normalized UI-tree check runs immediately before input, even with verification disabled. PRECONDITION_FAILED or PRECONDITION_UNAVAILABLE means no input was dispatched; inspect condition evidence and re-observe before deciding what to do next. Compact failures summarize the fresh condition evidence; use get_interaction_diagnostics with the returned diagnostics reference for the retained UI tree. This is not atomic with OS input delivery. Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: waitFor, deviceId, platform, selector, +6 more.
terminate_appC
Terminate a mobile app on Android or iOS simulator
Inputs: appId (required), platform (required), deviceId.
type_textA
Purpose: Type text into the currently focused Android input field.
Inputs:
text
platform/deviceId (optional)
Output Structure:
action_id, timestamp (ISO 8601), action_type
lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
source_module: runtime source of the action envelope
target.selector = { text }
success = true when text input was dispatched
failure_code/retryable when dispatch fails
ui_fingerprint_before/ui_fingerprint_after when available
Recommended Usage:
Resolve or focus the target input first
Call type_text
If needed, wait for UI stabilization using wait_for_*
Verify with expect_element_visible or expect_screen, depending on the intended outcome
Verification Guidance:
Prefer verifying the next expected element or screen state instead of inferring success from the text action alone
Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
Failure Handling:
TIMEOUT → retry once
UNKNOWN → re-focus the input or capture a snapshot
Conditional input: optionally supply expectedState { snapshotSessionId, snapshotRevision, timeoutMs? } from a successful get_ui_tree on the same explicit platform/deviceId. A fresh normalized UI-tree check runs immediately before input, even with verification disabled. PRECONDITION_FAILED or PRECONDITION_UNAVAILABLE means no input was dispatched; inspect condition evidence and re-observe before deciding what to do next. Compact failures summarize the fresh condition evidence; use get_interaction_diagnostics with the returned diagnostics reference for the retained UI tree. This is not atomic with OS input delivery. Compact results summarize observations, condition trees, state deltas and readiness probe evidence within a byte budget. Use get_interaction_diagnostics with the returned diagnostics session_id/result_id to retrieve the original result without replaying input. Debug output is unchanged. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: text (required), deviceId, platform, responseMode, +4 more.
wait_for_app_readyB
Wait within a single bounded budget for settled UI evidence. Reports loading, transitioning, settled or unknown with evidence and limitations. Managed Android and supported iOS simulator debugger pauses are reported from debugger evidence; unresponsive detection remains unsupported. Settled normalized foreground UI is not proof of app identity, responsiveness or backend completion. Results include device_readiness with timestamped device blocker evidence. Android reports supported power/keyguard signals; iOS signals may be unknown or explicitly unsupported. Launch/input dispatch success does not establish app visibility or input readiness. No automatic unlock or wake is performed.
Inputs: platform (required), deviceId, timeoutMs, stabilityMs, +1 more.
wait_for_debugger_eventC
Wait for bounded debugger events after a sequence cursor. Empty timeout does not affect execution; overflow is explicit.
Inputs: debugSessionId (required), timeoutMs, responseMode, afterSequence.
wait_for_screen_changeA
Purpose: Detect that a screen transition has occurred by waiting for the current fingerprint to differ from a previous fingerprint.
Capabilities:
Synchronization for uncertain navigation timing
Detection that something changed on screen
Constraints:
Does not verify correctness of the resulting state
Must not be used alone to confirm action success when an applicable expect_* tool exists
For backend/API activity without a visible UI change, pass the runtime action_type into classify_action_outcome and collect network evidence only if the result remains ambiguous
Recommended Usage:
Capture or define the expected outcome
Call an action tool
Use wait_for_screen_change when transition timing is uncertain
Follow with expect_screen when the expected destination is known
Inputs: previousFingerprint (required), deviceId, platform, timeoutMs, +1 more.
wait_for_uiB
Purpose: Resolve elements and/or detect that a UI transition or availability condition has occurred.
Capabilities:
Deterministic element resolution
Synchronization when element timing or availability is uncertain
Constraints:
Does not verify correctness of the resulting state
Must not be used alone to confirm action success when an applicable expect_* tool exists
Recommended Usage:
Use wait_for_ui to resolve an element before acting or to wait for UI readiness
Call the action tool
If the expected outcome is known, follow with expect_* as final verification Device-readiness blockers prevent readiness success; unknown/unsupported device signals remain explicit. Set requireReady=true to require both the existing predicate and settled UI readiness, using the same fresh samples and one timeout budget. The readiness summary explains uncertainty. Default predicate semantics are unchanged.
Inputs: match, retry, deviceId, platform, +5 more.
wait_for_ui_changeA
Purpose: Wait for a non-navigation UI mutation or in-place update to become stable.
Inputs:
expected_change (optional): hierarchy_diff, text_change, or state_change
timeout_ms (optional)
stability_window_ms (optional)
scope (optional): screen or subtree
target (optional): element_id when scope=subtree
Guidance:
Prefer wait_for_screen_change for navigation transitions.
Prefer wait_for_ui_change for in-place mutations and non-navigation updates.
Use the returned snapshot_revision as the observed synchronization point when available.
Scoped waits return scope-aware stability metadata and a lightweight change summary.
Failure Handling:
TIMEOUT means the UI did not change in a stable way within the allotted time. Device-readiness blockers prevent readiness success; unknown/unsupported device signals remain explicit. Set requireReady=true to require both the existing predicate and settled UI readiness, using the same fresh samples and one timeout budget. The readiness summary explains uncertainty. Default predicate semantics are unchanged.
Inputs: scope, target, deviceId, platform, +4 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 53 tools
Several tools have nearly identical purposes, especially get_app_readiness vs wait_for_app_ready, and wait_for_ui vs wait_for_ui_change vs wait_for_screen_change. find_element, wait_for_ui, and get_ui_tree also blur resolution/observation boundaries, making misselection likely despite long descriptions.
Tool names consistently use snake_case, mostly with a verb_noun pattern such as tap_element, start_app, get_debugger_stack, and stop_system_trace. Minor verb-only names like tap and swipe remain clear and internally consistent.
53 tools is far beyond a reasonable scoped surface and includes many overlapping wait/readiness/observation helpers. This is an extreme count mismatch for an agent toolset, increasing selection cost and coordination failure risk.
The surface covers app lifecycle, UI interaction, verification, debugger control, tracing, logs, screenshots, network evidence, build, and install. Minor gaps remain around installation cleanup, permission management, and device-level controls, but core workflows are well covered.
Maintenance
Related MCP Connectors
MCP server that lets your AI assistant build and deploy apps, hosting each one at a live URL.
MCP server for Appcircle mobile CI/CD platform.
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that enables AI assistants to build, test, and debug Android applications by interacting directly with the Android development environment. It provides tools for managing emulators, executing Gradle tasks, running ADB commands, and performing UI automation via accessibility trees.14105 npm19MIT
- AlicenseNot gradedqualityBmaintenanceMCP server and CLI for iOS development — build, test, automate, and diagnose from any AI agent or terminal.2MIT
- AlicenseAqualityDmaintenanceAn MCP server that gives AI agents full control of Android devices and emulators through plain ADB — no companion APK, no extra daemon, no telemetry.2614 npm12MIT
- FlicenseNot gradedqualityAmaintenanceMCP server that provides AI coding agents real Android development tools—Gradle, adb, logcat, lint, crash triage—through a local, permissioned interface. Enables agents to inspect projects, run safe Gradle tasks, capture logs/screenshots, and triage crashes.1-