Argent
OfficialArgent is an agentic toolkit that gives AI assistants direct control over iOS simulators, Android emulators/devices, Apple TV, Android TV, Fire TV, Electron, and Chromium apps for autonomous mobile/desktop development, testing, and debugging.
Device Management
List, boot, and stop iOS simulators, Android emulators/physical devices, Chromium apps, and Vega (Fire TV) devices
Launch, restart, reinstall apps by bundle ID / package name
Open URLs or deep links within apps
UI Interaction
Tap, swipe, scroll, drag, pinch, rotate, and perform custom gesture sequences
Press hardware buttons (home, back, power, volume, etc.) and type text or named keys
Navigate TV interfaces via D-pad/remote controls (Apple TV, Android TV, Fire TV)
Set device orientation and run multiple interaction steps in a single call
Screen & UI Inspection
Capture screenshots and perform visual regression diffs (OCR-aware)
Inspect accessibility/DOM element trees with normalized tap coordinates
Wait for UI elements to appear, disappear, or contain text; wait for screen to stop animating
Access low-level native UIKit view hierarchies, find views by class/identifier/label, and hit-test at native coordinates (iOS)
Debugging & Diagnostics
Connect to JS runtimes (Hermes, V8) via CDP; evaluate arbitrary JavaScript in the live app
Inspect React Native component trees with source file/line info
View clustered console logs, reload the Metro bundle, and stop the Metro process
Capture network requests at both JS (
fetch) and native (NSURLProtocol) levels
Chromium / Electron
Manage tabs (list, switch, open, close) and handle cookies and localStorage/sessionStorage
Performance Profiling
Start/stop/analyze Hermes CPU profiling and React commit capture; query by component, time range, call tree, or render counts
Start/stop/analyze native profiling via Xcode Instruments (iOS) or Perfetto (Android)
Generate combined cross-correlated reports aligning React commits with native hangs; drill into hotspots, hang stacks, memory leaks, and thread breakdowns
Load previously saved profiling sessions from disk
Flow Recording & Replay
Record sequences of device interactions as reusable YAML flows, annotate with labels, define prerequisites, and replay them deterministically
Project & Workspace
Gather structured snapshots of project config (package.json, metro/babel config, CLI versions, CI config, etc.)
Maintenance
Apply or dismiss pending Argent version updates; manage telemetry settings
Provides AI agents with direct access to Android Emulators, enabling UI interactions (tapping, swiping, typing), running apps, and capturing logs and crash reports for debugging.
Enables AI agents to control iOS Simulators, perform gestures and hardware button actions, run profilers, and reproduce issues manually.
Offers native support for React Native apps, allowing agents to build, launch, and iterate on React Native projects with UI interaction and profiling capabilities.
Integrates with Xcode Instruments to perform and analyze profiling sessions on iOS apps, providing comprehensive summaries for performance optimization.
Click on "Install 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., "@Argentopen the iOS simulator and tap the login button"
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.
Argent is an agentic toolkit that gives your AI assistant direct access to iOS Simulators, Android emulators and physical devices, TVs (Apple TV, Android TV, Fire TV) and Electron/Chromium desktop and web apps. Ask it to tap a button, run a profiler or reproduce an issue manually - all from within your CLI, without switching context.
npx @swmansion/argent@latest init
# or, in a pnpm project (where npm's devEngines check may refuse to run npx):
pnpm dlx @swmansion/argent@latest initSupported platforms
Argent drives a growing set of targets through a single toolkit, each with the right interaction model - touch, remote or mouse:
Platform | Targets | Interaction |
iOS | Simulators and physical iPhones | Touch / gesture |
Android | Emulators (AVDs) and physical devices over adb | Touch / gesture |
TV | Apple TV (tvOS), Android TV / Google TV, Amazon Fire TV (Vega) | D-pad / remote |
Desktop & web | Electron and Chromium apps (incl. React Native Web / Expo web) over CDP | Mouse / keyboard |
Related MCP server: Maestro MCP Server
Capabilities
Autonomous mobile, TV and desktop development - Allow your agent to work with iOS, Android, TV and Electron/web apps on its own - let it build, open, interact with the app and debug it. Ask for reproducing issues, testing features manually, profiling your app and much more, without ever interrupting your work.
UI interaction - Give your agent the full control toolkit - tapping, swiping, pinching, typing, gestures and hardware buttons on mobile; the directional remote on TV; mouse, scroll and drag on desktop/web. Let it navigate your app exactly as a user would, without lifting a finger.
Record & replay flows - Capture a sequence of interactions once and let your agent replay it deterministically, so manual repros and smoke tests become repeatable.
Visual regression - Diff two screenshots (or a saved baseline against a live capture) with OCR- and font-aware comparison to catch unintended UI changes.
Profiling with batteries included - Argent can perform and analyze React Native (Hermes), React DevTools and native (Xcode Instruments / Android Perfetto) profiling sessions - down to fiber renders, CPU hotspots and cross-correlated commit-vs-hang reports. Get comprehensive summaries and ask to optimise your app where you find fit.
Debugging and diagnostics - Let your agent inspect logs, capture network traffic (JS
fetchand native), evaluate JS in the running app, walk the native UIKit and React component trees, and reproduce failing states - so you can jump straight to the fix.Desktop & web control - For Electron and Chromium apps your agent can drive tabs, read and write cookies and storage, walk the DOM and inspect network over the Chrome DevTools Protocol.
React Native out of the box - Argent works with React Native apps natively, so your agent can build, launch, and iterate on your RN project the same way it would any native app - no extra setup required.
Tip: Once installed, ask your assistant "What can Argent do?" - it will walk you through all capabilities available.
Installation
Prerequisites
Node.js 20.12 or later
For iOS / tvOS: macOS with Xcode installed (Apple TV uses tvOS simulators — Xcode downloads the tvOS runtime on demand)
For Android / Android TV: Android SDK Platform Tools (
adb) onPATH, and the Android Emulator package if you want to boot AVDs from Argent. Create AVDs via Android Studio oravdmanager.For Fire TV (Vega): the Vega SDK (
vegaCLI) onPATHFor Electron / Chromium: nothing extra to control an already-running app - just launch it with
--remote-debugging-port, or let Argent spawn your Electron app for you
Linux host: extra prerequisites for Android emulators
Argent runs Android emulators on Linux but the default install can be slow if a few host-side knobs aren't right. Cover these once and the experience matches macOS:
KVM access. The emulator falls back to slow software emulation (TCG) without
/dev/kvm. Make sure virtualization is enabled in BIOS/UEFI (vmxfor Intel,svmfor AMD in/proc/cpuinfo) and that your user can read/write/dev/kvm— on most distros that means joining thekvmgroup:sudo usermod -aG kvm "$USER" # log out and back in so the new group takes effectGPU mode (
-gpu swiftshaderon Linux, override available). The Android emulator's Linux GPU story is messy:-gpu autofrequently resolves to lavapipe (slow software Vulkan via host libvulkan, ~10× cold-boot regression on flagship hardware), and-gpu hostsilently produces a corrupted or black emulator window on hosts with non-trivial GL stacks — dual-GPU / Optimus laptops, NVIDIA + Mesa coexistence via libglvnd, Wayland sessions on hybrid graphics, headless / containerized hosts. The failure mode is invisible to argent's framebuffer-based screenshot tool, so an agent reports success while the developer sees a black window.Argent picks
-gpu swiftshaderon Linux for universal compatibility: it sidesteps the host GL stack entirely and renders via the emulator's bundled SwiftShader. On modern multi-core machines this is indistinguishably smooth from hardware-accelerated-gpu host(and far faster than lavapipe).Override with the
ARGENT_EMULATOR_GPU_MODEenv var if you've verified-gpu hostworks on your machine (typical single-GPU Mesa box with a healthy X session):ARGENT_EMULATOR_GPU_MODE=host argent ...Argent's boot-device preflight prints a warning if
/dev/kvmisn't usable — the condition that causes a 10–50× TCG-vs-KVM slowdown.System image. Prefer the
defaultorgoogle_apisvariants ofx86_64system images for headless agent workflows;google_apis_playstoreadds noticeable boot-time CPU churn from Play services. Always pickx86_64on Intel/AMD hosts — ARM images run via QEMU translation and are dramatically slower.AVD config. AVDs created via
avdmanager create avddefault tohw.gpu.enabled=no. Argent overrides this with an explicit-gpuarg at launch (so the on-disk config doesn't need editing). For the smoothest experience under heavy native builds (gradle compilations alongside the AVD), bump the AVD's RAM and CPU count — edit~/.android/avd/<name>.avd/config.ini:hw.ramSize = 8192 hw.cpu.ncore = 6 vm.heapSize = 512Stock 2 GB / 4 vCPU AVDs can be CPU-starved into wedged-system_server states by a concurrent gradle/Kotlin compile.
Headless / CI mode (
ARGENT_EMULATOR_NO_WINDOW=1). Argent shows the emulator window by default so a local developer can see the AVD UI. In a headless context — CI runner, container, or a Wayland-only session where the emulator's bundled Qt has nowaylandplatform plugin and SIGABRTs on the crash-consent dialog — opt out by exportingARGENT_EMULATOR_NO_WINDOW=1before starting the tool-server. This appends-no-windowto the spawn args, selectingqemu-system-x86_64-headlesswhich doesn't need a Qt window. Argent's screencap-based screenshot tool reads the in-memory framebuffer correctly without a visible window.
Run init in your project
From your project root:
npx @swmansion/argent@latest init
# or, in a pnpm project (where npm's devEngines check may refuse to run npx):
pnpm dlx @swmansion/argent@latest initThis command triggers an installation wizard which:
Installs
@swmansion/argentgloballyDetects your editor and registers the MCP server
Copies skills, rules, and agent definitions into your workspace
Prefer a manual install?
npm install -g @swmansion/argent
argent initShare Argent with your team (committable install)
By default Argent installs globally. To version Argent with your repo so every
teammate gets the same setup on npm install — no per-developer global install, no
argent init — choose the local mode:
npx @swmansion/argent@latest init --local
# or, in a pnpm project:
pnpm dlx @swmansion/argent@latest init --localNote: in a freshly
pnpm init-ed project,npxitself may refuse to run (npm'sdevEnginescheck) — use thepnpm dlxform there.
This adds @swmansion/argent to your project's devDependencies and writes MCP
configs that launch the project-local copy (node node_modules/@swmansion/argent/dist/cli.js mcp).
Commit package.json + your lockfile, the generated MCP config (.mcp.json,
.cursor/mcp.json, …), .argent/install.json, and the skills/rules/agents files.
Teammates then just run npm install.
Pass --global to force the default mode in scripts; --local and --global are
mutually exclusive. A non-interactive (--yes) run defaults to global unless the
project already opted into local mode (a committed .argent/install.json, or
@swmansion/argent declared in the project's own package.json).
In local mode the committed MCP config runs the project-local copy, so the bare
argentcommand is not on teammates'PATH. Note thatnpm installbuilds Argent's native deps (tree-sitter) on each machine — prebuilt for macOS, Linux x64, and Windows x64; other targets (Linux arm64, Windows arm) compile from source and need a C/C++ toolchain.
CLI Reference
Command | Description |
| Install and configure MCP in the current workspace ( |
| Alias for |
| Pull the latest version and refresh workspace configuration (acts on the present install — both when a global install and a project devDependency coexist; |
| Unregister the MCP server and uninstall the package ( |
| Alias for |
| Start MCP server instance, used internally by agent |
| List tools exposed by the tool-server ( |
| Invoke a tool by name |
| Manage the shared tool-server: |
| Open Argent Lens bound to a fresh coding-agent session — Claude by default, |
| Route client requests to a remote tool-server |
| Remove the persisted remote tool-server link |
| Enable a predefined feature flag ( |
| Disable a feature flag ( |
| List available feature flags and their state |
| Inspect and manage external device providers: |
| Manage telemetry: |
Supported Editors
argent init auto-detects and configures MCP for:
Editor | Config location |
Claude Code |
|
Cursor |
|
VS Code |
|
Windsurf |
|
Zed |
|
Gemini CLI |
|
Codex CLI |
|
Hermes |
|
opencode |
|
Kiro |
|
Privacy
Argent collects opt-out usage and diagnostic telemetry to help us prioritise features and fix what breaks.
You can opt out at any time:
argent telemetry disable # check status with: argent telemetry statusFor the full details — see the Argent Privacy Notice (Telemetry).
License
Argent uses a mixed licensing model.
Source code is released under the Apache License 2.0.
Proprietary binaries (the per-platform bin/<platform>/simulator-server and bin/darwin/ax-service executables and the .dylib files in native-devtools-ios) are the intellectual property of Software Mansion S.A. and are licensed solely for use within this project. Decompiling, reverse-engineering, or redistributing them without explicit written permission is prohibited.
By using Argent, you acknowledge and agree to this structure. See LICENSE for full details.
Argent is created by Software Mansion
Since 2012 Software Mansion is a software agency with experience in building web and mobile apps. We are Core React Native Contributors and experts in dealing with all kinds of React Native issues. We can help you build your next dream product – Hire us.
Available Tools
75 toolsawait-screen-idleA
Block until the screen has rendered content and stopped changing, or a timeout elapses.
Polls the same accessibility / DOM tree as describe every pollIntervalMs (default 200ms) until it
has content and that content holds identical for minStableMs (default 250ms), or timeoutMs (default
3000ms) is reached. Returns { settled, waitedMs, polls } — settled=false means the screen never went
still before the timeout. Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id). | |
| timeoutMs | No | Max time to wait for the screen to settle before giving up (default 3000). | |
| minStableMs | No | The screen must hold the same content for at least this long to count as settled (default 250). | |
| pollIntervalMs | No | How often to re-read the tree (default 200). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses polling behavior, thresholds, return object fields (settled, waitedMs, polls), and explains that settled=false means timeout reached. It also references the same tree as 'describe'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is efficient (~100 words), well-structured with purpose first, then mechanism and usage advice. No superfluous text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains return value thoroughly. Complex tool with 4 parameters all covered. Sufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining default values, roles of each parameter, and the polling mechanism shared with 'describe'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool blocks until screen content settles or timeout, using a specific verb 'Block until' and resource 'screen content settled'. It distinguishes itself from siblings like 'describe' and 'await-ui-element'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'Use after a launch/navigation to wait for the UI to render before screenshotting or tapping', providing clear when-to-use context. No explicit when-not, but the context is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
await-ui-elementA
Block until a UI element reaches an expected state or a timeout elapses, so you don't have to poll screenshot/describe yourself.
Conditions:
exists — the selector matches an element anywhere in the tree.
visible — the selector matches an element with a non-zero on-screen frame.
hidden — the selector matches nothing, or only a zero-area element (e.g. a spinner that disappeared).
text — the first VISIBLE match in reading order (topmost, then leftmost; falling back to the first match
overall if none is visible) contains expectedText (case-insensitive substring), or exactly matches
it when textMatch is equals. A loose selector can match several elements; only that one is
inspected, so if a different match is the one holding the text the wait still reports failure —
narrow the selector to target it.
The selector is { text?, identifier?, role? }; every provided field must match. text and role match as
case-insensitive substrings of the element's label/value and role; identifier matches exactly (case-insensitive),
also accepting the unqualified Android resource-id name ('submit' matches 'com.example.app:id/submit').
It polls the same accessibility / DOM tree as describe
(iOS simulator AXRuntime, physical-iOS runner snapshot, Android uiautomator, Chromium CDP,
Vega automation toolkit) every pollIntervalMs
(default 400ms) until timeoutMs (default 5000ms).
Returns { success: boolean, elapsed: number, note?, cause? } — success=false means the wait ended without the
condition holding, which is not always a verdict on the condition: cause says which it was — unmet (the tree
was read and the condition was false there), unreadable (no trustworthy read, so nothing was judged) or
cancelled — and note describes what was seen. Only unmet licenses rewriting the check. Use this after a
tap/navigation to wait for the next screen, or before tapping an element that appears asynchronously.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id). | |
| bundleId | No | Optional iOS app bundle id, passed to the describe fallback (see `describe`). Ignored on Android / Chromium, and on physical iOS. | |
| selector | Yes | Element to match (text / identifier / role). | |
| condition | Yes | What to wait for. `exists`: selector is anywhere in the tree. `visible`: selector is present with a non-zero on-screen frame. `hidden`: selector is absent or zero-area. `text`: the first visible match in reading order (topmost), falling back to the first match overall if none is visible, contains (or, with textMatch `equals`, exactly matches) expectedText — if a loose selector hits several elements, only that one is checked, so narrow it to target the intended element. | |
| textMatch | No | For condition `text`: how expectedText is compared. `contains` (default) is a case-insensitive substring; `equals` is a case-insensitive full-string match. | |
| timeoutMs | No | Max time to wait for the condition before giving up (default 5000). | |
| expectedText | No | For condition `text`: the string the first visible matched element (topmost in reading order; the first match overall if none is visible) must contain (default) or equal — see `textMatch`. Case-insensitive. | |
| pollIntervalMs | No | How often to re-check the tree (default 400). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it delivers: it explains polling intervals, defaults, return shape, and the crucial nuance that success=false is not always a verdict on the condition, with cause values of unmet, unreadable, and cancelled. It also discloses selector matching pitfalls, reading order, hidden zero-area semantics, and the underlying accessibility/DOM sources. This is exemplary behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with headings and front-loaded purpose. Some condition details are repeated from the schema, which adds length, but the additional context about selector resolution, failure causes, and polling justifies most of the content. It is dense but organized enough for an agent to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 8 parameters, a nested selector object, multiple conditions, and no output schema or annotations, the description is remarkably complete. It explains the return value shape, failure semantics, when a failure licenses rewriting the check, and even the environmental tree types. There are no critical gaps that would prevent correct use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial meaning beyond the schema: it explains reading order for visible text matches, the loose-selector trap, the unqualified Android resource-id matching behavior, and the exact meaning of each condition. It clarifies expectedText and textMatch behavior contextually rather than merely restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Block until a UI element reaches an expected state or a timeout elapses.' It clearly distinguishes itself from polling screenshot/describe by stating it removes that need, and the conditions section further defines exact behavioral scope. This is much more than a tautology and stands apart from sibling tools like describe and await-screen-idle.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The final sentence gives explicit usage guidance: 'Use this after a tap/navigation to wait for the next screen, or before tapping an element that appears asynchronously.' It also explicitly contrasts with polling screenshot/describe yourself. It does not formally enumerate when not to use it or name all sibling alternatives like await-screen-idle, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
boot-deviceA
Start an iOS simulator, launch an Android emulator, start a Vega (Fire TV) Virtual Device, or spawn an Electron app and wait until it is ready to accept interactions. Pick the platform by which argument you pass: 'udid' for an iOS simulator from list-devices, 'avdName' for an Android AVD (a serial is assigned automatically), 'vvdImage' for a Vega VVD (the 'vvdImage' of a vega device from list-devices, e.g. 'tv'), or 'electronAppPath' for an Electron app (a CDP remote-debugging port is picked automatically, or pass 'electronPort' to fix one). Use at the start of a session once you have picked a target. Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted } or { platform: 'vega', serial, vvdImage, booted } or { platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device). Android boots take 2–10 minutes depending on machine and cold/warm state; the tool transparently hot-boots from the AVD's default_boot snapshot when usable and falls back to cold boot otherwise. Vega starts the single SDK-managed VVD via the vega CLI (~10s) and returns once it reports running. If an Android/Electron boot stage fails, the tool terminates the device it spawned so the next retry starts clean.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | No | iOS: simulator UDID to boot (from `list-devices`). Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`. | |
| force | No | Shut down and re-boot the device even if already running. | |
| sound | No | Android only: boot the emulator with audio output enabled. Defaults to false — argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega/Electron, which argent never mutes. | |
| avdName | No | Android: AVD name to launch a new emulator from (from `list-devices` → `avds[].name`). Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`. | |
| headless | No | iOS only: boot the simulator core WITHOUT opening the Simulator.app GUI window. The device still streams via simulator-server; used by Argent Lens. Set the `ARGENT_SIMULATOR_NO_WINDOW` env var (1/true/yes) to force this host-wide without passing the flag per call (the iOS analog of `ARGENT_EMULATOR_NO_WINDOW`). Ignored on Android/Vega/Electron, which have no equivalent GUI step. | |
| vvdImage | No | Vega (Fire TV): VVD image to boot — the `vvdImage` of a Vega device from `list-devices` (e.g. `tv`). Starts the single SDK-managed Vega Virtual Device. Provide exactly one of `udid`, `avdName`, `vvdImage`, or `electronAppPath`. | |
| electronArgs | No | Electron-only: extra CLI arguments forwarded to the Electron binary after the app path. | |
| electronPort | No | Electron-only: CDP remote-debugging port to expose. Defaults to a free port; the resulting device id is `chromium-cdp-<port>`. | |
| bootTimeoutMs | No | Android/Vega: overall budget for the boot sequence. Default 480000 (8 min) on Android, 120000 (2 min) on Vega. Clamped to [30s, 15min]. Ignored on iOS. | |
| electronAppPath | No | Electron: path to the Electron app to launch. Either a packaged .app bundle / executable, or a project directory whose package.json points the Electron binary at the entry script. Mutually exclusive with udid/avdName. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full behavioral burden and does so thoroughly. It discloses that the tool waits until the target is ready, returns a tagged payload, can take 2–10 minutes on Android, hot-boots from snapshots with cold-boot fallback, and terminates spawned devices on Android/Electron boot failure. This is unusually rich operational transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although long, the description is dense and well structured: core action first, then platform selection, usage timing, return shapes, and operational caveats. Every sentence carries information needed to invoke the tool correctly, and the critical selector rule is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex four-platform tool with 10 parameters, no annotations, and no output schema, the description is complete. It explains return payloads for every platform, mutual exclusivity of platform-selector parameters, boot durations, snapshot behavior, and failure cleanup. The schema handles remaining platform-specific parameter details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds cross-parameter meaning by explaining that the passed argument selects the platform, that Android assigns a serial automatically, and that a CDP port is auto-picked unless electronPort is supplied. This is more than a per-field schema listing provides centrally.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: start an iOS simulator, launch an Android emulator, start a Vega VVD, or spawn an Electron app. It also explains that each platform is selected by a specific argument, which makes the tool's purpose distinct from siblings like list-devices and launch-app.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: 'Use at the start of a session once you have picked a target.' It also explains that the choice of platform is determined by which argument is passed. However, it does not explicitly name when-not-to-use cases or contrast with post-boot tools like launch-app or restart-app.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
buttonA
Press a device hardware button (iOS simulator or physical device, Android emulator or device). iOS simulators send a Down then Up event automatically; Android injects a single adb key event.
Supported buttons depend on the platform: home, back, power, volumeUp, volumeDown, appSwitch, actionButton; buttons not present on the target platform (e.g. 'back' on iOS, 'actionButton' on Android, 'power' or 'appSwitch' on a physical iPhone) are rejected with a clear error.
Use when you need to trigger hardware button events.
Returns { pressed: buttonName }.
Fails if the device backend is not reachable: the simulator-server for iOS, or adb for Android (Android presses are injected with adb shell input keyevent).
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| button | Yes | Hardware button to press |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the behavioral burden. It discloses platform-specific event injection behavior (iOS Down/Up vs Android adb keyevent), unsupported-button rejection, the return value shape, and failure conditions when the backend is unreachable. This is exceptionally transparent for a tool with no annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but every sentence earns its place: platform behavior, supported buttons, usage intent, return value, and failure modes. It is front-loaded with the core action and structured logically, making it easy for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema and no annotations, the description covers return format, failure conditions, platform specifics, and supported values. Given the moderate complexity of this tool, nothing essential is missing for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the schema already describes both parameters with useful descriptions. The description goes beyond the schema by explaining platform-specific meaning of the button enum, which buttons are rejected on which platforms, and how the press is actually injected. This adds genuine value beyond the structured field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Press') and resource ('device hardware button'), with platform scope explicitly covered. It clearly distinguishes itself from sibling gesture and keyboard tools by focusing on hardware buttons and even gives platform-specific examples.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit usage sentence: 'Use when you need to trigger hardware button events.' It also clarifies platform-dependent behavior and which buttons are rejected, giving practical guidance. It does not explicitly mention alternatives like gesture-tap or keyboard, but the hardware-button focus makes the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chromium-cookiesA
Read and write cookies of a Chromium (CDP) app (via the Network domain, so HttpOnly cookies are included).
action="get" (url?): list cookies, optionally restricted to given URLs (defaults to the active page).
action="set" (name, value, + url OR domain, optional path/secure/httpOnly/sameSite/expires): create or update a cookie.
action="delete" (name, + url/domain/path): remove a matching cookie.
action="clear": remove ALL browser cookies. Use when seeding an authenticated session before a flow (set the session cookie, then navigate) or asserting cookie state after one. Returns { cookies, count } for get, or a small status object ({ set } / { deleted } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing name/value. Chromium-only.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | get: restrict to these URLs (defaults to the active page). set/delete: scope the cookie by URL. | |
| name | No | set/delete: cookie name. | |
| path | No | set/delete: cookie path (default /). | |
| udid | Yes | Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`). | |
| value | No | set: cookie value. | |
| action | Yes | get: read cookies. set: create/update a cookie. delete: remove a named cookie. clear: remove all browser cookies. | |
| domain | No | set/delete: scope the cookie by domain (alt to url). | |
| secure | No | set: mark Secure. | |
| expires | No | set: expiry as a Unix timestamp (seconds). Omit for a session cookie. | |
| httpOnly | No | set: mark HttpOnly. | |
| sameSite | No | set: SameSite policy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It discloses that HttpOnly cookies are included, the actions are destructive (e.g., 'clear removes ALL browser cookies'), and failure cases (non-Chromium device, missing params). It also describes return values for each action. Missing details on idempotency or rate limiting, but covers major behaviors.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear introduction, bulleted action list, usage guidance, return types, and failure conditions. It is front-loaded with the core purpose. A minor reduction for length, but every sentence serves a purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 11 parameters, 4 actions, no output schema, and no annotations, the description covers purpose, usage, parameter roles by action, return values, and failure conditions. It lacks details about the format of returned cookie objects, but overall provides sufficient context for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by grouping parameters per action (e.g., 'action="get" (url?)... defaults to the active page'), which provides context beyond the schema's individual parameter descriptions. It clarifies which parameters apply to which actions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read and write') and resource ('cookies of a Chromium (CDP) app'), and enumerates four distinct actions (get, set, delete, clear). It clearly distinguishes the tool's scope from siblings like 'chromium-storage' which handles other storage types.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool: 'Use when seeding an authenticated session before a flow... or asserting cookie state after one.' It also notes Chromium-only requirement and failure conditions. However, it does not mention alternative tools for related tasks (e.g., localStorage), leaving some ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chromium-storageA
Read and write localStorage / sessionStorage of a Chromium (CDP) app's active page.
action="get": with
key, returns that value; withoutkey, returns all entries.action="set" (key, value): write an entry.
action="remove" (key): delete an entry.
action="clear": empty the store. Set
storeto "local" or "session". Storage is per-origin, so it reflects the active tab's document. Use when seeding feature flags / auth tokens before a flow or asserting persisted app state after one. Returns { value } for a single key, { entries, count } for all, or a status object ({ set } / { removed } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing key/value. Chromium-only.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | get (optional) / set / remove: the storage key. | |
| udid | Yes | Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`). | |
| store | Yes | Which Web Storage area: `local` (localStorage) or `session` (sessionStorage). | |
| value | No | set: the value to store. | |
| action | Yes | get: read one key (with `key`) or all entries. set: write `key`=`value`. remove: delete `key`. clear: empty the store. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so description covers all behavioral traits: lists actions, return values, failure conditions (non-CDP, missing keys), per-origin scope. Comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet points, front-loaded main purpose, no fluff. Each sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description fully explains return shapes for all actions, constraints (Chromium-only), and failure reasons. Complete for a 5-param, 4-action tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage 100% with descriptions. Description adds return format details and action behaviors beyond schema, e.g., value vs entries+count, status objects.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Read and write localStorage/sessionStorage of a Chromium (CDP) app's active page.' Specific verb and resource, distinct from siblings like chromium-cookies or chromium-tabs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when seeding feature flags / auth tokens before a flow or asserting persisted app state after one.' Provides context but no explicit when-not-to-use or alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
chromium-tabsA
List and switch the tabs / windows of a Chromium (CDP) app (an Electron app's BrowserWindows or a Chromium browser's tabs), and open or close them.
action="list": enumerate page targets with stable ids (
t1,t2, …), title, url, and which is active.action="select" (tab=<tabId|label>): make that tab the active one. The active tab is what describe / gesture-tap / screenshot / debugger-evaluate / open-url all operate on, so switch before driving a different tab.
action="new" (url?, label?): open a new tab/page and activate it.
action="close" (tab?=<tabId|label>): close a tab (defaults to the active one); if the active tab is closed, another live tab becomes active. Use when an app exposes multiple windows or tabs and you need to inspect or drive one other than the current page, or to open/close a page during a flow. tabIds are stable for the session and never reused. Returns { tabs: [{ tabId, targetId, title, url, active, label? }] }. Fails if the device is not a Chromium (CDP) device, or the requested tabId/label no longer matches a live tab. Chromium-only.
| Name | Required | Description | Default |
|---|---|---|---|
| tab | No | Target tab for `select` / `close`: a tabId like `t2` or a label. `close` defaults to the active tab. | |
| url | No | `new` only: URL to open (defaults to about:blank). | |
| udid | Yes | Chromium device id from `list-devices` (e.g. `chromium-cdp-9222`). | |
| label | No | `new` only: a memorable label usable interchangeably with the tabId. | |
| action | Yes | list: enumerate tabs/windows. select: make a tab active (every other tool then acts on it). new: open a tab. close: close a tab. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses all behavioral traits: actions, tab stability, default active tab, closure behavior, return format, and failure cases. No annotations so description carries full burden, which it meets thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet points for each action, clear and efficient language. Every sentence adds value, no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: all four actions, preconditions, return value, failure modes, and Chromium-only restriction. No output schema, but return structure is described. Complete for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds valuable context such as tabId stability, label interchangeability, and default for close. Exceeds baseline of 3 by providing extra information beyond schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it lists, switches, opens, and closes tabs/windows of a Chromium (CDP) app, distinguishing from sibling tools by specifying the target platform and actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance on when to use (multiple windows/tabs, to inspect/drive a different page, open/close during flow) and failure conditions. Does not explicitly mention alternatives but context is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-component-treeA
Fetch the current screen of a running React Native app as a compact component text tree. Only shows on-screen components with unique positions — off-screen (scrolled) content, full-screen transparent wrappers, and implementation-detail components are pruned.
Each visible component is listed with its name, text content, and normalized tap coordinates in [0,1] space (fractions of the screen, not pixels — same space as tap/swipe/gesture).
This is the preferred element discovery tool for React Native apps. More information in argent-react-native-app-workflow skill.
Workflow:
Call this tool to get the component tree.
Find the desired element by name, text, testID, or accessibilityLabel.
Use the (tap: x,y) coordinates directly with the tap tool.
Call again after navigation or state changes since positions may shift. Set includeSkipped=true to see a summary of all filtered components. Use when you need tap coordinates for a React Native UI element. Returns a compact text tree with (tap: x,y) coords. Fails if Metro debugger is not connected.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| maxNodes | No | Maximum total nodes to include. When exceeded, intermediate single-child wrapper chains are collapsed to preserve both root structure and leaf elements. Default: no limit. | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). | |
| onScreenOnly | No | When true (default), only components visible on screen are returned. Set to false to include all mounted components including those scrolled off-screen. Useful when you need to understand the full page structure. | |
| includeSkipped | No | When true, appends a summary of all filtered components: total fiber count, JS-side skip counts by name, and TS-side filter pass removals. Useful for understanding what was pruned from the tree. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses pruning of off-screen components, normalized coordinates in [0,1], and failure condition (Metro debugger not connected). No annotations exist, so description carries full burden—adequate but could mention potential performance impact or other constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Information is front-loaded with clear structure including workflow steps. Some redundancy (last sentence echoes earlier points), but overall efficient and well-organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers tool purpose, output format (text tree with coordinates), workflow, and failure case. No output schema needed as description explains what is returned. Adequate for a read-only diagnostic tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and all parameters are well-described in the schema. Description reinforces usage context (e.g., includeSkipped) but does not add significant new meaning beyond what schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it fetches the current screen as a compact component text tree with tap coordinates, distinguishes from siblings by being the preferred element discovery tool for React Native apps, and notes pruning behavior.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a detailed workflow and explicit use case (getting tap coordinates), advises re-calling after navigation/state changes, and mentions includeSkipped option. Lacks explicit when-not-to-use or comparison to all alternatives but is clear overall.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-connectA
Connect to a JS runtime CDP debugger. iOS / Android / Vega: connects to Metro's CDP endpoint on the given port. Chromium: re-uses the page CDP session opened by boot-device — port is ignored. Returns connection info including port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), and isNewDebugger. If already connected, returns the existing connection. Use when starting a debug session or before calling other debugger-* tools. Fails if the runtime is unreachable (Metro down, or Chromium CDP terminated).
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port (ignored for Chromium — its CDP port is encoded in device_id) | |
| device_id | Yes | Device id from list-devices: iOS simulator UDID, Android serial, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>). Pass this SAME id as device_id to every subsequent debugger-* call to pin them to this device. The returned logicalDeviceId is informational (Metro's own per-connection handle, absent on Vega); you do not switch to it — forwarding it still resolves here, but the list-devices id is the stable one. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It explains idempotent behavior (returns existing connection if already connected), platform-specific differences, and failure modes. Could mention if any state is mutated, but overall transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with core purpose, then structured by platform. Each sentence adds value. Slightly verbose but efficient for the complexity. Could be more concise, but still well-organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description thoroughly explains return fields, failure conditions, and the tool's role relative to siblings. Covers platform differences and id usage, leaving no major gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds value: explains that 'port' is ignored for Chromium and provides extra context for 'device_id' (stable id, logicalDeviceId informational). This goes beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Connect to a JS runtime CDP debugger.' It details platform-specific behaviors (iOS/Android vs Chromium) and distinguishes from siblings by being the prerequisite for other debugger-* tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when starting a debug session or before calling other debugger-* tools.' It also mentions failure conditions (Metro down, CDP terminated). Lacks explicit 'when not to use' but context implies it's the initial step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-evaluateA
Execute arbitrary JavaScript in the app's JS runtime via CDP — Hermes on iOS / Android / Vega, V8 on Chromium. Returns the evaluation result as a JSON-serializable value, along with deviceName, appName, and logicalDeviceId for context. Use when you need to read app state, call app functions, or test logic at runtime. The result is serialized by value, so cyclic objects (many RN runtime values — fiber nodes, navigation refs, global — are cyclic) fail with a serialization error rather than returning silently. Fails if the expression throws or the runtime is not connected.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port (ignored for Chromium) | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id. | |
| expression | Yes | JavaScript expression to evaluate in the app runtime |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It details runtime environments (Hermes, V8), that results are serialized by value, that cyclic objects cause a serialization error (not silent), and that evaluation fails if the expression throws or runtime is not connected. It does not explicitly clarify whether evaluation is read-only or can have side effects, but the caveats are useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two paragraphs: first states purpose and return, second lists caveats. It is front-loaded with the main verb and resource. Slightly lengthy but no wasted words, and all information is relevant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given three parameters and no output schema, the description covers return value (JSON-serializable plus deviceName, appName, logicalDeviceId) and failure modes. It does not mention expression length limits, timeouts, or security restrictions, but for a development tool this is sufficient. Sibling tools are not compared, but overall completeness is adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%. The description adds value beyond the schema: for device_id it clarifies it is the same id from list-devices or debugger-connect, preferring list-devices. For port, it notes it is ignored for Chromium. Expression parameter description is redundant with schema but consistent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool executes arbitrary JavaScript in the app's runtime via CDP, specifying the engine per platform (Hermes on iOS/Android/Vega, V8 on Chromium). It lists specific use cases: read app state, call functions, test logic, and describes the return value. This distinguishes it from sibling tools like debugger-status or debugger-component-tree.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides usage guidance: 'Use when you need to read app state, call app functions, or test logic at runtime.' It also mentions limitations (cyclic objects fail). However, it does not explicitly state when not to use this tool or suggest alternatives among the many sibling tools, which would improve clarity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-inspect-elementA
Inspect the React component hierarchy at a screen coordinate (x, y). Returns components from the tapped element upward through its parent hierarchy, each with its source file:line and a code fragment.
The first items (lowest indices) are the most specific — the exact component under the tap point and its direct parents. Higher indices are broader context (page, navigator). Default shows 35 items which covers all app-specific code; use maxItems=70+ to also see the navigation/screen structure.
Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate. Set resolveSourceMaps to false to skip symbolication and get raw bundled locations instead. Set includeSkipped=true to see filtered items annotated with skip reasons. Use when you need the source file and line for a component at a tap coordinate. Fails if the app is not connected or the coordinate is outside the screen.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Logical X coordinate on device screen | |
| y | Yes | Logical Y coordinate on device screen | |
| port | No | Metro server port | |
| maxItems | No | Maximum number of hierarchy items to return, counted from the bottom (most specific component first). The hierarchy walks from the tapped element up to the root — the first items are the most relevant for editing. Increase to 70+ if you need to understand the broader navigation/screen structure. | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). | |
| contextLines | No | Lines of source context to include around the component definition | |
| includeSkipped | No | When true, items that would normally be filtered are kept in the response with skipped=true and a skipReason. Useful for understanding what was pruned. | |
| resolveSourceMaps | No | When true, resolves bundled frame locations to original source files via Metro symbolication and includes a code fragment. When false, returns the raw bundled frame info (file, line, column) without symbolication or source reading. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden. It discloses internal mechanisms ('Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate') and explains behavior of parameters like maxItems and resolveSourceMaps. It does not explicitly state read-only nature but implies no mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately concise with multiple paragraphs, but each sentence serves a purpose. Front-loaded with the core function, then details. Could be slightly tighter but not overly verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully explains return value: 'components... each with its source file:line and a code fragment', including hierarchy ordering. It also covers failure conditions, parameter effects, and internal details. Comprehensive for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds significant value beyond schema, explaining the ordering of returned items ('first items are most specific') and the purpose of maxItems (covers app-specific code vs navigation structure). This justifies a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Inspect the React component hierarchy at a screen coordinate (x, y)' with a specific verb and resource. It differentiates from siblings by focusing on React component inspection via coordinates, unlike tools like native-view-at-point or debugger-component-tree.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes 'Use when you need the source file and line for a component at a tap coordinate' and 'Fails if the app is not connected or the coordinate is outside the screen'. While explicit about when to use and failure conditions, it does not mention specific alternatives or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-log-registryA
Get a summary of all console logs captured from the app's JS runtime. Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android / Vega) and V8 (Chromium). Use when investigating warnings, errors, or unexpected output — call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet — but check { note }, which is present only when the stats are empty BECAUSE a stop-all-simulator-servers tore the previous debugger session down and deleted its log file. Absent that note, empty really does mean the app has logged nothing. When the debugger cannot be reached, this tool does not fail: it returns { status: "not_connected", reason, detail, guidance } with NO log file — follow the guidance (do not retry in a loop, and do not try to read a log file from this state). A "connected" result's stats may come from a session whose socket has since died — use debugger-status, not this tool, to judge debugger health.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port (ignored for Chromium) | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It details return contents (path, counts, clusters), empty-state semantics including the note about stop-all-simulator-servers, the not_connected response shape with guidance, and the dead-socket caveat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but information-dense, covering many edge cases. It is front-loaded with core purpose, though the single-paragraph format is dense. Every sentence earns its place given the lack of annotations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description thoroughly explains return values, error states, and caveats, providing a complete picture for an agent to use the tool correctly and know when to choose alternatives.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides thorough descriptions for both parameters (port and device_id), including the Chromium ignore and device-id preference. The description adds no new parameter semantics beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Get a summary of all console logs captured from the app's JS runtime.' It clearly distinguishes from sibling network-log tools by scoping to console logs and mentions supported runtimes (Hermes/V8).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is provided: 'Use when investigating warnings, errors, or unexpected output — call this first for an overview.' It also names an alternative: 'use debugger-status, not this tool, to judge debugger health,' and warns against retry loops when not connected.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-reload-metroA
Restart the Metro JS bundle in the connected React Native app without restarting the native process. Use when you want to apply code changes or reset JS state. Returns { reloaded, port, method, deviceName, appName, logicalDeviceId } indicating which reload path was used and which device/app was targeted. Fails if Metro is not running on the given port.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description covers key behaviors: no native restart, failure condition if Metro not running, and return fields. Missing potential side effects like state reset, but implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three well-structured sentences: purpose, use-case, then return/failure conditions. No redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Explains return shape, failure conditions, and usage context. Distinguishes from siblings like 'restart-app' and 'stop-metro'. Complete for its complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already describes parameters (100% coverage). Description adds essential usage context for 'device_id' (must match debugger-connect's id), adding value beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verb 'Restart' and noun 'Metro JS bundle', clearly differentiating from sibling tools like 'restart-app' (whole app restart) and 'stop-metro' (stop, not reload).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'apply code changes or reset JS state'. Does not explicitly state when not to use, but context is clear given siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
debugger-statusA
Get JS runtime debugger connection status and diagnostic info. Use when you need to verify connectivity before using other debugger tools. Never fails when the runtime is simply unreachable — it returns a discriminated result instead:
{ status: "connected", ... } with port, projectRoot (empty on Chromium and on legacy Metro, e.g. Vega), deviceName, appName, logicalDeviceId (absent on Vega), isNewDebugger (false on the legacy inspector), connected flag, loadedScripts count, and sourceMapReady (always true — waits for pending source maps before returning; no-op on Chromium).
{ status: "not_connected", connected: false, reason, detail, guidance } (port omitted on Chromium) when Metro is not running (reason "metro_not_running"), no app is attached ("no_app_connected"), the device_id matches no target ("device_mismatch"), the CDP endpoint is unreachable or answered malformed ("cdp_unreachable"), the runtime accepted the connection but never answered ("runtime_unresponsive"), the cached connection went stale ("stale_connection"), or a reconnect is in flight ("reconnecting"). Follow the guidance field — do not retry in a loop.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port (ignored for Chromium) | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden, and it delivers excellently. It discloses that the tool never fails when the runtime is unreachable but returns a discriminated result, enumerates all failure reasons, and explains nuances like 'sourceMapReady always true - waits for pending source maps' and 'port omitted on Chromium.' This is far beyond basic expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly long but well-structured with bullet-like enumeration of result variants. It opens with a concise summary of purpose and usage, then dives into necessary detail. Every sentence contributes value, though the length is on the upper edge, making it not a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must fully explain return values, and it does so thoroughly. It covers the connected and not_connected variants, all failure reasons, optional fields, and important behavioral details. For a tool with this complexity, the description is remarkably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage with detailed descriptions for both parameters, including the relationship to debugger-connect and preference for list-devices id. The tool description adds no additional parameter-level semantics beyond the schema, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('Get') and resource ('JS runtime debugger connection status and diagnostic info'). It distinguishes this tool from sibling debugger tools (debugger-connect, debugger-evaluate) by focusing specifically on status/connectivity verification.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when you need to verify connectivity before using other debugger tools,' providing clear context. It also advises following the 'guidance' field and not retrying in a loop, but does not explicitly mention when not to use or alternatives, which would make it a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describeA
Get the accessibility / DOM element tree for the current screen.
On iOS, uses the AXRuntime accessibility service to inspect whatever is currently visible — including
system dialogs, permission prompts, and any foreground app content. On a physical iOS device the tree
covers only the app registered by launch-app. On Android, runs uiautomator dump.
On Chromium, walks the renderer's DOM via Chrome DevTools Protocol — every visible element with its ARIA
role, accessible name, and bounding rect (normalized to 0–1).
On Vega (Fire TV), reads the on-device automation toolkit (getPageSource); each element carries
[focused]/[selected] so you can see where the D-pad cursor is, then move it with the tv-remote tool
(Vega is remote-driven, not touch). If describe returns an empty tree on Vega, relaunch the foreground
app (the toolkit attaches at launch) and try again.
When a system dialog is visible, describe returns the dialog's interactive elements (buttons, text)
with tap coordinates. When no dialog is present, it returns the foreground app's accessible elements.
On a physical iOS device, launch-app com.apple.springboard first to read system dialogs.
Returns { description, source } where description is a text rendering of the UI tree — one
line per element with its role, label/value/id, interactivity flags, and frame. Frame coordinates
are normalized [0,1] fractions of the screen / window width/height (not pixels) — the same space as
gesture-tap / gesture-swipe / gesture-pinch.
To tap an element use the centre of its frame: tap_x = frame.x + frame.width / 2,
tap_y = frame.y + frame.height / 2. The same formula appears in the response header so it
can be applied to a line in isolation.
The tree carries no z-order or occlusion information: an element listed at a point may be covered
by an overlay (e.g. a toolbar over list rows), so check a screenshot when a tap lands unexpectedly.
For app-scoped inspection with full UIKit properties (accessibilityIdentifier, viewClassName), use native-describe-screen with an explicit bundleId instead (iOS simulator only). For React Native apps, debugger-component-tree returns React component names with tap coordinates.
On a TV target (Apple TV / Android TV — a list-devices entry with runtimeKind 'tv') this returns
the focus-driven view instead: the currently FOCUSED element and the list of FOCUSABLE elements,
since a TV UI has no tap coordinates. Move the highlight with tv-remote (up/down/left/right/select/
back/menu/home), then call describe again to confirm where focus landed.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id). | |
| bundleId | No | Optional app bundle ID. Used as a target hint on iOS when the AX-service returns no elements and the describe tool falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on Android / Chromium, and on a physical iOS device. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does so thoroughly. It discloses platform-specific implementation details, coordinate normalization, lack of z-order/occlusion information, Vega's empty-tree retry behavior, TV focus-driven output, and the physical iOS device limitation. It also explains the return shape { description, source } and how to compute tap coordinates.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place given the multi-platform complexity. It is front-loaded with the core purpose, then organized by platform, return format, caveats, and alternatives. There is no redundant filler or restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no output schema and no annotations, so the description must fully compensate. It covers platform-specific behaviors, return format, coordinate system, tap calculation, limitations, fallback suggestions, and sibling alternatives. Nothing an agent needs to invoke and interpret this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The main description does not add much parameter-specific meaning beyond the schema, but the schema itself already documents udid and bundleId, including bundleId's fallback behavior and platform limitations. Thus the description adds no significant extra value here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get the accessibility / DOM element tree for the current screen.' It then clarifies what this means across iOS, Android, Chromium, and Vega, and explicitly distinguishes itself from native-describe-screen and debugger-component-tree, so an agent can select it correctly among many siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: use native-describe-screen for app-scoped UIKit inspection, use debugger-component-tree for React Native component names, and use tv-remote on TV targets. It also provides platform prerequisites such as launching com.apple.springboard before reading system dialogs on physical iOS devices.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dismiss-updateA
Clear the Argent update notification for the given number of hours. Use when the user asks to postpone or silence update reminders. Returns { message } confirming the suppression duration. Fails if the hours value is negative or the suppression state cannot be persisted.
| Name | Required | Description | Default |
|---|---|---|---|
| hours | Yes | Number of hours to suppress the update notification |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses return value format, failure conditions (negative hours, persistence failure), and the side effect of suppressing notifications. Adequate for a state-changing tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with action, no unnecessary words. Every sentence adds value, making it highly concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one parameter, no output schema, and no nested objects, the description covers purpose, usage, behavior, and failure conditions completely. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with description for 'hours' including minimum and purpose. The description adds 'given number of hours' and 'suppression duration', but does not provide new meaning beyond what the schema already states. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Clear the Argent update notification', which is a specific verb+resource. It defines the tool's action well but does not explicitly differentiate from siblings like 'update-argent', though the purpose is clear and distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Use when the user asks to postpone or silence update reminders.' It does not list alternatives or when not to use, but the context is clear and the failure conditions are noted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow-add-echoA
Record an echo step in the flow named by name + project_root. Echo steps print a message when the flow is replayed — useful as labels between tool calls.
Use when you want to annotate a recorded flow with a human-readable label or checkpoint message.
Returns { message, stepCount, savedTo }. Fails if that flow has no recording in progress.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the flow being recorded — the one passed to flow-start-recording. | |
| message | Yes | Message to echo when the flow is replayed | |
| project_root | Yes | Absolute path to the project root of the flow being recorded — the same value passed to flow-start-recording. Together with `name` it identifies which recording this echo belongs to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the return shape ({ message, stepCount, savedTo }) and the failure condition (no recording in progress). It also explains the side effect of echoing a message when replayed. Absent are details about mutations to the flow file, but the behavior is adequately characterized.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: it states the purpose in the first sentence, then provides usage guidance, return information, and failure condition in a few sentences. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for this tool's complexity: it explains what the tool does, when to use it, what it returns, and a key error condition. Even without an output schema, the return shape is explicitly stated, making the tool's behavior fully comprehensible in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage, with each parameter described (name, project_root, message). The description's mention that `name` + `project_root` identifies the flow is already embodied in the project_root schema. Thus the description adds no significant semantic value beyond the schema, matching the baseline for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Record an echo step in the flow named by `name` + `project_root`' and explains that echo steps print a message on replay, distinguishing it from flow-add-step. It is specific and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: 'Use when you want to annotate a recorded flow with a human-readable label or checkpoint message.' It also notes the failure condition when no recording is in progress. However, it doesn't explicitly name alternatives like flow-add-step, so it stops short of a full alternatives comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow-add-stepA
Execute a tool call and record it as a step in the flow named by name + project_root (the recording must already be open — see flow-start-recording). Use when recording a flow and you want to run and capture each action. A coordinate gesture-tap is recorded as a portable tap: { selector } step when the tapped element has stable text/identifier (otherwise coordinates are kept with a warning); a restart-app is recorded as a launch step (record one FIRST to make the flow a self-contained e2e flow; restart-app has no chromium support, so a chromium flow records as a fragment — add the launch: { chromium: <app path> } line to the YAML afterward, deleting the executionPrerequisite line if one was recorded: a flow that starts with a launch must not declare it).
A recorded await-ui-element that PASSED is re-probed against the tree the RUNNER resolves await:/assert: directives against, which is NOT the tree the live call read; a wait that came back { success: false } is not probed at all, and its warning says so; when the condition does not hold there the step is still recorded and message carries a warning to read before converting — whether the conversion actually breaks depends on WHY the two disagree, since a screen that moved on between the live wait and the re-probe reads the same way. If that tree could not be read at all, the warning says so instead: the conversion is UNKNOWN, not known-bad. The probe judges the selector exactly as recorded, so write the conversion in the strict map spelling ({ visible: { text: Continue } }, copying the step's selector:) — the bare-string spelling ({ visible: Continue }) re-parses as a loose selector that resolves identifier-first and falls back to text, which is a different check. message also warns when the live wait itself came back { success: false } — that tool reports a failed wait by returning rather than throwing, so the step is recorded either way. That warning names the cause, because only one of them judges the condition: a genuine miss will stop the run at replay, while a wait whose tree source was unreadable, or one that was cancelled, observed nothing and leaves the condition UNKNOWN.
Returns { message, toolResult, stepCount, recorded, savedTo } on success — message is Step added to "<name>" flow plus any warning about what was recorded (read it; a warning never means the step was skipped). If it fails an error is returned and nothing is recorded. Two calls SUCCEED while recording nothing, and omit recorded to say so: a command naming a recording tool, and one naming a flow-file directive rather than a tool. Both answer with what to do instead — usually the call to make (the tool that records that directive, or the recording tool called directly), but wait, long-press, scroll-to, snapshot and when have no recording tool, so those name no call and say what to record or add by hand in its place. Either way nothing runs at the device and the take is left untouched — read recorded, not the status, to know whether a step was appended.
If a step was recorded by mistake, remove it from the .yaml after flow-finish-recording rather than during the recording: against a remote client the in-memory copy is authoritative and every write serializes it over your edit, and in host mode a mid-recording edit renumbers the steps, which costs the finish the cross-tree verdicts anchored to them.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Tool arguments as a JSON string, e.g. '{"udid": "ABC", "x": 0.5, "y": 0.3}'. Omit for tools with no arguments. | |
| name | Yes | Name of the flow being recorded — the one passed to flow-start-recording. | |
| command | Yes | MCP tool name (e.g. "gesture-tap", "screenshot", "launch-app") — a TOOL, not a flow directive. A flow-file directive name ("tap", "launch", "run", "type", "await", "assert", "pinch", "swipe", "echo", "wait", "long-press", "scroll-to", "snapshot", "when") is answered with guidance, and nothing runs or is recorded: most name the tool that records the directive, while "wait", "long-press", "scroll-to", "snapshot" and "when" have no recording tool at all and are answered with what to do instead. A recording tool (flow-add-step, flow-add-echo, flow-start-recording, flow-finish-recording) is refused the same way, each for its own reason — nesting one would erase this flow at replay, end the take, or write the step twice. | |
| delayMs | No | Milliseconds to sleep before executing this step during replay. | |
| project_root | Yes | Absolute path to the project root of the flow being recorded — the same value passed to flow-start-recording. Together with `name` it identifies which recording this step belongs to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description must fully disclose behavior, and it does: gesture-tap conversion to tap, restart-app to launch, await-ui-element re-probing against a different tree, returned fields, the two success-with-no-recording cases, and the warning semantics. It even covers mid-recording edits and remote vs host mode.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is accurate and front-loaded, but it is extremely long and dense, with nested clauses and repeated warnings. It would benefit from bullets or segmented edge-case sections; the current monolithic paragraphs make it easy to miss the core while parsing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating recording tool with no annotations and no output schema, the description is remarkably complete: it states success return shape, error behavior, when `recorded` is omitted, what to do for directives, and how to undo a mistaken step. Nothing an agent needs to safely decide and invoke the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description goes beyond the schema by detailing command-specific recording behavior for gesture-tap, restart-app, and await-ui-element, and by explaining that `name`+`project_root` jointly identify the recording. It does not add much on args/delayMs, but those are already well documented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Execute a tool call and record it as a step in the flow', and it anchors the flow identity to `name` + `project_root`. This clearly distinguishes it from recording siblings like flow-start-recording and flow-add-echo.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states 'Use when recording a flow and you want to run and capture each action', and it instructs the agent to see flow-start-recording if no recording is open. It also delineates when a call is refused (directives, recording tools) and even lists directives with no recording tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow-executeA
Run a saved flow from the .argent/flows/ directory, or an explicit boundary-managed flow_path.
Use when a scenario is already authored as YAML and the whole of it should replay in one call with a
per-step verdict; reach for the individual gesture tools when nothing is authored yet, and for
run-sequence when the steps are an ad-hoc list rather than a stored flow.
Steps run in order: launch starts an app from scratch (terminate + relaunch) and waits until it is
ready (on iOS it also pins later element lookups to that app rather than auto-detecting the frontmost
one); tool calls dispatch through the registry (a raw tool step ends that iOS pin, so lookups
auto-detect again until the next launch, though a tool that cannot change the foreground app leaves the
launched id as a fallback for a timed-out auto-detect, and launch-app/restart-app leave the id they
started as that fallback instead); tap/long-press/type resolve a selector to an
element and act on it (tap: { on, times: 2 } double-taps; long-press: { on, duration } presses and
holds; tap/long-press alternatively take a raw normalized point — bare { x, y } or on: { x, y };
any selector may scope its matches geometrically, the CSS combinators read off frames: within: <selector>
(descendant — inside that container's frame), after: <selector> (CSS ~ — following it in reading
order), next: <selector> (CSS + — the nearest such follower, which unlike CSS reaches past a
non-matching neighbour rather than failing), plus any: true (CSS * — legal only WITH a scope and
never beside text/id/role). Scopes nest to disambiguate — within: { id: card, within: { id: list } }
reads "inside card inside list", each container's frame inside the next);
swipe performs one finger flick (swipe: left, or swipe: { from?, direction|to|by, momentum?, duration? } —
direction is the FINGER's travel, the opposite sense of scroll-to's content direction; by: { x?, y? } — signed
0–1 screen fractions, combined length at least 0.03 (a diagonal clears it where neither axis does); duration in ms,
default 300, minimum 150, maximum 10000; each bound is a parse error that rejects the file before any step runs;
momentum: false lands exactly where the finger lifts instead of flinging);
scroll-to scrolls (momentum-free) until a target is visible; pinch zooms
(pinch: { on?, scale } — scale > 1 in, < 1 out; screen center when on is omitted); rotate is the
two-finger rotation gesture (rotate: { on?, by } — degrees, + clockwise, within ±3000°; screen center
when on is omitted; distinct from the rotate tool, which changes device orientation); await waits
for a UI condition, and additionally takes the one condition that has no selector: idle: true waits
until the screen has content and stops moving in BOTH the UI tree and the rendered pixels (it never
fails a run — a screen that never settles passes carrying a warning, which is what makes it safe to
persist; the one idle outcome that does stop the run is an error for a tree source THIS step could not
read at all — a broken window rather than a verdict about the app, which leaves the run not-ok and skips
every later step; it says nothing about WHICH screen settled — a dropped tap leaves the source screen
perfectly idle — so pair it with the element check that names the destination); wait pauses for a fixed number of milliseconds; assert checks one now; snapshot
diffs a screenshot — or, with cropOn: <selector>, one element's cropped region — against a stored
baseline (a missing baseline fails the step — set updateBaselines to adopt the current screen; a
cropped element whose size drifted fails on dimensions); echo annotates; run executes another flow
inline — a YAML path resolved against the directory of the flow file that references it (co-located
runs only).
A selector-less gesture — a coordinate tap/long-press/swipe, or a pinch/rotate with no on — resolves
no frame out of the tree, so an unreadable tree source does NOT stop it the way it stops idle: it
settles best-effort, dispatches anyway, and the step PASSES carrying a warning that quotes the source's
own error. That green says the gesture was SENT, not that it landed. Restore the tree source (usually
relaunch the app so the instrumentation loads), or accept the warning where the app can serve no tree;
the first such gesture proves the outage and later ones spend that verdict without paying the settle
window again. A tree read that comes back, or a relaunch, retires that verdict — which only makes the
next gesture pay a fresh window, and it warns again if the source is still down.
A when: block (condition + steps:, no else) runs its steps only if the condition holds —
checked once with the short assert grace — for one-sided divergences like interstitials and coach
marks; a skipped block reports distinctly and failures inside an entered block are real failures.
A flow that begins with a launch step is a self-contained e2e flow; one that doesn't runs against the
device's current state. Device id is injected by the runner (flows store none) — pass device or
platform to pick one, else the single booted device is used. On Chromium a launch step's value is an
Electron app path ({ chromium: | { path, args } }) the runner boots (on the tool-server host) rather
than an installed app id it relaunches. With no explicit device, a run whose leading launch is
unambiguously chromium (platform: chromium, or a lone { chromium: … } target) boots that app and
starts there — following a leading run:, so a fragment that composes a chromium e2e flow boots too;
otherwise the first launch attaches to an already-running instance and never kills it. Every later
launch — a nested e2e flow's own, or a mid-flow relaunch — boots a fresh instance the run moves onto;
an instance the run already owns for that same app is killed first (its exit awaited) so the
replacement can't lose the race against its single-instance lock. Instances the runner still owns at
run end are torn down then. A launch declaring no id for the run's platform is an error, not a cue to
switch platforms. Every step hard-stops the flow on failure; later steps are reported as skipped.
Returns a structured report ({ flow, device, executionPrerequisite, ok, aborted?, passed, failed,
skipped, errored, steps }) — device is the device the run STARTED on; when launches moved it onto
runner-booted instances, each names its instance in that step's reason and marks the move — run moved off <id>, or retired <id> (same app relaunched) when the instance it left was the one killed —
a relaunch that retired an older owned instance names both.
If a fragment has an execution prerequisite and prerequisiteAcknowledged is not set to true, the tool returns a notice with the prerequisite instead of running. Pass exactly one flow source: name for a saved flow under project_root, or flow_path for an explicit YAML — both together, or neither, fails the call.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name of a saved flow to run from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set. | |
| device | No | Device id to run against (iOS UDID, Android/Vega serial, Chromium id) — the id list-devices reports. Auto-detected when omitted, but only when exactly one booted device matches (optionally narrowed by `platform`); with several booted the run fails and lists them, so pass this explicitly whenever more than one device is up. | |
| platform | No | Restrict auto-detection to this platform when several devices are booted. `chromium` does more than filter: with no `device` it SELECTS the self-boot branch for an e2e flow - the runner boots an Electron instance from the `launch` step's chromium value and tears it down after the run (a single-key `launch: { chromium: … }` map selects it on its own, without this parameter). When it selects that branch it never falls back to device auto-detection (a fragment, or an e2e launch map with no `chromium` key, still does), and the launch value must be a real Electron app path on the tool-server host: a bare-string `launch:` - what the recorder writes - holds an installed-app bundle id, so passing `chromium` for one fails the whole run with `Electron boot: path does not exist`. Edit the launch to `{ chromium: <app path> }` first. | |
| flow_file | No | Path to the flow .yaml as readable by the tool-server. Internal — the argent client derives it from project_root and name automatically; leave unset. | |
| flow_path | No | Omit when name is set. Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. For remote execution, pass name + project_root instead. | |
| project_root | Yes | Absolute path to the calling agent's project root — the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the flow, its run: siblings, and baselines all resolve beside the YAML instead, so pass the agent's cwd. | |
| updateBaselines | No | Write/refresh screenshot baselines for `snapshot` steps instead of diffing against them. | |
| prerequisiteAcknowledged | No | Set to true to confirm the execution prerequisite has been met. Required (LLM path) when a fragment defines an executionPrerequisite. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden—and it delivers. It discloses execution order (launch, tool, tap, swipe, scroll-to, etc.), side effects (iOS pinning, instance teardown, baseline updates), failure semantics (hard-stop, skipped later steps), and the exact structure of the returned report. It even explains edge cases like how selector-less gestures handle unreadable tree sources and how warnings differ from errors. This is exceptional behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but the tool is exceptionally complex—8 parameters, many step types, many edge cases. It is front-loaded with the primary use case and then systematically walks through each step kind. Some sentences are densely packed and use nested parentheticals that could be easier to parse, but every sentence adds factual content; there is no filler. For the complexity, this level of detail is justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must explain return values—and it does: "Returns a structured report ({ flow, device, executionPrerequisite, ok, aborted?, passed, failed, skipped, errored, steps })" plus details on device field semantics. It also covers prerequisites, device selection, chromium-specific behavior, and error conditions. Given the tool's complexity and the absence of an output schema, the description is fully complete for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, yet the description still adds substantial meaning beyond the schema. It clarifies that device auto-detection only works when exactly one booted device matches, that platform=chromium selects a self-boot branch with fallback rules, that project_root resolves flow files/baselines differently depending on name vs flow_path, and that updateBaselines alters snapshot behavior. These operational details are not fully captured in the schema property descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states precisely what the tool does: "Run a saved flow from the .argent/flows/ directory, or an explicit boundary-managed flow_path." It names the resource (flows, YAML) and the action (run), and later distinguishes itself from siblings by saying to use individual gesture tools when nothing is authored and run-sequence for ad-hoc lists. This is a clear, specific description that an agent can act on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool versus alternatives: "Use when a scenario is already authored as YAML and the whole of it should replay in one call... reach for the individual gesture tools when nothing is authored yet, and for run-sequence when the steps are an ad-hoc list rather than a stored flow." It also provides rules for choosing between name and flow_path, and warns about the prerequisiteAcknowledged flow. This leaves no ambiguity about invocation context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow-finish-recordingA
Finish recording the flow named by name + project_root, leaving recordings under any other key untouched. Returns { message, path, executionPrerequisite, steps, summary, flowFile, savedTo } - a summary of all recorded steps plus the final YAML. Use when you have added all desired steps and want to finalize the flow file. Fails if that flow has no recording in progress.
A warning flow-add-step raised on a recorded await-ui-element is repeated in summary as a warning: line of its own, right below the step it judges, and message counts them by kind. A warning is repeated only while the step it judges is still identifiable by its number: hand-editing the .yaml during the recording moves the steps, so those warnings are DROPPED rather than pinned on whichever step inherited the number, and message says how many were dropped. A step that carries a cross-tree warning was re-probed against the runner's tree: read it before converting that wait to await:/assert:, which is what the verdict is about and what this moment is for. A step that recorded a wait which did not pass was never probed at all, and its own warning names the CAUSE, because only one of them judges the condition: an unmet wait was read and found false, and it stops the run at replay; a wait whose tree source could not be read, or one that was cancelled, observed nothing and leaves the condition UNKNOWN rather than known-bad. Read those before replaying.
You can still edit the .yaml file directly afterwards to remove or reorder steps.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the flow being recorded — the one passed to flow-start-recording. | |
| project_root | Yes | Absolute path to the project root of the flow being recorded — the same value passed to flow-start-recording. Together with `name` it identifies which recording to finish. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavior, and it does so thoroughly. It explains side effects (leaving other recordings untouched), the return shape, failure conditions, and the nuanced warning propagation/dropping behavior for hand-edited YAML, cross-tree warnings, unmet waits, and UNKNOWN conditions. It even notes that the YAML can still be edited afterward.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but dense, with no filler. Core purpose, return value, and usage guidance are front-loaded in the first paragraph, while the later paragraphs explain important warning and replay semantics that genuinely affect how the result should be interpreted. It could be tightened, but every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of annotations, and the absence of an output schema, the description is remarkably complete. It covers the return keys, the failure condition, the subtle warning behavior, what to read before replaying, and the option to edit the YAML afterward. An agent has enough context to invoke the tool and interpret the result correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides full descriptions for both parameters, with 100% coverage. The description reinforces that `name` and `project_root` together identify the recording and must match the values passed to flow-start-recording, but this adds only marginal meaning beyond the schema's own wording. Schema coverage does the heavy lifting here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Finish recording the flow named by `name` + `project_root`' and distinguishes this from related recording tools by stating it finalizes the flow and returns the recorded steps plus final YAML. It also gives the exact use case: 'Use when you have added all desired steps and want to finalize the flow file.' This clearly separates it from siblings like flow-add-step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: after all desired steps have been added and the flow file should be finalized. It also states a precondition/failure mode: 'Fails if that flow has no recording in progress.' It does not explicitly enumerate alternatives or when-not-to-use cases, but the usage context is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow-read-prerequisiteA
Read the execution prerequisite of a flow without running it — a saved flow from the .argent/flows/ directory, or an explicit boundary-managed flow_path.
Returns { flow, executionPrerequisite }: the logical name, plus the precondition its author recorded
verbatim. Empty when none was declared, which is always so for a self-contained scenario: one opening
on a launch may declare no prerequisite, because it builds its own start state.
Use when deciding whether the device already sits where a fragment expects it (correct app foregrounded,
correct account, correct screen) before committing to a run, or when relaying that requirement to a human.
Touches no device: nothing is launched, tapped, dispatched or torn down, and no simulator or emulator
needs booting, so calling this costs nothing but a file read.
Fails if the flow file does not exist.
Address the flow exactly as you will address it in flow-execute: name or flow_path, one and only one; supplying both or neither is rejected. The name goes in name, which resolves /.argent/flows/.yaml.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Name of a saved flow to inspect from `.argent/flows` (e.g. "settings-explore"). Omit when flow_path is set. | |
| flow_file | No | Path to the flow .yaml as readable by the tool-server. Internal — the argent client derives it from project_root and name automatically; leave unset. | |
| flow_path | No | Omit when name is set. Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. Pass the same flow source here as to flow-execute, so the prerequisite you read belongs to the flow that will run; for remote reads, pass name + project_root instead. | |
| project_root | Yes | Absolute path to the calling agent's project root — the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the prerequisite is read from that YAML instead, so pass the agent's cwd. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it does so thoroughly. It discloses the return shape, the empty-result behavior when no prerequisite is declared, the fact that no device is touched, that no simulator/emulator needs booting, that it is just a file read, and that it fails if the file does not exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and logically ordered, with no filler, but it is somewhat dense and repeats the name/flow_path distinction and the flow location. These repetitions reinforce important constraints, so the slight redundancy costs only one point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description covers all essential context: what is returned, what empty means, what a prerequisite represents, failure behavior, cost/risk profile, and parameter constraints. An agent can decide whether to call it and construct a correct call without needing extra information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, but the description adds critical cross-parameter semantics: name and flow_path are mutually exclusive, supplying both or neither is rejected, name resolves under project_root/.argent/flows/, and flow_path must be supplied through the file-input boundary. This materially improves correct invocation beyond the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and object: 'Read the execution prerequisite of a flow without running it', and clearly scopes the resource to a saved flow from .argent/flows/ or a boundary-managed flow_path. It also distinguishes itself from siblings by repeatedly stressing that executing the flow is not what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use it: before committing to a run, to check whether the device is already in the expected state, or to relay a precondition to a human. It ties addressing to flow-execute ('Address the flow exactly as you will address it in flow-execute'), giving the agent a clear alternative and preventing misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
flow-start-recordingA
Start recording a new flow, resetting .argent/flows/.yaml to an empty flow and replacing any existing one.
Use when you want to capture a reusable sequence of device interactions for later replay.
Returns { message, flowFile, savedTo } and optionally { restarted, discardedSteps } if a live recording of the same flow was discarded.
Whether this server writes that file depends on where your project is: co-located, it creates it and fails if the .argent/flows/ directory cannot be created or the file cannot be written; against a remote tool-server it writes nothing and savedTo is a directive your client applies (a null savedTo back means it did not).
Several flows can be recorded at once — each keyed by the name + project_root
that every subsequent recording tool repeats — and one recording's steps never
land in another's file. Steps still run LIVE, so give each concurrent recording
its own device and pick a name unique to your task.
After starting, use flow-add-step to append tool calls — each step is executed
LIVE so you can verify it works before it gets recorded. Read each step's
message: an await-ui-element whose condition never held is still recorded (it
returns success:false rather than failing), and a check that passes live can
still fail once polished into an await:/assert: directive, which resolves
against a different tree. flow-add-step warns about both when you record the
wait DIRECTLY. A wait nested inside a recorded run-sequence gets neither warning
— that tool reports its own shape — so for those, read toolResult. For a self-contained
e2e flow, record a restart-app of the app under test as the FIRST step (captured
as the flow's launch step); for a reusable fragment, skip that and pass
executionPrerequisite instead. Use flow-add-echo to add labels. Call
flow-finish-recording when done.
If a recorded step turns out to be wrong, edit the .yaml file directly to remove or reorder steps - after flow-finish-recording, not during the recording. Against a remote client the in-memory copy is authoritative and every write serializes it over your edit; in host mode the recorder re-reads the file before each append, so a mid-recording edit renumbers the steps and costs the finish the cross-tree verdicts anchored to them.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name for this flow (e.g. "settings-explore") — letters, digits, underscore and hyphen only. | |
| project_root | Yes | Absolute path to the project root directory (the directory that contains or should contain `.argent/flows/`). The flow file is created at `<project_root>/.argent/flows/<name>.yaml`. | |
| executionPrerequisite | No | Fragments only: the app/device state assumed on entry (e.g. "Settings app open on General page"). For a self-contained e2e flow, omit this and record a `restart-app` as the first step instead — it is captured as the flow's `launch` step. restart-app has no chromium support, so a chromium flow records as a fragment; add the `launch: { chromium: <app path> }` line to the YAML afterward, deleting the executionPrerequisite line if you passed one — a flow that starts with a launch must not declare it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so extensively: it discloses the destructive reset behavior, the exact return shape, the co-located vs. remote mode difference, concurrency semantics, live execution of steps, and file-edit conflicts. This is far beyond a basic invocation-level description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured and front-loaded with the core purpose. Each block earns its place: return value, mode differences, concurrency, next steps, and file-editing caveats. It is somewhat dense and includes details that could arguably live in flow-add-step's docs, which prevents a perfect conciseness score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of annotations, and the lack of an output schema, the description is remarkably complete. It covers invocation, return values, failure behavior, environment-specific behavior, concurrency, next steps, and post-recording editing rules. An agent has enough context to call this tool correctly in most scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds real semantic value: it explains that name and project_root together key each recording, that names should be unique per task, that executionPrerequisite is for fragments only, and how restart-app relates to launch steps. This meaningfully exceeds the raw schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states the exact action: 'Start recording a new flow, resetting .argent/flows/<name>.yaml to an empty flow and replacing any existing one.' It names the resource, the verb, and the side effect, and clearly differentiates this from sibling tools like flow-add-step, flow-finish-recording, and flow-execute by framing it as the entry point for capturing a recording.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when you want to capture a reusable sequence of device interactions for later replay' and gives concrete next-step guidance ('After starting, use flow-add-step...', 'Call flow-finish-recording when done'). It also distinguishes e2e flows from reusable fragments. It does not explicitly list when-not-to-use or name a direct alternative for starting a recording, so it misses the full 'exclusions' bar for a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gather-workspace-dataA
Fetch a structured snapshot of a mobile app project's workspace.
Returns package.json contents, metro/babel config text, app.json, eas.json, tsconfig, platform directory presence (ios/, android/), presence of android/gradlew (android_has_gradle), iOS .xcworkspace name and Podfile presence, lockfile type, .env file keys (no values), installed CLI tool versions, scripts/ directory listing, husky hooks, CI config type, Makefile targets, lint-staged config, and a list of detected config files.
DO NOT RUN THIS TOOL IF YOU ARE THE MAIN AGENT AND THIS TASK CAN BE DELEGATED TO A SUBAGENT.
If you are a subagent tasked with exploring the project environment, run this as the first step. The snapshot provides the raw data needed to determine the project type (React Native, Expo, Flutter, native iOS/Android, or other), build commands, startup scripts, platform support, package manager, and QA tooling. Follow up with Read/Glob/Grep for deeper exploration of anything the snapshot surfaces. Use when you need to inspect project configuration without manually reading multiple files. Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections. Fails if the workspacePath is not an absolute path or the directory cannot be accessed.
| Name | Required | Description | Default |
|---|---|---|---|
| workspacePath | Yes | Absolute path to the project root directory to inspect (e.g. /Users/dev/MyApp) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses partial data behavior: 'Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections.' Also states failure conditions: 'Fails if the workspacePath is not an absolute path or the directory cannot be accessed.' No annotations to contradict.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and efficient, starting with a one-line summary, then detailing returned data, usage instructions, and behavior. It avoids redundancy, though it is slightly long due to the extensive list of returned fields; each field adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of the tool (returns many data points) and no output schema, the description fully enumerates all returned items and covers edge cases (partial data, failure modes). No gaps in what the agent needs to know.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter, providing an absolute path example. The tool description does not add additional semantics beyond the schema, which is already adequate. Baseline score 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Fetch a structured snapshot of a mobile app project's workspace.' It enumerates the specific data returned (package.json, metro config, etc.), and distinguishes itself from siblings, which are mostly device interaction and debugging tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use (inspect project configuration) and when not to: 'DO NOT RUN THIS TOOL IF YOU ARE THE MAIN AGENT AND THIS TASK CAN BE DELEGATED TO A SUBAGENT.' Provides a clear usage sequence: 'If you are a subagent... run this as the first step.' Also recommends follow-up tools (Read/Glob/Grep).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-customA
Send a sequence of touch events for complex gestures. Use for: long press, drag-and-drop, custom scroll, pinch (second touch point). For simple taps use the gesture-tap tool. For straight-line scrolling use the gesture-swipe tool. For pinch gestures use gesture-pinch. For rotation gestures use gesture-rotate. All x/y values are normalized 0.0–1.0 (screen fractions, not pixels). delayMs controls the delay before each event (default 16ms ≈ 60fps). Set interpolate to auto-generate smooth intermediate Move events between your keyframes. Physical iOS: Down then Up only. Same point = press-hold. Other point = drag (Up delayMs = rest before the move). One Move at the Down point between them = long-press pickup (Move delayMs = hold, Up delayMs = move time). No second finger, no other waypoints; scroll with gesture-swipe. Returns { events: number } with the total count of events dispatched. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the target device is not booted or an event type is invalid.
Example long-press at center: [{"type":"Down","x":0.5,"y":0.5},{"type":"Up","x":0.5,"y":0.5,"delayMs":800}]
Example pick up a list item with a long press, then drag it up: [{"type":"Down","x":0.5,"y":0.6},{"type":"Move","x":0.5,"y":0.6,"delayMs":800},{"type":"Up","x":0.5,"y":0.3,"delayMs":500}]
Example smooth scroll down: [{"type":"Down","x":0.5,"y":0.7}, {"type":"Move","x":0.5,"y":0.6},{"type":"Move","x":0.5,"y":0.5},{"type":"Move","x":0.5,"y":0.4}, {"type":"Up","x":0.5,"y":0.3}]
Example pinch-to-zoom (with interpolate:10 for smoothness): events: [{"type":"Down","x":0.4,"y":0.5,"x2":0.6,"y2":0.5}, {"type":"Up","x":0.2,"y":0.5,"x2":0.8,"y2":0.5}] interpolate: 10
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| events | Yes | Sequence of touch events; x/y (and optional second touch) are normalized 0.0–1.0, not pixels | |
| interpolate | No | Number of intermediate Move events to auto-insert between each pair of consecutive events. Smooths out gestures by linearly interpolating both primary (x,y) and secondary (x2,y2) coordinates. The delay is split evenly across interpolated frames. Default: no interpolation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It explains coordination normalization, delay defaults, interpolate behavior, return values, platform-specific limitations on physical iOS, and failure conditions. This is exemplary transparency for a gesture automation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: purpose, alternatives, key parameter semantics, physical iOS caveats, return values, failure modes, and four illustrative examples. It is front-loaded with the most important routing information and organized so an agent can quickly understand when to use it and how to construct events.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description thoroughly explains what the tool returns, when it fails, and how platform differences affect behavior. The examples cover the main complex gesture types and the interpolate option, making the tool's expected invocation and results fully understandable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the input schema already documents all parameters, the description adds substantial semantic meaning beyond that. It explains how to compose event sequences for long-press, drag, smooth scroll, and pinch, gives concrete examples, and clarifies the meaning of delayMs and interpolate in the context of real gestures. This goes well beyond the baseline schema-provided information.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: sending a sequence of touch events for complex gestures. It further distinguishes itself from siblings by naming specific use cases like long press, drag-and-drop, custom scroll, and two-finger pinch, while also calling out simpler alternatives. This makes the tool's purpose unambiguous and easy to differentiate.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage guidance: 'Use for: long press, drag-and-drop, custom scroll, pinch' and then explicitly routes simple taps to gesture-tap, straight-line scrolling to gesture-swipe, standard pinch to gesture-pinch, and rotation to gesture-rotate. It also provides physical iOS-specific constraints and failure conditions, leaving little room for incorrect tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-dragA
Press the left mouse button at a start point, move to an end point, and release — a desktop mouse drag in a Chromium app. All positions are normalized 0.0–1.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe, except that a coordinate of exactly 1.0 lands one pixel inside the window edge (gesture-tap maps it to the edge itself). Interpolates mouse-move events at ~60fps over durationMs for a natural drag (a momentum-free drag samples more finely when durationMs is short, so its ease-out has a curve). Use for slider thumbs, drag-and-drop, text selection, or draggable UI elements. Dragging never scrolls content on desktop — use gesture-scroll for lists/pages. Chromium only — on iOS/Android use gesture-swipe. Pass momentum:false for a momentum-free drag that decelerates into the release, so apps that compute a fling from the pointer stream read ~0 velocity and the drag ends where it was aimed instead of flinging past it (a durationMs under ~100ms is too short for the deceleration to suppress the fling entirely). Returns { dragged: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.
| Name | Required | Description | Default |
|---|---|---|---|
| toX | Yes | Release x: normalized 0.0–1.0 (not pixels; same space as tap). | |
| toY | Yes | Release y: normalized 0.0–1.0 (not pixels; same space as tap). | |
| udid | Yes | Target Chromium device id from `list-devices` (chromium-cdp-<port>). | |
| fromX | Yes | Press x: normalized 0.0–1.0 (fraction of window width, not pixels). | |
| fromY | Yes | Press y: normalized 0.0–1.0 (fraction of window height, not pixels). | |
| settle | No | Retired: renamed to `momentum` with the opposite sense. Pass `momentum: false` for what `settle: true` meant; `settle: false` was the default, so drop the key. | |
| momentum | No | Whether the drag releases with momentum; default true (a constant-speed drag). Pass false to decelerate into the release point (ease-out) so an app deriving fling from pointer release velocity (carousels, drag libraries) reads ~0 and applies little to no momentum — use it when the drag must stop where it was aimed rather than fling past. Deceleration needs wall clock: under ~100ms the whole drag fits inside the velocity window a page averages over (tens of ms), so some fling survives, and under ~70ms its extra frames cannot dispatch fast enough to fit durationMs. Keep durationMs at its default when the fling must be fully suppressed. | |
| durationMs | No | Total drag duration in milliseconds (default 300, at most 10000 - the button stays down for exactly this long), interpolated at ~60fps. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses the normalized coordinate system, the 1.0 edge-case behavior, the ~60fps interpolation, and the nuanced momentum/deceleration characteristics. It also states the return value and the failure condition when the CDP session is unreachable, leaving little to inference.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place. It front-loads the core operation, then covers coordinate semantics, use cases, alternatives, momentum behavior, and return/failure conditions in logical order. There is no filler or repetition that does not add value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex gesture tool with no annotations and no output schema, the description is fully complete. It covers coordinate mapping, edge cases, use cases, alternative tools, momentum semantics, the return value, and a failure mode. An agent has everything needed to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, which sets a baseline of 3. The description adds meaningful extra context beyond the schema: the shared coordinate space with gesture-tap and describe, the specific edge case where coordinate 1.0 lands one pixel inside the window, and the interaction between durationMs and momentum:false. While the schema already documents momentum and durationMs in detail, the description's coordinate-space clarifications elevate it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise, actionable definition: 'Press the left mouse button at a start point, move to an end point, and release — a desktop mouse drag in a Chromium app.' It names the exact resource and action, and immediately differentiates from sibling tools like gesture-tap (same coordinate space), gesture-scroll (does not scroll), and gesture-swipe (platform-specific).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool: 'Use for slider thumbs, drag-and-drop, text selection, or draggable UI elements.' It also gives direct alternatives: 'Dragging never scrolls content on desktop — use gesture-scroll for lists/pages' and 'on iOS/Android use gesture-swipe.' The momentum:false guidance adds a clear condition for a specific scenario.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-pinchA
Execute a pinch-to-zoom gesture by moving two fingers toward or away from a center point to change the scale of on-screen content. All positions and distances are normalized 0.0–1.0 (fractions of screen width/height, not pixels)—same coordinate space as gesture-tap and gesture-swipe. startDistance > endDistance = pinch in (zoom out). startDistance < endDistance = pinch out (zoom in). Typical values: startDistance 0.2, endDistance 0.6 for a zoom-in pinch at screen center. Auto-generates interpolated frames at ~60fps. The angle parameter controls the axis (0 = horizontal, 90 = vertical). Optional endCenterX/endCenterY drift the centroid linearly over the gesture (omitted = fixed center). Use when you need to zoom in or out on a map, image, or zoomable view. Returns { pinched: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| angle | No | Axis angle in degrees along which the fingers are placed (default 0 = horizontal). | |
| centerX | Yes | Center of pinch, horizontal: normalized 0.0–1.0 (fraction of screen width, not pixels) | |
| centerY | Yes | Center of pinch, vertical: normalized 0.0–1.0 (fraction of screen height, not pixels) | |
| durationMs | No | Total gesture duration in milliseconds (default 300) | |
| endCenterX | No | Final horizontal center of the pinch: normalized 0.0–1.0. When set, the centroid drifts linearly from centerX to endCenterX over the gesture (e.g. to keep expanding fingers on-screen near an edge). Omit for a fixed center. | |
| endCenterY | No | Final vertical center of the pinch: normalized 0.0–1.0. When set, the centroid drifts linearly from centerY to endCenterY over the gesture. Omit for a fixed center. | |
| endDistance | Yes | Final distance between the two fingers: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.6 = fingers 60% of screen apart. Use a larger endDistance than startDistance to pinch out (zoom in). | |
| startDistance | Yes | Initial distance between the two fingers: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.2 = fingers 20% of screen apart. Use a larger startDistance than endDistance to pinch in (zoom out). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses normalized coordinates, auto-generated frames at ~60fps, angle parameter, optional centroid drift, return value, and failure condition. Explains distance relationship for zoom direction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single paragraph with ~7 sentences, front-loading purpose and coordinate system. Concise overall, but could be slightly more structured (e.g., bullet points for parameters). No wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 9 parameters, no annotations, and no output schema, the description covers coordinate system, gesture mechanics, typical values, optional behavior, return format, and failure condition. Leaves little ambiguity for the agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds significant value: repeats coordinate normalization, gives typical values, explains drift mechanism, and clarifies start/end distance relationship. Exceeds baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it executes a pinch-to-zoom gesture with specific verb and resource. Distinguishes from sibling gesture tools by noting same coordinate space as gesture-tap and gesture-swipe, but could be more explicit about when to use vs. gesture-rotate or gesture-custom.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a clear use case: 'Use when you need to zoom in or out on a map, image, or zoomable view.' But does not specify when not to use or mention alternatives beyond coordinate space hint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-rotateA
Send a two-finger circular arc gesture to rotate on-screen content by a specified angle. Two fingers are placed opposite each other at a fixed radius from the center, then swept from startAngle to endAngle degrees. All positions and radii are normalized 0.0–1.0 (fractions of screen width/height, not pixels)—same coordinate space as gesture-tap and gesture-swipe. endAngle > startAngle = clockwise rotation. Typical values: radius 0.15, startAngle 0, endAngle 90 for a 90° clockwise turn. A single radius applies to both axes, so on a non-square screen it traces a physical ellipse (finger separation varies through the turn); pass radiusX+radiusY (fractions of width/height with radiusX·width = radiusY·height) for a physically circular orbit instead. Auto-generates interpolated frames at ~60fps. Unlike gesture-pinch which moves fingers linearly to zoom, this orbits fingers in an arc to change orientation. Use when you need to rotate a map, image picker, or any rotateable UI element. Returns { rotated: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device. Size the orbit with radius, or with radiusX and radiusY together (the pair overrides radius); one half of the pair alone, or none of the three, is rejected.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| radius | No | Distance from center to each finger: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.15 = fingers placed 15% of screen away from center. One value for both axes, so on a non-square screen the orbit is a physical ellipse — pass radiusX+radiusY instead for a true circle. Required unless radiusX and radiusY are given. | |
| centerX | Yes | Center of rotation, horizontal: normalized 0.0–1.0 (fraction of screen width, not pixels) | |
| centerY | Yes | Center of rotation, vertical: normalized 0.0–1.0 (fraction of screen height, not pixels) | |
| radiusX | No | Per-axis finger distance, horizontal: normalized 0.0–1.0 fraction of screen WIDTH. Give both radiusX and radiusY (they override radius) with radiusX·screenWidth = radiusY·screenHeight for a physically circular orbit — constant finger separation, no pinch coupled into the turn. | |
| radiusY | No | Per-axis finger distance, vertical: normalized 0.0–1.0 fraction of screen HEIGHT. Always paired with radiusX — see radiusX. | |
| endAngle | Yes | Ending angle in degrees. endAngle > startAngle = clockwise. | |
| durationMs | No | Total gesture duration in milliseconds (default 300) | |
| startAngle | Yes | Starting angle in degrees (0 = right, 90 = down) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full weight. It discloses normalized coordinates, auto-generated ~60fps interpolation, return value structure, failure conditions, radius override behavior, and rejection criteria for partially specified radiusX/radiusY. It even explains the physical ellipse vs. circle nuance—highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but every sentence adds value. It opens with purpose, then covers normalization, direction, typical values, parameter relationships, and failure modes. Structured logically with each paragraph addressing a key aspect. Despite length, it is tightly packed and front-loaded, with no redundant fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex gesture with 9 parameters and no output schema, the description covers all necessary aspects: physical interpretation of radius, angle semantics, coordinate space, failure rejection, return value, and frame rate. It fully compensates for the lack of annotations and enriches the schema. Complete for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds substantial meaning beyond the schema. It explains the coordinate space (normalized fractions), gives typical values (radius 0.15, startAngle 0, endAngle 90), clarifies that endAngle > startAngle is clockwise, and details how radiusX/radiusY interact with radius and override it. This aids correct parameter selection.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states what the tool does: 'Send a two-finger circular arc gesture to rotate on-screen content by a specified angle.' It specifies the verb (send/gesture), resource (on-screen content), and scope (rotate by angle). It also distinguishes from sibling gesture-pinch by noting it 'orbits fingers in an arc to change orientation' vs. linear zoom.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit context: 'Use when you need to rotate a map, image picker, or any rotateable UI element.' It directly differentiates from gesture-pinch and notes the coordinate space shared with gesture-tap and gesture-swipe. Failure conditions are also mentioned (backend unreachable), giving clear guidance on when it may not work.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-scrollA
Scroll content in a Chromium app by dispatching mouse-wheel events at a point. Anchor x/y are normalized 0.0–1.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe. Deltas are fractions of the window too: deltaY 0.5 scrolls down half a window; negative scrolls back up. Use when content is below/above the fold (describe shows off-screen elements with zero height) or a list needs scrolling. Chromium only — on iOS/Android use gesture-swipe. Returns { scrolled: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Anchor x: normalized 0.0–1.0 (fraction of window width, not pixels). The wheel events land here — put it over the element you want to scroll. | |
| y | Yes | Anchor y: normalized 0.0–1.0 (fraction of window height, not pixels). | |
| udid | Yes | Target Chromium device id from `list-devices` (chromium-cdp-<port>). | |
| deltaX | No | Horizontal scroll distance as a fraction of the window width (e.g. 0.5 = half a window). Positive scrolls content right (reveals content to the right). | |
| deltaY | No | Vertical scroll distance as a fraction of the window height (e.g. 0.5 = half a window). Positive scrolls content down (reveals content below), like rolling a mouse wheel toward you. | |
| durationMs | No | Spread the scroll over this many milliseconds in wheel-event steps (default 300) so scroll handlers fire progressively. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses the event type, coordinate space, return value, and failure condition (CDP session unreachable). Lacks details on default delta values or error messages, but covers core behavior well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph but well-structured with clear, informative sentences. It is appropriately sized for the complexity, though could be slightly more concise without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 6 parameters, no output schema, and no annotations, the description covers usage, platform, coordinates, return format, and failure. However, it does not specify default values for optional delta parameters (defaults to 0?), which is a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions. The tool description adds value beyond schema by explaining normalization, coordinate space shared with other tools, and delta direction (positive scrolls down). Enhances understanding for all 6 parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool scrolls content by dispatching mouse-wheel events. It specifies the coordinate system (normalized 0.0-1.0) and platform (Chromium). It distinguishes from sibling 'gesture-swipe' by noting Chromium-only vs iOS/Android.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells when to use (content below/above fold, lists needing scrolling) and when not (use gesture-swipe on iOS/Android). Provides clear context and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-swipeA
Execute a smooth swipe / drag touch gesture between two points on the device (iOS simulator or physical device, or Android emulator). All from/to positions are normalized 0.0–1.0 (fractions of screen width/height, not pixels), same as gesture-tap. Generates interpolated Move events for a natural feel (~60fps). Swipe up (fromY > toY) to scroll content down. Use when you need to scroll a list, dismiss a modal, drag an element, or navigate between pages. Not supported on Chromium — use gesture-scroll there instead. Physical iOS: an edge gesture (back-swipe) needs fromX 0 exactly; durationMs sets drag speed, not time; momentum:false only rests 300ms at the end and does not damp. Pass momentum:false for a momentum-free swipe that lands where the finger lifts (little to no fling at the 300 default), when you need a deterministic scroll distance; it needs durationMs >= 150 and is rejected below that, a shorter ease-out leaving the OS too little wall clock to read the deceleration as a stop. At 150 it lands short of the lift point instead, and 2 of 47 runs still flung backwards. A plain swipe takes any duration up to 10000ms and is delivered as close to the speed it was authored as a 16ms frame allows: below ~32ms the whole travel lands in one or two frames, which the OS flings as hard as it flings anything. Returns { swiped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend is not reachable for the given device.
| Name | Required | Description | Default |
|---|---|---|---|
| toX | Yes | End x: normalized 0.0–1.0 (not pixels; same as tap) | |
| toY | Yes | End y: normalized 0.0–1.0 (not pixels; same as tap) | |
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| fromX | Yes | Start x: normalized 0.0–1.0 (not pixels; same as tap) | |
| fromY | Yes | Start y: normalized 0.0–1.0 (not pixels; same as tap) | |
| settle | No | Retired: renamed to `momentum` with the opposite sense. Pass `momentum: false` for what `settle: true` meant; `settle: false` was the default, so drop the key. | |
| momentum | No | Whether the swipe releases with momentum; default true (a natural flinging swipe). Pass false for a momentum-free swipe at the default durationMs: the finger decelerates into the end point (ease-out) so the OS reads ~0 release velocity and applies little to no fling. Use false for scroll-to-element loops. momentum: false needs durationMs >= 150 and is rejected below it: a shorter ease-out gives the OS velocity fit too little wall clock to read the deceleration as a stop, and it flings harder than a plain swipe instead (on Android, backwards). At 150 itself the swipe lands short of where the finger stopped, and 2 of 47 runs still flung backwards. | |
| durationMs | No | Total gesture duration in milliseconds (default 300, at most 10000 - the gesture holds a finger down for exactly this long) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and handles it thoroughly: it discloses interpolation at ~60fps, direction semantics, physical iOS quirks, momentum behavior, return shape, failure conditions, and the reactivated field. This goes far beyond a basic 'performs a swipe' statement and gives an agent concrete expectations for execution and results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core operation, but it quickly becomes a dense, run-on block of edge cases and empirical observations (e.g., '2 of 47 runs still flung backwards'). It also repeats much of the schema's momentum/duration text nearly verbatim, which adds length without new value. Every sentence carries some information, but the structure is not clean and the redundancy hurts conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex gesture tool with no annotations and no output schema, the description is remarkably complete: it explains platform support, coordinate normalization, return value, failure behavior, timing constraints, momentum semantics, and physical-device caveats. An agent has enough context to invoke the tool correctly and interpret its result in most scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description adds genuine extra meaning for parameters, notably that fromY > toY means swipe up to scroll down, that physical iOS edge gestures require fromX exactly 0, and that momentum:false requires durationMs >= 150. Much of the momentum and duration detail is redundant with the schema, but the unique insights push it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: executing a smooth swipe/drag touch gesture between two normalized points. It names use cases (scroll, dismiss modal, navigate) and even an alternative for Chromium, but it does not fully differentiate from the sibling gesture-drag, which the description also claims to cover with 'drag an element.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly lists when to use the tool ('Use when you need to scroll a list, dismiss a modal, drag an element, or navigate between pages') and gives a clear when-not with an alternative ('Not supported on Chromium — use gesture-scroll there instead'). However, it does not clarify when gesture-drag or gesture-tap should be preferred, leaving some sibling differentiation to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
gesture-tapA
Press the device screen (iOS simulator or physical device, Android emulator, or Chromium app) at normalized coordinates: x and y are fractions of screen width and height in 0.0–1.0 (not pixels).
Sends a Down event followed by an Up event at the same point. For Chromium, this dispatches a CDP mouse-press/release on the renderer.
Set clickCount: 2 for a double-tap / double-click — the taps are dispatched as one gesture with proper click counting, which two separate tap calls cannot guarantee.
Use when you need to tap a button, link, or any tappable element on the screen.
Returns { tapped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend / Chromium CDP is not reachable for the given device.
On a physical iPhone use describe; native-describe-screen is simulator-only.
Before tapping, determine the correct coordinates by using discovery tools — pick by platform: iOS / Android use describe, native-describe-screen, or debugger-component-tree; Chromium uses describe (the DOM walker), since the native and RN-specific discovery tools don't apply. More information in argent-device-interact skill
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Normalized horizontal position 0.0–1.0 (left=0, right=1), not pixels | |
| y | Yes | Normalized vertical position 0.0–1.0 (top=0, bottom=1), not pixels | |
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id). | |
| clickCount | No | Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts land as separate taps. Default 1. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and does so thoroughly. It details the Down/Up event sequence, Chromium CDP behavior, clickCount semantics across platforms, physical iOS reactivation behavior, return values, and failure conditions. This is far more transparent than typical tool descriptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although the description is long, it is dense with necessary operational detail and every sentence adds value. The core action and coordinate system are front-loaded, followed by platform behavior, usage guidance, return values, and failure modes. The length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a tool of this complexity: it covers coordinate interpretation, event semantics, double-tap behavior, platform-specific execution, return payload, failure modes, and how to choose discovery tools. With no output schema or annotations, this level of detail is exactly what an agent needs to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers all 4 parameters with descriptions, so baseline is 3. The description adds meaningful semantics beyond the schema: it explains normalized coordinates, clickCount behavior for double-tap/double-click, cross-platform differences, and the guarantee of proper click counting. This raises it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it presses the screen at normalized coordinates and sends a Down/Up event to tap a button, link, or tappable element. It clearly differentiates tap behavior from multi-tap and provides platform-specific semantics, making it distinguishable from sibling gesture tools like gesture-swipe or gesture-custom.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool ('Use when you need to tap a button, link, or any tappable element') and gives strong platform-specific guidance on which discovery tools to use before tapping. It does not explicitly name sibling alternatives like gesture-swipe or gesture-drag, but the usage context is clear enough for an agent to select this tool correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
keyboardA
Type text or press special keys on the device (iOS simulator, Android emulator or device, Chromium app, Vega Virtual Device, or Apple TV / Android TV) using keyboard events. Use when you need to enter text or trigger a named key such as enter, escape, or arrow keys. On Vega and Apple TV / Android TV, prefer the remote tools for D-pad navigation; use keyboard to type into a focused text field (e.g. a search or login box). Returns { typed: string, keys: number }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if text and key are both given in one call (rejected before anything is typed), if an unsupported key name is provided, or if the device's input backend is not reachable. A failure is not rolled back. An unsupported key name is always rejected before anything is sent. Un-typeable text is not: the iOS simulator and Chromium reject it mid-string and leave the characters before it in the field (Android, Vega and TV targets check the whole string up front). A transport failure partway also leaves the text already sent. On a retry, read the field's actual contents — do not assume it is unchanged.
text: types a string (supports uppercase, digits, common punctuation). To type a credential, use
{{secret:<NAME>}}— resolved server-side from theARGENT_SECRET_<NAME>env var or an argent secrets file (.argent/secrets.envin the project,~/.argent/secrets.env, or anARGENT_SECRET_-prefixed key in the project's.env/.env.local), so the plaintext never enters agent context; the result echoes the placeholder, not the value, and the after-typing auto-screenshot is skipped. To submit after typing a secret, put both steps in ONErun-sequence— that keeps the skip covering the Enter, which a second barekeyboardcall would not.key: presses a single named key (enter, escape, backspace, tab, arrow-up/down/left/right, f1-f12). NOT supported on TV targets; move focus with
tv-remoteinstead. Physical iOS: onlyenterandbackspace. On a TV target (runtimeKind 'tv') onlytextapplies — focus a text field first (withtv-remote), then type into it (injected HID keyboard on Apple TV,adb input texton Android TV). One call does one action: pass text OR key, never both. To type and then press a key, send twokeyboardsteps in onerun-sequence— { text: "hello" } then { key: "enter" } — which also keeps it to a single round-trip.
| Name | Required | Description | Default |
|---|---|---|---|
| key | No | Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1-f12. Cannot be combined with `text` in one call: one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Not supported on TV targets; move focus with `tv-remote` (up/down/left/right) instead. Physical iOS: only `enter` and `backspace`. | |
| text | No | Text to type character by character. Cannot be combined with `key` in one call — one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` — e.g. text: "{{secret:APP_PASSWORD}}". The value is resolved on the machine running the tool-server, from the first source that defines the name: the `ARGENT_SECRET_<NAME>` environment variable, `.argent/secrets.env` in the project, the project's `.env.local` / `.env` (only their `ARGENT_SECRET_`-prefixed keys), then `~/.argent/secrets.env`. Nothing else on the host is reachable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, the failure lists the available names and every source it looked in — ask the user to add it to one of them (a secrets file applies immediately; an env var needs a restart), NEVER ask the user to paste the secret value into the conversation. | |
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id). | |
| delayMs | No | Delay in ms between key presses (default 50). Ignored on Android phones/tablets (typed via `adb input text`, which has no per-key cadence), on Vega (text/keys injected in a single shot), on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence), and on physical iOS. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With zero annotations, the description carries the full burden — and it delivers exhaustively. It discloses failure modes and their ordering (text+key rejected before anything is typed; unsupported key rejected up front; un-typeable text partially applied on iOS sim/Chromium but pre-checked on Android/Vega/TV), non-rollback semantics, retry guidance ('read the field's actual contents'), secret resolution behavior (server-side, echoed as placeholder, auto-screenshot skipped), and the reactivated flag on physical iOS.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but nearly every sentence earns its place given the tool's platform matrix, failure semantics, and secrets handling. It is front-loaded with purpose and organized into clear sections (usage, returns/failures, parameter details, TV specifics). It loses one point only because the density of caveats could tax an agent's parsing, and a few points (e.g., repeated 'one call does one action' admonitions) appear in both the prose and the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter, multi-platform tool with no output schema and no annotations, the description is remarkably complete. It covers the return shape ({ typed, keys }), all failure modes with retry implications, platform-specific behaviors, the text OR key constraint, and cross-tool coordination with tv-remote and run-sequence. Nothing an agent needs to call this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100% (baseline 3), the description adds substantial meaning beyond the schema: the secret placeholder mechanism with its full source-resolution order, the per-platform ignored conditions for delayMs, platform-specific key restrictions (TV targets, physical iOS limited to enter/backspace), and the character-set limitation on text. This materially changes how an agent would populate parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource pairing ('Type text or press special keys on the device') and enumerates the exact target surfaces (iOS simulator, Android emulator/device, Chromium app, Vega, TV). It distinguishes itself from sibling tools by naming what it is not — D-pad navigation belongs to remote tools — so an agent can differentiate it from tv-remote and the gesture family without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance ('Use when you need to enter text or trigger a named key') and clear exclusions ('On Vega and Apple TV / Android TV, prefer the remote tools for D-pad navigation'), plus a platform-specific rule ('NOT supported on TV targets; move focus with tv-remote instead'). It also instructs when to pair with run-sequence for multi-step actions, giving the agent a complete decision procedure.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch-appA
Open an app by its bundle id (iOS) or package name (Android), or confirm the running renderer (Chromium).
Use when starting any app — prefer this over tapping home-screen / launcher icons. Also prepares the native-devtools injection before the app starts (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven — use the tv-* tools rather than coordinate taps.
Returns { launched, bundleId, note? }. Fails if the app is not installed on the target device (iOS / Android). On a physical iPhone this registers the app every other tool acts on; com.apple.springboard and com.apple.Spotlight register without launching. note warns when runner signing is not ready.
For Chromium, the app is already running behind a CDP port; this call simply refreshes the cached viewport and acknowledges the bundleId tag. To change the visible route, use open-url.
On Vega (Fire TV), pass the interactive component app id from manifest.toml (e.g. com.example.app.main) as bundleId.
Common iOS bundle ids: com.apple.MobileSMS, com.apple.mobilesafari, com.apple.Preferences, com.apple.Maps, com.apple.camera, com.apple.Photos, com.apple.mobilemail, com.apple.mobilenotes, com.apple.MobileAddressBook Common Android packages: com.android.settings, com.android.chrome, com.google.android.apps.maps, com.google.android.gm, com.android.vending, com.google.android.dialer, com.google.android.apps.messaging
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id). | |
| activity | No | Android-only: fully-qualified Activity name (e.g. `.MainActivity` or `com.example/com.example.MainActivity`). If omitted on Android, the app's default launcher activity is used. Ignored on iOS / Chromium. | |
| bundleId | Yes | App identifier. iOS: bundle id (e.g. com.apple.MobileSMS). Android: package name from build.gradle `applicationId` (e.g. com.android.settings). Chromium: arbitrary tag; the call is a no-op since the renderer is already running. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does so thoroughly. It discloses side effects like native-devtools injection, registration behavior on physical iPhones, failure when the app is not installed, the no-op behavior on Chromium, and the note about runner signing readiness. It even explains special cases like com.apple.springboard and Spotlight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured, with the core launch semantics front-loaded and platform-specific details separated into paragraphs. The common bundle id/package name list is lengthy but practical, and every section serves a distinct purpose. It is not perfectly concise, but the detail is justified given the cross-platform complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description discloses the return shape ({ launched, bundleId, note? }), failure modes, installation requirements, platform differences, and side effects. This makes the tool's behavior predictable across iOS, Android, Chromium, tvOS, and Vega, which is a complete picture for an agent selecting and invoking it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds real value by listing common iOS bundle ids and Android package names, explaining Chromium's arbitrary bundleId tag as a no-op, and adding the Vega Fire TV manifestation. It could have also elaborated on the activity parameter, but the schema already covers it well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Open an app by its bundle id (iOS) or package name (Android), or confirm the running renderer (Chromium).' It clearly distinguishes the tool from alternatives by naming open-url for changing Chromium routes and positioning this as the preferred way to start apps over launcher icons.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool: 'Use when starting any app.' It also provides platform-specific guidance, including using tv-* tools on tvOS and using open-url for Chromium route changes. This gives clear context and names the relevant alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list-devicesA
List iOS simulators, Android emulators, connected physical Android devices, running Chromium apps, and Vega (Fire TV) devices in one place.
Use at the start of a session to pick a target id ('udid' for iOS entries, 'serial' for Android/Vega entries, 'id' for Chromium) to pass to interaction tools, and to see which targets are already running.
Returns { devices, avds } where each device carries a 'platform' discriminator ('ios', 'android', 'chromium', or 'vega'); 'avds' lists Android AVDs bootable via boot-device. A Vega VVD is listed under 'devices' whether running or stopped (state 'running'/'stopped'); start a stopped one with boot-device using its 'vvdImage'.
Android entries also carry a 'kind' ('emulator' for a local AVD, 'device' for a physical phone connected over USB / wireless adb) — physical phones are detected from adb devices (any serial that is not an emulator-* one) and are driven through the same interaction tools as emulators; they do not need boot-device (just connect the phone with USB debugging authorised).
Physical iPhones appear as iOS entries with kind 'device' (no iPads); no boot-device. State 'connected' = cabled and usable; 'paired' = not reachable over USB, never auto-bound.
TV targets are tagged with runtimeKind 'tv' (Apple TV simulators on iOS, Android TV / leanback devices on Android) — these are focus-driven, not touch-driven: use describe to read focus, tv-remote for remote presses (up/down/left/right/select/back/menu/home), and keyboard to type, rather than the coordinate/gesture tools.
iOS simulators from an additional CoreSimulator device set (the 'ios.additionalDeviceSets' configuration — e.g. devices created by Radon IDE) are listed alongside default-set ones, tagged with their owning 'deviceSet' path; they are driven through the same tools by udid, but run headless (no Simulator.app window attaches to them).
Chromium apps are discovered by probing CDP debugging ports (default 9222; extend via the ARGENT_CHROMIUM_PORTS= env var). They must already be running with --remote-debugging-port= — use boot-device with electronAppPath to launch one.
Booted/ready devices are listed first. Platforms whose CLI is unavailable are silently omitted — an empty result usually means xcode-select, Android platform-tools, or the Vega SDK is not installed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and delivers extensively: it discloses return shape ({ devices, avds }), platform discriminators, states (running/stopped/connected/paired), headless behavior for additional CoreSimulator devices, silent omission of platforms with unavailable CLIs, and empty-result meaning. No annotation contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although long, the description is front-loaded with the core purpose and usage, then organized in clear platform-specific paragraphs. Each sentence adds operational detail (discovery mechanism, state semantics, alternatives) rather than filler, so the length is justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex multi-platform inventory tool with no output schema or annotations, and the description covers all the context an agent needs: return format, target-id selection, per-platform behaviors, prerequisites, state/ordering semantics, and failure interpretation. It is effectively self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and schema coverage is 100%, so the baseline is 4; there are no parameter semantics to document. The description instead adds meaning to the returned fields (udid/serial/id, kind, state, runtimeKind), which is more relevant than parameter docs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a precise verb ('List') with an explicit resource scope: iOS simulators, Android emulators, connected physical Android devices, running Chromium apps, and Vega/Fire TV devices. It also distinguishes the tool from interaction-focused siblings like boot-device and tv-remote by saying it returns target ids to pass to them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use it at the start of a session to pick a target id and see running targets. It names alternatives and conditions: use boot-device to boot stopped Vega devices and AVDs, no boot-device needed for physical phones, boot-device with electronAppPath for Chromium, and tv-remote/keyboard/describe for TV targets instead of gestures.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-describe-screenA
Read the running app's native accessibility screen description via injected native devtools.
Returns a flat list of accessibility leaf elements with:
raw native point-space frame and tapPoint
normalizedFrame and normalizedTapPoint relative to the app's main screen bounds
top-level screenFrame metadata
traits and optional labels/identifiers
This is a low-level native inspection tool. The normalized fields are intended to help with backend migration work, but the public describe contract is still separate.
Use when you are evaluating or debugging the lower-level native data behind the public describe tool, or when you need its raw point-space geometry rather than describe's normalized contract.
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help — restart the tool-server (argent server stop && argent server start --detach) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting — do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised — follow the message (re-boot the simulator) rather than retrying this tool.
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal — never retry it), and the screen query itself can error or time out.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Simulator UDID | |
| bundleId | Yes | Bundle ID of the app | |
| skipClasses | No | Exact UIView class names whose entire subtree should be pruned (e.g. ["UIImageView"] to drop image-heavy branches) | |
| skipClassPrefixes | No | Class name prefixes to prune entire subtrees. For SwiftUI apps use ["_TtGC7SwiftUI"] to drop mangled SwiftUI generic type subtrees while keeping UIKit bridges. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It thoroughly discloses return contents (flat list of leaf elements, frames, tapPoints, normalized fields, traits, labels) and behavioral quirks (statuses for not-connected apps, restart logic, service_stale requiring tool-server restart, connect_pending meaning do not restart, init_failed requiring simulator reboot, rejection of Apple system apps). This is exceptionally transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Despite being long, every sentence adds valuable information. It front-loads the core purpose, then details output, usage context, and error handling in a logical order. No fluff or repetition; the length is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex (low-level native inspection with multiple statuses and failure modes) and lacks an output schema. The description fully compensates by explaining return values, usage scenarios, and detailed error recovery steps. It also clarifies the relationship with the describe tool, ensuring complete context for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all four parameters have descriptions in the schema (udid, bundleId, skipClasses, skipClassPrefixes) with helpful examples. The description does not add extra parameter semantics beyond what the schema already provides, so a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads the running app's native accessibility screen description via injected devtools, and distinguishes it from the sibling 'describe' tool by calling it a low-level native inspection tool with raw point-space geometry. It explicitly mentions the separate public describe contract.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when you are evaluating or debugging the lower-level native data behind the public describe tool, or when you need its raw point-space geometry rather than describe's normalized contract.' It also provides detailed status handling instructions (restart_required, service_stale, connect_pending, init_failed) and failure modes (Apple system app rejection), making when-to-use and how-to-handle conditions very clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-devtools-statusA
Check whether native devtools are connected to a specific app and whether the next launch is prepared for injection. Use when you need to verify native devtools readiness before calling native-full-hierarchy, native-describe-screen, or native-network-logs.
Returns { envSetup, appRunning, connected, requiresRestart, state, message, nextLaunchWillBeInjected, injectable }:
envSetup: DYLD_INSERT_LIBRARIES is configured in the simulator's launchd environment
appRunning: the target bundle currently has a running UIKit process on the simulator
connected: the dylib is active in the current running process for this bundleId
requiresRestart: the app is already running and a fresh process would reach this simulator's devtools endpoint where the current one does not — it carries no argent injection, was pointed at an earlier tool-server's listener, or could not be inspected to tell. Always false for a non-injectable app, and false when state is unregistered or connecting, where a relaunch cannot help.
state: why devtools are or aren't live, measured from the running process. "connected"; "not_running"; "stale_process" (the process cannot reach this simulator's devtools endpoint — launched either before argent's instrumentation was in place or against an earlier tool-server's listener — so restart-app fixes it); "unregistered" (the process IS injected and pointed at this simulator's devtools endpoint yet the service never registered it, so restarting the app cannot help); "connecting" (the process IS injected but launched moments ago and is still connecting, so waiting is what helps); "indeterminate" (the process could not be inspected). Omitted when injectable is false, which is terminal on its own.
message: the remedy for that state, in full. Omitted when connected or non-injectable. Prefer it over inferring one from the booleans — it is the only field that can tell you to stop restarting the app.
nextLaunchWillBeInjected: if you launch this bundle now, native devtools env setup is already in place (always false for a non-injectable app)
injectable: whether this app is a supported target for Argent native devtools. Apple system apps (bundle ids under com.apple.) are not: they are never the app under test, so the native tools refuse to read one.
Call this before using app-scoped native hierarchy tools or native-network-logs.
If injectable is false: treat this as TERMINAL — the app is not a supported native-devtools target, and no relaunch changes that. Do NOT restart/retry. Use the standard describe tool (its accessibility path reads the screen without injection) or screenshot (then interact by coordinate). Do not fall back to the native-devtools feature tools (native-describe-screen, native-find-views, native-full-hierarchy, native-network-logs, native-view-at-point, native-user-interactable-view-at-point) — they run the same injection precheck and fail with the same non-injectable error.
If appRunning is false and nextLaunchWillBeInjected is true: use launch-app normally.
If requiresRestart is true: call restart-app once, then proceed with the native feature. Read state before acting on a second such reading — indeterminate reaches this rule too, and its line below bounds it at that one restart.
If state is unregistered: do NOT restart the app again — it already launched under the terms a restart would recreate. Restart the tool-server (argent server stop && argent server start --detach), then retry. If it reads unregistered again after that restart, stop: the process loads argent's dylib but never dials, and no further restart on either side changes it — treat native devtools as unavailable, then use describe or screenshot and drive by coordinate.
If state is connecting: do NOT restart the app — launching it is what starts the connection, so a relaunch discards the one in progress and returns this same state. Wait a few seconds and repeat this call.
If state is indeterminate: the process could not be inspected, so restart-app is worth one attempt. If this call still reports it after that restart, do NOT restart the app again — the service is stale rather than the app uninjected, so restart the tool-server (argent server stop && argent server start --detach) and retry. Remote simulators can never inspect the process, so this is the only unconnected state a running app reaches there.
Returns { status: "init_failed", message, attempts } instead when the simulator's native-devtools environment failed to initialize.
Fails if the simulator server is not running for the given UDID.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Simulator UDID | |
| bundleId | Yes | Bundle ID of the app to check (e.g. com.example.MyApp) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it meets it thoroughly. It explains every returned field, each possible state, the meaning of requiresRestart, terminal non-injectable behavior, and the init_failed alternative return. It also discloses failure conditions such as the simulator server not running and remote simulator limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every section earns its place: purpose, return contract, state semantics, then actionable decision rules. It is front-loaded with the core purpose and structured so the agent can quickly locate the branch relevant to its observed state. There is no filler or redundant framing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is effectively a complete operational spec for a two-parameter diagnostic tool. It defines all return fields, enumerates every state and its remedy, distinguishes terminal from recoverable conditions, and documents the failure return. Since there is no output schema, this in-description documentation is essential and fully supplied.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already covers both parameters with 100% description coverage: udid is 'Simulator UDID' and bundleId is 'Bundle ID of the app to check.' The description references bundleId and the simulator server context but adds little semantic detail beyond the schema. Baseline 3 is appropriate because the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Check whether native devtools are connected to a specific app and whether the next launch is prepared for injection.' It clearly names the downstream native tools that depend on this readiness check, so an agent can distinguish it from siblings without opening their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance ('Call this before using app-scoped native hierarchy tools or native-network-logs') and a detailed decision tree covering each state. It also names non-native alternatives like describe and screenshot, and explicitly forbids retrying native feature tools when injectable is false. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-find-viewsA
Search for specific UIViews in the running app by class name, accessibility identifier, label, tag, or React Native nativeID.
Use when you need to locate a specific view by its properties without dumping the entire hierarchy.
Returns { status: "ok", matches } with matching views including their frames, properties, optional ancestors, and optional children. Much more targeted than native-full-hierarchy.
At least one of className, identifier, label, tag, or nativeID must be provided.
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help — restart the tool-server (argent server stop && argent server start --detach) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting — do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised — follow the message (re-boot the simulator) rather than retrying this tool.
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal — never retry it), and the hierarchy query itself can error or time out.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | UIView tag integer to match | |
| udid | Yes | Simulator UDID | |
| label | No | Accessibility label to match (exact) | |
| fields | No | View fields to include. Defaults: className, frame, hidden, alpha, identifier, label, nativeID, userInteractionEnabled, depth. Additional: pointer, tag, windowFrame, bounds, center, opaque, clipsToBounds, transform, contentMode, backgroundColor, tintColor, layerName | |
| bundleId | Yes | Bundle ID of the app | |
| nativeID | No | React Native nativeID prop to match (exact) | |
| className | No | UIView class name to match (exact, e.g. UIButton) | |
| identifier | No | Accessibility identifier to match (exact) | |
| includeChildren | No | Include child views for each matched view (default true) | |
| includeAncestors | No | Include ancestor chain for each matched view (default true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so thoroughly. It explains return shape, each possible status with specific recovery actions, the fact that not-connected/running apps surface as statuses rather than failures, and failure cases such as Apple system app rejection and hierarchy query errors/timeouts.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded: purpose, when-to-use, return shape, constraint, then operational statuses. It is long due to complex runtime behaviors, but every sentence adds necessary guidance; the troubleshooting block is justified because there is no output schema or annotations to cover it.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, 10 parameters, and no output schema, the description is remarkably complete. It specifies the return format, optional ancestors/children, required search criteria, status-specific recovery flows, and terminal failure cases, so an agent has enough context to invoke and recover from failures.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all parameters with 100% coverage, so the description does not need to repeat them. It adds meaningful cross-parameter semantics by stating that at least one of className, identifier, label, tag, or nativeID is required, which is not encoded in the schema itself.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Search for specific UIViews in the running app' and enumerates all search criteria (class name, accessibility identifier, label, tag, or nativeID). It differentiates from the closest sibling by stating 'Much more targeted than native-full-hierarchy.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says when to use the tool: 'Use when you need to locate a specific view by its properties without dumping the entire hierarchy.' It also names the alternative native-full-hierarchy and emphasizes the at-least-one search-criterion requirement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-full-hierarchyA
Get the complete UIKit view tree for the running app.
WARNING: Output can be extremely large (100KB–500KB+) for complex apps, especially those built with SwiftUI. Prefer native-find-views for targeted queries.
Use skipClasses / skipClassPrefixes to prune SwiftUI internal subtrees and reduce output size. Use the fields param to request only the properties you need.
Use when you need deep layout debugging, finding views with no accessibility labels, or verifying view structure not exposed through the accessibility tree.
Returns { status: "ok", windows } with the full view hierarchy.
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help — restart the tool-server (argent server stop && argent server start --detach) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting — do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised — follow the message (re-boot the simulator) rather than retrying this tool.
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal — never retry it), and the hierarchy query itself can error or time out.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Simulator UDID | |
| fields | No | View fields to include. Use EXACT names: className, frame, hidden, alpha, identifier, label, nativeID, userInteractionEnabled, depth, pointer, tag, windowFrame, bounds, center, opaque, clipsToBounds, transform, contentMode, backgroundColor, tintColor, layerName. Defaults to all of the first group when omitted. | |
| bundleId | Yes | Bundle ID of the app | |
| maxDepth | No | Maximum recursion depth (default 8). Increase for deeper inspection, decrease to reduce output size. | |
| skipClasses | No | Exact UIView class names whose entire subtree should be pruned (e.g. ["UIImageView"] to drop image leaf nodes) | |
| skipClassPrefixes | No | Class name prefixes to prune entire subtrees. For SwiftUI apps use ["_TtGC7SwiftUI"] to drop mangled SwiftUI generic type subtrees while keeping _UIHostingView and UIKit bridges. Avoid broad prefixes like "_UI" — they prune useful system views. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure, and it does so thoroughly. It warns about extremely large output (100KB–500KB+), lists statuses (restart_required, service_stale, connect_pending, init_failed) with exact recovery actions, and clarifies that non-connected apps return statuses rather than failures. This goes far beyond the schema's static parameter descriptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though long, every section earns its place: warning first, then alternatives, parameter tuning advice, and careful status handling. The structure is front-loaded with the most critical information, and the status guidance is exhaustive enough to prevent dangerous retry loops.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has no output schema and no annotations, the description is remarkably complete. It covers expected return shape, failure modes, status-value semantics, terminal cases, and advice about scaling output. An agent can invoke this tool correctly and know what to do after almost every possible result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description adds meaningful guidance on top: skipClasses/skipClassPrefixes examples, a concrete SwiftUI prefix value, a warning against broad prefixes like '_UI', a default for maxDepth, and a recommendation to use the fields parameter to limit output. This materially helps an agent pick and fill the right parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource: 'Get the complete UIKit view tree for the running app.' It also distinguishes itself from the sibling tool by saying 'Prefer native-find-views for targeted queries' and notes when this tool is useful (deep layout debugging, accessibility label checks). This is unambiguous and avoids confusion with siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool versus native-find-views and gives concrete use cases: 'deep layout debugging, finding views with no accessibility labels, or verifying view structure not exposed through the accessibility tree.' It also explains when not to retry, including terminal conditions for Apple system apps and specific instructions for each status code.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-network-logsA
Retrieve network requests captured at the native NSURLProtocol level.
Unlike the JS-level network inspector (view-network-logs), this captures ALL network traffic from the app including native modules, Swift/Objective-C networking, and background transfers that bypass JS fetch.
Use when you need to inspect native-level HTTP traffic that is invisible to JS fetch interception.
Returns { status, count, events } where each event contains URL, method, status code, headers, and timing.
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help — restart the tool-server (argent server stop && argent server start --detach) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting — do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised — follow the message (re-boot the simulator) rather than retrying this tool.
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal — never retry it), while a missing host dependency or a udid that is not an Apple device is not.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Simulator UDID | |
| clear | No | Clear the log after reading | |
| limit | No | Maximum number of events to return (most recent first) | |
| bundleId | Yes | Bundle ID of the app |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It transparently discloses several behavioral traits: the tool returns a status field that can be 'restart_required', 'service_stale', 'connect_pending', or 'init_failed', each with a specific recommended action (e.g., restart app, restart server, wait, or re-boot simulator). It also explains that non-connected or non-running apps are returned as statuses rather than failures, and that certain failures (Apple system app rejection) are terminal and should never be retried. This goes beyond a simple description and provides concrete operational guidance, enhancing transparency significantly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is quite long but well-structured: it starts with the purpose, then differentiates from sibling, provides a use case, and then dives into status handling. While it's verbose, every section serves a purpose—especially the detailed status handling which is critical for correct usage. It front-loads the core purpose and comparison, then provides valuable conditional logic. It's not overly redundant, and the length is justified by the complexity of the tool's response statuses.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (handling various statuses, failures, and retry logic), the description is remarkably complete. It covers what the tool does, when to use it, how to interpret different statuses, and what failure scenarios look like. There is no output schema, but the description explicitly states the return structure: { status, count, events } and lists what each event contains (URL, method, status code, headers, and timing). This provides enough information for an agent to fully utilize the tool without further documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% description coverage for all four parameters (udid, bundleId, clear, limit) with clear descriptions. The tool description does not add much param detail beyond the schema, but it does provide context on how the tool uses them (e.g., 'Clear the log after reading' and 'Maximum number of events'). Given the high schema coverage baseline is 3, the description's mention of limit default of 50 and the status handling provides slight added semantics, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool retrieves network requests captured at the NSURLProtocol level, clearly distinguishing it from the JS-level network inspector (view-network-logs). It specifies the resource (network requests), the scope (native-level, all traffic including native modules and background transfers), and explicitly names the sibling alternative, making it unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use this tool: when needing to inspect native-level HTTP traffic invisible to JS fetch interception. It also contrasts with an alternative tool (view-network-logs) and gives a clear use case. Additionally, it details action paths for various status values (restart_required, service_stale, connect_pending, init_failed) including when to avoid restating the tool or restart the server, and explains that not-connected or not-running app cases come back as statuses, with separate failure scenarios (system app rejection, missing host dependency, invalid udid). This is comprehensive usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-profiler-analyzeA
Analyze exported native trace data and return an LLM-optimized markdown report. iOS: parses CPU time profile, UI hangs, and memory leaks from the exported XML files. Android: queries the Perfetto .pftrace via the in-process Perfetto trace-processor engine for CPU hotspots, UI hangs with jank reason + main-thread state breakdown, GC annotation, and an RSS-growth weak signal. Returns a structured markdown report with severity indicators, tables, and actionable suggestions. After presenting the report, ask the user whether to investigate further (drill-down with profiler-stack-query for hang stacks, CPU context, leak details) or implement fixes and re-profile. Call native-profiler-stop first to export the trace data. Use when you need to interpret a completed native profiling recording. Fails if native-profiler-stop has not been called first to export trace data.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | Target device id from `list-devices` (iOS UDID or Android serial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It discloses platform-specific analysis behavior, the markdown report format, severity indicators, tables, actionable suggestions, and the follow-up interaction of asking the user before deeper investigation. It could be slightly more explicit about side effects, but for an analysis tool this is adequately transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and logically organized, covering platform details, output format, usage condition, and follow-up workflow. There is some redundancy: 'Call native-profiler-stop first...' and 'Fails if native-profiler-stop has not been called first...' repeat the same prerequisite. This minor duplication prevents a perfect score but the description is still concise enough.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema and no annotations, the description covers input, platform-specific behavior, output format, prerequisite, failure mode, and recommended next action. This is sufficient for an agent to decide when to use the tool, invoke it correctly, and handle the resulting markdown report appropriately.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the single device_id parameter is already well described with its source: 'Target device id from list-devices (iOS UDID or Android serial).' The main description does not add further parameter-specific meaning beyond what the schema provides. Therefore the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: 'Analyze exported native trace data and return an LLM-optimized markdown report.' It further specifies iOS XML parsing and Android Perfetto querying, giving clear resource and platform scope. This clearly distinguishes it from sibling tools like profiler-stack-query and react-profiler-analyze.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool: 'Use when you need to interpret a completed native profiling recording.' It also gives a prerequisite and failure condition: 'Call native-profiler-stop first' and 'Fails if native-profiler-stop has not been called first.' The reference to profiler-stack-query as a downstream drill-down option adds useful usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-profiler-startA
Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal). Auto-detects the running app process unless app_process is explicitly provided. After starting, let the user interact with the app, then call native-profiler-stop. Use when you want to capture native CPU, hang, and memory data for a running app. Returns { status, pid, traceFile } confirming the recording has started. Fails if no app is running on the device, or the profiler cannot attach to the process.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| app_process | No | iOS: the CFBundleExecutable or display name of the app to profile. Android: the app's package name. If omitted, auto-detects the currently running foreground app. Only provide this if auto-detection picks the wrong app. | |
| template_path | No | iOS-only: path to an Instruments .tracetemplate file (defaults to bundled Argent template). Ignored on Android. | |
| malloc_stack_logging | No | iOS-only. When true, cold-launches the app under the profiler with Malloc Stack Logging enabled so memory leaks carry an allocation backtrace (responsible frame + library). Without it, leaks are still detected but unattributable — Instruments reports '<Call stack limit reached>'. Trade-offs: this RESTARTS the app (current state is lost), adds memory/CPU overhead, and makes the app noticeably slow to launch (every startup allocation records a backtrace), so leave it off for pure CPU/hang profiling. Requires a non-degraded Xcode: on Xcode 26.4 and later the cold-launch path is broken, so the call is rejected up front (re-run without the flag, or set ARGENT_IOS_CAPTURE=device to override if the device path works on your host). ARGENT_IOS_CAPTURE=all-processes — e.g. exported globally for the normal capture path — also rejects this flag up front, since that fallback cannot cold-launch; unset it (or set it to device) first. Ignored on Android. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly. It discloses auto-detection behavior, return shape ({ status, pid, traceFile }), failure conditions, platform-specific behavior, and detailed trade-offs for malloc_stack_logging including app restart, overhead, Xcode limitations, and environment variable interactions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place. It is well-structured with platform breakdown, usage flow, return value, failure modes, and parameter-specific caveats, making it dense but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (two platforms, four parameters, no output schema, no annotations), the description is remarkably complete. It covers return values, failure conditions, platform differences, and operational workflow, leaving no major gaps for an agent to misuse the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds significant value beyond the schema: it explains when to provide app_process (only if auto-detection picks wrong app), that template_path defaults to a bundled Argent template and is ignored on Android, and gives extensive context for malloc_stack_logging including when to leave it off and when the call is rejected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool starts native profiling on a booted device, with platform-specific details (iOS Instruments via xctrace, Android Perfetto). It distinguishes itself from sibling tools like react-profiler-start and native-profiler-stop by specifying native CPU, hang, and memory capture.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when you want to capture native CPU, hang, and memory data for a running app' and instructs to call native-profiler-stop after user interaction. It does not explicitly contrast with react-profiler-start, but the native vs. React distinction is implied by tool naming and context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-profiler-stopA
Stop native profiling and export trace data.
iOS: sends SIGINT to xctrace, waits for packaging, then exports CPU, hangs, and leaks XML.
Android: sends SIGTERM to the perfetto daemon, polls /proc/, then adb pulls the .pftrace.
Call native-profiler-start first.
Use when the user has finished the interaction to profile and you need to export the trace.
Returns { traceFile, exportedFiles, exportDiagnostics? }; traceFile is the raw trace bundle and exportedFiles the exports, all downloadable artifacts materialized to local paths.
Fails if no active native-profiler-start session exists for the given device_id.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | Target device id from `list-devices` (iOS UDID or Android serial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It transparently describes the platform-specific behaviors (iOS vs Android), signals, polling, and pull operations. It discloses the failure condition (no active session). However, it does not describe side effects like whether profiling is terminated or any cleanup, but given the nature of stop, this is acceptable. It adds context beyond the simple stop action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably concise, with three sentences covering purpose, method, and usage. It front-loads the action. It includes platform details and return value info, but the length is moderate. It is structured well; the platform breakdown is clear. Slight improvement would be trimming redundant details, but it's acceptable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (platform-specific stops), the description covers key behaviors: signals, packaging, polling, exporting, return fields, and failure. It lacks an output schema, so it properly explains the return value. It's complete for an agent to select and invoke this tool, especially with the precondition 'Call native-profiler-start first.'
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a detailed description for device_id. The description reiterates the parameter's origin ('from list-devices') and platform-specific formats, which slightly adds value beyond the schema. It doesn't explain any additional parameter aspects, but with one parameter well-covered, this is sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: stop native profiling and export trace data. It distinguishes from siblings like native-profiler-start and native-profiler-analyze by specifying the stop/export action. It is not just a verb+resource, but it does not explicitly mention that it is the inverse of start, though it says 'Call native-profiler-start first.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides concrete usage context: 'Call native-profiler-start first' sets a precondition, and 'Use when the user has finished the interaction to profile and you need to export the trace' gives a clear scenario. It doesn't explicitly mention when not to use or alternatives, but the 'call start first' is strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-user-interactable-view-at-pointA
Inspect the deepest UIView at a raw native window point that would actually receive touch input.
Unlike native-view-at-point, this respects userInteractionEnabled and is closer to UIKit hit-testing semantics.
Use when a tap lands somewhere unexpected or does nothing, to see which control UIKit would hand the touch to — a transparent overlay swallowing it, a parent recognizer, a disabled button.
Returns { status: "ok", view }: the hit-test winner with its class name, frames, identifier, label and layer name, its ancestor chain by default, and its subviews on request. view is null when no touchable view sits under that point.
IMPORTANT: x and y are raw iOS window coordinates in points, NOT normalized [0,1] simulator tap coordinates.
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help — restart the tool-server (argent server stop && argent server start --detach) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting — do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised — follow the message (re-boot the simulator) rather than retrying this tool.
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal — never retry it), and the point query itself can error or time out.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Raw X coordinate in the app window's native point space. NOT normalized [0,1] tap space. | |
| y | Yes | Raw Y coordinate in the app window's native point space. NOT normalized [0,1] tap space. | |
| udid | Yes | Simulator UDID | |
| fields | No | View fields to include. Defaults: pointer, className, tag, frame, windowFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor | |
| bundleId | Yes | Bundle ID of the app | |
| maxDepth | No | Maximum depth for returned child/ancestor serialization (default 150) | |
| skipClasses | No | Exact UIView class names whose entire subtree should be pruned | |
| includeChildren | No | Include child views for the matched view (default false) | |
| includeAncestors | No | Include ancestor chain for the matched view (default true) | |
| skipClassPrefixes | No | Class name prefixes to prune entire subtrees |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the transparency burden and does so thoroughly. It discloses return shape, null behavior, ancestor/subview defaults, raw coordinate semantics, all special statuses with concrete recovery steps (restart app, restart tool-server, wait), and failure cases such as Apple system apps being rejected outright.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but every sentence earns its place: purpose, comparison, use cases, return contract, coordinate warning, and detailed status handling. It is front-loaded with the core purpose and then moves into operational details, though the status block is dense and could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex 10-parameter tool with no output schema and no annotations. The description fully compensates by covering return values, coordinate semantics, defaults, status codes, recovery actions, and error boundaries. An agent has enough information to select, invoke, and interpret results correctly without guessing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds real value beyond the schema by explaining that x and y are raw iOS window coordinates NOT normalized [0,1] tap coordinates, and by clarifying default behaviors for ancestors and subviews that affect includeAncestors/includeChildren interpretation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action: inspecting the deepest UIView at a raw native window point that would actually receive touch input. It explicitly distinguishes itself from the sibling native-view-at-point by noting it respects userInteractionEnabled and follows UIKit hit-testing semantics.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear when-to-use guidance: 'Use when a tap lands somewhere unexpected or does nothing' and names the sibling alternative native-view-at-point as a contrast point. It also provides explicit do-not-retry/restart guidance for error statuses, which helps the agent decide whether to invoke or recover.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
native-view-at-pointA
Inspect the deepest visible UIView at a raw native window point.
Unlike native-user-interactable-view-at-point, this ignores userInteractionEnabled, so it answers "what is visually here?" rather than "what would receive the touch?".
Use when a screenshot shows something the accessibility tree does not name — an unlabeled icon, a decorative overlay, a custom-drawn cell — and you need the class, identifier or nativeID of whatever draws it.
Returns { status: "ok", view }: the matched view with its class name, frames, identifier, label and layer name, its ancestor chain by default, and its subviews on request. view is null when nothing is drawn at that point.
IMPORTANT: x and y are raw iOS window coordinates in points, NOT normalized [0,1] simulator tap coordinates.
If status is restart_required: follow the message (usually restart-app), then retry. If status is service_stale: the app is already injected, so restarting it cannot help — restart the tool-server (argent server stop && argent server start --detach) and retry. If the same status comes back after that restart, stop restarting: follow the message, which names the terminal fallback. If status is connect_pending: the app is injected and still connecting — do not restart it, wait a few seconds and retry. If status is init_failed: the simulator's native-devtools environment could not be initialised — follow the message (re-boot the simulator) rather than retrying this tool.
A not-connected or not-running app comes back as one of those statuses rather than a failure. Failures are separate: an Apple system app is rejected outright (terminal — never retry it), and the point query itself can error or time out.
| Name | Required | Description | Default |
|---|---|---|---|
| x | Yes | Raw X coordinate in the app window's native point space. NOT normalized [0,1] tap space. | |
| y | Yes | Raw Y coordinate in the app window's native point space. NOT normalized [0,1] tap space. | |
| udid | Yes | Simulator UDID | |
| fields | No | View fields to include. Defaults: pointer, className, tag, frame, windowFrame, bounds, hidden, alpha, opaque, clipsToBounds, userInteractionEnabled, depth, identifier, label, layerName, nativeID. Additional: center, transform, contentMode, backgroundColor, tintColor | |
| bundleId | Yes | Bundle ID of the app | |
| maxDepth | No | Maximum depth for returned child/ancestor serialization (default 150) | |
| skipClasses | No | Exact UIView class names whose entire subtree should be pruned | |
| includeChildren | No | Include child views for the matched view (default false) | |
| includeAncestors | No | Include ancestor chain for the matched view (default true) | |
| skipClassPrefixes | No | Class name prefixes to prune entire subtrees |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses the return format (status + view with class, frames, identifier, label, layer name, ancestor chain, subviews on request), the coordinate system (raw points, not normalized), and detailed error-handling for statuses (restart_required, service_stale, connect_pending, init_failed) and failure modes (system apps rejected). No contradictions with annotations since none are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured: it opens with the core purpose, then contrasts with a sibling, gives a use case, describes return structure, and concludes with status handling. Every paragraph covers a distinct aspect and includes necessary operational details. It could be slightly trimmed but remains efficient given the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (10 parameters, 4 required) and the absence of an output schema, the description is exceptionally complete. It covers the return value structure, all expected statuses with recovery steps, coordinate system specifics, and Edge cases (system app rejection). It leaves no major gaps for an agent to successfully use the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage of all 10 parameters, including descriptions for x/y coordinates and field lists. The description adds a warning about raw coordinates and clarifies default behavior (e.g., includeAncestors defaults true), but these are already in the schema. It does not significantly add value beyond what the schema documents, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it inspects the deepest visible UIView at a raw native window point, and explicitly contrasts with native-user-interactable-view-at-point, distinguishing it as answering 'what is visually here?' rather than 'what would receive the touch?'. This makes the purpose specific and distinct from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit when-to-use guidance: 'Use when a screenshot shows something the accessibility tree does not name — an unlabeled icon, a decorative overlay, a custom-drawn cell'. It also names the sibling alternative and explains the difference, fulfilling the when/when-not requirement fully.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open-urlA
Open a URL or URL scheme on the device. Use to navigate to a web page or deep-link into an app. On Chromium, this navigates the primary renderer to the given URL. Cross-platform schemes: https://, tel:, mailto:. iOS also: messages://, settings://, maps://. Android also: geo:, plus any app-specific deep link. Deep-linking caveat: an https:// link opens the native app only when an installed app is verified for the link's domain (iOS Universal Links / Android App Links) — otherwise it opens in the browser, and on iOS simulators it may open in Safari even when the owning app is installed. To reliably open an installed app, use its custom scheme (scheme://path) or launch-app with its bundle id. On a physical iPhone, http(s) URLs default to Safari and any other scheme needs bundleId; the receiving app becomes the app under automation. Returns { opened, url, note? }. note carries the deep-linking caveat when a web URL was opened on a native device. Fails if no app is registered to handle the URI (iOS/Android) or the renderer rejects the navigation (Chromium).
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL or scheme to open (e.g. https://example.com, messages://, tel:555, geo:37.0,-122.0). For Chromium this navigates the renderer. | |
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, or Chromium id). | |
| bundleId | No | Physical iOS only: the app that receives the URL. Defaults to Safari for http(s); required for any other scheme. Ignored elsewhere. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it succeeds. It discloses platform-specific behavior (Chromium renderer navigation, iOS Universal Links vs Android App Links, physical iPhone Safari default), the return shape { opened, url, note? }, and failure conditions when no app is registered or the renderer rejects navigation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but not bloated; every sentence covers an operational distinction. It front-loads the core action and use case, then adds platform caveats, return values, and failure behavior in a logical order.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and no annotations, the description is fully self-contained: it covers all parameters implicitly, platform differences, the return object, the note caveat, and failure modes. Nothing an agent needs to invoke this correctly and interpret results is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by explaining the deep-linking caveat for https URLs and detailing which schemes are valid on each platform, which helps agents choose the right url value and understand when bundleId is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Open a URL or URL scheme on the device.' It clearly distinguishes this tool from launch-app by stating that launch-app is the reliable route for opening installed apps, while open-url handles web pages and deep links.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly gives usage context: navigate to web pages, deep-link into apps, and which schemes are supported per platform. It also names the alternative (launch-app) and tells the agent when to use it instead: 'To reliably open an installed app, use its custom scheme (scheme://path) or launch-app with its bundle id.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pasteA
Paste text into the focused field: puts text on the DEVICE clipboard (the host clipboard is untouched), then triggers the platform's paste shortcut (iOS simulator, Android emulator).
Do NOT use this in place of keyboard. keyboard types as a user would and is the default for all text entry; use paste only where a real user would paste — a 2FA/OTP code copied from another app, a long link or token, or when testing the app's own paste handling.
Tap the field first so it has focus. Returns { pasted: true }. Fails on a TV target, when the device clipboard cannot be set, or when the simulator-server build lacks clipboard support.
Supports {{secret:<NAME>}} placeholders like keyboard; the value is never echoed back.
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes | Text to put on the device clipboard and paste into the focused field. Supports `{{secret:<NAME>}}` placeholders, resolved on the tool-server from the `ARGENT_SECRET_<NAME>` environment variable or an argent secrets file — the same sources as `keyboard` — so a credential never enters your context. If the secret is not set, the failure lists the available names and every source it looked in; ask the user to add it there, NEVER ask for the value in the conversation. | |
| udid | Yes | Target device id from `list-devices` (iOS simulator UDID or Android emulator serial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and does so exceptionally well. It discloses that only the device clipboard is affected (host clipboard untouched), that a paste shortcut is triggered, that it returns `{ pasted: true }`, and it lists specific failure conditions (TV target, clipboard failure, missing simulator-server support). It also explains the secret placeholder behavior and that secrets are never echoed back.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the core behavior, and every sentence earns its place: mechanism, usage boundaries, prerequisites, return value, failure modes, and secret handling. No fluff or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete for a tool of this complexity. It covers what happens, when to use it, prerequisites, return shape, failure conditions, and security-relevant secret behavior. The absence of an output schema is mitigated because the return value is explicitly stated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100%, with detailed per-parameter descriptions, so the baseline is 3. The tool description adds organic context beyond the schema: the text parameter's clipboard-vs-host behavior, the same-source relationship with `keyboard` for secrets, and the requirement that the target field have focus. This adds meaningful conceptual value, though the schema already documents the main mechanics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Paste text into the focused field', and explains the mechanism clearly (device clipboard + platform paste shortcut). It explicitly distinguishes itself from the sibling `keyboard` tool, both in purpose and in the user-action model.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: use `paste` only where a real user would paste, such as 2FA codes, long links/tokens, or testing paste handling. It also gives a clear negative instruction: 'Do NOT use this in place of `keyboard`', and provides a prerequisite step ('Tap the field first').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profiler-combined-reportA
Generate a cross-correlated report combining React Profiler and native profiler data. Maps native hangs to React commits using wall-clock time alignment. Requires both react-profiler-analyze and native-profiler-analyze to have been called first. Call this tool when both profilers were run in parallel on the same session. Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints. Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| device_id | Yes | iOS Simulator/device UDID or Android serial |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the method (wall-clock time alignment), output format (markdown report), and behavior on failure (fails if prerequisites not met). No contradictory annotation exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, well-organized, and front-loaded with the main purpose. Every sentence contributes value—purpose, method, prerequisites, usage context, output, and failure condition—without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers what the tool does, its prerequisites, its output, and its failure modes. For a tool with only two simple parameters and no output schema, this is complete and sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the description adds no parameter-specific meaning beyond what the schema already provides. Baseline 3 is appropriate as the schema fully documents the parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: generating a cross-correlated report combining React Profiler and native profiler data. It distinguishes itself from siblings by specifically combining both data sources and mapping native hangs to React commits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states prerequisites (both profiler analyze tools must have been called first), when to use it (when both profilers ran in parallel on the same session), and failure conditions. This provides clear guidance on proper usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profiler-commit-queryA
Query React commit data for iterative investigation of render performance. Requires react-profiler-stop to have been called first. Modes:
by_component: All commits where a specific component rendered, with causes and durations.
by_time_range: What happened in a specific time window.
by_index: Full detail dump of a single commit (all components, props changed, parent cascade).
cascade_tree: Parent-child cascade tree for a commit showing who triggered whom. Use when drilling into specific components or time windows after react-profiler-analyze. Returns a markdown table or tree of commit data matching the requested mode. Fails if react-profiler-stop has not been called or no commit data is stored.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | Query mode: by_component (commits for a component), by_time_range (commits in a window), by_index (full detail for one commit), cascade_tree (parent-child cascade for a commit) | |
| port | No | Metro server port | |
| top_n | No | Max results to return. Defaults to 20 for by_component / by_time_range, which count commits. by_index counts individual fibers and returns all of them unless this is set, because one commit's fibers collapse to far fewer distinct components — a small cap there can show less than the analyze report it is meant to expand on. | |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). | |
| commit_index | No | Commit index for by_index and cascade_tree modes | |
| time_range_ms | No | Time range filter for by_time_range mode | |
| component_name | No | Component name for by_component mode |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of behavioral disclosure, and it does well: it explains the four query modes, states that output is a markdown table or tree, and discloses failure conditions ('Fails if react-profiler-stop has not been called or no commit data is stored'). It does not explicitly state that the tool is read-only, but 'Query' and the output/return framing imply no mutation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a one-sentence purpose, a required precondition, a compact mode list, a use-case pointer, an output summary, and a failure condition. Every sentence contributes useful information without repetition or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (7 parameters, nested time_range object, 4 modes, no output schema), the description provides a complete picture: purpose, preconditions, mode semantics, return type, and failure modes. It complements the 100% schema coverage well and leaves no major operational gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful semantic value beyond the schema by explaining each mode's behavior and result shape, e.g., 'by_component: All commits where a specific component rendered, with causes and durations.' It also clarifies the mode-specific meaning of top_n through the schema description, which is reinforced conceptually by the mode list.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Query React commit data for iterative investigation of render performance.' It clearly distinguishes the tool from siblings by focusing on commit-level query modes (by_component, by_time_range, by_index, cascade_tree) and explicitly frames it as follow-up drilling after react-profiler-analyze.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: 'Requires react-profiler-stop to have been called first' and 'Use when drilling into specific components or time windows after react-profiler-analyze.' It also states failure conditions. It lacks an explicit excluded-alternative statement, but the context is sufficiently clear to guide tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profiler-cpu-queryA
Query Hermes CPU profile data with targeted modes for iterative investigation. Requires react-profiler-stop (and ideally react-profiler-analyze) to have been called first. Modes:
top_functions: Global CPU hotspots ranked by self-time. Optional time_window_ms to filter.
time_window: CPU breakdown for a specific time range (e.g. during a slow commit or hang).
Self-times are the summed sampling intervals of the samples that landed in the window, so they measure sampled coverage rather than the window's width and do not change if you widen the query. Every table states how many samples it covers and how much of that was idle.
call_tree: For a given function_name, show its callees and optionally callers.
component_cpu: For a given component_name, aggregate CPU activity across all its commits. Use when investigating JS CPU hotspots or correlating CPU cost with specific components. Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown. Fails if no CPU profile is stored — run react-profiler-stop first.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | Query mode: top_functions (global hotspots), time_window (CPU in a time range), call_tree (callers/callees of a function), component_cpu (CPU during a component's commits) | |
| port | No | Metro server port | |
| top_n | No | Number of results to return (default 15) | |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). | |
| function_name | No | Function name for call_tree mode | |
| component_name | No | Component name for component_cpu mode | |
| time_window_ms | No | Time window filter for time_window mode (ms since profiling started — the same clock profiler-commit-query prints) | |
| include_callers | No | For call_tree mode: also show callers of the function |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses a crucial sampling behavior (self-times are summed sampling intervals and do not change when widening a window), states that every table shows covered samples and idle fraction, and notes the fatal failure condition. This goes well beyond a generic description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose and prerequisite, then presents modes in a compact bullet-style list, adds the nuanced sampling explanation, and ends with a usage hint and failure condition. Every sentence adds value; no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 8 parameters, no output schema, and no annotations, the description is remarkably complete: it explains modes, parameter roles, return format ('markdown table'), preconditions, and failure behavior. The subtle sampling caveat fills a gap that could mislead users into thinking wider windows increase data.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema provides detailed per-parameter descriptions. However, the description adds extra semantic context for key parameters beyond the schema: it explains the meaning of time_window_ms (the clock reference 'same clock profiler-commit-query prints') and connects function_name/component_name to their modes. Slight deduction because not every parameter is explicitly tied to a mode in the description (port, top_n), but the schema covers those.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Query') and resource ('Hermes CPU profile data'), enumerates the four modes (top_functions, time_window, call_tree, component_cpu), and explains what each returns. It clearly distinguishes from sibling profiler tools by scoping to CPU ('CPU profile data', 'CPU hotspots') vs the react-profiler-* / native-profiler-* / profiler-commit-query / profiler-stack-query siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use ('Use when investigating JS CPU hotspots or correlating CPU cost with specific components') and names the required prerequisite ('Requires react-profiler-stop (and ideally react-profiler-analyze) to have been called first'). It also warns of failure mode if the prerequisite is not met ('Fails if no CPU profile is stored — run react-profiler-stop first').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profiler-loadA
Fetch and restore a previously captured profiling session from disk into memory so query tools can operate on it. This is the disk-restore counterpart to react-profiler-stop/native-profiler-stop, which write data, and to the query tools (profiler-cpu-query, profiler-commit-query, profiler-stack-query), which read it. Use when you need to revisit past session data without capturing a new recording. Modes:
list: Show all available profiling sessions in the project's debug directory.
load_react: Load a React profiler session (CPU profile + commit tree) into memory. Requires session_id.
load_native: Re-parse native profiler XML files into memory. Requires session_id and device_id. For Android .pftrace restores, pass app_process for older sessions that do not have a metadata sidecar. Returns a summary of the loaded session or a session list for the list mode. Fails if the session_id is not found or required XML files are missing from disk.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | list: show available sessions on disk. load_react: load a React profiler session into memory for query tools. load_native: re-parse native profiler XML files (xctrace on iOS) into memory for query tools. | |
| port | No | Metro port — the loaded React data is cached under this port for query tools (default 8081) | |
| device_id | Yes | Target device id from `list-devices`. Used to cache the loaded React session under the correct port+device key, and required to resolve the native profiler session for load_native. | |
| session_id | No | Timestamp-based session identifier (e.g. '20250313-143022') from the list output. Required for load_react and load_native modes. | |
| app_process | No | Android package name to use when restoring older load_native .pftrace sessions that do not have a metadata sidecar. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It covers the core disk-to-memory restore behavior, return types for each mode, failure cases when data is missing, and the special app_process handling for older Android sessions. It stops short of specifying what happens to previously loaded sessions or cache keys, but the main operational behavior is clearly conveyed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: the main purpose is stated first, followed by differentiation, usage guidance, a scannable mode list, and failure conditions. Each sentence contributes operational or decision-making value without unnecessary repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with five parameters, three modes, no output schema, and no annotations, the description is sufficiently complete. It explains what the tool does, when to use it, what each mode does, what inputs are required for each mode, what it returns, and when it fails. This gives the agent enough context to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3 even with no extra parameter semantics in the description. The description does add some mode-level context around session_id, device_id, and app_process, but most parameter meaning is already fully captured in the input schema. It does not significantly go beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Fetch and restore a previously captured profiling session from disk into memory.' It clearly distinguishes itself from sibling tools by naming the write-side tools (react-profiler-stop/native-profiler-stop) and the read-side query tools (profiler-cpu-query, profiler-commit-query, profiler-stack-query), and by listing its three modes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool: 'Use when you need to revisit past session data without capturing a new recording.' It also provides mode-specific prerequisites (session_id for load_react/load_native, device_id for load_native, app_process for older Android sessions) and describes failure conditions, giving the agent clear decision guidance versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profiler-stack-queryA
Query native profiler trace data for iterative investigation of native performance. Requires native-profiler-stop → native-profiler-analyze to have been called first. Modes:
hang_stacks: Full CPU context during a specific hang (by hang_index).
function_callers: Who calls a specific native function and what it calls.
thread_breakdown: CPU time split by thread, optionally filtered.
leak_stacks: Memory leak details (iOS only), optionally filtered by object_type. Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze. Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode. Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | Query mode: hang_stacks (full CPU context during a hang), function_callers (who calls a native function), thread_breakdown (CPU split by thread), leak_stacks (leak details by object type) | |
| top_n | No | Max results to return (default 15) | |
| thread | No | Thread filter. thread_breakdown: case-insensitive substring match. function_callers: exact raw thread name (e.g. ".blueskyweb.app"), or "main" for the UI thread; omit to search ALL threads (each result is tagged with its thread). Run thread_breakdown first to see the exact raw names. | |
| device_id | Yes | iOS Simulator UDID or Android serial. | |
| hang_index | No | 0-based index into the hang list for hang_stacks mode | |
| object_type | No | Object type filter for leak_stacks mode | |
| function_name | No | Function name for function_callers mode |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the behavioral burden. It discloses the prerequisite, failure condition ('Fails if native-profiler-analyze has not been run'), iOS-only restriction for leak_stacks, and return format (markdown report). It doesn't explicitly state read-only or side effects, but 'Query' and the failure discussion make it clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is well-structured and front-loaded: prerequisite first, then bulleted modes, usage guidance, return type, and failure condition. Every sentence contributes meaningful information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter tool with no annotations and no output schema, the description covers prerequisites, mode behavior, filters, output type, and error cases. It could be slightly more complete with an example invocation or more detail on the iterative workflow, but it is nearly sufficient for an agent to select and use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces mode semantics and adds small details (e.g., function_callers shows what a function calls, leak_stacks is iOS-only), but it does not significantly expand on the parameter schema, which already documents behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses specific verb 'Query' with clear resource 'native profiler trace data' and enumerates four distinct modes with precise behaviors. It clearly distinguishes from sibling profiler tools by specifying that native-profiler-analyze must have been called first.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states prerequisite chain ('Requires native-profiler-stop → native-profiler-analyze') and gives a clear use case: 'Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze.' However, it does not name alternatives or explicitly state when not to use this tool versus other profiler query tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-analyzeA
Analyze stored profiling data and return a markdown performance report. Returns { report, reportFile, hotCommitsTotal, hotCommitsShown, sessionFiles }. The report is structured around hot React commits (≥16ms absolute floor) with per-commit render cascades, root cause identification, and a top components table. Raw profiling data is saved to disk with a unique session timestamp for later reload via profiler-load. After presenting the report, ask the user whether to investigate further (drill-down with profiler-cpu-query / profiler-commit-query) or implement fixes and re-profile for comparison. Requires react-profiler-stop to have been called first. Optional annotations param: provide Array<{offsetMs, label}> to annotate commits with the user action that preceded them. Compute offsetMs = tapTimestampMs - startedAtEpochMs where tapTimestampMs is the timestampMs returned by the tap/swipe tool and startedAtEpochMs is returned by react-profiler-start. Use when the profiling session is complete and you need to interpret the collected data. Fails if react-profiler-stop has not been called or no profiling data is stored.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| platform | No | Target platform | ios |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). | |
| rn_version | No | React Native version (e.g. "0.73.4") | unknown |
| annotations | No | Optional list of user actions with their time offset from profiling start. Compute offsetMs = tapTimestampMs - startedAtEpochMs, where tapTimestampMs comes from the tap/swipe tool return value and startedAtEpochMs comes from react-profiler-start return value. | |
| project_root | Yes | Absolute path to the RN project root for session context detection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully bears the burden of transparency. It details the output structure, that raw data is saved to disk for later reload via profiler-load, the report's focus on hot commits, and the prerequisite of react-profiler-stop. It also explains the annotations parameter's calculation. No contradictions exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: first sentence states purpose and output, followed by report structure, annotations explanation, prerequisites, and usage flow. At around 180 words, it is concise but could slightly reduce repetition (e.g., offsetMs explanation appears twice). Still, it efficiently conveys all necessary information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, no output schema, multiple sibling tools), the description is highly complete. It covers prerequisites, output shape, report structure, failure conditions, workflow after report, and relationship to other tools. The absence of an output schema is compensated by detailing the return fields. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by thoroughly explaining the 'annotations' parameter, including how to compute offsetMs using other tool outputs (tap/swipe and react-profiler-start). For other parameters, it largely repeats schema descriptions but provides helpful context (e.g., linking device_id to debugger-connect). This additional guidance justifies a score above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Analyze stored profiling data and return a markdown performance report.' It specifies the output fields and report structure, and distinguishes itself from sibling tools by outlining the workflow and mentioning related profiler tools for drill-down, such as profiler-cpu-query and profiler-commit-query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: 'Use when the profiling session is complete and you need to interpret the collected data.' It states the prerequisite ('Requires react-profiler-stop to have been called first'), describes the post-report workflow (ask user about further investigation), and explains how to compute the optional annotations parameter. It also mentions failure conditions, offering complete usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-component-sourceA
Find a React component's source via tree-sitter AST lookup: returns file path, line number, memoization status (isMemoized, hasUseCallback, hasUseMemo), and 50 lines of source for a named React component. Call this per-finding after react-profiler-analyze to inspect source before proposing a fix. Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules). When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col) — check it before assuming the returned file is the one you meant.
| Name | Required | Description | Default |
|---|---|---|---|
| project_root | Yes | Absolute path to the RN project root | |
| component_name | Yes | Name of the React component to look up |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behaviors: returns found:false for node_modules components, handles multiple matches with otherMatches[], returns 50 lines of source and memoization status. No destructive actions mentioned; for a read tool this is sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Only two sentences, front-loaded with primary function and output, then usage instruction and edge cases. Every sentence adds value; no waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description thoroughly covers return values (file path, line number, memoization, 50 lines of source, found status, otherMatches). Also explains the not-found case and ambiguity handling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and description adds context like component_name for lookup and project_root for file system. Also explains how parameters are used in the context of multiple matches.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Find' and resource 'React component's source', listing exact return fields. It distinguishes itself from siblings like debugger-component-tree by stating its specific role in the profiling workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Call this per-finding after react-profiler-analyze to inspect source before proposing a fix.' Provides clear context but no explicit exclusion of alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-cpu-summaryA
Return a raw Hermes CPU flamegraph summary (top hotspot functions by self-time). FOR DEDICATED CPU INVESTIGATION ONLY — do NOT call this as part of a normal profiling session. Use react-profiler-analyze instead; it covers all React rendering performance analysis. Use when you specifically need to investigate JS CPU hotspots that are NOT tied to React rendering (e.g. regex slowness, cryptography, heavy computations). Call react-profiler-stop first. Reads directly from the stored cpuProfile. Returns a markdown table of the top hotspot functions with self-time, total-time, and location. Fails if react-profiler-stop has not been called or no CPU profile is stored.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| top_n | No | Number of top hotspot functions to return (default 20) | |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). | |
| react_only | No | If true, only show React component functions (PascalCase names) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavior: reads from stored cpuProfile, requires prior call to 'react-profiler-stop', returns a markdown table, and fails if prerequisites are not met. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear purpose, usage, prerequisites, and return format. It is slightly repetitive (e.g., 'do NOT call' is implied by alternatives) but every sentence adds value. Few words could be trimmed for conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description explains the return value format (markdown table with self-time, total-time, location). It covers prerequisites, failure conditions, and source. Tool complexity is moderate (4 params, no output schema), and description is thorough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% (all 4 parameters have descriptions). The tool description does not add significant new semantics beyond the schema, except for describing the overall return format (markdown table with fields). Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a raw Hermes CPU flamegraph summary with top hotspot functions by self-time. It distinguishes from sibling tools by specifically naming 'react-profiler-analyze' as the alternative for broader React performance analysis.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides when to use (dedicated CPU investigation for non-React hotspots) and when not to use (normal profiling session). Recommends 'react-profiler-analyze' as alternative and lists prerequisite: call 'react-profiler-stop' first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-fiber-treeA
Inspect the React fiber tree and return a JSON representation of the component hierarchy. Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component). Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children. Fails if the React DevTools hook is not present or no fiber roots have been committed yet.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| filter | No | Regex string to filter component names | |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). | |
| max_depth | No | Maximum tree depth to traverse (default 10) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It describes the output structure (name, tag, actualDuration, etc.) and failure cases (missing DevTools hook or no committed roots). This is sufficient transparency for a read-like operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is five sentences, each adding distinct value: purpose, usage guidance, output format, failure conditions. No fluff, front-loaded with the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters, no output schema, and no annotations, the description explains the output structure and failure modes adequately. It could benefit from an example or note about performance, but overall it is sufficient for an agent to use correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with descriptions for all 4 parameters. The description does not add additional meaning beyond what the schema already provides, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Inspect the React fiber tree and return a JSON representation of the component hierarchy.' This is a specific verb (inspect) and resource (fiber tree) that differentiates it from siblings like react-profiler-analyze or react-profiler-renders.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use when tracing ancestry of a library component or checking for useMemoCache hook'. It also states failure conditions. While it doesn't list when not to use it vs alternatives, the guidance is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-rendersA
Scan the live React fiber tree to collect component render counts and durations. Returns a markdown table of the top re-rendering components. No profiling session required — works on a live connected app. Use when you want a quick snapshot of render counts without a full profiling session. Fails if the React DevTools hook is not present in the runtime or the app is not connected.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| top_n | No | Number of top re-rendering components to return (default 20) | |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description must cover behavior. It discloses failure conditions and that it works on a live app, but does not mention read-only nature or performance impact, which would be helpful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no wasted words; front-loaded with action and main value, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage context, failure conditions, and output format (markdown table). Lacks details on response structure but is adequate for a focused tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the description does not need to add parameter details. It adds no extra meaning beyond the schema, meeting the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'scan' and the resource 'live React fiber tree', and it explicitly distinguishes from sibling profiling tools by noting 'no profiling session required'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly recommends use for 'quick snapshot...without a full profiling session', but could clarify when not to use it or contrast with specific siblings like react-profiler-analyze.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-startA
Start CPU profiling + React commit capture on the connected Hermes runtime. Delegates React commit capture to the in-app React DevTools backend (ri.startProfiling). If another tool-server already owns the session, returns { already_running: true, owner, stale, how_to_reclaim } without clobbering their data. Pass { force: true } to reclaim a fresh owner's session, but BEFORE OVERTAKING - ask the user for approval first, see relevant skill for guidance. Before calling this, ask the user if they also want native profiling (native-profiler-start) — recommend running both in parallel for a complete picture. After starting, ask the user to perform the interaction to profile, then call react-profiler-stop. Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above. Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| force | No | Take over an active profiling session even when it is owned by another tool-server and still fresh. Set to true only when you know the prior owner is gone. | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). | |
| sample_interval_us | No | CPU sampling interval in microseconds (default 100) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations exist, description carries full burden. It discloses delegation to in-app backend, returns already_running payload without clobbering, force reclaim behavior, and failure conditions (Hermes unreachable, Metro connection fail). However, does not mention potential performance impact or state modifications beyond profiling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Each sentence earns its place: main action, delegation, special case, usage guidance, return values, failure conditions. Well-structured with logical flow. Slightly longer than minimal but no dead content. Could be condensed slightly but remains efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 4 parameters, no output schema, and moderate complexity, the description covers purpose, usage workflow, behavioral edge cases, failure modes, and integration with sibling tools. It fully addresses the information gap needed for an AI agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all 4 parameters described in schema). The description adds context for the force parameter (user approval before overtaking), which goes beyond the schema description. For other parameters, schema suffices, so description adds moderate extra semantic value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Start CPU profiling + React commit capture on the connected Hermes runtime,' which clearly states the verb (start) and resource (profiling on Hermes runtime). It distinguishes from siblings like native-profiler-start and react-profiler-stop by mentioning delegation to React DevTools backend and the parallel native profiling recommendation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: ask user about native profiling before calling, recommend running both in parallel, ask user to perform interaction after starting, then call react-profiler-stop. Also explains when to use force=true and warns to get user approval before overtaking another session. No alternative guidance is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-statusA
Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session — no token-threading is required. Returns { session_status, is_running, current_owner, … }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| device_id | Yes | Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses side-effect-free nature, server-side ownership verification, absence of token-threading, return fields, and the taken_over behavior after process restart. This is comprehensive for a status check tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Relatively concise with no redundant information, but slightly dense. Each sentence adds meaningful context. Could be more structured (e.g., bullet points) but still effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately explains return shape and important states (taken_over). Also clarifies ownership verification and token handling. Fully addresses likely agent questions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by linking device_id to debugger-connect and noting port's default, but does not elaborate further. Slight improvement over baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the verb 'Check' and resource 'state of the React profiler session', with the critical qualifier 'without side effects'. Distinguishes from sibling tools like react-profiler-start/stop by focusing on status inspection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly specifies when to use (after interruption) and provides decision guidance: continue with stop, start new session, or reconnect. Even gives a concrete alternative command (react-profiler-start { force: true }) for the taken_over case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
react-profiler-stopA
Stop CPU profiling and collect the cpuProfile + React commit tree. Reads commit data from the in-app React DevTools backend. Stores results in the ReactProfilerSession for later use by react-profiler-analyze or react-profiler-cpu-summary. Call react-profiler-start first, then exercise the app, then call this. Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices } summarizing the session. When any commit had fibers whose display name could not be resolved at stop time (typically transient components like modals/tooltips/animations that unmounted before stop), the response also includes { unattributed_ms, unattributed_fiber_count, unattributed_commit_count } — these quantify how much work is not accounted for in the per-component breakdown (the per-commit duration itself remains correct). Fails if no active profiling session exists or the CDP connection was lost during recording.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| device_id | Yes | Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: it reads from the in-app React DevTools backend, stores results, and details the return structure. It also explains edge cases with unattributed data when fibers unmount before stop.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single paragraph but well-structured with logical flow: action, source, storage, sequence, return, edge case. Each sentence adds value without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 2 parameters (100% schema coverage) and no output schema, the description comprehensively covers purpose, usage, return fields, and edge cases. It also positions the tool within the profiling workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents parameters. However, the description adds context: port defaults to 8081, device_id must be the same as passed to debugger-connect. This enhances understanding beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it stops CPU profiling and collects the cpuProfile + React commit tree. It specifies the action (stop), resource (CPU profiling), and outcome (collect data). It distinguishes from siblings like native-profiler-stop by mentioning React-specific data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a clear usage sequence: call react-profiler-start first, then exercise the app, then call this. It also mentions failure conditions (no active session or CDP lost). It does not explicitly state when not to use, but the sequence is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reinstall-appA
Install or reinstall an app on the device. The previous installation (if any) is uninstalled first so app data and runtime permissions are cleared. Use for a full reinstall after rebuilding, or to start from a clean app state. Returns { reinstalled, bundleId }. Fails if the app path does not exist or the package does not match the platform (.app for iOS, .apk for Android, .vpkg for Vega).
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| appPath | Yes | Path to the app bundle. iOS: `.app` directory (e.g. ./build/.../MyApp.app). Android: `.apk` file (e.g. android/app/build/outputs/apk/debug/app-debug.apk). Vega: `.vpkg` file. Relative paths are resolved from the current working directory. | |
| bundleId | Yes | App identifier that matches the bundle at `appPath`. iOS: bundle id (used to uninstall first). Android: package name (used to uninstall first; the install itself identifies the app from the APK). Vega: interactive component app id (e.g. com.example.app.main), used to uninstall first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description thoroughly discloses key behaviors: uninstalls first, clears data and permissions, return value shape, and failure conditions (path existence, platform mismatch).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences front-loading the main purpose, with no unnecessary words. Efficient and clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers return value shape, failure conditions, and platform-specific details. Without an output schema, the description provides sufficient context for an agent to understand the tool's behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with detailed descriptions for all three parameters. The main description does not add extra parameter-specific meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('install or reinstall') and resource ('app on the device'), and distinguishes from siblings like 'launch-app' and 'restart-app' by emphasizing reinstallation and data clearing.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'full reinstall after rebuilding' or 'start from a clean app state'. Does not explicitly mention alternatives or when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restart-appA
Terminate then relaunch an app by bundle id / package name. Use when you need a clean in-memory state without a full reinstall. Also refreshes the native-devtools injection before the relaunch (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven — use the tv-* tools rather than coordinate taps. Returns { restarted, bundleId }. Fails if the app is not installed.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| activity | No | Android-only: relaunch a non-launcher Activity (e.g. `.SettingsActivity` or `com.example/com.example.SettingsActivity`). If omitted, the app's default launcher activity is used. Ignored on iOS. | |
| bundleId | Yes | App identifier. iOS: bundle id. Android: package name. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses terminating and relaunching, refreshing native-devtools injection, tvOS focus-driven interaction, return value, and failure condition. Missing potential side effects like persistence of app data, but the tool's purpose (restart) implies no data loss beyond state. Overall transparent for the operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: action, usage scenario, platform-specific behavior, outcome/failure. Front-loaded with main purpose. No unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema, but description specifies return format '{restarted, bundleId}', which is sufficient. Covers parameters (all in schema) and platform specifics (tvOS vs iOS). Could mention that app data persists, but not required for basic understanding. Complete for a simple restart tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. Description adds context like 'udid' from 'list-devices' and notes 'activity' is Android-only, which is already in schema. No additional semantics beyond schema that significantly aid selection.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb 'Terminate then relaunch' and the resource 'app by bundle id / package name'. It distinguishes from sibling tools like 'reinstall-app' by noting 'without a full reinstall' and from 'launch-app' by implying a restart rather than fresh launch. Also mentions tvOS-specific behavior, differentiating from other tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when you need a clean in-memory state without a full reinstall', providing when-to-use guidance. Also advises on tvOS to use 'tv-* tools rather than coordinate taps', which is an exclusion. States failure condition 'Fails if the app is not installed'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rotateA
Set the device orientation to Portrait, LandscapeLeft, LandscapeRight, or PortraitUpsideDown.
Use to test layout in a different orientation. Re-run describe afterwards — frame coordinates change with the orientation.
Returns { orientation }. Fails if the target device is not booted.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| orientation | Yes | Target orientation |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that frame coordinates change, that the tool returns `{ orientation }`, and that it fails if the device is not booted. Since no annotations are provided, the description carries the full burden and does so well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, no wasted words. Front-loaded with purpose and allowed values.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, usage context, side effect, failure condition, and return value. For a simple two-parameter tool with no output schema, this is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. Description does not add further meaning beyond what the schema provides for the two parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (set device orientation), lists the four allowed values, and sets it apart from sibling tools like gesture-rotate which handles rotation gestures.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises to use before testing layout in a different orientation and to re-run `describe` afterwards. Does not mention alternatives or when not to use, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run-sequenceA
Execute multiple device interaction steps in a single call (iOS simulator or physical device, Android emulator, Apple TV / Android TV, or Chromium app).
On a physical iOS device only gesture-tap, gesture-swipe, gesture-custom, button, keyboard, and await-ui-element steps run; others fail at their own gate.
Use when you need sequential actions and do NOT need to observe the screen between them
(e.g. scrolling multiple times, typing then pressing enter, rotating back and forth).
Returns { completed, total, steps } with per-step results. Fails if an unrecognised tool name is used in a step (error returned at that step, execution stops).
One screenshot is captured automatically after the whole sequence (not per step) — call screenshot separately only for a baseline BEFORE it, or to observe an intermediate step.
That single capture is also why a secret belongs in this call rather than in two bare ones: the skip is decided from the whole request, so a {{secret:...}} in any step suppresses the capture that would otherwise follow the submit.
ONLY use this when every step is known in advance. If any step depends on the result of a previous one (e.g. tapping a menu item that only appears after a prior tap), use individual tool calls instead.
Allowed tools and their args (udid is auto-injected, do NOT include it in args):
gesture-tap: { x: number, y: number, clickCount?: number } [ios/android/chromium] gesture-swipe: { fromX: number, fromY: number, toX: number, toY: number, durationMs?: number, momentum?: boolean } [ios/android] gesture-scroll: { x: number, y: number, deltaX?: number, deltaY?: number, durationMs?: number } [chromium only] gesture-drag: { fromX: number, fromY: number, toX: number, toY: number, durationMs?: number, momentum?: boolean } [chromium only] gesture-custom: { events: [{ type: "Down"|"Move"|"Up", x: number, y: number, x2?: number, y2?: number, delayMs?: number }], interpolate?: number } [ios/android] gesture-pinch: { centerX: number, centerY: number, startDistance: number, endDistance: number, endCenterX?: number, endCenterY?: number, angle?: number, durationMs?: number } [ios/android] gesture-rotate: { centerX: number, centerY: number, radius?: number, radiusX?: number, radiusY?: number, startAngle: number, endAngle: number, durationMs?: number } [ios/android] button: { button: "home"|"back"|"power"|"volumeUp"|"volumeDown"|"appSwitch"|"actionButton" } [ios/android] keyboard: { text?: string, key?: string, delayMs?: number } (text OR key per step, never both; TV: text only) [ios/android/chromium/vega/tv] text supports {{secret:}} placeholders, resolved server-side from ARGENT_SECRET_ env vars or an argent secrets file — credentials never enter agent context paste: { text: string } (device clipboard + paste shortcut; only where a user would paste, e.g. an OTP — keyboard otherwise) [ios sim/android emu] rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android] shake: { count?: number } [ios sim/android emu] tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega] buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute — work on Android TV and Vega; rejected on the Apple TV simulator) await-ui-element: { condition: "exists"|"visible"|"hidden"|"text", selector: {text?,identifier?,role?}, expectedText?, timeoutMs?, pollIntervalMs? } [ios/android/chromium]
Example — scroll down three times (use gesture-scroll with positive deltaY on Chromium): { "udid": "", "steps": [ { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } } ]}
Example — type text and submit (two keyboard steps; one call cannot carry both): { "udid": "", "steps": [ { "tool": "keyboard", "args": { "text": "hello world" } }, { "tool": "keyboard", "args": { "key": "enter" } } ]}
Example — TV: move focus right twice then activate (one tv-remote step with a path is cheaper): { "udid": "", "steps": [ { "tool": "tv-remote", "args": { "button": ["right", "right", "select"] } } ]}
Example — tap, wait for the next screen's element, then tap it: { "udid": "", "steps": [ { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.9 } }, { "tool": "await-ui-element", "args": { "condition": "visible", "selector": { "text": "Continue" } } }, { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.5 } } ]} If the await-ui-element condition is not met before its timeout, the sequence stops there and the following steps do NOT run — so the tap above only fires once "Continue" is actually on screen.
Stops on the first error (or unmet await-ui-element condition) and returns partial results.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, Vega serial, or Chromium id) — shared across all steps. | |
| steps | Yes | Ordered list of interaction steps to execute sequentially |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it delivers: it discloses stop-on-first-error behavior, partial results, the automatic single screenshot after the sequence, the secret-suppression interaction with that screenshot, physical iOS step restrictions, and the platform compatibility matrix. This is extensive behavioral disclosure well beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long, but every section earns its place: summary, usage guidance, per-tool argument matrix, platform tags, examples, and failure semantics. It is front-loaded with the core purpose and usage rule before the detailed tool matrix, and the examples are compact and targeted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description states the return shape ({ completed, total, steps }), error behavior, screenshot behavior, secret handling, and per-step tool contracts. For a complex multi-step orchestration tool, this is a complete and self-sufficient definition.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds substantial meaning: a complete allowed-tools and args reference, the note that udid is auto-injected and must not appear in args, keyboard text/key exclusivity, TV-specific restrictions, and concrete examples for common sequences. It greatly exceeds what the schema alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource: 'Execute multiple device interaction steps in a single call' across a defined set of platforms. It clearly distinguishes from sibling individual gesture/keyboard tools by positioning itself as the batched sequential alternative, and even names the key constraint that differentiates it: you do not need to observe the screen between steps.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use guidance: 'Use when you need sequential actions and do NOT need to observe the screen between them.' It also gives an explicit when-not-to-use rule: 'ONLY use this when every step is known in advance. If any step depends on the result of a previous one... use individual tool calls instead.' Platform-specific limitations for physical iOS devices are also stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screen-recording-startA
Start recording the device screen to a video file (h264 mp4, 30fps at the device's native resolution).
By default stretches where the screen does not change are trimmed out (see trimStatic), so a long session with only brief activity comes back as a short clip instead of minutes of dead air.
By default every tap, swipe, drag, pinch and rotate is drawn into the video as an on-screen touch marker (see showTouches), so the recording shows where each interaction landed.
The recording keeps running across other tool calls (every result carries a reminder) until screen-recording-stop is called or timeLimitSeconds elapses — immediately after starting, set yourself a reminder/wakeup for the expected end of the recording so it is never left running.
Use when the user wants a video of an interaction, animation, or app behavior — for a single still frame use screenshot instead.
Returns { status: "recording", timeLimitSeconds, outputFile } — the video is retrieved later by screen-recording-stop, not by reading outputFile directly.
Fails if a recording is already running on the device, the device is not booted, ffmpeg is not installed, or the platform cannot be recorded (tvOS, Chromium, Vega and remote simulators are unsupported).
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS Simulator UDID or Android serial). | |
| trimStatic | No | Default true. Collapse stretches where the screen does not change: the first second of each still stretch is kept, then unchanged frames are dropped until something moves again, so a long recording with brief activity comes back short instead of full of dead air. The returned durationMs is the trimmed length; wallClockMs/trimmedMs report what was removed. Set false to keep a faithful real-time recording. | |
| showTouches | No | Default true. Draw simulator-server's touch visualizer into the recording: a pulse marks each tap, a comet trail follows swipes and drags, and paired markers show two-finger pinch/rotate, so the video makes clear where every interaction landed. Set false to record the raw screen with no overlay. | |
| timeLimitSeconds | No | Auto-stop cap in seconds (default 180, max 600). Set it to slightly more than the interaction you plan to capture. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully describes behavior: default trimming of static stretches, touch markers, recording lifecycle across calls, return format, and platform limitations. It also clarifies that outputFile is not to be read directly. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is thorough but efficient; each sentence serves a purpose. It front-loads the core action and then elaborates on behaviors. Slightly longer than minimal but justified by the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description details the return value and its usage. It covers the tool's lifecycle, defaults, and failure scenarios, providing a complete picture for an AI agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All four parameters have schema descriptions (100% coverage), but the description adds practical context beyond the schema: e.g., 'By default every tap... drawn as an on-screen touch marker' for showTouches, and 'Set it to slightly more than the interaction' for timeLimitSeconds. This enhances understanding despite high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Start recording the device screen to a video file' with specific format and resolution details. It distinguishes from the sibling tool 'screenshot' for still frames, making the purpose clear and unique.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Includes explicit usage advice: 'Use when the user wants a video... for a single still frame use screenshot instead.' Also explains lifecycle (keeps running, set a reminder) and lists failure conditions, providing clear guidance on when to use and what to avoid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screen-recording-stopA
Stop the screen recording started by screen-recording-start and retrieve the video: frame capture ends and ffmpeg finalizes the mp4.
Also retrieves the video when the recording already ended on its own (time limit reached, capture process died) — call it even after the cap fired.
Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.
Returns { video, durationMs, wallClockMs?, trimmedMs?, warning? }; video is a downloadable artifact materialized to a local path. When static-frame trimming removed dead air, durationMs is the trimmed video length and wallClockMs/trimmedMs report the real duration and how much was cut.
Fails if no recording (running or finished-but-unretrieved) exists for the given udid.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS Simulator UDID or Android serial). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description covers key behavioral details: it finalizes the mp4, handles early termination, returns specific fields, and fails if no recording exists. It lacks explicit mention of side effects (e.g., stopping capture process) but is otherwise thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the primary action. It contains three sentences, each serving a distinct purpose: main action, when to use, return value explanation. Slightly dense but effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite no output schema, the description explains the return structure (video, durationMs, etc.) and failure case. It covers the start-stop pattern context. Could mention dependency on screen-recording-start, but the first sentence implies it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter 'udid' is already described in the input schema as 'Target device id from list-devices'. The tool description repeats this verbatim, adding no new meaning beyond what the schema provides. With 100% schema coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool stops the recording started by screen-recording-start and retrieves the video, clearly distinguishing it from its start counterpart and other siblings like flow-finish-recording. It also covers edge cases like automatic termination.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context for when to use: 'Use when the interaction being captured is finished, or a tool-result note reminds you a recording is still running.' While it doesn't list explicit exclusions or alternatives, the usage scenario is well-defined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshotA
Capture a screenshot of the device screen (iOS simulator or physical device, Android emulator, Apple TV simulator, Vega, or Chromium app). Returns { image }; the MCP adapter renders it as a visible image unless the caller passed includeImageInContext: false. Use when you need a baseline image before an interaction or to inspect the current screen state after a delay. Fails if the simulator-server / emulator backend / Chromium CDP is not reachable for the given device.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID, Android serial, Apple TV UDID, Vega serial, or Chromium id). | |
| scale | No | Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency. | |
| rotation | No | Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation. Ignored on physical iPhones. | |
| downscaler | No | Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Mirrors sim-server's wire enum. Ignored on physical iPhones. | |
| includeImageInContext | No | Default true. Set false only when capturing a full-resolution PNG (scale: 1.0) to save as a baseline/current for screenshot-diff — the file is still written, but the image bytes are not attached to the agent context. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the return shape, how the MCP adapter renders the image, the effect of includeImageInContext, and a key failure condition when the backend is unreachable. It does not over-claim or contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each earning its place: the first defines the action and result, the second gives usage guidance, and the third states a practical failure mode. The most important information is front-loaded and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema and no annotations, the description covers the supported platforms, the return value representation, the adapter rendering behavior, the primary use cases, and the main failure scenario. This is sufficient for an agent to decide when and how to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all 5 parameters with 100% coverage, so the baseline is 3. The description adds some context around includeImageInContext by tying it to whether the MCP adapter renders the image, but it does not meaningfully enrich the meaning of the other parameters beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Capture a screenshot of the device screen,' and enumerates all supported device types. This clearly distinguishes it from screenshot-diff and other inspection tools by stating exactly what it produces.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'Use when you need a baseline image before an interaction or to inspect the current screen state after a delay.' It does not explicitly list when-not-to-use cases or point to alternative tools, but the stated use cases are clear enough for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshot-diffA
Compare two PNG screenshots and return a compact visual-diff summary. Accepts saved baseline/current PNG paths, or one saved PNG plus one live full-resolution capture from a device. Always provide udid so the capture backend can be resolved. Use when stable before/after screenshots exist and the expected result is pixel-visible: layout, spacing, color, typography, image/icon rendering, clipping, overflow, or text rendering. For live captures, set exactly one of captureBaseline or captureCurrent; use baselinePath + captureCurrent for the common visual-regression flow. Physical iPhones: live captures are device-wide and need no registered app. Keep baselines per device model; different aspect ratios fail as a dimension mismatch. Returns { summary, diffPath, contextDiffPath }. The summary uses normalized [0,1] screen locations matching describe coordinates; diffPath is the full-size diff image and contextDiffPath is a downscaled image for MCP/agent display. Ignores the fixed top status-bar band for both pixel and OCR text comparisons. Fails if the input sources are invalid, PNG files cannot be read, outputDir cannot be written, or the simulator-server / emulator backend is not reachable.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS UDID or Android serial). | |
| rotation | No | Orientation override for live baseline/current captures. Ignored on physical iPhones. | |
| outputDir | No | Directory where diff artifacts should be written. Optional — defaults to a temp directory; the diff images are returned in the result either way. | |
| currentPath | No | Path to the current PNG file. Required unless captureCurrent is true. | |
| baselinePath | No | Path to the baseline PNG file. Required unless captureBaseline is true. | |
| captureCurrent | No | Capture the current screenshot live at full resolution before diffing. Cannot be combined with captureBaseline. | |
| captureBaseline | No | Capture the baseline screenshot live at full resolution before diffing. Cannot be combined with captureCurrent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and it delivers extensively. It discloses the return contract ({ summary, diffPath, contextDiffPath }) and the coordinate normalization scheme ([0,1] screen locations matching describe coordinates). It also reveals important behavioral quirks: the fixed top status-bar band is ignored for both pixel and OCR comparisons, and live captures on physical iPhones are device-wide. It explicitly lists failure conditions (invalid sources, unreadable PNGs, unwritable outputDir, unreachable simulator-server/emulator backend), which is exactly the kind of behavioral context an agent needs and that annotations do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action, and each subsequent sentence adds distinct information: input modes, when to use, live-capture configuration, physical-device caveats, return format, ignored band, and failure conditions. It is dense but earned; every sentence carries a different fact. It loses a point only because it is longer than strictly necessary, and a couple of details appear twice in slightly different forms (the exactly-one live-capture rule appears in the body and again in the schema descriptions).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter comparison tool with no output schema and no annotations, this description is remarkably complete. It covers all input modes, the return value shape, coordinate conventions, the ignored status-bar band, device-specific behaviors, and failure modes. There is no obvious category of information an agent would need to invoke this tool correctly that is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% parameter coverage, so the baseline for this dimension is 3. The description adds significant semantics above that baseline: it explains the pipeline rule (exactly one of captureBaseline or captureCurrent; the common flow is baselinePath + captureCurrent), clarifies the role of outputDir (defaults to temp directory, artifacts still returned), and gives the physical-iPhone caveat that rotation is ignored. It also ties udid to backend resolution ('Always provide udid so the capture backend can be resolved'). These are real additions beyond the schema field comments, not repetition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-object pair ('Compare two PNG screenshots') and identifies the tool as a visual-diff operation distinct from the many sibling tools. It explicitly enumerates what the comparison covers (layout, spacing, color, typography, rendering, clipping, overflow, text rendering), so an agent can clearly distinguish this from screenshot or other capture tools. The sibling list contains many capture/gesture tools, but this one is unambiguously the diffing/comparison tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('Use when stable before/after screenshots exist and the expected result is pixel-visible'), and provides concrete guidance on how to configure live captures ('set exactly one of captureBaseline or captureCurrent; use baselinePath + captureCurrent for the common visual-regression flow'). It also gives device-specific guidance (physical iPhones need no registered app, keep baselines per device model) and documents a key limitation (different aspect ratios fail). This is among the most usage-rich descriptions possible for a tool with no separate usage-hints annotation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
settings-permissionsA
Grant, deny, or reset a runtime permission for an app without navigating the system Settings UI. Use during test setup to pre-authorize (or explicitly deny) a service before the app asks, or reset so the permission dialog appears again on next use. Always per-app: bundleId is required.
Permissions: camera, microphone, photos, contacts, notifications, calendar, location, location-always, media-library, motion, reminders.
iOS simulator: edits the simulator's TCC store, always per-app. notifications is not supported (no iOS equivalent). reset is per-app — a device-wide reset is a no-op for existing grants on recent iOS, so it is not offered. grant location/location-always needs the app already installed (location auth isn't stored in TCC and isn't applied to a bundle id until the app exists) — enforced on local simulators; a remote simulator can't be probed for install state, so ensure the app is installed there first. Other services can be granted before install.
Android: changes the mapped android.permission.* runtime permissions (reset also best-effort clears the user-set permission flags). The app must be installed and declare them in its manifest; reminders has no Android equivalent.
Some permission changes terminate the app if it is running (system behavior on both platforms) — set permissions before launching, or relaunch after.
Returns { action, permission, bundleId, applied, skipped? }: applied lists the platform-level services/permissions actually changed; skipped (Android) lists mapped permissions the package manager rejected, e.g. ones the manifest doesn't declare. Fails if nothing could be applied.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS simulator UDID or Android serial). | |
| action | Yes | `grant` pre-authorizes the permission, `deny` refuses it, `reset` returns it to the not-yet-asked state so the app prompts on next use. | |
| bundleId | Yes | App to change the permission for — required for every action. iOS: bundle id (e.g. com.example.app). Android: package name. `reset` is per-app too: simctl's device-wide reset (no bundleId) silently leaves existing per-app grants untouched on recent iOS, so the permission is always reset for this one app. | |
| permission | Yes | The permission to change. `notifications` is Android-only (iOS has no simctl service for it); `reminders` is iOS-only; `camera` works on Android and on iOS only when the target simulator's runtime models the service (varies by simruntime, not by the installed Xcode). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility and excels. It discloses per-app requirement, platform differences (iOS TCC store vs Android permissions), termination of running app on permission change, return format with applied/skipped fields, and failure conditions. This is comprehensive behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is appropriately sized for a complex tool, well-structured with a high-level purpose first, then per-platform details, and finally return value. Every sentence adds necessary information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description explains the return value (applied/skipped). It covers all necessary aspects: actions, parameters, platform specifics, error conditions (e.g., failure if nothing applied). The tool is complex, but the description is fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds significant value beyond the schema. For action, it explains per-app reset behavior; for bundleId, it clarifies per-app reset; for permission, it provides platform-specific notes (e.g., notifications Android-only, reminders iOS-only). This extra context is critical for correct usage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a clear statement of what the tool does: 'Grant, deny, or reset a runtime permission for an app without navigating the system Settings UI.' It specifies the verb (grant/deny/reset), resource (runtime permission), and clearly distinguishes the tool from siblings, none of which manage permissions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises use during test setup to pre-authorize or deny permissions before the app asks, or to reset the permission dialog. It covers platform-specific behaviors but does not explicitly state when not to use the tool, though it implies limitations (e.g., notifications unsupported on iOS, app must be installed for location).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
shakeA
Shake the device (iOS simulator or Android emulator).
Use to trigger anything bound to the shake gesture: iOS's "Undo Typing" / "Redo Typing" prompt in a text field, React Native's developer menu in a debug build, or an app's own shake-to-report handler.
iOS delivers one discrete shake per gesture (the same motion event a physical device raises). Android has no OS-level shake event — the accelerometer is driven through a burst of hard direction changes so app-side detectors fire, and the resting orientation is restored afterwards.
Set count above 1 when a detector needs sustained motion before it triggers.
Returns { shaken: true, count }.
Works on local and remote (sim-remote) iOS simulators.
Only phone/tablet simulators and emulators are supported.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id from `list-devices` (iOS simulator UDID or Android emulator serial). | |
| count | No | How many shake gestures to deliver back-to-back (default 1, max 10). Raise it for apps whose shake detector needs sustained motion before it fires. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels. It explains platform-specific differences (iOS discrete shake vs. Android accelerometer bursts with orientation restore), how `count` affects sustained motion, the return value, and supported local/remote iOS simulators.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the action verb and resource, then efficiently covers usage, platform behavior, parameters, return value, and supported targets. Each sentence is informative and no words are wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with two parameters, no output schema, and no annotations, the description is comprehensive. It explains the gesture's purpose, platform-specific mechanics, `count` behavior, return value, and device compatibility, leaving no critical gap for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already has 100% coverage for both parameters. The description reinforces `count` semantics ('Set `count` above 1 when a detector needs sustained motion') and adds context for `udid` by specifying supported simulator types, adding value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Shake the device (iOS simulator or Android emulator).' It clearly distinguishes this from sibling tools like gesture-tap or gesture-swipe by focusing on the shake gesture and its use cases.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool ('Use to trigger anything bound to the shake gesture') and gives concrete examples (iOS undo/redo, React Native dev menu, shake-to-report). It also notes platform limitations ('Only phone/tablet simulators and emulators are supported'), though it doesn't explicitly name alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop-all-simulator-serversA
Stop the services a device owns - simulator-server processes (iOS + Android), native devtools, the iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, native profiler sessions, and JS-runtime debugger sessions along with the network inspectors and React profiler sessions that ride on them - freeing their spawned processes, sockets and ports. Call this when your session ends or the user says they are done.
PASS devices with the device ids this session used — one tool-server serves every agent, subagent and CLI call using this argent install, and an unscoped call tears down THEIR devices too (a mid-recording devtools teardown degrades another agent's flow to brittle coordinate taps; that agent is warned, but its recorded steps are already the worse kind). Omit devices only when a machine-wide cleanup is what you actually want. Passing an EMPTY array scopes to nothing and stops nothing - it is not a way to ask for the machine-wide sweep.
A JS-runtime debugger session is keyed by the id you called debugger-connect with. On a Metro serving two or more devices that id is not a udid or serial - connect refuses those and tells you to re-target with the logicalDeviceId it returns - so a scope built from list-devices ids cannot reach that session. Pass any such logicalDeviceId in devices ALONGSIDE the device id; { left_running } names the ones you missed.
Returns { stopped } - the URNs of the services that were actually live and got shut down; an ERROR node is disposed too but never appears there, so an empty stopped only means nothing was still running. { unmatched } lists supplied ids that own no service here, so a mistyped id - or a device NAME passed where an id was expected - does not read as a clean machine. It is NOT proof the id is wrong: a Vega device is driven through CLI/adb shell-outs, so one you only booted and drove with the remote registers no service and always lands here — as does a real device of any platform this session never started anything on. Present ONLY when devices was supplied AND at least one id matched nothing - absent on an unscoped call and when every id matched. Stopping the same device twice does not report it unmatched: ownership counts regardless of service state. { left_running } lists live debugger sessions (and the network inspectors / React profiler sessions riding on them) whose id no device scope can name - re-call with that id to reap them. { aborted: true } means the caller cancelled the request part-way, so the rest of the machine was left untouched and neither of the other two fields was computed. Past the schema - which rejects an unknown key outright, so the udids slip is an error rather than a silent machine-wide sweep - the call always succeeds; reaping nothing is a result, not a failure.
| Name | Required | Description | Default |
|---|---|---|---|
| devices | No | Device ids (iOS UDID / Android serial / Chromium id) to scope the teardown to — pass the devices THIS session actually used. Omit only for a deliberate machine-wide cleanup: one tool-server serves every agent using this argent install, so an unscoped stop also kills devices another agent is mid-session on. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden; it thoroughly discloses destructive scope (spawned processes, sockets, ports), cross-agent side effects (unscoped call tears down other agents' devices), and return-field semantics (stopped, unmatched, left_running, aborted). It even notes the call always succeeds and reaping nothing is a result, not failure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Though long, the description is dense and front-loaded with the action and scope; every sentence addresses a distinct concern (what is stopped, when to use, scoping pitfalls, return value interpretation). The length is justified by the tool's complexity and high-stakes destructive behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description provides a full account of the return object and its edge cases. It also covers safety warnings and scoping restrictions, making it complete for an agent to select and invoke correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has one documented `devices` parameter, but the description adds substantial meaning: omit vs empty array distinction, logicalDeviceId alongside device id, duplicate handling, and unmatched semantics. This goes far beyond the schema's own description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Stop the services a device owns' and enumerates a specific list (simulator-server processes, native devtools, iOS accessibility service, TV-control daemons, Chromium CDP sessions, screen recordings, profilers, debugger sessions), clearly distinguishing it from a generic stop. It also differentiates device-scoped from machine-wide cleanup, separating it from the sibling stop-simulator-server.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs 'Call this when your session ends or the user says they are done.' It also tells when to omit devices ('only when a machine-wide cleanup is what you actually want') and warns against empty-array misuse. This is explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop-metroA
Stop the Metro bundler process listening on a given port (default 8081). Use when ending a React Native session or when Metro must be restarted. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE — always ask the user for confirmation before calling this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | TCP port Metro is listening on (default 8081) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Describes return format '{ stopped, port, pids }', states behavior when no process found (stopped=false), and mentions failure conditions (timeout, cannot kill). Explicitly labels the tool as DESTRUCTIVE, which compensates for absent annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences plus a warning. Front-loaded with purpose in the first sentence. No redundant words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers usage, return value, failure modes, and destructive nature. Despite no output schema, the description fully explains the return shape. Adequate for a simple tool with one parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (port) with 100% schema coverage. Description adds little beyond what the schema provides: mentions default 8081 (already in schema) but no extra semantic depth. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specifically states 'Stop the Metro bundler process listening on a given port', with verb 'Stop' and resource 'Metro bundler process'. Clearly distinguishes from sibling tools like 'stop-simulator-server' and 'stop-all-simulator-servers' which target different server types.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use when ending a React Native session or when Metro must be restarted', and includes a mandatory confirmation note. Does not explicitly mention when not to use or alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stop-simulator-serverA
Stop the transport session for a specific device (iOS simulator / Android: simulator-server process; physical iOS: the on-device runner; Chromium: CDP WebSocket) and free its resources; on a TV target it also reaps that device's TV-control daemons. Use when you are done interacting with one device but want to keep others running, or to restart a wedged transport. On iOS / Android / TV it deliberately leaves this device's native-devtools, accessibility, profiler and debugger services running - to drain those as well, use stop-all-simulator-servers with devices. On CHROMIUM that does not hold: the JS-runtime debugger declares the CDP session as a dependency, so stopping the transport cascades to it and its captured console history goes with it - reconnect with debugger-connect afterwards. Returns { stopped, udid }. Fails silently if no session is open for the given id.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target device id (iOS UDID, Android serial, or Chromium id) whose transport session to stop |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full behavioral burden and does so thoroughly. It discloses the silent-failure behavior, the return shape, platform-specific resource cleanup (including TV daemon reaping), what is deliberately left running on iOS/Android/TV, and the Chromium-specific cascade where the CDP session and console history are terminated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Although longer than average, every sentence earns its place by covering a distinct aspect: core action, usage trigger, exclusions, platform exception, return value, and failure mode. The information is logically ordered and front-loaded with the primary purpose before caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the multi-platform complexity, no output schema, and no annotations, the description is remarkably complete. It explains what happens per platform, what is preserved, what is destroyed, how to reconnect if needed, what is returned, and how failure behaves. An agent has enough information to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% parameter coverage: the single required `udid` is described as 'Target device id (iOS UDID, Android serial, or Chromium id) whose transport session to stop.' The description adds only the phrase 'given id' and the context that it refers to a specific device, which matches the schema rather than extending it. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Stop') and resource ('transport session for a specific device') and immediately disambiguates across iOS, Android, physical iOS, Chromium, and TV. It clearly differentiates from the sibling stop-all-simulator-servers by emphasizing 'specific device' while keeping others running.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: use when done with one device but want to keep others alive, or to restart a wedged transport. It also gives an explicit exclusion and alternative—use stop-all-simulator-servers with `devices` to drain native-devtools, accessibility, profiler, and debugger services on iOS/Android/TV.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tv-remoteA
Press a TV remote / D-pad button (or a whole path of them) on a TV device — Apple TV (tvOS), Android TV (leanback), or Vega (Fire TV).
A TV is navigated with a directional remote, not touch — use this instead of gesture-tap/swipe (which do not apply on a TV). Move focus with up/down/left/right, confirm with select, go back with back/menu, exit with home, and use playPause/rewind/fastForward/next/previous/volumeUp/volumeDown/mute for the corresponding remote keys. (On the Apple TV simulator the media-transport and volume keys are rejected — its HID stack ignores them; they work on Android TV and Vega.)
Single press: { button: "down" }. Repeat the same button: { button: "down", repeat: 3 }.
Multi-step navigation: pass a path as { button: ["up","right","right","select"] } — it runs in one tool call, far cheaper than separate presses.
Read the screen with describe before and after to see where focus landed.
Returns { pressed, count }.
| Name | Required | Description | Default |
|---|---|---|---|
| udid | Yes | Target TV device id from `list-devices` (Apple TV, Android TV, or Vega). | |
| button | No | A single TV-remote button, or a path of them run in one call. Buttons: up/down/left/right (D-pad), select (OK), back, home, menu, playPause, rewind, fastForward, next, previous, volumeUp, volumeDown, mute. The media-transport and volume keys work on Android TV and Vega; on the Apple TV simulator they are rejected (its HID stack ignores them) — the D-pad/select/back/menu/home/playPause core works on all three. For multi-step navigation pass an array, e.g. ["up","right","right","select"] — strongly prefer this over multiple `tv-remote` calls: the whole path runs in a single call. | |
| repeat | No | Repeat the whole `button` value this many times (default 1). Compact for long same-button runs, e.g. { button: "down", repeat: 12 }. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that on Apple TV simulator, media-transport and volume keys are rejected due to HID stack limitations. It also explains the behavior of repeat and multi-step paths, and the return value {pressed, count}. However, it does not mention error handling, concurrency, or rate limits, though these are less critical for this tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded: it starts with the core action, then details usage, examples, and return value. Every sentence adds value. While it is somewhat lengthy, it is appropriate given the complexity of explaining multi-platform behavior and path usage. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main use cases, platform differences, and best practices. It explains the return value and advises using describe for screen reading. It does not explicitly mention error handling or timeouts, but given the tool's simplicity and the schema's coverage, it is fairly complete. Missing output schema is compensated by describing return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds significant value beyond the schema by explaining how to use single buttons, repeat, and multi-step paths. It includes platform-specific caveats (Apple TV simulator rejecting certain keys) and examples. This helps the agent understand parameter usage beyond enum values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states that the tool presses TV remote/D-pad buttons on specific TV devices (Apple TV, Android TV, Vega). It distinguishes itself from gesture-tap/swipe by explicitly noting that those do not apply on a TV. The verb 'press' and the resource 'TV remote button' are specific and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: 'use this instead of gesture-tap/swipe (which do not apply on a TV)'. It also advises to 'strongly prefer this over multiple tv-remote calls' for multi-step navigation and recommends reading the screen with `describe` before and after. This clearly tells the agent when and how to use this tool versus alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update-argentA
Apply a pending Argent update. Only call this tool when the user has explicitly consented to updating Argent in this conversation. Use when an update notification indicates a new version is available and the user agrees to update. By default updates the install serving this session; pass target to choose global/local/both. Returns { message } with the update status and version info. The tool server will restart automatically after the update. Fails if no update is available or an update is already in progress.
| Name | Required | Description | Default |
|---|---|---|---|
| target | No | Which install to update. 'auto' (default) updates the install serving this session — the global PATH install or this project's local devDependency, whichever this server runs from. Pass 'global' / 'local' to force one, or 'both' when the user has both and wants each updated. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses important behavioral traits: the tool server restarts automatically, failure conditions (no update available or update in progress), and return value structure. Given no annotations, the description carries full burden and does well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise and well-structured: front-loaded with main action, then details on usage, parameter, side effect, and failure modes. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple tool with one parameter and no output schema, the description is complete. It covers purpose, when to call, parameter details, behavior, and return value. Little room for improvement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds value beyond the schema by explaining the default behavior of the 'target' parameter and the meaning of each option. Schema coverage is 100%, but description enriches understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Apply a pending Argent update.' It specifies the resource (Argent update) and action (apply), and distinguishes from the sibling tool 'dismiss-update' by indicating when to apply vs. dismiss.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage guidance: 'Only call this tool when the user has explicitly consented to updating Argent in this conversation.' It also specifies conditions (update notification, user agreement) and default behavior. However, it does not explicitly mention the alternative sibling 'dismiss-update' for cases where the user declines.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
view-network-logsA
Retrieve captured network (HTTP) requests from the running app. Returns a paginated list of requests with method, URL, status, resource type, size, and duration. Each entry includes a requestId that can be passed to view-network-request-details for full details. On React Native (iOS / Android / Vega) interception is injected into the JS runtime — it captures fetch() calls. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types). Use when inspecting outbound HTTP traffic or debugging API calls in the running app. Fails if the app is not connected (RN) or the device is not reachable (Chromium).
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port (RN only; ignored on Chromium) | |
| device_id | Yes | Device id from list-devices (iOS simulator UDID or Android serial) — the same id used with debugger-connect. | |
| pageIndex | No | Page index (0-based) or "latest" for the most recent page. Each page contains up to 50 entries. | latest |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description fully covers behavioral traits. It details the returned data (method, URL, status, size, duration), pagination (up to 50 entries per page), platform-specific differences (React Native vs Chromium), and failure cases.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (about 100 words) and well-structured. It starts with a clear purpose statement, then provides details about the output, platform differences, usage guidance, and failure conditions without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description adequately explains the return format (paginated list with fields). It also covers purpose, usage context, failure modes, and platform variations, making it complete for an agent to use effectively.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds minimal extra context beyond the schema, such as mentioning that each page contains up to 50 entries (relevant to pageIndex) and that port is ignored on Chromium.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves captured network requests from the running app. It distinguishes from related sibling tools like view-network-request-details by noting that each entry includes a requestId for further details.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context: 'Use when inspecting outbound HTTP traffic or debugging API calls in the running app.' It also mentions failure conditions. However, it does not explicitly state when not to use or suggest alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
view-network-request-detailsA
Get full details of a specific network request by its requestId (from view-network-logs). Returns request/response headers (sensitive headers redacted), status, timing, and optionally the response body. Large response bodies are truncated. Use when you need headers, body, or timing for a specific request after listing logs. Returns an error message string if the requestId is not found — use view-network-logs to get valid requestId values.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | Metro server port | |
| device_id | Yes | Device id from list-devices (iOS simulator UDID or Android serial) — the same id used with debugger-connect. | |
| requestId | Yes | The requestId from view-network-logs to get full details for | |
| includeBody | No | Whether to include the response body (if captured). Defaults to true. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that sensitive headers are redacted, large response bodies are truncated, and includes optional body parameter. Also mentions return type for error (error message string). Given no annotations, this adequately describes behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each serving a purpose: core definition, returned data details, usage guidance, and error handling. No redundant or tangential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description covers essential aspects: purpose, parameter source, return types (including error), and limitations (truncation, redaction). Could mention that network logging must be active, but overall sufficient for effective invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all parameters (100%), but description adds value: device_id linked to list-devices and debugger-connect, requestId sourced from view-network-logs, and includeBody clarifies '(if captured)'. This enriches understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it gets full details of a specific network request by requestId, which distinguishes it from sibling tool view-network-logs that lists requests. The verb 'get' and resource 'details of a specific network request' are specific.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: when you need headers, body, or timing for a specific request after listing logs. Also explains error case: if requestId not found, use view-network-logs to get valid IDs. Provides clear context but does not explicitly mention alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
10 tool updates
v0.24.0- Changed
await-ui-element1 field changed- changed
Input schema / properties / bundleId / descriptionPrevious value: -"Optional iOS app bundle id, passed to the describe fallback (see `describe`). Ignored on Android / Chromium."New value: +"Optional iOS app bundle id, passed to the describe fallback (see `describe`). Ignored on Android / Chromium, and on physical iOS."
- Changed
describe1 field changed- changed
Input schema / properties / bundleId / descriptionPrevious value: -"Optional app bundle ID. Used as a target hint on iOS when the AX-service returns no elements and the describe tool falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on Android / Chromium."New value: +"Optional app bundle ID. Used as a target hint on iOS when the AX-service returns no elements and the describe tool falls back to native-devtools inspection. If omitted, the fallback auto-detects the frontmost connected app. Ignored on Android / Chromium, and on a physical iOS device."
- Changed
flow-add-step1 field changed- changed
Input schema / properties / command / descriptionPrevious value: -"MCP tool name (e.g. \"gesture-tap\", \"screenshot\", \"launch-app\") — a TOOL, not a flow directive. A flow-file directive name (\"tap\", \"launch\", \"run\", \"type\", \"await\", \"assert\", \"pinch\", \"echo\", \"wait\", \"long-press\", \"scroll-to\", \"snapshot\", \"when\") is answered with guidance, and nothing runs or is recorded: most name the tool that records the directive, while \"wait\", \"long-press\", \"scroll-to\", \"snapshot\" and \"when\" have no recording tool at all and are answered with what to do instead. A recording tool (flow-add-step, flow-add-echo, flow-start-recording, flow-finish-recording) is refused the same way, each for its own reason — nesting one would erase this flow at replay, end the take, or write the step twice."New value: +"MCP tool name (e.g. \"gesture-tap\", \"screenshot\", \"launch-app\") — a TOOL, not a flow directive. A flow-file directive name (\"tap\", \"launch\", \"run\", \"type\", \"await\", \"assert\", \"pinch\", \"swipe\", \"echo\", \"wait\", \"long-press\", \"scroll-to\", \"snapshot\", \"when\") is answered with guidance, and nothing runs or is recorded: most name the tool that records the directive, while \"wait\", \"long-press\", \"scroll-to\", \"snapshot\" and \"when\" have no recording tool at all and are answered with what to do instead. A recording tool (flow-add-step, flow-add-echo, flow-start-recording, flow-finish-recording) is refused the same way, each for its own reason — nesting one would erase this flow at replay, end the take, or write the step twice."
- Changed
gesture-drag4 fields changed- changed
Input schema / properties / durationMs / descriptionPrevious value: -"Total drag duration in milliseconds (default 300), interpolated at ~60fps."New value: +"Total drag duration in milliseconds (default 300, at most 10000 - the button stays down for exactly this long), interpolated at ~60fps." - added
Input schema / properties / durationMs / maximumAdded value: +10000 - added
Input schema / properties / momentumAdded value: +{ + "description": "Whether the drag releases with momentum; default true (a constant-speed drag). Pass false to decelerate into the release point (ease-out) so an app deriving fling from pointer release velocity (carousels, drag libraries) reads ~0 and applies little to no momentum — use it when the drag must stop where it was aimed rather than fling past. Deceleration needs wall clock: under ~100ms the whole drag fits inside the velocity window a page averages over (tens of ms), so some fling survives, and under ~70ms its extra frames cannot dispatch fast enough to fit durationMs. Keep durationMs at its default when the fling must be fully suppressed.", + "type": "boolean" +} - added
Input schema / properties / settleAdded value: +{ + "description": "Retired: renamed to `momentum` with the opposite sense. Pass `momentum: false` for what `settle: true` meant; `settle: false` was the default, so drop the key.", + "not": {} +}
- Changed
gesture-swipe6 fields changed- changed
Input schema / properties / durationMs / descriptionPrevious value: -"Total gesture duration in milliseconds (default 300)"New value: +"Total gesture duration in milliseconds (default 300, at most 10000 - the gesture holds a finger down for exactly this long)" - added
Input schema / properties / durationMs / maximumAdded value: +10000 - added
Input schema / properties / momentumAdded value: +{ + "description": "Whether the swipe releases with momentum; default true (a natural flinging swipe). Pass false for a momentum-free swipe at the default durationMs: the finger decelerates into the end point (ease-out) so the OS reads ~0 release velocity and applies little to no fling. Use false for scroll-to-element loops. momentum: false needs durationMs >= 150 and is rejected below it: a shorter ease-out gives the OS velocity fit too little wall clock to read the deceleration as a stop, and it flings harder than a plain swipe instead (on Android, backwards). At 150 itself the swipe lands short of where the finger stopped, and 2 of 47 runs still flung backwards.", + "type": "boolean" +} - changed
Input schema / properties / settle / descriptionPrevious value: -"Momentum-free swipe: decelerate into the end point (ease-out) so the OS reads ~0 release velocity and applies little to no fling. Use for scroll-to-element loops; default false (a natural flinging swipe)."New value: +"Retired: renamed to `momentum` with the opposite sense. Pass `momentum: false` for what `settle: true` meant; `settle: false` was the default, so drop the key." - added
Input schema / properties / settle / notAdded value: +{} - removed
Input schema / properties / settle / typeRemoved value: -"boolean"
- Changed
gesture-tap1 field changed- changed
Input schema / properties / clickCount / descriptionPrevious value: -"Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires. Default 1."New value: +"Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts land as separate taps. Default 1."
- Changed
keyboard2 fields changed- changed
Input schema / properties / delayMs / descriptionPrevious value: -"Delay in ms between key presses (default 50). Ignored on Android phones/tablets (typed via `adb input text`, which has no per-key cadence), on Vega (text/keys injected in a single shot), and on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence)."New value: +"Delay in ms between key presses (default 50). Ignored on Android phones/tablets (typed via `adb input text`, which has no per-key cadence), on Vega (text/keys injected in a single shot), on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence), and on physical iOS." - changed
Input schema / properties / key / descriptionPrevious value: -"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1–f12. Cannot be combined with `text` in one call — one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Not supported on TV targets — move focus with `tv-remote` (up/down/left/right) instead."New value: +"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1-f12. Cannot be combined with `text` in one call: one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Not supported on TV targets; move focus with `tv-remote` (up/down/left/right) instead. Physical iOS: only `enter` and `backspace`."
- Changed
open-url1 field changed- added
Input schema / properties / bundleIdAdded value: +{ + "description": "Physical iOS only: the app that receives the URL. Defaults to Safari for http(s); required for any other scheme. Ignored elsewhere.", + "pattern": "^[A-Za-z_][A-Za-z0-9._-]*$", + "type": "string" +}
- Changed
screenshot2 fields changed- changed
Input schema / properties / downscaler / descriptionPrevious value: -"Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Mirrors sim-server's wire enum."New value: +"Downscaling algorithm when scale<1 on Chromium. Defaults to lanczos3 (highest quality). Mirrors sim-server's wire enum. Ignored on physical iPhones." - changed
Input schema / properties / rotation / descriptionPrevious value: -"Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation."New value: +"Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation. Ignored on physical iPhones."
- Changed
screenshot-diff1 field changed- changed
Input schema / properties / rotation / descriptionPrevious value: -"Orientation override for live baseline/current captures."New value: +"Orientation override for live baseline/current captures. Ignored on physical iPhones."
2 tool updates
v0.22.1- Changed
boot-device1 field changed- added
Input schema / properties / soundAdded value: +{ + "description": "Android only: boot the emulator with audio output enabled. Defaults to false — argent boots emulators MUTED so several agent-driven devices don't all play sound on the host machine; pass `true` when the task involves playing, hearing, or testing audio. Takes effect at boot: if the emulator is already running muted, add `force: true` to reboot it with sound. A boot snapshot saved in the other audio mode can't be reused, so the first boot after toggling is a slower cold boot. The `boot-sound` argent flag flips this default to true. Ignored on iOS/Vega/Electron, which argent never mutes.", + "type": "boolean" +}
- Changed
flow-add-step1 field changed- changed
Input schema / properties / command / descriptionPrevious value: -"MCP tool name (e.g. \"gesture-tap\", \"screenshot\", \"launch-app\")"New value: +"MCP tool name (e.g. \"gesture-tap\", \"screenshot\", \"launch-app\") — a TOOL, not a flow directive. A flow-file directive name (\"tap\", \"launch\", \"run\", \"type\", \"await\", \"assert\", \"pinch\", \"echo\", \"wait\", \"long-press\", \"scroll-to\", \"snapshot\", \"when\") is answered with guidance, and nothing runs or is recorded: most name the tool that records the directive, while \"wait\", \"long-press\", \"scroll-to\", \"snapshot\" and \"when\" have no recording tool at all and are answered with what to do instead. A recording tool (flow-add-step, flow-add-echo, flow-start-recording, flow-finish-recording) is refused the same way, each for its own reason — nesting one would erase this flow at replay, end the take, or write the step twice."
16 tool updates
v0.22.0- Changed
flow-execute2 fields changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "name" - ] - }, - { - "required": [ - "flow_path" - ] - } -] - changed
Input schema / properties / flow_path / descriptionPrevious value: -"Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. For remote execution, pass name + project_root instead."New value: +"Omit when name is set. Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. For remote execution, pass name + project_root instead."
- Changed
flow-read-prerequisite2 fields changed- removed
Input schema / oneOfRemoved value: -[ - { - "required": [ - "name" - ] - }, - { - "required": [ - "flow_path" - ] - } -] - changed
Input schema / properties / flow_path / descriptionPrevious value: -"Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. Pass the same flow source here as to flow-execute, so the prerequisite you read belongs to the flow that will run; for remote reads, pass name + project_root instead."New value: +"Omit when name is set. Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. Pass the same flow source here as to flow-execute, so the prerequisite you read belongs to the flow that will run; for remote reads, pass name + project_root instead."
- Changed
gesture-rotate1 field changed- removed
Input schema / anyOfRemoved value: -[ - { - "required": [ - "radiusX", - "radiusY" - ] - }, - { - "not": { - "anyOf": [ - { - "required": [ - "radiusX" - ] - }, - { - "required": [ - "radiusY" - ] - } - ] - }, - "required": [ - "radius" - ] - } -]
- Changed
keyboard2 fields changed- changed
Input schema / properties / key / descriptionPrevious value: -"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1–f12. When combined with `text`, the key is pressed AFTER the text is typed (so text + enter types and submits). Not supported on TV targets — move focus with `tv-remote` (up/down/left/right) instead."New value: +"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1–f12. Cannot be combined with `text` in one call — one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Not supported on TV targets — move focus with `tv-remote` (up/down/left/right) instead." - changed
Input schema / properties / text / descriptionPrevious value: -"Text to type character by character. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` — e.g. text: \"{{secret:APP_PASSWORD}}\". The value is resolved on the machine running the tool-server, from the first source that defines the name: the `ARGENT_SECRET_<NAME>` environment variable, `.argent/secrets.env` in the project, the project's `.env.local` / `.env` (only their `ARGENT_SECRET_`-prefixed keys), then `~/.argent/secrets.env`. Nothing else on the host is reachable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, the failure lists the available names and every source it looked in — ask the user to add it to one of them (a secrets file applies immediately; an env var needs a restart), NEVER ask the user to paste the secret value into the conversation."New value: +"Text to type character by character. Cannot be combined with `key` in one call — one call per action; to type and then press a key, put two `keyboard` steps in one `run-sequence`. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` — e.g. text: \"{{secret:APP_PASSWORD}}\". The value is resolved on the machine running the tool-server, from the first source that defines the name: the `ARGENT_SECRET_<NAME>` environment variable, `.argent/secrets.env` in the project, the project's `.env.local` / `.env` (only their `ARGENT_SECRET_`-prefixed keys), then `~/.argent/secrets.env`. Nothing else on the host is reachable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, the failure lists the available names and every source it looked in — ask the user to add it to one of them (a secrets file applies immediately; an env var needs a restart), NEVER ask the user to paste the secret value into the conversation."
- Changed
native-profiler-analyze1 field changed- added
Input schema / properties / device_id / minLengthAdded value: +1
- Changed
native-profiler-start1 field changed- added
Input schema / properties / device_id / minLengthAdded value: +1
- Changed
native-profiler-stop1 field changed- added
Input schema / properties / device_id / minLengthAdded value: +1
- Added
paste - Changed
profiler-combined-report1 field changed- added
Input schema / properties / device_id / minLengthAdded value: +1
- Changed
profiler-commit-query5 fields changed- added
Input schema / properties / device_id / minLengthAdded value: +1 - changed
Input schema / properties / time_range_ms / properties / end / descriptionPrevious value: -"End of range in ms (performance.now clock)"New value: +"End of range in ms since profiling started — the same clock profiler-commit-query prints" - changed
Input schema / properties / time_range_ms / properties / start / descriptionPrevious value: -"Start of range in ms (performance.now clock)"New value: +"Start of range in ms since profiling started — the same clock profiler-commit-query prints" - removed
Input schema / properties / top_n / defaultRemoved value: -20 - changed
Input schema / properties / top_n / descriptionPrevious value: -"Max results to return (default 20)"New value: +"Max results to return. Defaults to 20 for by_component / by_time_range, which count commits. by_index counts individual fibers and returns all of them unless this is set, because one commit's fibers collapse to far fewer distinct components — a small cap there can show less than the analyze report it is meant to expand on."
- Changed
profiler-cpu-query4 fields changed- added
Input schema / properties / device_id / minLengthAdded value: +1 - changed
Input schema / properties / time_window_ms / descriptionPrevious value: -"Time window filter for time_window mode (ms, performance.now clock)"New value: +"Time window filter for time_window mode (ms since profiling started — the same clock profiler-commit-query prints)" - changed
Input schema / properties / time_window_ms / properties / end / descriptionPrevious value: -"End of window in ms (performance.now clock)"New value: +"End of window in ms since profiling started — the same clock profiler-commit-query prints" - changed
Input schema / properties / time_window_ms / properties / start / descriptionPrevious value: -"Start of window in ms (performance.now clock)"New value: +"Start of window in ms since profiling started — the same clock profiler-commit-query prints"
- Changed
profiler-load1 field changed- added
Input schema / properties / device_id / minLengthAdded value: +1
- Changed
profiler-stack-query1 field changed- added
Input schema / properties / device_id / minLengthAdded value: +1
- Changed
run-sequence1 field changed- changed
Input schema / properties / steps / items / properties / tool / descriptionPrevious value: -"Tool name — one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, rotate, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."New value: +"Tool name — one of: gesture-tap, gesture-swipe, gesture-scroll, gesture-drag, gesture-custom, gesture-pinch, gesture-rotate, button, keyboard, paste, rotate, shake, tv-remote, await-ui-element. On a TV target (Apple TV / Android TV / Vega) use tv-remote (remote presses) and keyboard (text)."
- Changed
screenshot2 fields changed- changed
Input schema / properties / rotation / descriptionPrevious value: -"Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium)."New value: +"Orientation override for the screenshot (rotates the captured image after Page.captureScreenshot on Chromium). On Android the capture already follows the device's rotation." - changed
Input schema / properties / scale / descriptionPrevious value: -"Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.3 if unset for iOS/Android. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency."New value: +"Scale factor (0.01-1.0). Defaults to ARGENT_SCREENSHOT_SCALE env var, or 0.25 if unset for iOS/Android. On Chromium the default is 1.0 (no downscale); pass <1 to opt in. Downscaling on Chromium requires the optional `sharp` dependency."
- Added
shake
6 tool updates
v0.20.0- Changed
flow-add-echo3 fields changed- added
Input schema / properties / nameAdded value: +{ + "description": "Name of the flow being recorded — the one passed to flow-start-recording.", + "type": "string" +} - added
Input schema / properties / project_rootAdded value: +{ + "description": "Absolute path to the project root of the flow being recorded — the same value passed to flow-start-recording. Together with `name` it identifies which recording this echo belongs to.", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "message" -]New value: +[ + "name", + "project_root", + "message" +]
- Changed
flow-add-step4 fields changed- changed
Input schema / properties / command / descriptionPrevious value: -"MCP tool name (e.g. \"tap\", \"screenshot\", \"launch-app\")"New value: +"MCP tool name (e.g. \"gesture-tap\", \"screenshot\", \"launch-app\")" - added
Input schema / properties / nameAdded value: +{ + "description": "Name of the flow being recorded — the one passed to flow-start-recording.", + "type": "string" +} - added
Input schema / properties / project_rootAdded value: +{ + "description": "Absolute path to the project root of the flow being recorded — the same value passed to flow-start-recording. Together with `name` it identifies which recording this step belongs to.", + "type": "string" +} - changed
Input schema / requiredPrevious value: -[ - "command" -]New value: +[ + "name", + "project_root", + "command" +]
- Changed
flow-execute2 fields changed- changed
Input schema / properties / device / descriptionPrevious value: -"Device id to run against (iOS UDID, Android/Vega serial, Chromium id). Auto-detected when omitted."New value: +"Device id to run against (iOS UDID, Android/Vega serial, Chromium id) — the id list-devices reports. Auto-detected when omitted, but only when exactly one booted device matches (optionally narrowed by `platform`); with several booted the run fails and lists them, so pass this explicitly whenever more than one device is up." - changed
Input schema / properties / platform / descriptionPrevious value: -"Restrict auto-detection to this platform when several devices are booted."New value: +"Restrict auto-detection to this platform when several devices are booted. `chromium` does more than filter: with no `device` it SELECTS the self-boot branch for an e2e flow - the runner boots an Electron instance from the `launch` step's chromium value and tears it down after the run (a single-key `launch: { chromium: … }` map selects it on its own, without this parameter). When it selects that branch it never falls back to device auto-detection (a fragment, or an e2e launch map with no `chromium` key, still does), and the launch value must be a real Electron app path on the tool-server host: a bare-string `launch:` - what the recorder writes - holds an installed-app bundle id, so passing `chromium` for one fails the whole run with `Electron boot: path does not exist`. Edit the launch to `{ chromium: <app path> }` first."
- Changed
flow-finish-recording3 fields changed- added
Input schema / properties / nameAdded value: +{ + "description": "Name of the flow being recorded — the one passed to flow-start-recording.", + "type": "string" +} - added
Input schema / properties / project_rootAdded value: +{ + "description": "Absolute path to the project root of the flow being recorded — the same value passed to flow-start-recording. Together with `name` it identifies which recording to finish.", + "type": "string" +} - added
Input schema / requiredAdded value: +[ + "name", + "project_root" +]
- Changed
flow-start-recording2 fields changed- changed
Input schema / properties / executionPrerequisite / descriptionPrevious value: -"Fragments only: the app/device state assumed on entry (e.g. \"Settings app open on General page\"). For a self-contained e2e flow, omit this and record a `restart-app` as the first step instead — it is captured as the flow's `launch` step."New value: +"Fragments only: the app/device state assumed on entry (e.g. \"Settings app open on General page\"). For a self-contained e2e flow, omit this and record a `restart-app` as the first step instead — it is captured as the flow's `launch` step. restart-app has no chromium support, so a chromium flow records as a fragment; add the `launch: { chromium: <app path> }` line to the YAML afterward, deleting the executionPrerequisite line if you passed one — a flow that starts with a launch must not declare it." - changed
Input schema / properties / name / descriptionPrevious value: -"Name for this flow (e.g. \"settings-explore\")"New value: +"Name for this flow (e.g. \"settings-explore\") — letters, digits, underscore and hyphen only."
- Changed
stop-all-simulator-servers2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / devicesAdded value: +{ + "description": "Device ids (iOS UDID / Android serial / Chromium id) to scope the teardown to — pass the devices THIS session actually used. Omit only for a deliberate machine-wide cleanup: one tool-server serves every agent using this argent install, so an unscoped stop also kills devices another agent is mid-session on.", + "items": { + "type": "string" + }, + "type": "array" +}
3 tool updates
v0.19.0- Changed
flow-execute5 fields changed- added
Input schema / oneOfAdded value: +[ + { + "required": [ + "name" + ] + }, + { + "required": [ + "flow_path" + ] + } +] - added
Input schema / properties / flow_pathAdded value: +{ + "description": "Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. For remote execution, pass name + project_root instead.", + "type": "string" +} - changed
Input schema / properties / name / descriptionPrevious value: -"Name of the flow to run (e.g. \"settings-explore\")"New value: +"Name of a saved flow to run from `.argent/flows` (e.g. \"settings-explore\"). Omit when flow_path is set." - changed
Input schema / properties / project_root / descriptionPrevious value: -"Absolute path to the project root directory that contains `.argent/flows/<name>.yaml`."New value: +"Absolute path to the calling agent's project root — the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the flow, its run: siblings, and baselines all resolve beside the YAML instead, so pass the agent's cwd." - changed
Input schema / requiredPrevious value: -[ - "name", - "project_root" -]New value: +[ + "project_root" +]
- Changed
flow-read-prerequisite5 fields changed- added
Input schema / oneOfAdded value: +[ + { + "required": [ + "name" + ] + }, + { + "required": [ + "flow_path" + ] + } +] - added
Input schema / properties / flow_pathAdded value: +{ + "description": "Absolute path to a co-located flow .yaml on the client and tool server's shared filesystem. This must be supplied through the file-input boundary. Pass the same flow source here as to flow-execute, so the prerequisite you read belongs to the flow that will run; for remote reads, pass name + project_root instead.", + "type": "string" +} - changed
Input schema / properties / name / descriptionPrevious value: -"Name of the flow to inspect (e.g. \"settings-explore\")"New value: +"Name of a saved flow to inspect from `.argent/flows` (e.g. \"settings-explore\"). Omit when flow_path is set." - changed
Input schema / properties / project_root / descriptionPrevious value: -"Absolute path to the project root directory that contains `.argent/flows/<name>.yaml`."New value: +"Absolute path to the calling agent's project root — the cwd it is working in. With name, the saved flow is read from `.argent/flows/<name>.yaml` under this root; with flow_path, the prerequisite is read from that YAML instead, so pass the agent's cwd." - changed
Input schema / requiredPrevious value: -[ - "name", - "project_root" -]New value: +[ + "project_root" +]
- Changed
keyboard1 field changed- changed
Input schema / properties / text / descriptionPrevious value: -"Text to type character by character. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` types the value of the `ARGENT_SECRET_<NAME>` environment variable set on the machine running the tool-server — e.g. text: \"{{secret:APP_PASSWORD}}\" types the value of `ARGENT_SECRET_APP_PASSWORD`. Only env vars with the `ARGENT_SECRET_` prefix are resolvable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, ask the user to export it as `ARGENT_SECRET_<NAME>` and restart the session — NEVER ask the user to paste the secret value into the conversation."New value: +"Text to type character by character. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` — e.g. text: \"{{secret:APP_PASSWORD}}\". The value is resolved on the machine running the tool-server, from the first source that defines the name: the `ARGENT_SECRET_<NAME>` environment variable, `.argent/secrets.env` in the project, the project's `.env.local` / `.env` (only their `ARGENT_SECRET_`-prefixed keys), then `~/.argent/secrets.env`. Nothing else on the host is reachable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, the failure lists the available names and every source it looked in — ask the user to add it to one of them (a secrets file applies immediately; an env var needs a restart), NEVER ask the user to paste the secret value into the conversation."
15 tool updates
v0.17.0- Changed
debugger-component-tree1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
- Changed
debugger-connect1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id: iOS simulator UDID, Android logicalDeviceId returned by Metro, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>) from list-devices. When a logicalDeviceId is returned, forward it as device_id to all subsequent debugger-* calls to pin them to this device; when none is returned (Vega), keep passing the id you connected with."New value: +"Device id from list-devices: iOS simulator UDID, Android serial, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>). Pass this SAME id as device_id to every subsequent debugger-* call to pin them to this device. The returned logicalDeviceId is informational (Metro's own per-connection handle, absent on Vega); you do not switch to it — forwarding it still resolves here, but the list-devices id is the stable one."
- Changed
debugger-evaluate1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, Vega serial, or Chromium device id)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
- Changed
debugger-inspect-element1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
- Changed
debugger-log-registry1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, Vega serial, or Chromium device id)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
- Changed
debugger-reload-metro1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
- Changed
debugger-status1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, Vega serial, or Chromium device id)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID, Android serial, Vega serial, or Chromium device id). The logicalDeviceId debugger-connect returns also resolves here, but prefer the stable list-devices id."
- Changed
gesture-pinch2 fields changed- added
Input schema / properties / endCenterXAdded value: +{ + "description": "Final horizontal center of the pinch: normalized 0.0–1.0. When set, the centroid drifts linearly from centerX to endCenterX over the gesture (e.g. to keep expanding fingers on-screen near an edge). Omit for a fixed center.", + "type": "number" +} - added
Input schema / properties / endCenterYAdded value: +{ + "description": "Final vertical center of the pinch: normalized 0.0–1.0. When set, the centroid drifts linearly from centerY to endCenterY over the gesture. Omit for a fixed center.", + "type": "number" +}
- Changed
gesture-rotate5 fields changed- added
Input schema / anyOfAdded value: +[ + { + "required": [ + "radiusX", + "radiusY" + ] + }, + { + "not": { + "anyOf": [ + { + "required": [ + "radiusX" + ] + }, + { + "required": [ + "radiusY" + ] + } + ] + }, + "required": [ + "radius" + ] + } +] - changed
Input schema / properties / radius / descriptionPrevious value: -"Distance from center to each finger: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.15 = fingers placed 15% of screen away from center."New value: +"Distance from center to each finger: normalized 0.0–1.0 (fraction of screen, not pixels). E.g. 0.15 = fingers placed 15% of screen away from center. One value for both axes, so on a non-square screen the orbit is a physical ellipse — pass radiusX+radiusY instead for a true circle. Required unless radiusX and radiusY are given." - added
Input schema / properties / radiusXAdded value: +{ + "description": "Per-axis finger distance, horizontal: normalized 0.0–1.0 fraction of screen WIDTH. Give both radiusX and radiusY (they override radius) with radiusX·screenWidth = radiusY·screenHeight for a physically circular orbit — constant finger separation, no pinch coupled into the turn.", + "type": "number" +} - added
Input schema / properties / radiusYAdded value: +{ + "description": "Per-axis finger distance, vertical: normalized 0.0–1.0 fraction of screen HEIGHT. Always paired with radiusX — see radiusX.", + "type": "number" +} - changed
Input schema / requiredPrevious value: -[ - "udid", - "centerX", - "centerY", - "radius", - "startAngle", - "endAngle" -]New value: +[ + "udid", + "centerX", + "centerY", + "startAngle", + "endAngle" +]
- Changed
react-profiler-start1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
- Changed
react-profiler-stop1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device logicalDeviceId from debugger-connect (iOS simulator UDID or Android logicalDeviceId)."New value: +"Device id from list-devices — the SAME id you passed to debugger-connect (iOS simulator UDID or Android serial)."
- Added
screen-recording-start - Added
screen-recording-stop - Changed
view-network-logs1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device UDID (logicalDeviceId)."New value: +"Device id from list-devices (iOS simulator UDID or Android serial) — the same id used with debugger-connect."
- Changed
view-network-request-details1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device UDID (logicalDeviceId)."New value: +"Device id from list-devices (iOS simulator UDID or Android serial) — the same id used with debugger-connect."
12 tool updates
v0.16.0- Changed
await-ui-element5 fields changed- changed
Input schema / properties / condition / descriptionPrevious value: -"What to wait for. `exists`: selector is anywhere in the tree. `visible`: selector is present with a non-zero on-screen frame. `hidden`: selector is absent or zero-area. `text`: the first match in reading order (topmost) contains expectedText — if a loose selector hits several elements, only that topmost one is checked, so narrow it to target the intended element."New value: +"What to wait for. `exists`: selector is anywhere in the tree. `visible`: selector is present with a non-zero on-screen frame. `hidden`: selector is absent or zero-area. `text`: the first visible match in reading order (topmost), falling back to the first match overall if none is visible, contains (or, with textMatch `equals`, exactly matches) expectedText — if a loose selector hits several elements, only that one is checked, so narrow it to target the intended element." - changed
Input schema / properties / expectedText / descriptionPrevious value: -"For condition `text`: case-insensitive substring the first matched element (topmost in reading order) must contain."New value: +"For condition `text`: the string the first visible matched element (topmost in reading order; the first match overall if none is visible) must contain (default) or equal — see `textMatch`. Case-insensitive." - added
Input schema / properties / selector / additionalPropertiesAdded value: +false - changed
Input schema / properties / selector / properties / identifier / descriptionPrevious value: -"Case-insensitive substring of the element's identifier (accessibilityIdentifier / resource-id / testid)."New value: +"The element's identifier (accessibilityIdentifier / resource-id / testid), matched case-insensitively as the exact identifier or the unqualified resource-id name ('submit' matches 'com.example.app:id/submit')." - added
Input schema / properties / textMatchAdded value: +{ + "description": "For condition `text`: how expectedText is compared. `contains` (default) is a case-insensitive substring; `equals` is a case-insensitive full-string match.", + "enum": [ + "contains", + "equals" + ], + "type": "string" +}
- Changed
debugger-connect1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id: iOS simulator UDID, Android logicalDeviceId returned by Metro, or Chromium device id (chromium-cdp-<port>) from list-devices. The returned logicalDeviceId must be forwarded as device_id to all subsequent debugger-* calls to pin them to this device."New value: +"Device id: iOS simulator UDID, Android logicalDeviceId returned by Metro, Vega serial (amazon-...), or Chromium device id (chromium-cdp-<port>) from list-devices. When a logicalDeviceId is returned, forward it as device_id to all subsequent debugger-* calls to pin them to this device; when none is returned (Vega), keep passing the id you connected with."
- Changed
debugger-evaluate1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, or Chromium device id)."New value: +"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, Vega serial, or Chromium device id)."
- Changed
debugger-log-registry1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, or Chromium device id)."New value: +"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, Vega serial, or Chromium device id)."
- Changed
debugger-status1 field changed- changed
Input schema / properties / device_id / descriptionPrevious value: -"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, or Chromium device id)."New value: +"Device id from debugger-connect (iOS simulator UDID, Android logicalDeviceId, Vega serial, or Chromium device id)."
- Changed
flow-execute4 fields changed- added
Input schema / properties / deviceAdded value: +{ + "description": "Device id to run against (iOS UDID, Android/Vega serial, Chromium id). Auto-detected when omitted.", + "type": "string" +} - added
Input schema / properties / platformAdded value: +{ + "description": "Restrict auto-detection to this platform when several devices are booted.", + "enum": [ + "ios", + "android", + "chromium", + "vega" + ], + "type": "string" +} - changed
Input schema / properties / prerequisiteAcknowledged / descriptionPrevious value: -"Set to true to confirm the execution prerequisite has been met. Required when the flow defines an executionPrerequisite."New value: +"Set to true to confirm the execution prerequisite has been met. Required (LLM path) when a fragment defines an executionPrerequisite." - added
Input schema / properties / updateBaselinesAdded value: +{ + "description": "Write/refresh screenshot baselines for `snapshot` steps instead of diffing against them.", + "type": "boolean" +}
- Changed
flow-start-recording2 fields changed- changed
Input schema / properties / executionPrerequisite / descriptionPrevious value: -"Describes the required app/device state before running this flow (e.g. \"App on home screen after a fresh reload\", \"Settings app open on General page\")"New value: +"Fragments only: the app/device state assumed on entry (e.g. \"Settings app open on General page\"). For a self-contained e2e flow, omit this and record a `restart-app` as the first step instead — it is captured as the flow's `launch` step." - changed
Input schema / requiredPrevious value: -[ - "name", - "project_root", - "executionPrerequisite" -]New value: +[ + "name", + "project_root" +]
- Changed
gesture-swipe1 field changed- added
Input schema / properties / settleAdded value: +{ + "description": "Momentum-free swipe: decelerate into the end point (ease-out) so the OS reads ~0 release velocity and applies little to no fling. Use for scroll-to-element loops; default false (a natural flinging swipe).", + "type": "boolean" +}
- Changed
gesture-tap1 field changed- added
Input schema / properties / clickCountAdded value: +{ + "description": "Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires. Default 1.", + "maximum": 10, + "minimum": 1, + "type": "integer" +}
- Changed
keyboard3 fields changed- changed
Input schema / properties / delayMs / descriptionPrevious value: -"Delay in ms between key presses (default 50). Ignored on Vega (text/keys injected in a single shot) and on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence)."New value: +"Delay in ms between key presses (default 50). Ignored on Android phones/tablets (typed via `adb input text`, which has no per-key cadence), on Vega (text/keys injected in a single shot), and on TV targets (Apple TV / Android TV type the whole string at the daemon's own cadence)." - changed
Input schema / properties / key / descriptionPrevious value: -"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1–f12. Not supported on TV targets — move focus with `tv-remote` (up/down/left/right) instead."New value: +"Named key to press: enter, escape, backspace, tab, space, arrow-up, arrow-down, arrow-left, arrow-right, f1–f12. When combined with `text`, the key is pressed AFTER the text is typed (so text + enter types and submits). Not supported on TV targets — move focus with `tv-remote` (up/down/left/right) instead." - changed
Input schema / properties / text / descriptionPrevious value: -"Text to type character by character. Handles uppercase and common punctuation."New value: +"Text to type character by character. Handles uppercase and common punctuation. To type a credential without its plaintext ever entering your context, use a secret placeholder: `{{secret:<NAME>}}` types the value of the `ARGENT_SECRET_<NAME>` environment variable set on the machine running the tool-server — e.g. text: \"{{secret:APP_PASSWORD}}\" types the value of `ARGENT_SECRET_APP_PASSWORD`. Only env vars with the `ARGENT_SECRET_` prefix are resolvable. Placeholders can be embedded in longer text and are never echoed back resolved. If the secret you need is not set, ask the user to export it as `ARGENT_SECRET_<NAME>` and restart the session — NEVER ask the user to paste the secret value into the conversation."
- Changed
native-profiler-start1 field changed- added
Input schema / properties / malloc_stack_loggingAdded value: +{ + "description": "iOS-only. When true, cold-launches the app under the profiler with Malloc Stack Logging enabled so memory leaks carry an allocation backtrace (responsible frame + library). Without it, leaks are still detected but unattributable — Instruments reports '<Call stack limit reached>'. Trade-offs: this RESTARTS the app (current state is lost), adds memory/CPU overhead, and makes the app noticeably slow to launch (every startup allocation records a backtrace), so leave it off for pure CPU/hang profiling. Requires a non-degraded Xcode: on Xcode 26.4 and later the cold-launch path is broken, so the call is rejected up front (re-run without the flag, or set ARGENT_IOS_CAPTURE=device to override if the device path works on your host). ARGENT_IOS_CAPTURE=all-processes — e.g. exported globally for the normal capture path — also rejects this flag up front, since that fallback cannot cold-launch; unset it (or set it to device) first. Ignored on Android.", + "type": "boolean" +}
- Added
settings-permissions
70 tool updates
v0.15.0- First observed
await-screen-idle - First observed
await-ui-element - First observed
boot-device - First observed
button - First observed
chromium-cookies - First observed
chromium-storage - First observed
chromium-tabs - First observed
debugger-component-tree - First observed
debugger-connect - First observed
debugger-evaluate - First observed
debugger-inspect-element - First observed
debugger-log-registry - First observed
debugger-reload-metro - First observed
debugger-status - First observed
describe - First observed
dismiss-update - First observed
flow-add-echo - First observed
flow-add-step - First observed
flow-execute - First observed
flow-finish-recording - First observed
flow-read-prerequisite - First observed
flow-start-recording - First observed
gather-workspace-data - First observed
gesture-custom - First observed
gesture-drag - First observed
gesture-pinch - First observed
gesture-rotate - First observed
gesture-scroll - First observed
gesture-swipe - First observed
gesture-tap - First observed
keyboard - First observed
launch-app - First observed
list-devices - First observed
native-describe-screen - First observed
native-devtools-status - First observed
native-find-views - First observed
native-full-hierarchy - First observed
native-network-logs - First observed
native-profiler-analyze - First observed
native-profiler-start - First observed
native-profiler-stop - First observed
native-user-interactable-view-at-point - First observed
native-view-at-point - First observed
open-url - First observed
profiler-combined-report - First observed
profiler-commit-query - First observed
profiler-cpu-query - First observed
profiler-load - First observed
profiler-stack-query - First observed
react-profiler-analyze - First observed
react-profiler-component-source - First observed
react-profiler-cpu-summary - First observed
react-profiler-fiber-tree - First observed
react-profiler-renders - First observed
react-profiler-start - First observed
react-profiler-status - First observed
react-profiler-stop - First observed
reinstall-app - First observed
restart-app - First observed
rotate - First observed
run-sequence - First observed
screenshot - First observed
screenshot-diff - First observed
stop-all-simulator-servers - First observed
stop-metro - First observed
stop-simulator-server - First observed
tv-remote - First observed
update-argent - First observed
view-network-logs - First observed
view-network-request-details
TDQS
Descriptions are unusually explicit about boundaries — describe vs native-describe-screen vs debugger-component-tree each state their exact niche and when to use which. Two genuine ambiguities remain: the text/key tools look like duplicates of keyboard (a sub-function split into separate tools), and rotate (device orientation) vs gesture-rotate (two-finger rotation) share near-identical names, forcing the description to spell out the distinction.
Several strong families exist (gesture-*, debugger-*, react-profiler-*, native-*, flow-*, screen-recording-*), but conventions mix heavily: single-word imperatives (describe, paste, shake, button), hyphenated verb_noun (launch-app, list-devices), and standalone nouns (keyboard, key, text). The text/key pair is particularly confusing since they are keyboard's own functions surfaced as separate tools with inconsistent naming with their parent.
At 75 tools this is far over the comfortable threshold, even accounting for the genuinely broad multi-platform scope (iOS/Android/Chromium/Vega/TV). Much of the surface is fragmented rather than earned: text and key as clones of keyboard, several near-duplicate native view-inspection tools (native-view-at-point vs native-user-interactable-view-at-point), and many separate profiler-query modes that could be parameterized.
The surface is remarkably complete for its stated purpose of driving and instrumenting mobile apps: full device lifecycle (list/boot/launch/restart/reinstall/stop), every interaction gesture, multiple observation paths, JS and native debugging, dual profilers with analysis and query tools, network inspection at two layers, and a flows capture/replay system. No obvious dead ends or missing lifecycle phases.
Maintenance
Related MCP Connectors
Control real Android and iOS devices with LLM agents — tap, swipe, type, automate flows.
Cloud iOS simulators and Android emulators your agent can create, drive, and throw away.
Build, run, and inspect iOS apps in disposable hosted Simulators from cloud coding agents.
Drive real Android & iOS devices and web browsers from natural language for mobile + web QA. 290+ tools across device control, app management, automation sessions, browser automation, and flow recording / replay. Bearer-auth — get a token at robotactions.com → Profile → API Tokens.
Related MCP Servers
AlicenseBqualityAmaintenanceEnables AI assistants to automate mobile app testing and development for iOS and Android through natural language interactions. Supports intelligent element identification, session management, automated test generation, and comprehensive device interactions including clicks, swipes, screenshots, and app management.3112,466467Apache 2.0- AlicenseNot gradedqualityDmaintenanceEnables interaction with the Bitcoin blockchain through the Maestro API platform. Provides tools for exploring blocks, transactions, addresses, mempool monitoring, market prices, wallet operations, and node RPC calls on Bitcoin mainnet and testnet4.24Apache 2.0

agent-deviceofficial
AlicenseBqualityAmaintenanceDiscovery router for the agent-device CLI with status, install, help, prompts, and resources.57138,1884,391MIT- AlicenseBqualityDmaintenanceEnables AI agents to inspect, log, and control React Native apps on Android emulators or iOS simulators, including UI tree, tap, scroll, and hot reload.221,2405MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/software-mansion/argent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server