scroll
Navigate app content in any direction or to top/bottom edges, repeating until a target selector becomes visible. Provides movement feedback and refuses when no progress is possible.
Instructions
Scroll in a direction, or toward the top/bottom edge of scrollable content. Set until to a selector to reach an off-screen target in one command rather than a scroll-and-check loop. The optional amount is the finger-path fraction of the viewport axis, honored up to 0.8 of it; directional scrolls reduce release momentum, while app scroll physics determine the final content offset. A visible keyboard shortens the swiped band instead of being dismissed; when too little is left, the command refuses with scroll_keyboard_occludes_surface. A directional scroll also reports the movement it observed as movement: moved, at-edge, unchanged, or unobserved when the two reads could not back a claim either way; an unchanged surface inside a container that still hides content in that direction refuses with scroll_no_progress rather than repeating the requested distance. The movement field is absent where a tier verifies per pass (top/bottom, until), where the runtime cannot read a screen, or where a settle observation or a replay already owns that observation. Times out after 90s; a caller-supplied budget extends it.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| udid | No | Apple device or simulator UDID; the selector that pins one device when several share a name. | |
| debug | No | Enable debug diagnostics. | |
| runId | No | Lease run identifier. | |
| until | No | Repeat scroll passes until this selector is visible on screen, then stop. Not valid with the top/bottom edge directions, which carry their own stop condition. | |
| amount | No | Platform scroll amount. | |
| device | No | Device name selector (a UDID belongs in udid, a serial in serial). | |
| pixels | No | Pixel scroll amount. | |
| serial | No | Android, HarmonyOS, or Vega VVD serial selector. | |
| settle | No | After the action, wait for the UI to go quiet and return the settled diff vs the pre-action tree in the same response. Best-effort; never fails the action. | |
| target | No | Alias for deviceTarget on commands without a UI target field. Interaction commands reserve target for the UI element. | |
| tenant | No | Remote tenant identifier. | |
| leaseId | No | Existing lease identifier. | |
| session | No | Agent-device session name. | |
| noRecord | No | Do not record this action. | |
| platform | No | Platform selector used to resolve a device. | |
| direction | Yes | ||
| timeoutMs | No | Settle: wait deadline in milliseconds (default 10000). | |
| durationMs | No | Scroll duration in milliseconds when the backend supports pacing. | |
| includeCost | No | Include per-command agent-cost (cost.wallClockMs, …) in structuredContent. Defaults to off; the default response shape is unchanged. | |
| deviceTarget | No | Device target form. Maps to the CLI --target flag. | |
| responseLevel | No | Response verbosity: token-cheap digest / default (today) / full. Defaults to default; the default response shape is unchanged. | |
| settleQuietMs | No | Settle: quiet window in milliseconds (default 500). | |
| mcpOutputFormat | No | MCP text content format. Defaults to optimized agent-friendly text; use json for JSON text. Structured content is always returned separately. | |
| androidDeviceAllowlist | No | Android serial allowlist used for device resolution. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| edge | No | ||
| until | No | Until scrolls only: the selector the passes stopped on. | |
| amount | No | ||
| passes | No | Edge and until scrolls only: how many scroll-and-check passes ran. | |
| pixels | No | ||
| settle | No | ||
| message | No | ||
| movement | No | Directional scrolls only: what the owner observed after its gesture. `moved` means the content inside the scroller the swipe ran in differs from the tree the session stored immediately before the gesture; `at-edge` and `unchanged` mean it did not change, with no hidden content left to reveal and with no end-of-content signal to read, respectively; `unobserved` means the pair could not back a claim in either direction — nothing comparable was available (no stored tree, a capture from another lineage, a surface that never came to rest), or every difference sits outside the scroller that was swiped, which a changing status bar does on Android — so the reported distance rests on the gesture plan alone. The field is absent — which is never a claim that nothing moved — on the tiers that verify per pass (`scroll top`/`bottom`, `--until`), on a runtime bound without a capture, on a platform whose scroll dispatches no swipe (the Linux wheel), and where the caller already owns that observation (`--settle`, or a replay with `postGestureStabilization: false`). | |
| direction | Yes | ||
| durationMs | No | ||
| keyboardMinY | No | Where the keyboard began, in the same unit as the gesture coordinates. Clipped scrolls only. | |
| keyboardAvoided | No | Present only when an on-screen keyboard forced the swipe into the band above it; the reported pixels were planned against the shorter referenceHeight. |