Skip to content

Agent Devices tool reference ​

These are the tools DeviceCloud's hosted MCP server (https://api.devicecloud.dev/mcp) offers for Agent Devices. Each description below is the one your agent sees. Every tool except list_devices and cheat_sheet takes an optional session_id. You can leave it out when your organization has exactly one open session.

A read-only connection offers only the tools marked Read-only. dcd mcp serves the same tools, and adds app_path to install_app and path to run for files on your machine.

The session block ​

Every result includes a session block, so the agent never needs a separate call to stay oriented:

FieldWhat it says
idThe session id, such as brave-teal-otter
statequeued, provisioning, ready, active, needs_human, released, expired or failed
release_reasonWhy the session ended, once it has
platform, modelThe device, such as ios and iphone-16-ios-26.5
client_labelWho is driving, such as claude-code
created_at, started_at, released_atWhen the session was asked for, got its device, and ended
expires_atWhen it reaches its maximum length
queueWhile it's queued: its position, eta_s (an estimate, or null), waited_s, and reason (waiting_for_device or fleet_busy)
time_remaining_sSeconds until its maximum length
idle_remaining_sSeconds until the idle timeout. null while it waits for a person
cost_so_far_usdWhat it has cost so far, after your organization's discount
installThe build it was asked to install: binary_upload_id, status (installing, installed or failed) and error
last_crashThe app's last crash: at and summary
warningsPlain-English warnings, such as an upcoming idle timeout, a crash or a failed install
monitor_urlThe session's page in the console, where you can watch it and take control

Errors ​

When a tool fails, its result is an error with the same error code and message as the REST API, plus the session block when there is one.

list_devices ​

List the cloud devices you can start (iOS simulators and Android emulators, with their OS versions and the defaults) and your organization's open device sessions. Use this first, before start_device, or to find a session_id.

Read-only.

No inputs.

start_device ​

Lease a fresh cloud iOS simulator or Android emulator. Use this when you need a mobile device and none is available locally. Billed per minute from when a device is assigned until the session ends ($0.03/min before any discount); call stop_device when you are done. Sessions end on their own after 5 idle minutes or their max duration. If a start_device call fails without an answer (a connection error, or a 502 or 504 from a proxy), a session may still have started: call list_devices before you start another. When the fleet is busy the session is "queued": that is not an error, it starts on its own. Waits up to 60s for the device and the app_binary_id install (wait: false returns at once). If it is still queued or provisioning, or install.status is "installing", call get_device_status with wait: true until it is not, and do not end your turn meanwhile: a device that becomes ready with nobody driving it is billed and stops after 5 idle minutes. Ask the user anything you need before you start the device; a question asked while it starts ends your turn, so use a sensible default instead. Give the user session.monitor_url as soon as you have it: there they can watch the screen live and take control. Share it and carry on; do not wait for a reply.

InputTypeRequiredDescription
platformios or androidYesios or android.
modelstringNoA model from list_devices, e.g. "iphone-16" or "pixel-10". Default: the platform default.
osstringNoiOS major (e.g. "26") or Android API level (e.g. "36"). Default: the model default.
google_playbooleanNoAndroid only: an image with Google Play services.
app_binary_idstringNoAn uploaded build to install when the device is ready.
max_duration_mininteger, more than 0NoEnd the session after this many minutes. Default and ceiling: your organization's limit, at most 60.
client_labelstringNoWho is driving, e.g. "claude-code". Shown to people watching the session.
recordbooleanNoRecord the session on video. Default true. A screenshot after each action and the device log are kept either way.
waitbooleanNoWait up to 60s for the device to be ready. Default true.

get_device_status ​

A session's state (queued, provisioning, ready, active, needs_human, released, expired, failed), its queue position, time and idle time left, cost so far, the app's last crash and warnings. After start_device or install_app, call this with wait: true until state is "ready" and install.status is not "installing"; each call waits up to 60s.

Read-only.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
waitbooleanNoIf the session is queued or provisioning, or an app is installing, wait up to 60s for it to finish. Default false.

stop_device ​

End a device session and release the device. Billing stops. Call this as soon as you are done with a device.

Ends the session.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.

install_app ​

