Skip to main content
Glama
mobile-debug-mcp

mobile-debug-mcp

tap_element

Taps a previously resolved mobile UI element by its elementId to trigger the intended interaction; verify the result with a separate expect_* check.

Instructions

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:

  1. Resolve the target with wait_for_ui or another deterministic resolver

  2. Call tap_element

  3. If needed, wait for transition using wait_for_*

  4. Verify outcome using expect_*

    • use expect_screen when navigation is expected

    • use expect_element_visible when the UI change is local

  5. 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.

Input Schema

NameRequiredDescriptionDefault
waitForNo
deviceIdNo
platformNo
selectorNo
elementIdNoA unique element identifier returned by wait_for_ui
responseModeNodebug
expectedStateNo
actionTimeoutMsNoDispatch budget in milliseconds, clamped to 100–30000.
verificationModeNofull
verificationTimeoutMsNoLight observation budget in milliseconds, clamped to 100–60000.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changedv0.34.0
    • addedInput schema / allOf
      Added value: +[
      +  {
      +    "if": {
      +      "required": [
      +        "expectedState"
      +      ]
      +    },
      +    "then": {
      +      "properties": {
      +        "deviceId": {
      +          "minLength": 1,
      +          "not": {
      +            "enum": [
      +              "booted",
      +              "default"
      +            ]
      +          },
      +          "pattern": "\\S",
      +          "type": "string"
      +        },
      +        "platform": {
      +          "enum": [
      +            "android",
      +            "ios"
      +          ]
      +        }
      +      },
      +      "required": [
      +        "platform",
      +        "deviceId"
      +      ]
      +    }
      +  }
      +]
    • addedInput schema / oneOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "selector"
      +      ]
      +    },
      +    "required": [
      +      "elementId"
      +    ]
      +  },
      +  {
      +    "not": {
      +      "required": [
      +        "elementId"
      +      ]
      +    },
      +    "required": [
      +      "selector"
      +    ]
      +  }
      +]
    • addedInput schema / properties / actionTimeoutMs
      Added value: +{
      +  "description": "Dispatch budget in milliseconds, clamped to 100–30000.",
      +  "type": "integer"
      +}
    • addedInput schema / properties / deviceId
      Added value: +{
      +  "type": "string"
      +}
    • addedInput schema / properties / expectedState
      Added value: +{
      +  "additionalProperties": false,
      +  "properties": {
      +    "snapshotRevision": {
      +      "maximum": 9007199254740991,
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    "snapshotSessionId": {
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    "timeoutMs": {
      +      "default": 15000,
      +      "maximum": 60000,
      +      "minimum": 100,
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "snapshotSessionId",
      +    "snapshotRevision"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / platform
      Added value: +{
      +  "enum": [
      +    "android",
      +    "ios"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / responseMode
      Added value: +{
      +  "default": "debug",
      +  "enum": [
      +    "compact",
      +    "debug"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / selector
      Added value: +{
      +  "properties": {
      +    "accessibility_id": {
      +      "type": "string"
      +    },
      +    "contains": {
      +      "type": "boolean"
      +    },
      +    "resource_id": {
      +      "type": "string"
      +    },
      +    "text": {
      +      "type": "string"
      +    }
      +  },
      +  "type": "object"
      +}
    • addedInput schema / properties / verificationMode
      Added value: +{
      +  "default": "full",
      +  "enum": [
      +    "none",
      +    "light",
      +    "full"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / verificationTimeoutMs
      Added value: +{
      +  "description": "Light observation budget in milliseconds, clamped to 100–60000.",
      +  "type": "integer"
      +}
    • addedInput schema / properties / waitFor
      Added value: +{
      +  "properties": {
      +    "condition": {
      +      "enum": [
      +        "exists",
      +        "visible",
      +        "clickable"
      +      ],
      +      "type": "string"
      +    },
      +    "match": {
      +      "properties": {
      +        "index": {
      +          "type": "number"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "pollIntervalMs": {
      +      "maximum": 1000,
      +      "minimum": 50,
      +      "type": "number"
      +    },
      +    "timeoutMs": {
      +      "maximum": 10000,
      +      "minimum": 100,
      +      "type": "number"
      +    }
      +  },
      +  "type": "object"
      +}
    • removedInput schema / required
      Removed value: -[
      -  "elementId"
      -]
  2. First observedv0.31.0

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, and the description carries the burden well: it warns that success means dispatch, not outcome, that delivery is not atomic with OS input, that no automatic unlock or wake occurs, and that expectedState triggers a fresh precondition check whose failure means nothing was dispatched. It stops short of documenting permissions, idempotency/repeat-tap behavior, or side effects on app state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Sectioned headers and numbered steps keep it navigable and the core guidance is front-loaded. However, it is long for one tool and repeats the same point twice ('Do not treat tap_element.success as outcome success' and 'This tool reports execution success only'), while the trailing compact/diagnostics and device_readiness paragraphs are dense boilerplate that dilutes the ranking of key constraints.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 10-parameter action tool with no output schema, the description supplies an exhaustive output-structure listing, failure handling, verification routing and diagnostics escalation — far more than typical. Completeness is only slightly undercut by the unmentioned waitFor/verificationMode/actionTimeoutMs parameters and the undocumented selector alternative.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 30% across 10 parameters, so the description must compensate and only partly does: it explains elementId, the expectedState conditional inputs and PRECONDITION_FAILED/PRECONDITION_UNAVAILABLE semantics, and compact-vs-debug responseMode. It is silent on waitFor, verificationMode, verificationTimeoutMs, actionTimeoutMs, platform/deviceId pairing, and the selector fallback path — and it implicitly contradicts the selector option by framing elementId as the only input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Tap a previously resolved UI element using its elementId') and scopes the target to a resolved handle. It does not, however, distinguish itself from the sibling 'tap' tool, and the schema's oneOf permits a raw selector in place of elementId, which the description never acknowledges.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit workflow (RESOLVE -> ACT -> WAIT -> EXPECT), names concrete alternatives (expect_screen vs expect_element_visible), states when wait_for_* must not be used as final verification, and maps each failure_code to a retry decision. The one missing routing cue is when to prefer tap_element over the plain 'tap' sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.