react-native-eye
Enables AI agents to observe and control React Native apps running on Android emulators or devices, including screenshots, layout inspection, taps, typing, app launching, permissions, and video recording via adb and a native instrumentation driver.
Supports connecting to Expo SDK 54+ dev builds, allowing agents to interact with Expo-based React Native apps through Metro and Hermes without adding an SDK or code changes.
Enables AI agents to observe and control React Native apps running on iOS simulators or devices, including screenshots, layout inspection, taps, typing, app launching, permissions, and video recording via XCUITest/AXe.
Connects to Metro's Chrome DevTools Protocol endpoint to reach the app's JS runtime, enabling layout inspection, input, logs, network, and state access without app code changes.
Integrates with React's fiber tree in React Native apps to measure elements and invoke press and text handlers directly for fast, JS-based input and layout retrieval.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@react-native-eyeConnect to my app, tap the login button, and check the logs for errors."
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.
react-native-eye connects Claude Code, Cursor or any other MCP client to your app through Metro's Chrome DevTools Protocol endpoint. The agent reads the screen, taps and types, and checks logs, network and state. The app needs no SDK and no code changes.
It is built for agent speed. Composite tools run a whole interaction in one call, so the agent does not pay one model round trip per tap.
Contents
Related MCP server: React Native Debug MCP
Quick start
1. Add the server to your MCP client.
Claude Code, from your project folder:
claude mcp add react-native-eye -- npx -y react-native-eye@latestCursor (.cursor/mcp.json), Claude Desktop and any other client that takes the standard config:
{
"mcpServers": {
"react-native-eye": {
"command": "npx",
"args": ["-y", "react-native-eye@latest"]
}
}
}Codex (~/.codex/config.toml):
[mcp_servers.react-native-eye]
command = "npx"
args = ["-y", "react-native-eye@latest"]2. Start Metro and a dev build. Run the app in an iOS simulator or an Android emulator the way you usually do. Metro on the standard ports (8081–8083, 19000–19002) is found automatically. For any other port, pass --port 8090 in args, set METRO_PORT, or give the port to the connect tool.
3. Ask the agent.
Connect to my app and tell me what is on the screen.
The agent calls connect, then observe. The first call on each device installs the native driver once.
Requirements
Node | 18 or newer |
App | React Native 0.70+ or Expo SDK 54+, as a dev build with Metro and Hermes running |
iOS | macOS with Xcode and a simulator. AXe CLI ( |
Android |
|
OCR ( | A macOS host with the Xcode Command Line Tools ( |
The JS paths (layout from the runtime, via: "js" taps and typing) need only a connected app.
What the agent can do
35 tools in five groups. Tools in bold are composite: one call instead of many. Prefer them.
Group | Tools |
See the screen |
|
Act |
|
Debug |
|
Measure |
|
Manage devices |
|
The composite tools:
Tool | What it does |
| Screenshot + interactive elements + recent errors + recent logs, in one call |
| A whole UI flow server-side: taps, typing, waits, assertions — aborts instantly on app errors, returns per-step results + an observe at the stop point |
| Current route + store state + unhandled errors |
A whole flow in one call
{ "steps": [
{ "type": { "text": "a@b.c", "into": { "placeholder": "Email" } } },
{ "type": { "text": "hunter2", "into": { "placeholder": "Password" } } },
{ "tap": { "text": "Log in", "via": "os" } },
{ "wait_for": { "text": "Home", "timeout_ms": 3000 } },
{ "expect_not": { "text": "Error" } }
] }Each step takes exactly one action (settle is a modifier) — a step with two actions is a validation error, not a silently skipped assertion. Steps run back-to-back with adaptive settling (two rendered frames, capped at 1s; override per step with "settle": 200). A redbox or uncaught exception anywhere in the flow aborts it immediately with full context, and steps that never ran are listed as such.
tap and type steps take the same selectors, via and into as the standalone tools — into accepts {testID}, {placeholder} or {label}, and a bare string is still a testID — and each step's result names the path it used. A step that asks for via: "os" gets a real touch even when a JS press was available: use it for anything driven by the responder lifecycle, and leave the default auto everywhere else.
How it works
The server reaches the app two ways and picks the cheaper one for each call.
Through the JS runtime. The server walks React's fiber tree over CDP. It measures elements and calls press and text handlers directly, with no touch involved. A press takes about a millisecond and a full-screen layout about 80 ms.
Through the device. A prebuilt driver ships in the npm package and installs itself on first use: an XCUITest runner on iOS, an instrumentation server on Android. It delivers real touches for gestures, system dialogs and native views, and types any Unicode text on Android. If it cannot start, input falls back to axe or adb.
No silent switching. Every response says which path ran: (input: js), (input: os/runner), (layout: js), (layout: os), with the reason when a path was skipped.
Measured in the project's own field tests against a busy video feed:
Native driver | The tool it replaces | |
iOS simulator, one feed swipe, median of 40 | 0.93 s | axe: 26.68 s, 3 of 40 timed out at 90 s |
Android emulator, view hierarchy over a playing video, median of 10 | 4.60 s, 10 of 10 answered |
|
Tool reference
Three parameters appear on many tools.
device— on every device-facing tool (tap,swipe,scroll_to,type_text,press_key,screenshot,get_layout,read_screen_text,observe,run_flow,launch_app,install_app,open_url,set_permission,record_video): a udid or device-name substring. Without it the device is taken from the connected app's target, and two booted devices with no hint is an error rather than a silent guess.via— ontap,type_text,scroll_to,swipe,press_keyand thetap/typesteps ofrun_flow:"js" | "os" | "auto", defaultauto.jsgoes through the app's own fiber tree — the element under the resolved point is found, its nearestonPress/onChangeTextis called directly, and the whole round trip is about a millisecond.osdelivers a real touch or HID keystroke through the simulator or device.autotriesjsand falls back toos, naming the reason.Every response says which path ran —
(input: js), or(input: os/axe — no press handler in ancestry)(os/runner,os/axeoros/adbnames the OS mechanism that delivered it) — mirroring(layout: js)/(layout: os).Selector, ambiguity and visibility rules are identical on both paths: the JS path replaces delivery, not judgement, so an off-screen or hidden element is refused either way.
connect—port,target_id(fromlist_targets), ordevice.
tap—duration_msfor a long press (also available onrun_flowtap steps). On the JS path aduration_msof 500 or more calls the element'sonLongPress; an element that has none falls back toos, which is what the response then says.swipe—directionorx1,y1,x2,y2,duration_ms,via. The JS path scrolls the container under the start point by the gesture's own vector (FlatList.scrollToOffset 0 → 640), so a feed scrolls in a millisecond instead of a 20 s touch; no scroll container under the point falls back tooswith the reason.scroll_to—{text | testID}, plusviaandmax_swipes(default 10): bring an element into view. The JS path finds the element's nearest scrollable ancestor and scrolls that container (ScrollView,FlatList/VirtualizedList, FlashList,@legendapp/list; an unrecognised container falls back toos). The OS path swipes toward the element, re-reading the layout after each swipe and stopping the moment it is visible. This is the missing half oftap's "element is off-screen — scroll to it first".type_text—intochooses the field:{"testID": "…"},{"placeholder": "…"}or{"label": "…"}(accessibilityLabel); a bare string is still read as a testID. Omitted, it types into the oneTextInputon the focused, topmost screen and refuses — listing the candidates by placeholder and position — when there is more than one. Two instances of the same screen in a stack (each with the same composer) are told apart by react-navigation / react-native-screens state: the field on the focused screen wins and the response says so; a match only on a background screen is typed into with a warning.submit: truefires the field's submit handlers after typing (seepress_key enter).verify(defaulttrue) reads the field back after typing and fails loudly, naming both strings, when what arrived is not what was sent.viaas above; the JS path callsonChangeText, so the app's real pipeline (debounce, request, re-render) runs.press_key—key: back | home | enter,via,into.backon the JS path calls the react-navigation container'sgoBack(); an empty stack is reported asDid not go back: nothing to go back toand deliberately does not fall through to the hardware key (on Android that would background the app).enterfires the field's ownonSubmitEditing→onEndEditing→onBlur(JS only;intopicks the field, otherwise the focused one).navigate—action: stack | navigate | push | back | pop | pop_to_top | reset, withname/params(navigate, push),count(pop),state(reset). The react-navigation container is found by walking the React tree for its ref context (react-navigation 6/7, Expo Router), cached onglobalThis.__RNE_NAV__; no app change needed.stackprints the focused branch level by level; every mutating action returns the new stack, and an action no navigator handled is an error carrying react-navigation's own message.run_flow—observecontrols the trailing snapshot:auto(default) attaches a screenshot and adds the full layout only when the flow failed,fullalways,nonenever.
get_layout—search(terms matched against text/testID),type,match: substring|exact,case_sensitive, orat: {x, y}to identify the element at a point.read_screen_text— on-host OCR of the current screen (Apple Vision, nothing leaves the machine): one line per text run as<text> @x,y, coordinates in tap units usable directly withtap {x,y}.search(substring filters),languages(e.g.["de","en"]; auto-detected by default),compare_tree(default true — lines that also exist in the JS layout are marked[tree]; prefertap {text}for those). Sees text the layout tree cannot: images, canvases, WebViews, native dialogs.screenshot—output_pathsaves to a file (format: png|jpeg,maskon iOS) and returns the path instead of an inline image.get_component_tree—max_depth. The budget counts only components a developer actually authored: host components (RCTView,RCTText, ...) and structural wrappers (forwardRef/memo/context, styling HOCs like NativeWind'scssInterop) are free and can repeat any number of times without spending depth. RN's own dev-only infrastructure (LogBox, the debugging overlay, the root tag context) is dropped from the output entirely, not just made free. A very large tree is capped and markedtruncatedrather than returned unbounded.
get_state—path(dot-path) anddepth; the value is summarised inside the app, so the result is always valid JSON.foundsays whether a store exists at all;resolvedsays whether the path walked all the way to a value — a mistyped segment reportsresolved:falsewithfailedAtandavailableKeysinstead of looking identical to an honestundefined.eval_js—timeout_msfor a legitimately slow promise (default 10s).background: truestarts the evaluation as a job and returns its id at once, for a measurement that outlives a tool call or a JS thread that is busy right now; the CDP message is queued by Hermes and runs when the thread frees.labelnames the job.get_job—idreturns a background job's status and value (or error); withoutid, lists jobs.profile_rendersalso runs as a job withbackground: true, so a profile can be driven withtap/swipewhile it collects.get_network—search(URL substring to keep),exclude(URL substrings to drop),include_dev(show dev-tooling noise: Metro/devtools ports and/symbolicate,/logs,/statuson local hosts are hidden by default — the footer says how many). Query strings are cut short in the list;detail: <seq>has the full URL and bodies.
All four work on a dev build with zero app setup.
Tool | What it does |
| Which components rendered, how often, and how long, over a window: per-commit render roots with why (changed props / own state / mount), self time per component from React's profiler fields — computed per commit, not the accumulated |
| One-shot Hermes CPU profile over CDP: busy/idle/GC split, top functions by self and inclusive time, symbolicated through Metro; the raw |
| CPU by thread from the host: main vs JS vs render/shadow, share of the app's work and busy fraction per thread, top native frames (macOS |
| Frame timing: real UI-thread frames on Android ( |
profile_renders—duration_ms(default 5s),top,background. Needs a dev build (the React DevTools hook is what it wraps).profile_js—duration_ms(default 5s),top,sampling_interval_us(Hermes may ignore it — the output says so),save(default true, to$RNE_OUTPUT_DIRor~/Downloads).sample_cpu—duration_s(default 3),app_idwhen the connected target does not name the app.get_fps—duration_ms(default 2s),app_id. On iOS only the JS-thread number is available without native code: UI-thread frames need a physical device and xctrace's Core Animation instrument.
launch_app—terminate_runningrestarts a running app;envpasses launch environment variables (iOS only).open_url— opens a deeplink or universal link (simctl openurlon iOS,am start -a android.intent.action.VIEWon Android). No touch is involved, so on iOS it is by a wide margin the cheapest way to reach a screen — see the touch cost in Limitations.set_permission—{service, status: "grant" | "revoke" | "reset", app_id?}(simctl privacyon iOS,pm grant/pm revokeon Android). Granting before launch is the reliable way to keep a permission alert off the screen; dismissing one costs a touch, and on iOS some services only pick up the change after the app is terminated — the response says so rather than failing quietly.record_video/stop_recording— screen recording; defaults to$RNE_OUTPUT_DIRor~/Downloads. Android clips cap at 3 minutes (screenrecord limit).ping— no arguments, returnspong. It answers without touching Metro, the app or a device, which is exactly what makes it useful: it separates "the MCP server is not running" from "the app is not connected".
Configuration
Variable | Effect |
| Metro's port when it is not one of the standard ones. |
| Default directory for recordings and saved profiles (default |
| Comma-separated tool names to hide |
| Where the compiled OCR helper lives (default |
| Never install or start the on-device runner (iOS) or server (Android). Taps, swipes, typing and OS layout go through axe/adb exactly as before the driver existed. On Android it also force-stops a server left running by an earlier session |
Native driver
For faster, more reliable OS input the package ships prebuilt on-device drivers; there is nothing to build (scripts/build-drivers.sh is only for contributors). On first use it installs, per device:
Platform | What is installed |
iOS simulator | The runner app |
Android |
|
If a driver cannot be installed or started, input and layout fall back to axe/adb automatically, and the response names the path that ran. RNE_NATIVE_DRIVER=off opts out entirely.
While the Android server is up it holds UiAutomation, so other UiAutomation clients on that device (Appium, uiautomator dump) fail until it is stopped (adb shell am force-stop dev.rneye.server, or RNE_NATIVE_DRIVER=off).
Privacy
No telemetry. No accounts. No cloud. The only network traffic is to localhost (Metro) and local device drivers. This is enforced by an automated test that fails the build if any external URL appears in the source, and another that fails if a license/account/feedback tool ever shows up in the tool surface.
Limitations
The short version: dev builds only, and the JS path calls handlers rather than performing gestures.
Limitation | Detail |
Dev builds only | Requires Metro + Hermes; production builds are unsupported. |
Single debugger (RN < 0.85) | Hermes allows one CDP client at a time; RN 0.85+ supports multiple. |
Input path | A JS press calls a handler; it is not a gesture. Native views outside the React tree, system dialogs and permission alerts, Reanimated gestures that run on the UI thread, drag handles and swipeable rows, and momentum scrolling are not reproduced — those need |
Cold start | Logs/network before |
Store access | Reliable |
Limitation | Detail |
In-app interceptor | The network hooks live in the app, so they outlive the server. Connecting with a newer build replaces them; if an older build left hooks that cannot be removed, |
Screenshots | Inline screenshots are downscaled to 800px JPEG by default (pass |
Layout source |
|
Off-screen and hidden elements | Elements scrolled out of the viewport, and those on a screen that is mounted but not on display (an inactive tab, a stack screen below the top, |
Which screen is live | Taken from react-navigation / react-native-screens state ( |
Text input |
|
Touch cost on the iOS simulator without the native driver | Delivering a touch through axe to a foregrounded, busy RN app measured 17–25 s (worst 29.8 s) on iPhone 17 Pro / iOS 26.2 with axe 1.7.1, while HID typing, hardware buttons and screenshots against the same app in the same state stayed at 0.3–0.6 s. The cost is per touch event, not per process, so batching does not amortise it ( |
Error capture | In a dev build LogBox is the |
Route in | Found by walking the React tree for a react-navigation container (react-navigation 6/7, Expo Router). An app that navigates some other way can still expose a ref on |
Profiling |
|
OCR |
|
Development
npm install
npm run build # compile to build/
npm test # unit tests
npm run dev # run the server from sourcenpm run test:integrationruns the device tests. They need a booted iOS simulator (its udid inRNE_INTEGRATION_UDID) or an Android emulator (its serial inRNE_INTEGRATION_ANDROID_SERIAL).scripts/build-drivers.shrebuilds the native drivers undernative/(Xcode for iOS; JDK 17+ and the Android SDK for Android). Any change undernative/changes the driver version.scripts/pack-test.shpacks the tarball, installs it into a fresh project and checks that the drivers arrive intact and the server answers.
Pull requests are welcome: see CONTRIBUTING.md. Report security issues privately as described in SECURITY.md.
License
MIT for react-native-eye itself. The native drivers include third-party components under Apache-2.0, BSD and MIT licenses. Attributions are in NOTICE, the Apache-2.0 text is in native/LICENSE-APACHE, and per-driver details are in native/ios-runner/THIRD_PARTY.md and native/android-server/THIRD_PARTY.md.
Available Tools
35 toolscheck_stateCheck stateA
One-shot: current route + store state (optional dot-path) + recent errors. The route is discovered automatically — the react-navigation container ref is found by walking the React tree, so no app-side setup is needed (globalThis.RNE_ROUTE / globalThis.RNE_NAV still take precedence when the app publishes them). If no navigator is found the route is null and the hint says why.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No |
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 real work: it discloses the auto-discovery mechanism (walking the React tree for the react-navigation container ref), the precedence rule for globalThis.__RNE_ROUTE__/__RNE_NAV__, and the explicit failure mode (route null plus a hint explaining why). It stops short of describing read-only semantics or how many/which 'recent errors' are included.
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 payload summary is front-loaded in the first sentence, with mechanism and fallback following in descending priority. The parenthetical about globalThis is slightly dense but genuinely informative, and no sentence is 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?
There is no output schema and no annotations, so the description must define the response — it names the three components and the null-route edge case but never describes the actual shape (route object fields, store state serialization, error list size/format). Adequate for a call decision, incomplete for interpreting the 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?
The single parameter has 0% schema description coverage, so the description must compensate — and it does, explaining that `path` is an optional dot-path into the store state, which tells the agent both its purpose and that it can be omitted. It does not state the default (whole store) or the path syntax, keeping it below a 5.
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 action (one-shot snapshot) and enumerates exactly what it returns: current route, store state at an optional dot-path, and recent errors. This is far more concrete than the sibling names get_state/get_errors, but the description never names those siblings or explains how this combined snapshot differs from calling them separately, leaving differentiation to inference.
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 word 'one-shot' plus the combined payload imply this is the quick triage call rather than a targeted getter, and it notes no app-side setup is required. However there is no explicit when-to-use/when-not guidance and no mention of alternatives like get_errors, get_state, or observe, so routing between them is left implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connectConnectA
Connect to a running React Native app via Metro. Optionally pass a port, a target_id from list_targets, or a device name — otherwise standard ports are scanned and the app's JS runtime is picked.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | ||
| device | No | ||
| target_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose useful non-obvious behavior: default port scanning and that the app's JS runtime is selected automatically. However it says nothing about idempotency (what happens if already connected), timeouts, failure modes, or whether an existing session is replaced — meaningful gaps for a stateful connection 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 compact clauses, front-loaded with the action and then the argument options. No filler, no restating the tool name, and the default-scanning fallback is stated inline rather than in a separate sentence.
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 and no annotations mean the description is the only source of behavioral detail, and while it covers parameters and default discovery, it omits what a successful connection yields and how errors surface. Adequate to call the tool, but thin for a session-establishing operation that everything else depends on.
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 0%, so the description must compensate, and it does name all three parameters with meaning: port, target_id (sourced from list_targets), and device name. The 'or' framing also implies these are alternatives, which the bare schema does not convey. It lacks format detail for device (name vs UDID) and precedence rules if multiple are supplied.
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 and resource — 'Connect to a running React Native app via Metro' — which is unambiguous and clearly distinct from sibling tools like list_targets or ping. It does not explicitly say how it differs from connect-adjacent siblings (e.g., launch_app), but the resource and transport are named precisely.
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 context for the two modes of use: pass one of port/target_id/device, or rely on default port scanning. It names list_targets as the source for target_id, which routes the agent correctly. It stops short of stating prerequisites (app must already be running, Metro must be up) or what to do if connection fails.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
eval_jsEvaluate JSA
Evaluate JavaScript in the app's runtime and return the result. Statements are allowed, and a promise result is awaited (await fetch(...), AsyncStorage.getItem(...)) — pass the promise itself, not await (Hermes has no async/await in evaluated code). Pass background: true for work that outlives one tool call (a long measurement, a snippet that samples for 30s) and collect the result with get_job.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| label | No | Name for a background job, shown by get_job. | |
| background | No | Start the evaluation and return a job id immediately instead of waiting for the result. | |
| timeout_ms | No | How long to wait for a promise result (default 10000; background jobs default to 600000). |
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 well: it discloses promise awaiting, the Hermes no-async/await constraint, and the semantics of background mode and result collection. It omits the most consequential trait — that this executes arbitrary code in the app with side effects and potential to mutate app state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then constraint details in a tight sequence. The parenthetical examples earn their place by showing valid promise usage, though the sentence structure is slightly dense and runs together multiple rules.
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 exists, and the description plus schema together convey the return behavior (immediate result vs job id). What is missing is safety/error context — whether failures throw, what happens on timeout — which matters for an arbitrary-code-execution 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 75%, and the description meaningfully supplements it: it explains what background: true does behaviorally and how its result is retrieved, beyond the schema's 'return a job id immediately'. 'code' and 'label' are left to the schema, which is acceptable at this 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?
States a specific verb and resource ('Evaluate JavaScript in the app's runtime and return the result'), which is unambiguous. It does not, however, distinguish itself from sibling 'profile_js', which likely also executes JS, leaving the agent to infer the boundary.
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 concrete guidance on when to pass a promise vs await, and explicitly says to use background: true for work outliving one call and to collect via get_job — naming a sibling correctly. It stops short of saying when NOT to use this tool or how it differs from profile_js/get_state.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_component_treeGet component treeA
Depth-limited React component tree via the React DevTools hook, with testID and text where present. max_depth counts only components a developer actually authored — host components (RCTView, RCTText, ...) and structural wrappers (forwardRef/memo/context, styling HOCs) are free and can repeat any number of times without spending budget. RN's own dev-only infrastructure (LogBox, the debugging overlay, the root tag context) is omitted from the output entirely. Large trees are capped and marked truncated rather than returned unbounded.
| Name | Required | Description | Default |
|---|---|---|---|
| max_depth | No |
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 substantial work: it defines what counts against budget, states that LogBox/overlay/root-tag-context nodes are omitted entirely, and that oversized trees are capped and flagged truncated rather than returned unbounded. What it leaves out is failure behavior — what happens if the React DevTools hook isn't present — and required app/connection state.
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, front-loaded with the purpose, then parameter semantics, then output filtering and truncation. Parenthetical examples are dense but each earns its place; there is no filler or restatement of the 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?
For a single-parameter read tool with no output schema and no annotations, it covers content of the returned nodes, exclusions, and truncation marking. The remaining gap is the response shape (nested tree vs flat list of nodes) and the runtime precondition for the DevTools hook, which an agent would need before calling.
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 0%, so the description must compensate, and it does: max_depth is explained as counting only developer-authored components, with host components, forwardRef/memo/context and styling HOCs explicitly free and repeatable. That is a real semantic rule an agent could not derive from the bare integer schema with a 1–10 range.
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: a depth-limited React component tree obtained via the React DevTools hook, enriched with testID and text. The resource is distinct enough from neighbors like get_layout or read_screen_text to be selectable, but the description never names a sibling or explicitly contrasts itself with 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?
Usage is only implied: an agent can infer this is for inspecting the React component hierarchy on a connected RN app, and that dev-only infrastructure is filtered out. There is no explicit 'use this when…' or 'prefer X instead' guidance, and no mention of prerequisites such as the DevTools hook being available or the app running in dev mode.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_errorsGet errorsB
Uncaught exceptions and redboxes captured since connecting. Includes the errors LogBox swallows, which never reach the debugger on their own.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses the capture window ('since connecting') and the unusual coverage (LogBox-swallowed errors that bypass the debugger), which is genuine behavioral value. It says nothing about ordering, whether results accumulate or are cleared, or what happens past the limit, so the transparency is partial.
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 tight sentences with zero filler, and the core scope is front-loaded in the first sentence before the LogBox qualifier. Every clause adds information an agent could not get from the name alone.
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 no-annotation, no-output-schema tool, the description adequately conveys what data is returned and over what time window. However, it omits the limit parameter's behavior and any sense of result shape or volume, leaving gaps an agent would need to discover by calling.
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 0% for the sole parameter 'limit', which has a max of 100 and an exclusive minimum of 0 but no documented meaning. The description never mentions limit at all, so it fails to compensate for the coverage gap; an agent must guess whether it caps error count, is a default of all, or affects ordering.
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 resource with a verb implied by the noun: 'Uncaught exceptions and redboxes captured since connecting.' The second sentence sharpens the scope further by naming LogBox and noting these errors never reach the debugger, which implicitly separates it from get_logs. It never names the sibling explicitly, so differentiation is inferred rather than stated.
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?
There is no explicit 'use this when...' guidance and no named alternative such as get_logs or read_screen_text. The usage is inferable from the content scope (errors since connecting), which is enough for an agent debugging a failure, but the boundary versus get_logs is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_fpsMeasure frame timingB
Measure frame timing for a short window. Android also reports real UI-thread frames from dumpsys gfxinfo; on the iOS simulator only the JS-thread requestAnimationFrame rate is available (UI-thread frames need a physical device and xctrace).
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | No | ||
| device | No | ||
| duration_ms | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It does disclose a genuinely important behavioral trait: results are platform-dependent, with real UI-thread frames only on Android/dumpsys gfxinfo and physical iOS devices via xctrace, while the iOS simulator yields only JS-thread rAF rate. It omits whether a device/app must be connected first, what the returned metrics look like, and any cost or blocking behavior of the 'short window'.
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 the core action, and the platform caveat follows efficiently. Slight vagueness in 'short window' rather than a concrete default keeps it from being maximally crisp.
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 annotations, no output schema, and zero schema description coverage on three parameters, the description should compensate but doesn't. It covers platform data-quality caveats well yet leaves the agent without guidance on required setup (connected device, running app) or what the measurement returns.
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 0% for three parameters (app_id, device, duration_ms), and the description never explains any of them. 'Short window' loosely gestures at duration_ms but gives no units or default, and app_id/device semantics (target selection, whether device is required) are entirely undocumented.
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 and resource ('Measure frame timing for a short window'), which is clear on its own. It doesn't name which sibling to prefer over it (profile_renders, profile_js, sample_cpu all sound related to performance measurement), so an agent must infer differentiation from the names alone.
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 implies a measurement use case but never says when to pick this over profile_renders, profile_js, or sample_cpu. The platform caveats tell the agent what data is trustworthy on Android vs the iOS simulator, which is useful context but not a when-to-use rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_jobGet background jobA
Collect the result of a background job started by eval_js (background: true). Without an id, lists every job the server is holding.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Job id, e.g. "j1". Omit to list all jobs. |
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 does not disclose whether reading a job result is non-destructive, whether jobs are consumed or retained after collection, whether the call blocks until completion, or what happens if the job is still running. For a job-result retrieval tool, these are meaningful gaps.
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 short sentences with no wasted words. The primary purpose and the originating call are front-loaded, and the no-id listing behavior follows directly.
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 simple with one optional parameter and no output schema, so the description does not need to explain return values in detail. However, it leaves job lifecycle and result-availability semantics unstated, which matters for an agent deciding whether and how to poll for results. It is adequate but incomplete.
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 single id parameter is already well documented in the schema. The description repeats that omitting the id lists all jobs, but adds no syntax, format, or meaning beyond that. Baseline 3 is appropriate when the schema does the work.
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 collects the result of a background job, and explicitly names the originating sibling call eval_js with background: true. It also distinguishes the no-id case as a listing operation, so an agent can identify the tool without opening the schema.
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 gives clear context for when to use the tool: after starting a background job via eval_js (background: true). It also explains the no-id behavior. It does not explicitly state when not to use it or name alternatives, but the prerequisite condition is clear enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_layoutGet layoutA
Interactive on-screen elements with center coordinates. Elements scrolled out of view are listed separately as off-screen. Optional: filter with search terms (matched against text/testID), narrow by element type, or pass at:{x,y} to get the element at a point. source picks the capture path (js = app runtime, os = axe/uiautomator, default auto).
| Name | Required | Description | Default |
|---|---|---|---|
| at | No | ||
| type | No | ||
| match | No | ||
| device | No | ||
| search | No | ||
| source | No | ||
| case_sensitive | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden; it does disclose useful behavior — center-coordinate semantics, that out-of-view elements are segregated as off-screen, and the default capture path. It says nothing about cost, permissions, freshness of the snapshot, or the shape of the returned data.
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 dense sentences with the core result (elements + coordinates) front-loaded and the optional modifiers following. No filler, though the parenthetical enumerations compress a lot of meaning into semicolons.
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?
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 0% with 7 parameters, so the description has to compensate and only partly does: it explains search (matched against text/testID), type, at:{x,y}, and source (js/os/auto with default). It leaves match, case_sensitive, and device undocumented, so three of seven parameters remain opaque.
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 and resource: retrieves interactive on-screen elements with their center coordinates, plus off-screen elements listed separately. Clear enough to know what you get back, but it never distinguishes itself from siblings like get_component_tree, read_screen_text, or observe, which an agent must choose between.
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?
Offers usage patterns for the optional modes (filter by search terms, narrow by type, point query via at:{x,y}) and explains the source default, so the agent knows how to use the parameters. It gives no guidance on when to prefer this over the sibling tree/state/text tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_logsGet logsA
Recent console logs from the app. Filter by level and/or search substring. Note: only logs emitted after connect are captured — reload_app to catch cold-start output.
| Name | Required | Description | Default |
|---|---|---|---|
| level | No | ||
| limit | No | ||
| search | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations at all, the description carries the full burden and does disclose a non-obvious behavioral limit — only logs emitted after connect are captured — plus the reload_app remedy. It still omits return shape (fields, ordering), whether the buffer is capped, and whether the call blocks or polls.
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 compact sentences: purpose first, filtering second, and a caveat that earns its place because it prevents a wrong conclusion about missing cold-start logs. 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 tool with zero annotations, zero schema descriptions, and no output schema, the definition covers purpose and the capture-window caveat well but leaves the agent guessing about the return payload and the `limit` semantics. Adequate, not 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 description coverage is 0%, so the description must compensate. It adds meaning for two of three params ('filter by level', 'search substring'), but says nothing about `limit` — neither default value nor whether it returns the newest or oldest N — and the schema gives that param no description either.
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 — 'Recent console logs from the app' — plus what can be filtered. It is distinct from get_errors/get_network in substance, but it never names those siblings, so the agent must infer the boundary rather than being told.
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 gives concrete usage context ('Filter by level and/or search substring') and an explicit alternative with a condition: use reload_app to catch cold-start output that predates connect. That is clear when-to-use guidance, though it lacks an exclusion pointing to get_errors when only errors are wanted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_networkGet networkA
Recent HTTP requests captured in-app. The list view shortens long URLs (query strings collapse to a char count) — pass detail: for the full URL and request/response bodies. Dev-tooling traffic (Metro, Expo, react-devtools, dev polls) is hidden unless include_dev:true; exclude:[...] drops URLs by substring. Note: requests before connect are missed (cold start).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| detail | No | ||
| search | No | ||
| exclude | No | ||
| include_dev | No |
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 well: it discloses that the list view truncates query strings, that dev traffic is hidden by default, and that requests before connect are missed due to cold start. It implies a read-only capture but never states whether results persist or how they are ordered.
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 dense sentences, front-loaded with what the tool returns before the modifier mechanics. Every clause carries usable information; the only mild cost is that the truncation/dev-filter/cold-start notes are packed into one paragraph.
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 five-param capture tool with no annotations and no output schema, the description covers the behaviors an agent most needs (truncation, default hidden dev traffic, cold-start gap). The remaining gap is the undocumented limit/search semantics, which is minor given their conventional meaning.
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 0%, so the description must compensate. It explains detail, exclude and include_dev with concrete mechanics, but limit and search are left entirely unexplained in both schema and description, so compensation is partial.
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 gives a specific resource (recent in-app HTTP requests) that is clearly distinct from network-adjacent siblings like get_logs and get_errors. It doesn't explicitly name a sibling to differentiate against, which keeps it from a 5.
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 gives concrete conditional guidance: pass detail:<seq> to get full URLs and bodies, include_dev:true reveals dev-tooling traffic, exclude:[...] drops by substring. That tells the agent how to shape the call, though it never states when to prefer this tool over get_logs or get_errors.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_stateGet stateA
Read app store state (Redux/Zustand/custom), summarised depth-first inside the app so the result stays valid JSON. Optionally a dot-path (e.g. 'user.name') and a depth (default 3). resolved says whether the path actually walked to a value — a mistyped segment reports resolved:false with failedAt and availableKeys instead of silently looking the same as an honest undefined. Assign your store to globalThis.RNE_STORES for reliable access.
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | ||
| depth | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and discloses depth-first summarization to keep JSON valid, default depth, resolved/failedAt/availableKeys error semantics for bad paths, and a store-global prerequisite. It does not explicitly state read-only/no side effects or what happens if the store is not registered beyond 'reliable access'.
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, front-loaded with purpose, then parameters, resolution behavior, and setup. Each sentence adds useful information with 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?
Given no annotations and no output schema, the description is fairly complete: purpose, parameter usage, error-resolution semantics, and store setup. It still leaves some return-shape and side-effect details implicit, so it is not fully comprehensive.
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 0%, so the description must compensate. It explains both parameters: optional dot-path with example 'user.name' and depth default 3. It does not restate schema bounds (maximum 8, exclusiveMinimum 0), but adds meaningful semantics beyond the raw 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?
States a specific verb and resource: 'Read app store state (Redux/Zustand/custom)' with depth-first summarization. It does not explicitly contrast with sibling tools like check_state or observe, so the purpose is clear but sibling differentiation is absent.
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?
Implies usage for reading Redux/Zustand/custom stores and includes a setup prerequisite ('Assign your store to globalThis.__RNE_STORES__'). It gives no explicit when-to-use/when-not guidance or alternatives such as check_state, observe, or eval_js.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
install_appInstall appC
Install an app bundle on the active device (.app/.ipa on iOS, .apk on Android).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| app_path | Yes |
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 identifies target device and bundle formats, but does not disclose whether installation overwrites an existing app, preserves app data, requires signing, or what happens on 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?
The definition is a single front-loaded sentence with no filler. It is efficient, though somewhat under-informative for a mutation tool.
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 a mutation tool with no annotations, no output schema, and low schema coverage, the description is incomplete. It covers bundle formats but not prerequisites, side effects, or device selection semantics.
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 0%, so the description must compensate. It usefully explains the app_path file formats, but it never clarifies the optional device parameter: whether it takes an ID, name, or defaults to the active device.
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: install an app bundle on the active device. It also names accepted platform-specific bundle types (.app/.ipa/.apk), though it does not explicitly distinguish itself from siblings like launch_app or reload_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?
It implies the basic use case but gives no guidance on when to choose install_app over launch_app or reload_app, and it omits prerequisites such as a connected or booted device.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
launch_appLaunch appB
Launch an app by bundle id (iOS) / package name (Android) on the active device. Optional: terminate_running to restart a running app, env to pass launch environment variables (iOS only).
| Name | Required | Description | Default |
|---|---|---|---|
| env | No | ||
| app_id | Yes | ||
| device | No | ||
| terminate_running | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It usefully discloses that env is iOS-only and that terminate_running restarts a running app, but says nothing about error behavior (e.g. app not installed), whether the call waits for launch to complete, or whether it foregrounds an already-running app.
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 tight sentences, front-loaded with the core action and identifier format, then the optional behaviors. Almost no waste; only the unexplained device parameter leaves something missing.
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 mutation tool with no annotations and no output schema, the description covers the main action and two optional parameters but omits the device parameter and any launch-failure or post-condition behavior. Adequate but with clear 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 0%, so the description must compensate. It explains terminate_running, env (including the iOS-only restriction absent from the schema), and the app_id format, but the device parameter is never mentioned despite the schema exposing it.
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 (launch) and resource (an app), and clarifies the identifier format per platform (bundle id on iOS / package name on Android). It does not explicitly distinguish itself from siblings like install_app or reload_app, but the action is 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?
Usage is implied: launch an app on the active device. There is no explicit guidance on when to use this versus install_app, reload_app, or open_url, nor any stated prerequisite such as the app needing to be installed first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesList devicesA
List available iOS simulators and Android devices (booted ones are marked).
| 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 burden, and it does disclose one useful trait beyond the name: booted devices are marked. It says nothing about whether the call is read-only in effect, whether it starts or scans for devices, latency, or how many devices are returned.
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?
A single short sentence, front-loaded with the verb and scope, with the useful "booted ones are marked" detail appended. No filler 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?
For a zero-parameter lister with no output schema, the description nearly suffices: it states what is listed and that boot status is flagged. It omits the return shape (device identifiers/names) that an agent needs to feed connect or install_app, which is the main remaining 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?
The tool takes zero parameters, so there is no parameter semantics for the description to explain; the baseline of 4 applies. The description correctly implies the tool is unfiltered and returns all devices.
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?
Names a specific verb and resource ("List available iOS simulators and Android devices") and adds the platform scope, so the agent knows what will be enumerated. It does not differentiate from the sibling list_targets, so the agent cannot tell at a glance which listing tool to pick.
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?
Usage is only implied: an agent can infer this is a discovery step before connect/install_app/open_simulator, but nothing says when to use it or when to prefer list_targets or ping instead. No exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_targetsList targetsA
List every debuggable React Native target Metro exposes (a device can have several: the JS runtime, the UI page, stale pages from earlier reloads). Pass a target_id to connect.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the burden. It usefully warns that stale pages from earlier reloads appear in results — a genuine behavioral caveat that prevents the agent from assuming duplicates are bugs. However, it says nothing about failure modes when Metro is unreachable, ordering, or whether the call is cheap/safe to repeat.
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 the action, with the parenthetical carrying only genuinely clarifying content. Nothing is redundant and nothing needs trimming.
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 does the important work of explaining what comes back (targets, including several per device, and a target_id to feed connect). Missing only the preconditions for calling it and any hint of the result shape beyond target_id.
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?
Zero parameters, so the baseline is 4; the schema has nothing to explain. The mention of target_id is not a parameter but an output-field hint, which adds value in the absence of an output 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?
Specific verb+resource ('List every debuggable React Native target Metro exposes') with a clarifying parenthetical that defines what a target is and why one device can yield several. It implicitly distinguishes itself from list_devices by noting targets live behind Metro, though it never names that sibling explicitly.
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?
'Pass a target_id to connect' establishes the downstream relationship to the connect tool, which is real routing guidance. But there is no explicit when-to-use or prerequisite statement (e.g., must Metro already be reachable? call list_devices first?), leaving the agent to infer the workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
observeObserveA
One-shot snapshot of the screen: screenshot + interactive elements + recent errors + recent logs. Sections are independent — one failing does not lose the rest. Prefer this over separate screenshot/get_layout/get_logs calls.
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| source | No | ||
| full_res | No | ||
| screenshot | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden, and it does useful work: "Sections are independent — one failing does not lose the rest" tells the agent that partial results are a normal outcome rather than a hard error. It does not mention that the tool is read-only, the cost or latency of capturing a full snapshot, or what the default device is when the device parameter is omitted.
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, no filler, with the payload description front-loaded and the routing preference and failure-tolerant behavior in the second. Every clause adds information an agent needs.
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 and no annotations, so the description must explain what the agent gets back, and it only names the four sections without describing their shape or size. Combined with the unexplained parameters, an agent knows when to call this but not how to configure it or what the payload will look like.
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 0%, so all four parameters (device, source, full_res, screenshot) are undocumented in both the schema and the description. The words "screenshot" and "full" appear in prose, but the description never explains what these flags do, what the js/os/auto source enum means, or what the defaults are.
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?
"One-shot snapshot of the screen" states a specific verb+resource, then enumerates exactly what is bundled (screenshot, interactive elements, recent errors, recent logs). This is enough to distinguish it from the sibling tools screenshot, get_layout, and get_logs without opening any schema.
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?
"Prefer this over separate screenshot/get_layout/get_logs calls" gives an explicit routing rule with the alternatives named, which is exactly the guidance an agent needs. It stops short of saying when this tool should NOT be used, for example when only logs are needed or full-resolution fidelity is required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_simulatorOpen SimulatorB
Open the iOS Simulator app (macOS only).
| 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 burden. It discloses the macOS-only constraint, which is real value, but says nothing about whether the call is idempotent when the simulator is already running, whether it blocks until ready, or whether it affects existing sessions.
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?
A single short sentence with the platform caveat wrapped in parentheses — front-loaded and with 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?
For a zero-parameter, no-output-schema tool the description is nearly sufficient, but lacking annotations it should still say what state the simulator is left in and whether re-invocation is safe.
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 takes zero parameters, so the baseline of 4 applies; there is no parameter semantics to clarify or omit.
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 and resource ('Open the iOS Simulator app') and adds a platform qualifier, so an agent can tell it is not launch_app or open_url. It does not explicitly name those siblings, so it stops short of a 5.
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?
No statement of when to reach for this versus launching an app or navigating to a URL, and no prerequisites (e.g. that a device may need to be booted first) are given. The agent must infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_urlOpen URLA
Open a deeplink or universal link on the active device (myapp://screen, https://…). Touch-free: it delivers no touch event, so it is unaffected by slow touch delivery and is usually the cheapest way to reach a screen.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| device | No |
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 does disclose a real behavioral trait: it delivers no touch event, so it is immune to slow touch delivery. It omits other important behavior such as what happens on an invalid or unhandled URL, whether the target app must be installed, and what the call returns.
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 the action and its input form, followed by a performance rationale. Every clause adds usable information and nothing is padded.
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 two-parameter tool with no output schema, this covers purpose, input form, and a genuine cost/performance consideration. The remaining gaps, device identification and error/return behavior, are minor but non-trivial since no output schema exists to fill them in.
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 0%, so the description must compensate. It usefully illustrates the 'url' format with two concrete schemes and 'active device' hints that 'device' defaults, but it never explains how the 'device' parameter is identified or formatted, leaving half the parameters undocumented.
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 (open) and resource (deeplink or universal link) with concrete URL examples (myapp://screen, https://…), making the input shape immediately obvious. It does not explicitly distinguish itself from the related sibling 'navigate', though the 'cheapest way to reach a screen' phrasing hints at that trade-off.
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 'usually the cheapest way to reach a screen' remark implies when to prefer this over touch-driven tools like tap, but no alternative is named and no when-not condition is given. The agent must infer the decision rule rather than being routed explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingPingA
Health check. Returns 'pong'.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
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 does disclose the return payload ('pong'), which is the key behavioral fact for a no-argument read-only probe. It omits what happens on failure (error vs. alternate string) and whether any side effects 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?
Two terse sentences, zero filler, with the core purpose front-loaded and the return value immediately after.
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 trivial parameterless probe with no output schema, the description covers what it does and what it returns. The only gap is failure behavior, which is minor but would help an agent interpret a non-'pong' 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?
The tool takes zero parameters, so the baseline of 4 applies; there is nothing further the description could reasonably add on this dimension.
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 action (health check) and its exact return value ('pong'), which immediately distinguishes it from functional siblings like get_state or check_state. It does not explicitly contrast itself with nearby tools, but the purpose is 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?
Usage is only implied: an agent can infer this is for verifying connectivity before other calls, but the description never says when to use it or what to do with the result. No alternatives or exclusions are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
press_keyPress keyA
Press a hardware key. "back" goes up one screen — via "js" (tried first by default) calls the navigation container's own goBack() with no touch, via "os" uses the hardware key (Android) or an edge swipe (iOS). "home" is OS-only. "enter" submits a text field by firing its own onSubmitEditing, the only route to a submit handler that does not need the OS keyboard — pass into to name the field when more than one is on screen and none holds focus.
| Name | Required | Description | Default |
|---|---|---|---|
| key | Yes | ||
| via | No | ||
| into | No | ||
| device | No |
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 well: it discloses that 'js' bypasses the OS entirely by invoking the navigation container's goBack(), that 'os' degrades to a hardware key or edge swipe depending on platform, and that 'enter' fires onSubmitEditing without the OS keyboard. It omits failure behavior (e.g., what happens if no navigation container exists) and the role of the `device` parameter.
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 core action is front-loaded and every clause about back/home/enter earns its place by disambiguating behavior. The prose is dense with parenthetical asides and em-dashes, which slightly impedes scanning but does not waste 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?
For a tool with no annotations, no output schema, and a nested object parameter, the description supplies most of what an agent needs: key semantics, strategy selection, and field targeting. The remaining gaps are the undocumented `device` parameter and the absence of any statement about return values or error cases.
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 0%, so the description must compensate, and it does for three of four parameters: it defines the semantics of each `key` value, the two `via` strategies plus the implicit default, and what `into` matches (label/testID/placeholder) when multiple fields are present. The `device` parameter is completely undiscussed, and the 'auto' enum value is never named.
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 and resource ('Press a hardware key') and then enumerates the three supported keys with their distinct behaviors. This is clearly distinguishable from siblings like tap, swipe, or navigate, which perform touch/gesture or route-level 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?
Explicitly guides the choice of `via`: 'js' is tried first by default and calls goBack() without touch, 'os' uses the hardware key or an edge swipe, and 'home' is OS-only. It also explains when to pass `into` for 'enter'. It stops short of telling the agent when to prefer this tool over navigate or tap in a navigation flow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_jsProfile JSA
Record a Hermes CPU profile for duration_ms, then report where the JS thread spent its time: busy/idle/GC split, the functions with the most self time, and the ones with the most inclusive time (symbolicated through Metro when it can). The raw .cpuprofile is saved to disk and opens in Chrome DevTools → Performance → Load. Drive the app (or leave it alone) while this runs — the profile covers whatever happens during the window.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | Rows per table (default 20). | |
| save | No | Write the raw .cpuprofile to disk (default true). Set false to get the summary only. | |
| duration_ms | No | How long to sample for (default 5000, max 120000). | |
| sampling_interval_us | No | Sampling interval in microseconds. Hermes may ignore it and keep its own default. |
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 does a solid job: it discloses that a raw .cpuprofile is written to disk, that it can be loaded in Chrome DevTools, that symbolication is best-effort ('through Metro when it can'), and that sampling is bounded by a window. It stops short of saying whether the call blocks the app, what its overhead is, or what happens when symbolication or the device connection fails.
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 tight sentences: capability and output first, artifact/DevTools second, capture-window advice last. No sentence is filler — even the parenthetical 'or leave it alone' resolves a real operator question.
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 steps up by enumerating the report contents and the on-disk artifact. It leaves a modest gap around blocking behavior, failure modes (no Metro, device disconnect), and what the summary looks like when save=false.
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 each parameter already documents its default, bounds, and even Hermes' tendency to ignore sampling_interval_us, so the description can safely defer. It adds only the implicit link between duration_ms and 'the window' and no syntax or behavior 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 gives a specific verb and resource ('Record a Hermes CPU profile') and even previews the output (busy/idle/GC split, top self-time and inclusive-time tables). It never names the closely related siblings sample_cpu or profile_renders, so the agent has to infer the distinction from the 'JS thread' phrasing rather than being told outright.
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?
'Drive the app (or leave it alone) while this runs — the profile covers whatever happens during the window' is genuinely useful operating guidance for the capture window. But there is no explicit when-to-use/when-not or routing to alternatives such as sample_cpu (process-level CPU) or profile_renders (render profiling), which is the main ambiguity an agent would face.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_rendersProfile rendersA
Count React re-renders over a window: which components rendered, how many times, how long they spent, and which update started each commit. Installs a switchable hook on the React DevTools global hook (dev builds only) that prunes untouched subtrees, so it costs roughly what the commits cost rather than what the tree costs. Nothing re-renders on its own — drive the app during the window, which usually means background: true plus tap/swipe, then get_job to collect.
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | How many components to list by render count (default 15). | |
| label | No | Name for the background job, shown by get_job. | |
| background | No | Start profiling and return a job id immediately, so you can drive the app while it runs. | |
| duration_ms | No | How long to profile (default 5000, max 60000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full load and does well: it names the React DevTools global hook, restricts to dev builds, explains subtree pruning and its cost model, and warns that nothing re-renders on its own. It omits lifecycle details such as whether the hook stays installed after the window or must be removed, which matters for a tool that mutates global state.
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 front-loaded sentences: capability first, cost/constraint second, how-to-drive-it third. Dense with zero filler, and each sentence carries distinct 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?
No output schema exists, yet the description still tells the agent what comes back (per-component render counts, durations, initiating update) and points to get_job for collection. Only gap is post-window behavior of the installed hook.
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 (top, label, background, duration_ms) are already documented in the schema with defaults and maxima. The description adds the background/get_job workflow context but no new semantics for top, label, or duration beyond what the schema states. Baseline 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?
Opens with a specific verb and resource ('Count React re-renders over a window') and enumerates the exact outputs: components rendered, counts, time spent, and the update that started each commit. That is specific enough to separate it from siblings like profile_js or get_fps without reading 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?
Gives concrete operating instructions: drive the app during the window, use background: true plus tap/swipe, then get_job to collect. It never explicitly says when to prefer this over profile_js or sample_cpu, so it stops short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_screen_textRead screen textA
Read the visible text off the screen with on-host OCR (Apple Vision). Works without a Metro connection and sees text the layout tree cannot: images, canvases, WebViews, native dialogs. Returns one line per recognized text run as <text> @x,y — x,y is the centre in tap units and can be passed straight to tap {x,y}. Lines that also exist in the app's JS layout are marked [tree]: prefer tap {text} for those, since an OCR box is just text, not a control. Optional: search (substring filters, case-insensitive), languages (e.g. ["de","en"]; auto-detected by default), compare_tree (default true). macOS host only; the first call compiles a small Vision helper (~10–30s, cached).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | ||
| search | No | ||
| languages | No | ||
| compare_tree | No |
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 does: it discloses the OCR engine (Apple Vision), that it runs on-host, the macOS-only platform constraint, and a first-call latency cost (~10-30s helper compile, then cached). It also explains the return line format and the [tree] marker semantics — none of which any structured field provides.
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?
Dense but front-loaded: purpose first, then differentiators, then output format, then optional params, then platform/latency caveats. Every sentence carries information an agent needs — no filler and no restatement of the 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?
There is no output schema, and the description compensates by specifying the exact line format (`<text> @x,y` in tap units) and the [tree] marker. Combined with platform limits, cold-start latency and parameter defaults, an agent has everything needed to call and interpret this 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 description coverage is 0%, so the description must compensate, and it does for three of four params: search is substring/case-insensitive, languages takes codes like ["de","en"] and defaults to auto-detect, compare_tree defaults true. The `device` parameter is never mentioned, leaving one of four params undocumented in both schema and prose.
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 ("Read the visible text off the screen with on-host OCR") and immediately scopes it against siblings: it sees text the layout tree cannot (images, canvases, WebViews, native dialogs). An agent can distinguish this from get_component_tree, get_layout and screenshot without opening any schema.
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 (works without a Metro connection; text the layout tree can't see), and explicit routing rules for interpreting results: lines marked [tree] should be handled with tap {text}, OCR boxes with tap {x,y}. Alternatives are named, not implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_videoRecord videoA
Start a screen recording (one at a time). Stop with stop_recording. Android uses screenrecord, which caps a clip at 3 minutes. codec applies to iOS only.
| Name | Required | Description | Default |
|---|---|---|---|
| codec | No | ||
| device | No | ||
| output_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It discloses real traits (single concurrent recording, Android's 3-minute cap, codec being iOS-only) but leaves out permissions, where the file lands / how to retrieve it, and what output_path means.
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 terse sentences, front-loaded with the core action and constraint; each clause (stop tool, duration cap, codec platform note) carries information the agent needs.
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 concurrency, platform limits, and how to stop, but with 3 undocumented params, no output schema, and no annotations, it should also explain output_path and device to be truly 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 0%, so the description must compensate, yet it only clarifies codec ('applies to iOS only'). device and output_path get no explanation of format, defaults, or effect, and codec's enum values already live in 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?
Specific verb+resource ('Start a screen recording') with scope ('one at a time'), and it explicitly names the sibling used to stop it. An agent can distinguish this from other capture tools without opening the schema.
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 the operating constraint (one at a time) and routes the agent to stop_recording to end it, plus platform-specific constraints. It does not discuss when to prefer this over screenshot, keeping it just short of explicit alternatives reasoning.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reload_appReload appA
Reload the JS bundle and wait for the new runtime (captures cold-start logs/network on the next run).
| 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 does useful work by disclosing that the tool waits for the new runtime and captures cold-start logs/network on the next run. It omits important side effects such as whether current app state is lost or whether this behaves like a restart.
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?
A single front-loaded sentence with a useful parenthetical and no wasted words. The key action and the blocking behavior are immediately 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?
For a zero-parameter action with no annotations and no output schema, the description covers the core operation and the wait behavior. It is not fully complete because it does not disclose whether reloading resets app state or other destructive side effects.
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 takes zero parameters, so the baseline is 4. There is nothing schema-related for the description to compensate for.
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 ('Reload') and resource ('the JS bundle') and adds the effect of waiting for a new runtime. It is clearly distinct from launch_app/install_app, though it does not explicitly name those 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 parenthetical implies a use case: capturing cold-start logs/network on the next run. However, it gives no explicit when-not guidance or comparison with siblings like launch_app or install_app.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_flowRun flowA
Run a sequence of UI steps server-side in one call (tap/type/swipe/wait_for/expect/expect_not/eval). Set via:'js' to dispatch taps and typing through the app's fiber tree instead of paying a simulator touch per step; each step's report line names the path it used. Aborts on the first failure or app error, and returns an observe snapshot at the stop point. Prefer this over many separate tap/observe calls.
| Name | Required | Description | Default |
|---|---|---|---|
| via | No | Default input path for every tap/type step: js dispatches the press through the app's own fiber tree (~1ms), os delivers a real simulator touch (17-25s against a hot iOS app), auto tries js and falls back naming the reason. A step's own `via` wins. Default auto. | |
| steps | Yes | Array of step objects, one action each, e.g. [{tap:{text:'Login'}},{expect:{text:'Home'}}] | |
| device | No | ||
| observe | No | Trailing snapshot: auto (default) = screenshot always, full layout only if the flow failed; full = both; none = neither. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, so the description carries the burden, and it discloses key runtime semantics: aborts on the first failure or app error, and returns an observe snapshot at the stop point. It also notes that each report line names the input path used. It does not state whether steps already executed before the abort remain applied to the app state (no rollback semantics), which is the main missing behavioral fact for a mutating batch 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?
Three sentences, front-loaded with the purpose and the alternative, with no filler. The middle clause about fiber-tree dispatch and per-step path naming partly duplicates the via enum description already in the schema, which is minor redundancy but keeps it from 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 does cover the return behavior (stop-point observe snapshot, per-step report lines), which is the right call. But for a tool whose required parameter is an array of untyped step objects, the agent is left without the step vocabulary at the payload level (what fields tap/type/swipe/wait_for/expect take), so it cannot reliably construct a multi-step flow from this description alone.
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 core required parameter, steps, has an unstructured item schema (additionalProperties: {}), and the description compensates with a list of step kinds and a short example, which is real added meaning. However, via and observe already have detailed enum descriptions in the schema, so the description mostly restates them rather than adding new semantics, and the payload shape of each step kind remains undefined.
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 and resource — 'Run a sequence of UI steps server-side in one call' — and enumerates the supported step kinds (tap/type/swipe/wait_for/expect/expect_not/eval). It explicitly contrasts itself with the sibling tools tap and observe, so an agent can pick it without opening the schema.
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 a clear selection rule: 'Prefer this over many separate tap/observe calls,' naming the alternatives directly. It also explains the via:'js' tradeoff as the reason to batch. It stops short of stating when NOT to use it (e.g. a single interactive tap you want to inspect step by step), so it is strong but not fully exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sample_cpuSample CPU by threadA
Profile the running app's threads for a few seconds and report which one is hot — the UI/main thread, the JS thread, or something else. iOS simulator: macOS sample, with native call-graph frames. Android: top -H, per-thread %CPU only (no frames).
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | No | ||
| device | No | ||
| duration_s | No |
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 disclose valuable platform-specific behavior: macOS `sample` with native call-graph frames on iOS simulator versus `top -H` giving only per-thread %CPU on Android. It also implies a short fixed sampling window. However, it omits prerequisites (app running, permissions), failure modes on unsupported platforms, and whether sampling blocks other calls.
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 the purpose and outcome, followed by the platform-specific mechanism. No filler, and the em-dash structure keeps the hot-thread enumeration scannable.
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 zero-annotation, no-output-schema tool, the description does well on explaining what comes back and how it differs by platform, but it leaves the parameter surface and prerequisites undocumented, which is significant given three optional parameters at 0% schema coverage.
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 0%, so the description must compensate for all three parameters, yet it never names app_id, device, or duration_s. 'For a few seconds' loosely hints at a duration and the platform branches hint at device, but app_id is entirely unexplained and no defaults or accepted values are given for a tool where every parameter is optional.
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 (profile) and resource (running app's threads) with the concrete outcome: identifying the hot thread among UI/main, JS, or other. This clearly distinguishes it from siblings like profile_js and profile_renders, which target JS work or renders rather than CPU-per-thread.
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?
Usage is implied by the outcome ('report which one is hot'), but the description never says when to pick this over profile_js or profile_renders, nor what prerequisites exist (does the app need to be running/foregrounded?). The agent must infer the selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshotScreenshotA
Capture the current screen. Without output_path returns an inline JPEG downscaled to 800px (pass full_res:true for the native PNG); an image that would still be too large for the caller fails with an actionable error instead of being returned. With output_path saves to a file (format png/jpeg; mask is iOS-only) and returns the path.
| Name | Required | Description | Default |
|---|---|---|---|
| mask | No | ||
| device | No | ||
| format | No | ||
| full_res | No | ||
| output_path | No |
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 real work: it discloses the 800px JPEG downscale default, the native PNG override, the actionable-error failure path when the image is too large, and that mask is iOS-only. It omits operational context such as permission or device prerequisites.
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 the core action, with the two modes laid out in a readable order. The second sentence is dense and slightly run-on, but every clause carries distinct 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?
No output schema and no annotations, yet the description states what is returned in both modes (inline image vs. file path) and the failure behavior, which is the key completeness requirement here. Only the undocumented `device` parameter keeps it from being fully self-sufficient.
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 0%, so the description must compensate, and it explains four of five parameters: output_path (save vs. inline), full_res (native PNG), format (png/jpeg), and mask (iOS-only). The `device` parameter is left entirely unexplained, which is the main remaining gap.
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?
Opens with a specific verb and resource ('Capture the current screen') and immediately splits into two well-defined modes (inline return vs. file save). It is clear what the tool does, but it never names the obvious alternatives (record_video, read_screen_text) to sharpen the boundary.
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 conditions for the two main branches: 'Without output_path...' versus 'With output_path...', plus the full_res escape hatch for native resolution. It tells the agent how to choose a mode, but offers no guidance about when to reach for this tool instead of sibling capture/inspection tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scroll_toScroll to elementA
Bring an off-screen element into view. Returns immediately when it is already visible. via: js asks the element's own scroll container to jump to it (no touch, no swipe); os swipes toward it and re-reads the layout after each swipe, stopping as soon as it appears; auto (default) tries js and names the reason when it falls back.
| Name | Required | Description | Default |
|---|---|---|---|
| via | No | ||
| text | No | ||
| device | No | ||
| testID | No | ||
| max_swipes | No |
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 well: it discloses the early-return short-circuit when the element is already visible, that os mode re-reads layout after each swipe and stops as soon as it appears, and that auto names its fallback reason. It omits failure behavior (what happens when the element is never found), interaction with max_swipes, and the return shape.
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 the core purpose in one sentence, then the early-return rule, then the mode breakdown. Dense but every clause carries information; the semicolon-delimited mode list is efficient rather than padded.
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 5-parameter action tool with no annotations and no output schema, the description covers the mechanism well but leaves element targeting, device selection, swipe budget, and the return/error contract entirely unaddressed. Adequate to call it, insufficient to call it correctly on the first try.
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 0% across 5 parameters, so the description must compensate. It thoroughly explains the `via` enum semantics, but says nothing about `text` vs `testID` (are they alternatives or combined? is one required?), `device`, or `max_swipes` — the latter is only obliquely implied by 're-reads the layout after each swipe'.
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 ('Bring an off-screen element into view') and immediately separates itself from the sibling swipe/tap tools by noting js mode does 'no touch, no swipe'. An agent can tell this is the element-targeted scrolling tool, not a raw gesture tool, without opening any schema.
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 concrete mode-selection guidance: js asks the element's own scroll container, os swipes and re-reads layout, auto (default) tries js then falls back. It explains why you'd pick each mode, but never states when NOT to use this tool or when to prefer siblings like swipe/navigate directly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_permissionSet permissionA
Grant, revoke or reset one privacy permission for an app, so the system alert never appears. iOS services: camera, photos, photos-add, location, location-always, contacts, contacts-limited, microphone, motion, calendar, reminders, media-library, siri, all. Android services: camera, microphone, photos, location, contacts, notifications. app_id defaults to the connected app.
| Name | Required | Description | Default |
|---|---|---|---|
| app_id | No | ||
| device | No | ||
| status | Yes | ||
| service | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden. It does disclose the most important behavioral trait — that this bypasses the system permission alert — plus the app_id default to the connected app. It does not explain reversibility of 'reset', whether the target app must be installed/running, or what an invalid service does.
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 dense sentences with zero filler, and the core action leads. The long service enumerations consume most of the length but each entry is functionally necessary given the free-string 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 mutation tool with no annotations and no output schema, the definition covers action, services, and one default but leaves the device parameter, reset semantics, and failure modes unexplained. Adequate to call correctly in the common case, incomplete at the edges.
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 0%, so the description must compensate, and it does: it documents the valid service strings per platform (iOS vs Android lists differ), which the bare 'service: string' schema omits, and it explains the app_id default. The 'device' parameter and the semantics of 'reset' remain undocumented.
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?
Opens with a specific verb triple (grant, revoke, reset) applied to a precise resource ('one privacy permission for an app'), and enumerates the valid services per platform. No sibling in the list manipulates permissions, so the agent can immediately tell this apart from tap/launch_app/observe.
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 phrase 'so the system alert never appears' gives a concrete decision context: use this instead of letting the OS permission dialog surface. It does not state exclusions (e.g. what to do if the app is not installed, or when to prefer manual UI handling), 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.
stop_recordingStop recordingA
Stop the active screen recording and return the file path.
| 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 burden; it does disclose the output (file path), which is helpful since there is no output schema. However, it omits whether the file is finalized/saved at a default location, whether the operation is idempotent, and what error occurs when no recording is running.
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?
A single front-loaded sentence with zero filler; the action and its result are stated immediately.
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 parameterless stop/teardown tool, action plus return value is nearly everything an agent needs. The only real gap is failure behavior when no recording is active, which is minor but non-zero.
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 takes zero parameters, so the description has nothing to compensate for and correctly stays silent on inputs. Baseline 4 applies for a parameterless tool.
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 and resource ('Stop the active screen recording') and names the artifact produced (file path). It is clearly distinguishable from siblings like record_video, though it never names that sibling explicitly.
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 phrase 'active screen recording' implies a precondition (a recording must be in progress), but the description never states what happens if none is active, nor does it point to record_video as the way to start one. Usage is inferable but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
swipeSwipeA
Swipe in a direction (scaled to the screen), or between explicit coordinates. via picks the delivery path: js scrolls the container under the start point by the same distance through the app runtime (no touch), os is a real simulator/device gesture, auto (default) tries js and names the reason when it falls back.
| Name | Required | Description | Default |
|---|---|---|---|
| x1 | No | ||
| x2 | No | ||
| y1 | No | ||
| y2 | No | ||
| via | No | ||
| device | No | ||
| direction | No | ||
| duration_ms | No |
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 well: it discloses that js mode performs a container scroll with no touch, os mode is a real device gesture, and auto tries js first and reports the fallback reason. It does not cover permissions, return values, or what happens with missing parameters, but the core behavioral distinctions are unusually well explained.
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 two operating modes are front-loaded in the first sentence, and the delivery-path explanation follows efficiently. The second sentence is dense but every clause adds useful 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?
For an 8-parameter tool with zero required parameters, no annotations, and no output schema, the description leaves important gaps: it does not clarify that at least a direction or a full coordinate pair is needed, nor does it explain duration_ms or device. It is minimally viable for the core use cases but not 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 description coverage is 0% for 8 parameters, so the description must compensate. It meaningfully explains 'via' values and implies that direction and coordinate modes exist, but it does not clarify whether x1/y1/x2/y2 must be supplied together, what device selects, or what duration_ms controls.
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 (swipe) and two clear modes: by direction scaled to the screen, or between explicit coordinates. It is clear what the tool does, though it does not explicitly distinguish itself from the sibling scroll_to 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?
Provides useful guidance on how to choose the 'via' delivery path (js vs os vs auto), including fallback behavior. However, it gives no guidance on when to use swipe instead of sibling tools like scroll_to or tap, and does not state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tapTapA
Tap an element by text, testID, or x+y coordinates. Pass duration_ms for a long press. via picks the delivery path (js = call the component's own press handler through the app runtime, os = a real simulator/device touch, default auto). Returns the coordinates tapped, the path used, and what changed on screen.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | ||
| y | No | ||
| via | No | ||
| text | No | ||
| device | No | ||
| testID | No | ||
| duration_ms | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does well: it discloses the default delivery path ('default auto'), the two execution semantics (calling the component's own handler through the app runtime vs a real device touch), and what is returned (coordinates, path used, screen changes). It omits failure behavior, such as what happens when text/testID matches nothing or matches multiple elements.
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 tight sentences, front-loaded with the core action and targeting modes before the modifiers and the return contract. No filler or restated 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?
For a 7-parameter tool with no annotations and no output schema, the description covers the essential contract including return values and the default path. The remaining gaps are the undocumented 'device' parameter and ambiguous-selector/error handling, which an agent would need in edge cases.
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 0%, so the description must compensate and largely does: text, testID, x, y, duration_ms, and the via enum are all given meaning beyond their names. However, the 7th parameter 'device' is never mentioned, and the precedence between element selectors and coordinates (or whether x and y must be supplied together) is left unspecified.
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 and resource ('Tap an element') and enumerates the three targeting modes (text, testID, x+y coordinates), which cleanly separates it from siblings like swipe, type_text, and press_key. An agent can pick this tool without opening the schema.
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 gives conditional guidance within the tool: duration_ms selects a long press, and via selects js vs os with an explicit 'auto' default. It does not name alternatives (e.g. when to prefer swipe or scroll_to instead), so exclusion guidance is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
type_textType textA
Type text into a text input. into selects the field by testID, placeholder or accessibilityLabel — omit it only when a single input is on screen. via "js" (default via "auto" tries it first) calls the field's own onChangeText in ~1ms and runs the app's real onChange pipeline; via "os" drives the simulator keyboard. verify (default true) reads the value back afterwards and fails loudly if it differs — the OS keyboard sends positional keycodes that a non-ASCII host keyboard layout silently rewrites.
| Name | Required | Description | Default |
|---|---|---|---|
| via | No | ||
| into | No | ||
| text | Yes | ||
| device | No | ||
| submit | No | ||
| verify | No |
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 it well: it explains the mechanism of each `via` mode, gives a timing figure (~1ms), states that verify defaults to true and fails loudly, and warns about positional keycodes being rewritten by non-ASCII host layouts. It omits the behavior of `submit` and `device`, which are behavioral as well as structural.
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 the action, then field targeting, then strategy selection, then verification — a sensible order with no filler. The em-dash clauses are dense but each carries real information; the sentence on keyboard layouts is long but earns its place as a warning.
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 6-parameter tool with a nested targeting object, no output schema and no annotations, the description covers the hard parts (targeting ambiguity, mode choice, verification). The gap is `submit` and `device`, which an agent would have to infer from the bare schema.
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 0%, so the description must compensate. It meaningfully documents `into` (matching by testID, placeholder, accessibilityLabel), `via` with defaults, and `verify` with its default and failure mode, but `text`, `device` and `submit` are entirely unaddressed. It also refers to `accessibilityLabel` while the schema field is named `label`, creating a naming mismatch an agent must resolve.
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?
Opens with a specific verb and resource: 'Type text into a text input.' An agent can immediately separate this from tap, press_key or eval_js. It does not explicitly name a sibling to contrast with, so it stops short of a 5.
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 concrete selection conditions: omit `into` only when a single input is on screen, and pick `js`/`os`/`auto` based on the tradeoff described. It lacks any guidance on when typing is not appropriate (e.g. use press_key for special keys) or ordering relative to tap/observe.
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.
35 tool updates
v0.1.0- First observed
check_state - First observed
connect - First observed
eval_js - First observed
get_component_tree - First observed
get_errors - First observed
get_fps - First observed
get_job - First observed
get_layout - First observed
get_logs - First observed
get_network - First observed
get_state - First observed
install_app - First observed
launch_app - First observed
list_devices - First observed
list_targets - First observed
navigate - First observed
observe - First observed
open_simulator - First observed
open_url - First observed
ping - First observed
press_key - First observed
profile_js - First observed
profile_renders - First observed
read_screen_text - First observed
record_video - First observed
reload_app - First observed
run_flow - First observed
sample_cpu - First observed
screenshot - First observed
scroll_to - First observed
set_permission - First observed
stop_recording - First observed
swipe - First observed
tap - First observed
type_text
TDQS
Scored across 35 tools
Most tools target distinct resources or actions, but several composite tools intentionally overlap with atomic tools: observe vs screenshot/get_layout/get_logs, check_state vs get_state/navigate, and run_flow vs tap/type_text/swipe/eval_js. Descriptions explicitly recommend the composite tools, which keeps selection mostly clear, though press_key 'back' and navigate 'back' also overlap.
Names consistently use snake_case and are mostly verb-first (list_devices, get_logs, type_text, profile_js). Minor deviations are single-word operational verbs such as tap, swipe, connect, and navigate, plus the noun 'screenshot', but the overall convention remains readable.
With 35 tools, the surface is well beyond a tightly scoped 3–15 range and past the 16–25 'heavy' bracket. Although the server spans many React Native debugging domains, the large number of atomic plus composite tools makes the selection surface excessive for an agent.
Coverage is broad: device/app management, targets, logs/errors/network, eval and background jobs, state/component tree, OCR/layout/tap/type/swipe, navigation/flows, recording, and performance profiling. Minor gaps remain around explicit app terminate/uninstall and standalone wait/assert helpers, but launch_app terminate_running and run_flow provide workarounds.
Maintenance
Related MCP Connectors
Drive and test your React Native and Expo apps end-to-end on iOS and Android. Supports real devices, simulators, and emulators. Snapshots, taps, typing, swipes, screenshots, deep links, reloads, builds and runtime errors.
Open a React Native app in a simulated phone: read the screen, tap, type, set device state.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
Let your AI agent control real iPhones: screenshots, tap, swipe, type and open apps.
Related MCP Servers
- AlicenseCqualityFmaintenanceProvides AI agents with visibility into React applications by exposing tools to inspect component state, props, and performance metrics. It enables debugging and state analysis for both web and React Native applications through the Model Context Protocol.454 npm1MIT
- 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.2291 npm5MIT
- AlicenseAqualityBmaintenanceEnables agents and LLMs to automate, inspect, and scrape native iOS and Android apps across simulators, emulators, and real devices through a platform-agnostic interface using accessibility snapshots or screenshot-based coordinates. It provides device, app, screen, input, log, and crash management tools, including optional cloud device reservation.3455,275 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceLets MCP-capable AI agents control an Expo / React Native app running live in Expo Go on a real phone, reading a compact token-cheap outline of the visible screen and performing taps, text entry, scrolling, toggles and navigation. Also exposes screenshots, layout, console logs, network requests and hardware keys, and attaches new JS errors and failed requests to the action that caused them.107 npm1MIT