Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
list-devicesA

List iOS simulators, Android emulators, connected physical Android devices, running Chromium apps, and Vega (Fire TV) devices in one place. Use at the start of a session to pick a target id ('udid' for iOS entries, 'serial' for Android/Vega entries, 'id' for Chromium) to pass to interaction tools, and to see which targets are already running. Returns { devices, avds } where each device carries a 'platform' discriminator ('ios', 'android', 'chromium', or 'vega'); 'avds' lists Android AVDs bootable via boot-device. A Vega VVD is listed under 'devices' whether running or stopped (state 'running'/'stopped'); start a stopped one with boot-device using its 'vvdImage'. Android entries also carry a 'kind' ('emulator' for a local AVD, 'device' for a physical phone connected over USB / wireless adb) — physical phones are detected from adb devices (any serial that is not an emulator-* one) and are driven through the same interaction tools as emulators; they do not need boot-device (just connect the phone with USB debugging authorised). TV targets are tagged with runtimeKind 'tv' (Apple TV simulators on iOS, Android TV / leanback devices on Android) — these are focus-driven, not touch-driven: use describe to read focus, tv-remote for remote presses (up/down/left/right/select/back/menu/home), and keyboard to type, rather than the coordinate/gesture tools. Chromium apps are discovered by probing CDP debugging ports (default 9222; extend via the ARGENT_CHROMIUM_PORTS= env var). They must already be running with --remote-debugging-port= — use boot-device with electronAppPath to launch one. Booted/ready devices are listed first. Platforms whose CLI is unavailable are silently omitted — an empty result usually means xcode-select, Android platform-tools, or the Vega SDK is not installed.

boot-deviceA

Start an iOS simulator, launch an Android emulator, start a Vega (Fire TV) Virtual Device, or spawn an Electron app and wait until it is ready to accept interactions. Pick the platform by which argument you pass: 'udid' for an iOS simulator from list-devices, 'avdName' for an Android AVD (a serial is assigned automatically), 'vvdImage' for a Vega VVD (the 'vvdImage' of a vega device from list-devices, e.g. 'tv'), or 'electronAppPath' for an Electron app (a CDP remote-debugging port is picked automatically, or pass 'electronPort' to fix one). Use at the start of a session once you have picked a target. Returns a tagged payload: { platform: 'ios', udid, booted } or { platform: 'android', serial, avdName, booted } or { platform: 'vega', serial, vvdImage, booted } or { platform: 'chromium', id, port, pid, booted } (an Electron app boots as a Chromium/CDP device). Android boots take 2–10 minutes depending on machine and cold/warm state; the tool transparently hot-boots from the AVD's default_boot snapshot when usable and falls back to cold boot otherwise. Vega starts the single SDK-managed VVD via the vega CLI (~10s) and returns once it reports running. If an Android/Electron boot stage fails, the tool terminates the device it spawned so the next retry starts clean.

launch-appA

