What Agents Can Do
Flows: do a task once, replay it with no model
Tasks you repeat are kept as flows: reviewed per-app scripts that replay without a model, so they cost no tokens. An agent finds the flows for an app on its own, runs one in a single call, and after a multi-step task with no flow it asks whether you want to keep what it just did.
What a flow is
A flow is a strict JSON file (version: 1) with the same guarded steps as phone_run_steps
(taps by locator, launch_app, typing, wait_for checkpoints and so on) plus named string
inputs. The iphone-use-mcp binary validates and runs one without any model in the loop. A flow stops
at the first failed step and never retries.
$ MCP="$HOME/Applications/iPhoneUse.app/Contents/MacOS/iphone-use-mcp"
$ "$MCP" flow validate examples/flows/search-spotlight.json # offline
$ IPHONE_USE_TOKEN=… "$MCP" flow run examples/flows/search-spotlight.json --input 'query=coffee'
How agents use flows
A launch_app response, or the first screen read in a newly entered app, carries a registry block listing the saved flows for that app. If one does the task, the agent runs it with phone_flow_run: one call instead of dozens.
Do you want me to save this as a flow?
When a response carries flow_suggestion, or a multi-step task finished with no flow, the agent asks you. The daemon has already recorded the steps as a draft.
Saving only happens when you agree:
- Draft: the agent gets the draft (
phone_flow_draft, orflow draft --out my-task.json), with atodolist of things to fix. - Fix and check: it fixes the todo list, validates the file and runs it once on the phone.
- Publish, with your OK: publishing opens a public PR to the registry, so the agent asks again before
phone_flow_publish(confirm=true).
IPHONE_USE_FLOWS_NO_SUGGEST=1 silences the save suggestions.
Record one in the browser
The Flow panel on the control page records what you do on the phone into a replayable flow file:
- Only acknowledged actions are recorded. Exact accessibility labels are preferred; coordinate gestures are marked fragile.
- Typed text becomes a named runtime input. The literal value is discarded and never written to the downloaded JSON.
- After each action the recorder may insert a reviewable
wait_forcheckpoint when a new unique identifier or a change of foreground app is provable; it never copies arbitrary labels or values into a checkpoint, because they may be private. - Review, reorder, delete and fill inputs, then download valid flow v1 JSON or run it once. Running requires every input filled and an explicit "no irreversible actions" check.
The official registry
leeguooooo/iphone-use-flows is the official, and the only
supported, source of reviewed per-app flows. The daemon keeps it fresh by itself
(IPHONE_USE_FLOWS_NO_AUTO_UPDATE=1 turns that off). Files are pure JSON, so installing the registry never
executes code; a checksum or validation failure aborts the whole update and leaves the store untouched.
$ "$MCP" flow update # mirror into ~/.iphone-use/flows: sha256 + strict validation
$ "$MCP" flow list --category health # id · risk · verified · inputs · name
$ "$MCP" flow info health/export-all-zh-cn # metadata and step templates
$ "$MCP" flow run health/export-all-zh-cn # failures say which step and why
$ "$MCP" flow draft --out my-task.json # what you just did, as a draft flow
$ "$MCP" flow add my.json --as myapp/daily # your own flow; survives update
$ "$MCP" flow publish my.json --as myapp/daily --alias MyApp --note "iPhone 17 Pro Max, iOS 26" # opens the PR via gh
$ "$MCP" flow report health/export-all --result @run.json --note "profile button renamed" # files a flow-broken issue
Risk levels
| risk | Meaning |
|---|---|
read_only | Reads the phone only. |
navigation | Moves around the app. |
side_effect | Sends, publishes, pays or deletes. Refuses to run without --confirm / confirm=true. |
When the app updates
Each flow records the app (or iOS) version it was proved on, the CLI reads what the phone has installed
(flow apps), and every listing shows a compat verdict: verified,
untested-newer, incompatible, broken, needs-verification,
draft or unknown. flow run refuses broken or incompatible flows without
--force. A nightly canary re-runs the verified read-only flows on a real phone: verified
refreshes the date, failed tags the flow and files a flow-broken issue, and
skipped (phone locked, owned, not drivable, or outcome unknown) leaves the flow exactly as it was.
When a run fails
The result grows a diagnosis block: the failed step, whether the screen could be read at all, a
reason such as locator_no_match or locator_ambiguous, and up to five candidate
elements. It is one bounded read after the run: nothing is re-sent and the flow is never silently edited.
--artifacts-dir DIR also writes a machine-readable record of the run (structure only: typed input and
screen text are never written).
--input KEY=VALUE resolves only for the current run and is never written back, but command-line values can
appear in shell history. Flow inputs must not carry credentials, codes or private content, and send, publish, pay and
delete actions must be declared side_effect.
Test suites and scheduled runs
Two things build on flows. Both run through the same engine as flow run.
iphone-use-mcp test suite.yaml turns "open it, tap around, check it's right" into a file you can rerun. Exit code 0 every case passed, 1 a case failed, 2 the suite is invalid or the phone cannot be driven. --junit FILE writes a JUnit XML report for CI.
The daemon runs a flow or a suite on a cron line. It waits when someone else is using the phone, and a failed, missed or skipped run raises a macOS notification. A side-effect target needs --confirm when you create the schedule.
$ iphone-use-mcp test examples/tests/settings-smoke.zh-CN.yaml --junit report.xml
$ iphone-use-mcp schedule add --cron "0 9 * * 1-5" --test ~/suites/smoke.yaml --name "morning smoke"
$ iphone-use-mcp schedule add --cron "@daily" --flow health/export-all-zh-cn
$ iphone-use-mcp schedule list
The same schedule list is on the control page at /schedules. Details: Testing and scheduled runs.
Next: what to ask your agent · connect your agent.