Install an app on the session's device: an uploaded build (app_binary_id; upload with dcd upload or the DeviceCloud console), or a build at an https URL (app_url, up to 500 MB). Android takes an .apk; iOS takes a zipped simulator .app (not an .ipa). Returns the app id. It installs in the background: call get_device_status with wait: true until install.status is "installed", then launch it with launch_app. A command sent meanwhile waits up to 45s for the install, then answers LIVE_NOT_READY (phase "installing_app").

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
app_binary_idstringNoAn uploaded build's id. Pass this or app_url.
app_urlstringNoAn https link to the build, e.g. a CI artifact or a signed storage URL. Pass this or app_binary_id.

launch_app ​

Launch an app on the device: the installed build by default, or any app by id (e.g. "com.apple.Preferences" for iOS Settings). clear_state wipes its data first.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
app_idstringNoBundle id or package name. Default: the installed build.
clear_statebooleanNoClear the app's data before launching.

inspect_screen ​

The current screen as compact JSON: every element of the app with text, an id, a label or a hint, with its bounds and any state (checked, selected, focused, enabled: false). Use it before tapping, and copy txt and rid values exactly into run commands (tapOn text / id). Shows the result of your last command. The on-screen keyboard's keys and the System UI (status bar, navigation bar) are left out and counted in hidden; keyboard_open says a keyboard is showing.

Read-only.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
allbooleanNoAlso list the keyboard keys and System UI elements. Default false.

take_screenshot ​

A screenshot of the device, showing the result of your last command. Prefer inspect_screen for finding things to tap; use this to see layout, images and colours.

Read-only.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.

run ​

Run Maestro on the device: yaml is one flow (a header naming the app, ---, then commands), run whole. Or flow_upload_id runs an uploaded zip of flows (flow names the entry file; omitted, all of them run). Waits up to 110s (wait_seconds changes it); a longer flow answers status "running" with a command_id: call get_command_status with wait: true. A failed run's result has screen_text, the app's visible text after the failure, and failed_at: the file, line and command that failed. See cheat_sheet for syntax.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
yamlstringNoOne Maestro flow, e.g. "appId: com.example\n---\n- tapOn: "Log in"".
flow_upload_idstringNoThe id of a flow bundle (a zip of flows) registered at POST /device/bundles. The local dcd mcp server uploads a directory for you.
flowstringNoThe entry flow inside the bundle, e.g. "flows/login.yaml".
envobject of stringsNoSecrets and variables for the flow, used in the YAML as ${NAME}, e.g. {"PASSWORD": "..."} with inputText: ${PASSWORD}. Stored encrypted, never shown, and masked in the output. Names starting with DCD_ are reserved.
wait_secondsnumber, 0 to 300NoHow long to wait for the flow before answering "running", up to 300. Default 110. Raise it for a flow you expect to take longer, so it finishes in one call.

get_command_status ​

The status and result of a run that answered "running" because it outlasted the wait. Call it with wait: true rather than polling or sleeping; each call waits up to 110s.

Read-only.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
command_idstringYesThe command_id run returned.
waitbooleanNoIf the run is still going, wait up to 110s for it to finish. Default false.

get_logs ​

The installed app's recent device log lines (logcat on Android, the unified log on iOS). Use after a failure or when the session warns that the app crashed. Narrow with level and grep: the newest 2000 lines are searched. The answer stops at 24 KB (truncated: true when older lines were left out).

Read-only.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
linesinteger, at most 2000NoHow many lines. Default 200.
levelwarning or errorNoOnly lines at this level and above. iOS has no warning level, so warning gives its errors and faults.
grepstring, up to 200 charactersNoOnly lines containing this text, any case.

request_human ​

Ask a person to do something on the device that you can't: enter a 2FA code, solve a CAPTCHA, approve a payment sheet, log in with credentials you don't have. The session waits for them (its idle timer pauses, for up to 30 minutes by default) and they see your reason in the DeviceCloud console. Tell the user what you need and give them session.monitor_url, where they can take control and hand back. Then poll get_human_status until handed_back is true, and read their note.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.
reasonstring, up to 500 charactersYesWhat the person should do, e.g. "Enter the 2FA code sent to the test phone, then hand back".

get_human_status ​

Whether the session is still waiting for a human (waiting, reason, expires_at), or a human has handed it back (handed_back, with their note). Poll this every 30 seconds or so after request_human.

Read-only.

InputTypeRequiredDescription
session_idstringNoThe session id from start_device, e.g. "brave-teal-otter". Optional when your organization has exactly one open session.

cheat_sheet ​

Maestro syntax and how to work with DeviceCloud device sessions. Read it before your first run.

Read-only.

No inputs.