Open an app by its bundle id (iOS) or package name (Android), or confirm the running renderer (Chromium). Use when starting any app — prefer this over tapping home-screen / launcher icons. Also prepares the native-devtools injection before the app starts (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven — use the tv-* tools rather than coordinate taps. Returns { launched, bundleId }. Fails if the app is not installed on the target device (iOS / Android). For Chromium, the app is already running behind a CDP port; this call simply refreshes the cached viewport and acknowledges the bundleId tag. To change the visible route, use open-url. On Vega (Fire TV), pass the interactive component app id from manifest.toml (e.g. com.example.app.main) as bundleId.

Common iOS bundle ids: com.apple.MobileSMS, com.apple.mobilesafari, com.apple.Preferences, com.apple.Maps, com.apple.camera, com.apple.Photos, com.apple.mobilemail, com.apple.mobilenotes, com.apple.MobileAddressBook Common Android packages: com.android.settings, com.android.chrome, com.google.android.apps.maps, com.google.android.gm, com.android.vending, com.google.android.dialer, com.google.android.apps.messaging

restart-appA

Terminate then relaunch an app by bundle id / package name. Use when you need a clean in-memory state without a full reinstall. Also refreshes the native-devtools injection before the relaunch (the iOS slice on iOS, the tvOS slice on Apple TV); on tvOS, interaction is focus-driven — use the tv-* tools rather than coordinate taps. Returns { restarted, bundleId }. Fails if the app is not installed.

reinstall-appA

Install or reinstall an app on the device. The previous installation (if any) is uninstalled first so app data and runtime permissions are cleared. Use for a full reinstall after rebuilding, or to start from a clean app state. Returns { reinstalled, bundleId }. Fails if the app path does not exist or the package does not match the platform (.app for iOS, .apk for Android, .vpkg for Vega).

open-urlA

Open a URL or URL scheme on the device. Use to navigate to a web page or deep-link into an app. On Chromium, this navigates the primary renderer to the given URL. Cross-platform schemes: https://, tel:, mailto:. iOS also: messages://, settings://, maps://. Android also: geo:, plus any app-specific deep link. Returns { opened, url }. Fails if no app is registered to handle the URI (iOS/Android) or the renderer rejects the navigation (Chromium).

screenshotA

Capture a screenshot of the device screen (iOS simulator, Android emulator, Apple TV simulator, Vega, or Chromium app). Returns { image }; the MCP adapter renders it as a visible image unless the caller passed includeImageInContext: false. Use when you need a baseline image before an interaction or to inspect the current screen state after a delay. Fails if the simulator-server / emulator backend / Chromium CDP is not reachable for the given device.

screenshot-diffA

Compare two PNG screenshots and return a compact visual-diff summary. Accepts saved baseline/current PNG paths, or one saved PNG plus one live full-resolution capture from a device. Always provide udid so the simulator-server dependency can be resolved. Use when stable before/after screenshots exist and the expected result is pixel-visible: layout, spacing, color, typography, image/icon rendering, clipping, overflow, or text rendering. For live captures, set exactly one of captureBaseline or captureCurrent; use baselinePath + captureCurrent for the common visual-regression flow. Returns { summary, diffPath, contextDiffPath }. The summary uses normalized [0,1] screen locations matching describe coordinates; diffPath is the full-size diff image and contextDiffPath is a downscaled image for MCP/agent display. Ignores the fixed top status-bar band for both pixel and OCR text comparisons. Fails if the input sources are invalid, PNG files cannot be read, outputDir cannot be written, or the simulator-server / emulator backend is not reachable.

gesture-tapA

Press the device screen (iOS simulator, Android emulator, or Chromium app) at normalized coordinates: x and y are fractions of screen width and height in 0.0–1.0 (not pixels). Sends a Down event followed by an Up event at the same point. For Chromium, this dispatches a CDP mouse-press/release on the renderer. Use when you need to tap a button, link, or any tappable element on the screen. Returns { tapped: true, timestampMs }. Fails if the simulator-server / emulator backend / Chromium CDP is not reachable for the given device. Before tapping, determine the correct coordinates by using discovery tools — pick by platform: iOS / Android use describe, native-describe-screen, or debugger-component-tree; Chromium uses describe (the DOM walker), since the native and RN-specific discovery tools don't apply. More information in argent-device-interact skill

chromium-tabsA

List and switch the tabs / windows of a Chromium (CDP) app (an Electron app's BrowserWindows or a Chromium browser's tabs), and open or close them.

  • action="list": enumerate page targets with stable ids (t1, t2, …), title, url, and which is active.

  • action="select" (tab=<tabId|label>): make that tab the active one. The active tab is what describe / gesture-tap / screenshot / debugger-evaluate / open-url all operate on, so switch before driving a different tab.

  • action="new" (url?, label?): open a new tab/page and activate it.

  • action="close" (tab?=<tabId|label>): close a tab (defaults to the active one); if the active tab is closed, another live tab becomes active. Use when an app exposes multiple windows or tabs and you need to inspect or drive one other than the current page, or to open/close a page during a flow. tabIds are stable for the session and never reused. Returns { tabs: [{ tabId, targetId, title, url, active, label? }] }. Fails if the device is not a Chromium (CDP) device, or the requested tabId/label no longer matches a live tab. Chromium-only.

chromium-cookiesA

Read and write cookies of a Chromium (CDP) app (via the Network domain, so HttpOnly cookies are included).

  • action="get" (url?): list cookies, optionally restricted to given URLs (defaults to the active page).

  • action="set" (name, value, + url OR domain, optional path/secure/httpOnly/sameSite/expires): create or update a cookie.

  • action="delete" (name, + url/domain/path): remove a matching cookie.

  • action="clear": remove ALL browser cookies. Use when seeding an authenticated session before a flow (set the session cookie, then navigate) or asserting cookie state after one. Returns { cookies, count } for get, or a small status object ({ set } / { deleted } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing name/value. Chromium-only.

chromium-storageA

Read and write localStorage / sessionStorage of a Chromium (CDP) app's active page.

  • action="get": with key, returns that value; without key, returns all entries.

  • action="set" (key, value): write an entry.

  • action="remove" (key): delete an entry.

  • action="clear": empty the store. Set store to "local" or "session". Storage is per-origin, so it reflects the active tab's document. Use when seeding feature flags / auth tokens before a flow or asserting persisted app state after one. Returns { value } for a single key, { entries, count } for all, or a status object ({ set } / { removed } / { cleared }) otherwise. Fails if the device is not a Chromium (CDP) device, or set is missing key/value. Chromium-only.

gesture-swipeA

Execute a smooth swipe / drag touch gesture between two points on the device (iOS simulator or Android emulator). All from/to positions are normalized 0.0–1.0 (fractions of screen width/height, not pixels), same as gesture-tap. Generates interpolated Move events for a natural feel (~60fps). Swipe up (fromY > toY) to scroll content down. Use when you need to scroll a list, dismiss a modal, drag an element, or navigate between pages. Not supported on Chromium — use gesture-scroll there instead. Returns { swiped: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device.

gesture-scrollA

Scroll content in a Chromium app by dispatching mouse-wheel events at a point. Anchor x/y are normalized 0.0–1.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe. Deltas are fractions of the window too: deltaY 0.5 scrolls down half a window; negative scrolls back up. Use when content is below/above the fold (describe shows off-screen elements with zero height) or a list needs scrolling. Chromium only — on iOS/Android use gesture-swipe. Returns { scrolled: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.

gesture-dragA

Press the left mouse button at a start point, move to an end point, and release — a desktop mouse drag in a Chromium app. All positions are normalized 0.0–1.0 (fractions of the window, not pixels), same coordinate space as gesture-tap and describe. Interpolates mouse-move events at ~60fps over durationMs for a natural drag. Use for slider thumbs, drag-and-drop, text selection, or draggable UI elements. Dragging never scrolls content on desktop — use gesture-scroll for lists/pages. Chromium only — on iOS/Android use gesture-swipe. Returns { dragged: true, timestampMs }. Fails if the Chromium CDP session is not reachable for the given device.

gesture-customA

Send a sequence of touch events for complex gestures. Use for: long press, drag-and-drop, custom scroll, pinch (second touch point). For simple taps use the gesture-tap tool. For straight-line scrolling use the gesture-swipe tool. For pinch gestures use gesture-pinch. For rotation gestures use gesture-rotate. All x/y values are normalized 0.0–1.0 (screen fractions, not pixels). delayMs controls the delay before each event (default 16ms ≈ 60fps). Set interpolate to auto-generate smooth intermediate Move events between your keyframes. Returns { events: number } with the total count of events dispatched. Fails if the target device is not booted or an event type is invalid.

Example long-press at center: [{"type":"Down","x":0.5,"y":0.5},{"type":"Up","x":0.5,"y":0.5,"delayMs":800}]

Example smooth scroll down: [{"type":"Down","x":0.5,"y":0.7}, {"type":"Move","x":0.5,"y":0.6},{"type":"Move","x":0.5,"y":0.5},{"type":"Move","x":0.5,"y":0.4}, {"type":"Up","x":0.5,"y":0.3}]

Example pinch-to-zoom (with interpolate:10 for smoothness): events: [{"type":"Down","x":0.4,"y":0.5,"x2":0.6,"y2":0.5}, {"type":"Up","x":0.2,"y":0.5,"x2":0.8,"y2":0.5}] interpolate: 10

gesture-pinchA

Execute a pinch-to-zoom gesture by moving two fingers toward or away from a center point to change the scale of on-screen content. All positions and distances are normalized 0.0–1.0 (fractions of screen width/height, not pixels)—same coordinate space as gesture-tap and gesture-swipe. startDistance > endDistance = pinch in (zoom out). startDistance < endDistance = pinch out (zoom in). Typical values: startDistance 0.2, endDistance 0.6 for a zoom-in pinch at screen center. Auto-generates interpolated frames at ~60fps. The angle parameter controls the axis (0 = horizontal, 90 = vertical). Use when you need to zoom in or out on a map, image, or zoomable view. Returns { pinched: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device.

gesture-rotateA

Send a two-finger circular arc gesture to rotate on-screen content by a specified angle. Two fingers are placed opposite each other at a fixed radius from the center, then swept from startAngle to endAngle degrees. All positions and radius are normalized 0.0–1.0 (fractions of screen width/height, not pixels)—same coordinate space as gesture-tap and gesture-swipe. endAngle > startAngle = clockwise rotation. Typical values: radius 0.15, startAngle 0, endAngle 90 for a 90° clockwise turn. Auto-generates interpolated frames at ~60fps. Unlike gesture-pinch which moves fingers linearly to zoom, this orbits fingers in an arc to change orientation. Use when you need to rotate a map, image picker, or any rotateable UI element. Returns { rotated: true, timestampMs }. Fails if the simulator-server / emulator backend is not reachable for the given device.

buttonA

Press a device hardware button (iOS simulator or Android emulator). Sends Down then Up events automatically. Supported buttons depend on the platform: home, back, power, volumeUp, volumeDown, appSwitch, actionButton — buttons not present on the target platform (e.g. 'back' on iOS, 'actionButton' on Android) are rejected with a clear error. Use when you need to trigger hardware button events. Returns { pressed: buttonName }. Fails if the simulator-server / emulator backend is not reachable for the given device.

keyboardA

Type text or press special keys on the device (iOS simulator, Android emulator, Chromium app, Vega Virtual Device, or Apple TV / Android TV) using keyboard events. Use when you need to enter text or trigger a named key such as enter, escape, or arrow keys. On Vega and Apple TV / Android TV, prefer the remote tools for D-pad navigation; use keyboard to type into a focused text field (e.g. a search or login box). Returns { typed: string, keys: number }. Fails if an unsupported key name is provided or the simulator-server / emulator backend / Chromium CDP / Vega adb / TV control daemons are not reachable for the given device.

  • text: types a string character by character (supports uppercase, digits, common punctuation)

  • key: presses a single named key (enter, escape, backspace, tab, arrow-up/down/left/right, f1–f12) — NOT supported on TV targets; move focus with tv-remote instead. On a TV target (runtimeKind 'tv') only text applies — focus a text field first (with tv-remote), then type into it (injected HID keyboard on Apple TV, adb input text on Android TV). Provide text, key, or both.

rotateA

Set the device orientation to Portrait, LandscapeLeft, LandscapeRight, or PortraitUpsideDown. Use to test layout in a different orientation. Re-run describe afterwards — frame coordinates change with the orientation. Returns { orientation }. Fails if the target device is not booted.

tv-remoteA

Press a TV remote / D-pad button (or a whole path of them) on a TV device — Apple TV (tvOS), Android TV (leanback), or Vega (Fire TV). A TV is navigated with a directional remote, not touch — use this instead of gesture-tap/swipe (which do not apply on a TV). Move focus with up/down/left/right, confirm with select, go back with back/menu, exit with home, and use playPause/rewind/fastForward/next/previous/volumeUp/volumeDown/mute for the corresponding remote keys. (On the Apple TV simulator the media-transport and volume keys are rejected — its HID stack ignores them; they work on Android TV and Vega.) Single press: { button: "down" }. Repeat the same button: { button: "down", repeat: 3 }. Multi-step navigation: pass a path as { button: ["up","right","right","select"] } — it runs in one tool call, far cheaper than separate presses. Read the screen with describe before and after to see where focus landed. Returns { pressed, count }.

run-sequenceA

Execute multiple device interaction steps in a single call (iOS simulator, Android emulator, Apple TV / Android TV, or Chromium app). Use when you need sequential actions and do NOT need to observe the screen between them (e.g. scrolling multiple times, typing then pressing enter, rotating back and forth). Returns { completed, total, steps } with per-step results. Fails if an unrecognised tool name is used in a step (error returned at that step, execution stops). No screenshot is captured automatically — call screenshot separately after the sequence if needed.

ONLY use this when every step is known in advance. If any step depends on the result of a previous one (e.g. tapping a menu item that only appears after a prior tap), use individual tool calls instead.

Allowed tools and their args (udid is auto-injected, do NOT include it in args):

gesture-tap: { x: number, y: number } [ios/android/chromium] gesture-swipe: { fromX: number, fromY: number, toX: number, toY: number, durationMs?: number } [ios/android] gesture-scroll: { x: number, y: number, deltaX?: number, deltaY?: number, durationMs?: number } [chromium only] gesture-drag: { fromX: number, fromY: number, toX: number, toY: number, durationMs?: number } [chromium only] gesture-custom: { events: [{ type: "Down"|"Move"|"Up", x: number, y: number, x2?: number, y2?: number, delayMs?: number }], interpolate?: number } [ios/android] gesture-pinch: { centerX: number, centerY: number, startDistance: number, endDistance: number, angle?: number, durationMs?: number } [ios only] gesture-rotate: { centerX: number, centerY: number, radius: number, startAngle: number, endAngle: number, durationMs?: number } [ios only] button: { button: "home"|"back"|"power"|"volumeUp"|"volumeDown"|"appSwitch"|"actionButton" } [ios/android] keyboard: { text?: string, key?: string, delayMs?: number } (TV: text only) [ios/android/chromium/vega/tv] rotate: { orientation: "Portrait"|"LandscapeLeft"|"LandscapeRight"|"PortraitUpsideDown" } [ios/android] tv-remote: { button: <remote button | array of them>, repeat?: number } [apple tv/android tv/vega] buttons: up/down/left/right/select/back/home/menu/playPause (+ rewind/fastForward/next/previous/volumeUp/volumeDown/mute — work on Android TV and Vega; rejected on the Apple TV simulator) await-ui-element: { condition: "exists"|"visible"|"hidden"|"text", selector: {text?,identifier?,role?}, expectedText?, timeoutMs?, pollIntervalMs? } [ios/android/chromium]

Example — scroll down three times (use gesture-scroll with positive deltaY on Chromium): { "udid": "", "steps": [ { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } }, { "tool": "gesture-swipe", "args": { "fromX": 0.5, "fromY": 0.7, "toX": 0.5, "toY": 0.3 } } ]}

Example — type text and submit: { "udid": "", "steps": [ { "tool": "keyboard", "args": { "text": "hello world" } }, { "tool": "keyboard", "args": { "key": "enter" } } ]}

Example — TV: move focus right twice then activate (one tv-remote step with a path is cheaper): { "udid": "", "steps": [ { "tool": "tv-remote", "args": { "button": ["right", "right", "select"] } } ]}

Example — tap, wait for the next screen's element, then tap it: { "udid": "", "steps": [ { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.9 } }, { "tool": "await-ui-element", "args": { "condition": "visible", "selector": { "text": "Continue" } } }, { "tool": "gesture-tap", "args": { "x": 0.5, "y": 0.5 } } ]} If the await-ui-element condition is not met before its timeout, the sequence stops there and the following steps do NOT run — so the tap above only fires once "Continue" is actually on screen.

Stops on the first error (or unmet await-ui-element condition) and returns partial results.

debugger-connectA

Connect to a JS runtime CDP debugger. iOS / Android: connects to Metro's CDP endpoint on the given port. Chromium: re-uses the page CDP session opened by boot-device — port is ignored. Returns connection info including port, projectRoot (empty on Chromium), deviceName, appName, logicalDeviceId, and isNewDebugger. If already connected, returns the existing connection. Use when starting a debug session or before calling other debugger-* tools. Fails if the runtime is unreachable (Metro down, or Chromium CDP terminated).

debugger-statusA

Get JS runtime debugger connection status and diagnostic info. Use when you need to verify connectivity before using other debugger tools. Returns port, projectRoot (empty on Chromium), deviceName, appName, logicalDeviceId, connected flag, loadedScripts count, and sourceMapReady (always true — waits for pending source maps before returning; no-op on Chromium). Fails if the runtime is unreachable.

debugger-evaluateA

Execute arbitrary JavaScript in the app's JS runtime via CDP — Hermes on iOS / Android, V8 on Chromium. Returns the evaluation result as a JSON-serializable value, along with deviceName, appName, and logicalDeviceId for context. Use when you need to read app state, call app functions, or test logic at runtime. The result is serialized by value, so cyclic objects (many RN runtime values — fiber nodes, navigation refs, global — are cyclic) fail with a serialization error rather than returning silently. Fails if the expression throws or the runtime is not connected.

debugger-reload-metroA

Restart the Metro JS bundle in the connected React Native app without restarting the native process. Use when you want to apply code changes or reset JS state. Returns { reloaded, port, method, deviceName, appName, logicalDeviceId } indicating which reload path was used and which device/app was targeted. Fails if Metro is not running on the given port.

debugger-component-treeA

Fetch the current screen of a running React Native app as a compact component text tree. Only shows on-screen components with unique positions — off-screen (scrolled) content, full-screen transparent wrappers, and implementation-detail components are pruned.

Each visible component is listed with its name, text content, and normalized tap coordinates in [0,1] space (fractions of the screen, not pixels — same space as tap/swipe/gesture).

This is the preferred element discovery tool for React Native apps. More information in argent-react-native-app-workflow skill.

Workflow:

  1. Call this tool to get the component tree.

  2. Find the desired element by name, text, testID, or accessibilityLabel.

  3. Use the (tap: x,y) coordinates directly with the tap tool.

Call again after navigation or state changes since positions may shift. Set includeSkipped=true to see a summary of all filtered components. Use when you need tap coordinates for a React Native UI element. Returns a compact text tree with (tap: x,y) coords. Fails if Metro debugger is not connected.

debugger-inspect-elementA

Inspect the React component hierarchy at a screen coordinate (x, y). Returns components from the tapped element upward through its parent hierarchy, each with its source file:line and a code fragment.

The first items (lowest indices) are the most specific — the exact component under the tap point and its direct parents. Higher indices are broader context (page, navigator). Default shows 35 items which covers all app-specific code; use maxItems=70+ to also see the navigation/screen structure.

Uses getInspectorDataForViewAtPoint + _debugStack + Metro /symbolicate. Set resolveSourceMaps to false to skip symbolication and get raw bundled locations instead. Set includeSkipped=true to see filtered items annotated with skip reasons. Use when you need the source file and line for a component at a tap coordinate. Fails if the app is not connected or the coordinate is outside the screen.

debugger-log-registryA

Get a summary of all console logs captured from the app's JS runtime. Returns the log file path, entry counts by level, and message clusters (grouped by similarity). Works against Hermes (iOS / Android) and V8 (Chromium). Use when investigating warnings, errors, or unexpected output — call this first for an overview, then read the returned file for details. Returns empty stats if no log data has been captured yet.

view-network-logsA

Retrieve captured network (HTTP) requests from the running app. Returns a paginated list of requests with method, URL, status, resource type, size, and duration. Each entry includes a requestId that can be passed to view-network-request-details for full details. On React Native (iOS/Android) interception is injected into the JS runtime — it captures fetch() calls. On Chromium it reads the browser's native CDP Network domain (the active tab; all request types). Use when inspecting outbound HTTP traffic or debugging API calls in the running app. Fails if the app is not connected (RN) or the device is not reachable (Chromium).

view-network-request-detailsA

Get full details of a specific network request by its requestId (from view-network-logs). Returns request/response headers (sensitive headers redacted), status, timing, and optionally the response body. Large response bodies are truncated. Use when you need headers, body, or timing for a specific request after listing logs. Returns an error message string if the requestId is not found — use view-network-logs to get valid requestId values.

describeA

Get the accessibility / DOM element tree for the current screen. On iOS, uses the AXRuntime accessibility service to inspect whatever is currently visible — including system dialogs, permission prompts, and any foreground app content. On Android, runs uiautomator dump. On Chromium, walks the renderer's DOM via Chrome DevTools Protocol — every visible element with its ARIA role, accessible name, and bounding rect (normalized to 0–1). On Vega (Fire TV), reads the on-device automation toolkit (getPageSource); each element carries [focused]/[selected] so you can see where the D-pad cursor is, then move it with the tv-remote tool (Vega is remote-driven, not touch). If describe returns an empty tree on Vega, relaunch the foreground app (the toolkit attaches at launch) and try again.

When a system dialog is visible, describe returns the dialog's interactive elements (buttons, text) with tap coordinates. When no dialog is present, it returns the foreground app's accessible elements.

Returns { description, source } where description is a text rendering of the UI tree — one line per element with its role, label/value/id, interactivity flags, and frame. Frame coordinates are normalized [0,1] fractions of the screen / window width/height (not pixels) — the same space as gesture-tap / gesture-swipe / gesture-pinch.

To tap an element use the centre of its frame: tap_x = frame.x + frame.width / 2, tap_y = frame.y + frame.height / 2. The same formula appears in the response header so it can be applied to a line in isolation.

For app-scoped inspection with full UIKit properties (accessibilityIdentifier, viewClassName), use native-describe-screen with an explicit bundleId instead (iOS only). For React Native apps, debugger-component-tree returns React component names with tap coordinates.

On a TV target (Apple TV / Android TV — a list-devices entry with runtimeKind 'tv') this returns the focus-driven view instead: the currently FOCUSED element and the list of FOCUSABLE elements, since a TV UI has no tap coordinates. Move the highlight with tv-remote (up/down/left/right/select/ back/menu/home), then call describe again to confirm where focus landed.

await-ui-elementA

Block until a UI element reaches an expected state or a timeout elapses, so you don't have to poll screenshot/describe yourself.

Conditions: exists — the selector matches an element anywhere in the tree. visible — the selector matches an element with a non-zero on-screen frame. hidden — the selector matches nothing, or only a zero-area element (e.g. a spinner that disappeared). text — the FIRST match in reading order (topmost, then leftmost) contains expectedText (case-insensitive substring). A loose selector can match several elements; only that topmost one is inspected, so if a lower match is the one holding the text the wait still reports failure — narrow the selector to target it.

The selector is { text?, identifier?, role? }; every provided field must match (case-insensitive substring). text matches the element's label or value. It polls the same accessibility / DOM tree as describe (iOS AXRuntime, Android uiautomator, Chromium CDP) every pollIntervalMs (default 400ms) until timeoutMs (default 5000ms).

Returns { success: boolean, elapsed: number } — success=false means the condition never held before the timeout (a note then explains what was seen). Use this after a tap/navigation to wait for the next screen, or before tapping an element that appears asynchronously.

await-screen-idleA

Block until the screen has rendered content and stopped changing, or a timeout elapses.

Polls the same accessibility / DOM tree as describe every pollIntervalMs (default 200ms) until it has content and that content holds identical for minStableMs (default 250ms), or timeoutMs (default 3000ms) is reached. Returns { settled, waitedMs, polls } — settled=false means the screen never went still before the timeout. Use after a launch/navigation to wait for the UI to render before screenshotting or tapping.

react-profiler-startA

Start CPU profiling + React commit capture on the connected Hermes runtime. Delegates React commit capture to the in-app React DevTools backend (ri.startProfiling). If another tool-server already owns the session, returns { already_running: true, owner, stale, how_to_reclaim } without clobbering their data. Pass { force: true } to reclaim a fresh owner's session, but BEFORE OVERTAKING - ask the user for approval first, see relevant skill for guidance. Before calling this, ask the user if they also want native profiling (native-profiler-start) — recommend running both in parallel for a complete picture. After starting, ask the user to perform the interaction to profile, then call react-profiler-stop. Returns { started_at, startedAtEpochMs, hermes_version, detected_architecture } on success, or the already_running payload described above. Fails if the Hermes runtime is not reachable or the Metro CDP connection cannot be established.

react-profiler-stopA

Stop CPU profiling and collect the cpuProfile + React commit tree. Reads commit data from the in-app React DevTools backend. Stores results in the ReactProfilerSession for later use by react-profiler-analyze or react-profiler-cpu-summary. Call react-profiler-start first, then exercise the app, then call this. Returns { duration_ms, sample_count, fiber_renders_captured, total_react_commits, hot_commit_indices } summarizing the session. When any commit had fibers whose display name could not be resolved at stop time (typically transient components like modals/tooltips/animations that unmounted before stop), the response also includes { unattributed_ms, unattributed_fiber_count, unattributed_commit_count } — these quantify how much work is not accounted for in the per-component breakdown (the per-commit duration itself remains correct). Fails if no active profiling session exists or the CDP connection was lost during recording.

react-profiler-statusA

Check the state of the React profiler session without side effects. Use after an interruption (debugger disconnect, unexpected error, agent pause) to decide whether to continue with react-profiler-stop, start a new session, or reconnect the debugger. Ownership is verified server-side against this tool-server's in-memory session — no token-threading is required. Returns { session_status, is_running, current_owner, … }. If this tool-server process restarted after react-profiler-start, status will report 'taken_over'; use react-profiler-start { force: true } to reclaim.

react-profiler-analyzeA

Analyze stored profiling data and return a markdown performance report. Returns { report, reportFile, hotCommitsTotal, hotCommitsShown, sessionFiles }. The report is structured around hot React commits (≥16ms absolute floor) with per-commit render cascades, root cause identification, and a top components table. Raw profiling data is saved to disk with a unique session timestamp for later reload via profiler-load. After presenting the report, ask the user whether to investigate further (drill-down with profiler-cpu-query / profiler-commit-query) or implement fixes and re-profile for comparison. Requires react-profiler-stop to have been called first. Optional annotations param: provide Array<{offsetMs, label}> to annotate commits with the user action that preceded them. Compute offsetMs = tapTimestampMs - startedAtEpochMs where tapTimestampMs is the timestampMs returned by the tap/swipe tool and startedAtEpochMs is returned by react-profiler-start. Use when the profiling session is complete and you need to interpret the collected data. Fails if react-profiler-stop has not been called or no profiling data is stored.

react-profiler-component-sourceA

Find a React component's source via tree-sitter AST lookup: returns file path, line number, memoization status (isMemoized, hasUseCallback, hasUseMemo), and 50 lines of source for a named React component. Call this per-finding after react-profiler-analyze to inspect source before proposing a fix. Returns found: false if the component is not found in user-owned code (e.g. lives in node_modules). When several files define a component with the same name (e.g. platform variants like List.tsx and List.web.tsx), returns the primary match and lists the rest under otherMatches[] (file/line/col) — check it before assuming the returned file is the one you meant.

react-profiler-cpu-summaryA

Return a raw Hermes CPU flamegraph summary (top hotspot functions by self-time). FOR DEDICATED CPU INVESTIGATION ONLY — do NOT call this as part of a normal profiling session. Use react-profiler-analyze instead; it covers all React rendering performance analysis. Use when you specifically need to investigate JS CPU hotspots that are NOT tied to React rendering (e.g. regex slowness, cryptography, heavy computations). Call react-profiler-stop first. Reads directly from the stored cpuProfile. Returns a markdown table of the top hotspot functions with self-time, total-time, and location. Fails if react-profiler-stop has not been called or no CPU profile is stored.

react-profiler-rendersA

Scan the live React fiber tree to collect component render counts and durations. Returns a markdown table of the top re-rendering components. No profiling session required — works on a live connected app. Use when you want a quick snapshot of render counts without a full profiling session. Fails if the React DevTools hook is not present in the runtime or the app is not connected.

react-profiler-fiber-treeA

Inspect the React fiber tree and return a JSON representation of the component hierarchy. Use when tracing ancestry of a library component or checking for useMemoCache hook (confirms React Compiler is active on a component). Returns a nested JSON tree of fiber nodes with name, tag, actualDuration, selfBaseDuration, and children. Fails if the React DevTools hook is not present or no fiber roots have been committed yet.

native-profiler-startA

Start native profiling on a booted device. iOS: Instruments via xctrace (CPU, hangs, memory). Android: Perfetto (CPU, jank, RSS-growth weak signal). Auto-detects the running app process unless app_process is explicitly provided. After starting, let the user interact with the app, then call native-profiler-stop. Use when you want to capture native CPU, hang, and memory data for a running app. Returns { status, pid, traceFile } confirming the recording has started. Fails if no app is running on the device, or the profiler cannot attach to the process.

native-profiler-stopA

Stop native profiling and export trace data. iOS: sends SIGINT to xctrace, waits for packaging, then exports CPU, hangs, and leaks XML. Android: sends SIGTERM to the perfetto daemon, polls /proc/, then adb pulls the .pftrace. Call native-profiler-start first. Use when the user has finished the interaction to profile and you need to export the trace. Returns { traceFile, exportedFiles, exportDiagnostics? }; traceFile is the raw trace bundle and exportedFiles the exports, all downloadable artifacts materialized to local paths. Fails if no active native-profiler-start session exists for the given device_id.

native-profiler-analyzeA

Analyze exported native trace data and return an LLM-optimized markdown report. iOS: parses CPU time profile, UI hangs, and memory leaks from the exported XML files. Android: queries the Perfetto .pftrace via the in-process Perfetto trace-processor engine for CPU hotspots, UI hangs with jank reason + main-thread state breakdown, GC annotation, and an RSS-growth weak signal. Returns a structured markdown report with severity indicators, tables, and actionable suggestions. After presenting the report, ask the user whether to investigate further (drill-down with profiler-stack-query for hang stacks, CPU context, leak details) or implement fixes and re-profile. Call native-profiler-stop first to export the trace data. Use when you need to interpret a completed native profiling recording. Fails if native-profiler-stop has not been called first to export trace data.

profiler-cpu-queryA

Query Hermes CPU profile data with targeted modes for iterative investigation. Requires react-profiler-stop (and ideally react-profiler-analyze) to have been called first. Modes:

  • top_functions: Global CPU hotspots ranked by self-time. Optional time_window_ms to filter.

  • time_window: CPU breakdown for a specific time range (e.g. during a slow commit or hang).

  • call_tree: For a given function_name, show its callees and optionally callers.

  • component_cpu: For a given component_name, aggregate CPU activity across all its commits. Use when investigating JS CPU hotspots or correlating CPU cost with specific components. Returns a markdown table of CPU hotspots, call tree, or per-component CPU breakdown. Fails if no CPU profile is stored — run react-profiler-stop first.

profiler-commit-queryA

Query React commit data for iterative investigation of render performance. Requires react-profiler-stop to have been called first. Modes:

  • by_component: All commits where a specific component rendered, with causes and durations.

  • by_time_range: What happened in a specific time window.

  • by_index: Full detail dump of a single commit (all components, props changed, parent cascade).

  • cascade_tree: Parent-child cascade tree for a commit showing who triggered whom. Use when drilling into specific components or time windows after react-profiler-analyze. Returns a markdown table or tree of commit data matching the requested mode. Fails if react-profiler-stop has not been called or no commit data is stored.

profiler-stack-queryA

Query native profiler trace data for iterative investigation of native performance. Requires native-profiler-stop → native-profiler-analyze to have been called first. Modes:

  • hang_stacks: Full CPU context during a specific hang (by hang_index).

  • function_callers: Who calls a specific native function and what it calls.

  • thread_breakdown: CPU time split by thread, optionally filtered.

  • leak_stacks: Memory leak details (iOS only), optionally filtered by object_type. Use when drilling into native hang stacks, thread CPU breakdown, or memory leaks after native-profiler-analyze. Returns a markdown report with native call stacks, thread weights, or leak details for the selected mode. Fails if native-profiler-analyze has not been run or no parsed trace data is in memory.

profiler-combined-reportA

Generate a cross-correlated report combining React Profiler and native profiler data. Maps native hangs to React commits using wall-clock time alignment. Requires both react-profiler-analyze and native-profiler-analyze to have been called first. Call this tool when both profilers were run in parallel on the same session. Returns a markdown report correlating hangs with React commits, memory leaks, and investigation hints. Fails if either react-profiler-analyze or native-profiler-analyze has not been called first.

profiler-loadA

Fetch and restore a previously captured profiling session from disk into memory so query tools can operate on it. This is the disk-restore counterpart to react-profiler-stop/native-profiler-stop, which write data, and to the query tools (profiler-cpu-query, profiler-commit-query, profiler-stack-query), which read it. Use when you need to revisit past session data without capturing a new recording. Modes:

  • list: Show all available profiling sessions in the project's debug directory.

  • load_react: Load a React profiler session (CPU profile + commit tree) into memory. Requires session_id.

  • load_native: Re-parse native profiler XML files into memory. Requires session_id and device_id. For Android .pftrace restores, pass app_process for older sessions that do not have a metadata sidecar. Returns a summary of the loaded session or a session list for the list mode. Fails if the session_id is not found or required XML files are missing from disk.

gather-workspace-dataA

Fetch a structured snapshot of a mobile app project's workspace.

Returns package.json contents, metro/babel config text, app.json, eas.json, tsconfig, platform directory presence (ios/, android/), presence of android/gradlew (android_has_gradle), iOS .xcworkspace name and Podfile presence, lockfile type, .env file keys (no values), installed CLI tool versions, scripts/ directory listing, husky hooks, CI config type, Makefile targets, lint-staged config, and a list of detected config files.

DO NOT RUN THIS TOOL IF YOU ARE THE MAIN AGENT AND THIS TASK CAN BE DELEGATED TO A SUBAGENT.

If you are a subagent tasked with exploring the project environment, run this as the first step. The snapshot provides the raw data needed to determine the project type (React Native, Expo, Flutter, native iOS/Android, or other), build commands, startup scripts, platform support, package manager, and QA tooling. Follow up with Read/Glob/Grep for deeper exploration of anything the snapshot surfaces. Use when you need to inspect project configuration without manually reading multiple files. Returns partial data if workspacePath does not exist or is not readable; missing items are represented as null or empty collections. Fails if the workspacePath is not an absolute path or the directory cannot be accessed.

native-devtools-statusA

Check whether native devtools are connected to a specific app and whether the next launch is prepared for injection. Use when you need to verify native devtools readiness before calling native-full-hierarchy, native-describe-screen, or native-network-logs.

Returns { envSetup, appRunning, connected, requiresRestart, nextLaunchWillBeInjected }:

  • envSetup: DYLD_INSERT_LIBRARIES is configured in the simulator's launchd environment

  • appRunning: the target bundle currently has a running UIKit process on the simulator

  • connected: the dylib is active in the current running process for this bundleId

  • requiresRestart: the app is already running but its current process does not have native devtools injected

  • nextLaunchWillBeInjected: if you launch this bundle now, native devtools env setup is already in place

Call this before using app-scoped native hierarchy tools or native-network-logs. If appRunning is false and nextLaunchWillBeInjected is true: use launch-app normally. If requiresRestart is true: call restart-app, then proceed with the native feature. Fails if the simulator server is not running for the given UDID or the bundleId is not found.

native-network-logsA

Retrieve network requests captured at the native NSURLProtocol level. Unlike the JS-level network inspector (view-network-logs), this captures ALL network traffic from the app including native modules, Swift/Objective-C networking, and background transfers that bypass JS fetch. Use when you need to inspect native-level HTTP traffic that is invisible to JS fetch interception. Returns { status, count, events } where each event contains URL, method, status code, headers, and timing. Returns { status: "restart_required" } if the dylib is not injected - if this happens, call "restart-app" then retry. Fails if native devtools are not connected or the app is not running.

native-find-viewsA

Search for specific UIViews in the running app by class name, accessibility identifier, label, tag, or React Native nativeID. Use when you need to locate a specific view by its properties without dumping the entire hierarchy. Returns { status: "ok", matches } with matching views including their frames, properties, optional ancestors, and optional children. Much more targeted than native-full-hierarchy. At least one of className, identifier, label, tag, or nativeID must be provided. Fails if native devtools are not connected, the app is not running, or status is restart_required (call restart-app then retry).

native-full-hierarchyA

Get the complete UIKit view tree for the running app. WARNING: Output can be extremely large (100KB–500KB+) for complex apps, especially those built with SwiftUI. Prefer native-find-views for targeted queries. Use skipClasses / skipClassPrefixes to prune SwiftUI internal subtrees and reduce output size. Use the fields param to request only the properties you need. Use when you need deep layout debugging, finding views with no accessibility labels, or verifying view structure not exposed through the accessibility tree. Returns { status: "ok", windows } with the full view hierarchy, or { status: "restart_required" } if the dylib is not injected. Fails if native devtools are not connected or the app is not running.

native-describe-screenA

Read the running app's native accessibility screen description via injected native devtools.

Returns a flat list of accessibility leaf elements with:

  • raw native point-space frame and tapPoint

  • normalizedFrame and normalizedTapPoint relative to the app's main screen bounds

  • top-level screenFrame metadata

  • traits and optional labels/identifiers

This is a low-level native inspection tool. The normalized fields are intended to help with backend migration work, but the public describe contract is still separate.

Useful for evaluating or debugging the lower-level native data that powers the public describe tool.

If status is restart_required: call restart-app then retry.

native-view-at-pointA

Inspect the deepest visible UIView at a raw native window point.

Unlike native-user-interactable-view-at-point, this ignores userInteractionEnabled, so it answers "what is visually here?" rather than "what would receive the touch?".

IMPORTANT: x and y are raw iOS window coordinates in points, NOT normalized [0,1] simulator tap coordinates.

If status is restart_required: call restart-app then retry.

native-user-interactable-view-at-pointA

Inspect the deepest UIView at a raw native window point that would actually receive touch input.

Unlike native-view-at-point, this respects userInteractionEnabled and is closer to UIKit hit-testing semantics.

IMPORTANT: x and y are raw iOS window coordinates in points, NOT normalized [0,1] simulator tap coordinates.

If status is restart_required: call restart-app then retry.

stop-simulator-serverA

Stop the transport session for a specific device (iOS / Android: simulator-server process; Chromium: CDP WebSocket) and free its resources. Use when you are done interacting with one device but want to keep others running. Returns { stopped, udid }. Fails silently if no session is open for the given id.

stop-all-simulator-serversA

Stop all running simulator-server processes (iOS + Android), native devtools services, and Chromium CDP sessions, freeing their resources. Call this when your session ends or the user says they are done. Returns { stopped } — an array of URNs that were shut down. Fails silently if no servers are running.

stop-metroA

Stop the Metro bundler process listening on a given port (default 8081). Use when ending a React Native session or when Metro must be restarted. Returns { stopped, port, pids }; stopped=false if no process is found on the port. Fails if the port lookup command times out or the process cannot be killed. This is DESTRUCTIVE — always ask the user for confirmation before calling this tool.

flow-start-recordingA

Start recording a new flow. Creates a .yaml file in the .argent/flows/ directory. Use when you want to capture a reusable sequence of device interactions for later replay. Returns { message, flowFile, savedTo } and optionally { previousFlow } if a prior recording was abandoned. Fails if the .argent/flows/ directory cannot be created or the flow file cannot be written.

After starting, use flow-add-step to append tool calls — each step is executed LIVE so you can verify it works before it gets recorded. Use flow-add-echo to add labels. Call flow-finish-recording when done.

If a recorded step turns out to be wrong, you can edit the .yaml file directly to remove or reorder steps.

flow-add-stepA

Execute a tool call and record it as a step in the active flow. Use when recording a flow with flow-start-recording and you want to run and capture each action. Returns { message, toolResult, flowFile } on success. If it fails an error is returned and nothing is recorded. Error if the tool name is not found in the registry or arguments are invalid JSON. If a step was recorded by mistake, edit the .yaml file directly to remove it.

flow-add-echoA

Record an echo step in the active flow. Echo steps print a message when the flow is replayed — useful as labels between tool calls. Use when you want to annotate a recorded flow with a human-readable label or checkpoint message. Returns { message, flowFile }. Fails if no active flow recording is in progress.

flow-finish-recordingA

Finish recording the active flow. Returns a summary of all recorded steps and the final YAML content. Use when you have added all desired steps and want to finalize the flow file. Fails if no active flow recording is in progress. You can still edit the .yaml file directly afterwards to remove or reorder steps.

flow-read-prerequisiteA

Read the execution prerequisite of a saved flow without running it. Returns the prerequisite description so you can verify the required state is met before calling flow-execute. Use when you need to check what app/simulator state is required before executing a flow. Fails if the flow file does not exist in the .argent/flows/ directory.

flow-executeA

Run a saved flow from the .argent/flows/ directory. Each step is executed in order: tool calls are dispatched through the registry, echo steps print a message. A tool step may carry delayMs: <ms> to sleep that long before the step runs. Returns the result of every step, including images. Use when you want to replay a recorded flow or run a scripted sequence of device actions. Fails if the flow file does not exist or a step tool raises an error (execution stops at that step). An await-ui-element step whose condition is not met before its timeout also stops the flow there (its later steps were recorded assuming the condition held), so use one to gate a step on a screen transition.

If the flow has an execution prerequisite and prerequisiteAcknowledged is not set to true, the tool returns a notice with the prerequisite instead of running. Use flow-read-prerequisite to inspect the prerequisite beforehand.

update-argentA

Apply a pending Argent update. Only call this tool when the user has explicitly consented to updating Argent in this conversation. Use when an update notification indicates a new version is available and the user agrees to update. By default updates the install serving this session; pass target to choose global/local/both. Returns { message } with the update status and version info. The tool server will restart automatically after the update. Fails if no update is available or an update is already in progress.

dismiss-updateA

Clear the Argent update notification for the given number of hours. Use when the user asks to postpone or silence update reminders. Returns { message } confirming the suppression duration. Fails if the hours value is negative or the suppression state cannot be persisted.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/software-mansion/argent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server