关于 iphone-use
iphone-use 是通过自带 XCTest 运行器控制实体 iPhone 的技能,不操作 Mac 屏幕或光标。它引导 Agent 浏览应用、运行已保存流程、批量执行操作并验证结果。
主要功能
- 01通过 XCTest 控制实体 iPhone
- 02运行已保存流程和 Jev 端侧任务
- 03批量执行界面操作并验证结果
- 04查看屏幕元素和主屏幕布局
- 05管理手机占用和重新连接
适用场景
- 01在 iPhone 应用中自动完成多步任务
- 02检查应用状态并操作可见控件
- 03复用或创建可重复执行的流程
MCP 相关
附带 MCP 服务,通过 `phone_*` 工具读取和控制手机、运行流程及管理会话。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ leeguooooo/ iphone-use --skill iphone-use安装后在 Claude Code 中输入/iphone-use确认已加载。
详细介绍
原文在翻译后有更新,译文可能不是最新。
iphone-use — 操控真实 iPhone
iphone-use 守护进程通过自己的 XCTest 设备运行器操控实体 iPhone。此运行器在 v0.14.0 中取代了 WebDriverAgent;它不使用 iPhone Mirroring。HTTP 接口与 WebDriverAgent 兼容,旧版“WDA”字段名指的就是此运行器。它绝不会操作 Mac 的屏幕或光标。使用下方的 HTTP API 或捆绑的 MCP 服务(phone_* 工具);操作循环相同。详情请参阅参考文档:curl -s -H "$AUTH" "$HOST/agent/reference" 提供的内容与当前运行的守护进程版本相匹配(下文各部分以标题命名;另见 docs/agent-reference.md)。
HOST="${IPHONE_USE_URL:-http://127.0.0.1:44321}"
AUTH="Authorization: Bearer $IPHONE_USE_TOKEN" # daemon password or IPHONE_USE_AGENT_TOKEN
MUTATION="X-Phone-Control: 1" # required on every state-changing POST
OWNER="X-Phone-Owner: <your-session-name>" # MCP sends this for you
curl -s -H "$AUTH" "$HOST/agent/status" # probe first; on failure stop and report
操作循环
-
探测。
GET /agent/status/phone_status。仅在drivable:true时操作。否则报告hint并停止。只有当用户当前任务需要使用手机时才重新连接一次(phone_reconnect/POST /agent/mode {"mode":"agent"}),绝不要为了健康检查而重新连接:每次启动运行器都可能需要操作员输入密码。如果owner属于另一个会话,则不要操作。→ 参考文档:手机状态与恢复 -
先查找已保存的工作流。 进入某个应用时——无论是
launch_app响应,还是刚进入应用后首次读取/agent/elements——都会附带一个registry块,列出该应用已保存的工作流。如果其中有能完成任务的工作流,就用phone_flow_run运行:一次调用即可,无需几十次调用,也无需截图。phone_flow_list/iphone-use-mcp flow list --app <bundle>可显示全部工作流。运行前检查risk和compat。→ 参考文档:工作流"$HOME/Applications/iPhoneUse.app/Contents/MacOS/iphone-use-mcp" flow run system/spotlight-search --input query=Health -
没有工作流?给 Jev 一个明确目标。
phone_jev_run/iphone-use-mcp jev run --goal "…" [--app <bundle>]会运行快速的手机端 Agent(TypeSafe 的 Jev 会选择每一步操作,每步约 1–2 秒,不经过大模型轮次),并返回done/blocked及其步骤历史。涉及发送、付款或删除的目标,先向用户确认;并自行检查最终屏幕。 -
否则分批操作,不要逐次点击。 每次调用都会耗费你一个完整轮次;手机操作约需 0.5 秒。用
launch_app打开应用,读取一次GET /agent/elements,然后将你已知道如何完成的所有操作作为一个批次发送(POST /agent/actions/phone_run_steps,最多 24 个步骤,每次屏幕变化后使用wait_for),并设置observe:true(MCP 默认值):响应会附带该批次结束时的屏幕,因此你无需再次读取就能决定下一批操作。如果你会在批次之间思考超过一分钟,请使用phone_hold,避免运行器被释放。单次点击(元素 + 快照、唯一标签、定位器)适用于探索尚未读取的屏幕;连续这样操作三次后,守护进程会提示你改用批次操作(batch_hint)。 -
验证每一步是否符合预期结果:MCP 操作工具默认会观察结果(HTTP:
?return=delta),并在同一次调用中返回稳定后的变化;同时也会捕获稳定后的屏幕,且phone_screenshot会立即返回截图——只有文字信息不足时才查看。ok:true表示操作已发送,不代表操作取得了任何效果。 → 参考文档:读取结果 -
提出保存工作流。 当响应中包含
flow_suggestion,或你完成了一个没有现有工作流覆盖的多步骤任务时,询问用户是否要将其保存为工作流。只有用户同意后:获取草稿(phone_flow_draft(save_as=…)/flow draft --out …/GET /agent/flow/draft),修正其中的todo列表,进行验证,并运行一次该文件。发布会创建一个公开 PR,因此调用phone_flow_publish(confirm=true)前还要再次询问。→ 参考文档:保存工作流
任务完成后,释放手机:phone_release_owner / POST /agent/owner {"release":true}。如果响应中包含 agent_focus,说明手机已为你的会话开启“勿扰模式”:告知用户;释放手机后会再次关闭该模式。
核心操作
| 内容 | HTTP /agent/input type | MCP | Flow / 批处理步骤 kind |
|---|---|---|---|
| 查找应用的 bundle id | GET /agent/apps?query=微信 | phone_apps | — |
| 打开应用 | launch_app bundle(内置应用可用 name,也可用任意应用的确切名称 app;若名称不唯一,会拒绝并给出候选项) | phone_run_steps 步骤 | launch_app(bundle 或 app) |
| 读取屏幕 | GET /agent/elements | phone_elements | wait_for(application、present、absent) |
| 点击元素 | tap + element + snapshot | phone_tap_element | tap_locator(持久定位) |
| 点击唯一标签 | tap + label | phone_tap_label | tap_label |
| 按定位器点击 | tap_locator + locator | phone_run_steps 步骤 | tap_locator |
| 点击某个坐标 | tap + x,y | phone_tap | tap |
| 输入文本 | text(输入到当前聚焦的字段;最多 20000 个字符 — 如果出现 text_partially_typed,仅发送 remaining_text 并设置 clear:false) | phone_type | type(input 指定运行时值) |
| 按键 | key return… | phone_key | key |
| 主屏幕 / Spotlight | shortcut | phone_shortcut | shortcut |
| 滚动 | scroll dy(80 ≈ 屏幕的 15%,400 ≈ 75%) | phone_scroll | scroll |
| 系统提醒 | alert button / action | phone_run_steps 步骤 | alert |
| 应用要求登录 | POST /agent/login(iphone-use auth login --bwu) | phone_login | — |
| 开关 / 滑块 | perform toggle / adjust | phone_run_steps perform 步骤(element + snapshot) | — |
所有操作(包括 swipe、drag、picker、set_value 和各种滚动操作)都列在参考文档中:操作目录。
curl -s -H "$AUTH" -H "$MUTATION" -H "$OWNER" -X POST "$HOST/agent/input" \
-d '{"type":"launch_app","bundle":"com.apple.Health"}' # response may carry `registry`
curl -s -m 40 -H "$AUTH" "$HOST/agent/elements" # give it ≥40s
curl -s -H "$AUTH" -H "$MUTATION" -H "$OWNER" -X POST "$HOST/agent/input?return=delta" \
-d '{"type":"tap","element":3,"snapshot":"<from that read>"}'
curl -s -H "$AUTH" -H "$MUTATION" -H "$OWNER" -X POST "$HOST/agent/actions" -d '{"steps":[
{"kind":"action","action":{"type":"tap_locator","locator":{"label":"资料","kind":"Button"}}},
{"kind":"wait_for","expect":{"present":[{"label":"导出所有健康数据"}]},"timeout_ms":8000}]}'
不要这样做 → 改用以下方式
| 不要这样做 | 改用以下方式 |
|---|---|
| 点击根据截图猜测的坐标 | 读取 phone_elements,通过 element + snapshot 或标签点击 |
| 每一步后都截图 | observe:true / ?return=delta 会返回变化 |
| 下一步操作已可见时仍每次只调用一次点击 | 使用包含 wait_for 的 phone_run_steps / /agent/actions 批处理 |
| 固定等待若干秒 | 使用带有 present / absent / application 的 wait_for |
| 点击系统提醒的按钮 | 使用 alert 操作(button 或 action) |
| 点击开关或滑块 | 使用 perform toggle / adjust |
在出现 outcome_unknown 或 retry_safe:false 后重新发送请求 | 先读取屏幕;手机可能已经执行了操作 |
重复执行返回 no_progress 的操作 | 重新读取屏幕,然后使用不同控件或 wait_for |
| 重新连接以检查状态 | 使用 phone_status;仅在任务需要手机时重新连接 |
| 未检查焦点就输入 | 确认前台应用和聚焦字段,然后输入 |
| 重复使用未找到的标签 | 使用错误提示中提供的 did you mean 标签,或重新读取 |
任务指标:iphone-use metrics / GET /agent/metrics 统计的是 HTTP 调用次数,而非模型轮次。若要精确统计一项任务,请将其包在 phone_run_start / phone_run_end 中(HTTP:POST /agent/run)。GET /agent/elements?scope=app(或 interactive、focused、changed&since=…)会返回同一读取结果的精简视图;仅当界面树不可用时,?image=auto 才会添加截图。
→ 参考文档:任务指标、运行与建议
Flow 只是保存下来的这些步骤
{
"version": 1,
"name": "New note",
"app": "com.apple.mobilenotes",
"risk": "navigation",
"locale": "zh-CN",
"inputs": { "body": { "type": "string", "description": "note text" } },
"steps": [
{ "kind": "launch_app", "bundle": "com.apple.mobilenotes" },
{ "kind": "wait_for", "expect": { "application": "备忘录" }, "timeout_ms": 15000 },
{ "kind": "tap_locator", "locator": { "label": "新建备忘录", "kind": "Button" } },
{ "kind": "type", "input": "body" }
]
}
完整字段列表、兼容值以及发布和报告步骤见参考文档:Flows。
硬性规则
retry_safe:false或outcome_unknown表示不得重放。 手机可能已经执行了操作。先读取屏幕;切勿盲目重新发送文本、发送消息、付款或删除。失败的工作流也同样如此。risk: side_effect和具有破坏性的点击都需要用户针对确切目标和输入明确同意(confirm=true/--confirm)。切勿在无人看管的情况下操作支付或 2FA 屏幕。- 文本会输入到当前获得焦点的字段中。 如果有人正在聊天,你输入的内容就会出现在他们的消息中。先确认前台应用和获得焦点的字段。在聊天应用中,Return 会发送消息,输入文本中的
\n也相当于 Return:除非用户需要换行,否则只发送一行。→ 参考:聊天应用:多行消息 - 系统警报需要使用
alert操作。 点击警报按钮会 ACK,但通常不起作用。开关需要使用perform toggle。无论如何都要验证新的value。 - 每部手机只能有一个会话。 发送
X-Phone-Owner。遇到409 phone_owned时,请等待;除非用户表示另一个会话已放弃,否则切勿接管。完成后释放你的租约。 - 只能通过
phone_login/iphone-use auth login --bwu登录。 它会在守护进程中填写用户自己的保险库条目。切勿向用户索要、输入或重复密码或验证码;切勿注册、修改密码或付款。如果 Face ID、PIN、验证码或登录phone_login无法完成:停止操作,使用phone_hold(secs, private=true)暂停屏幕读取,然后通过主机的问题工具询问用户(如果没有该工具或该工具当前不可用,则使用纯文本),并等待;随后解除暂停并重新读取屏幕。→ 参考: 需要用户本人登录时 - 是否保存和发布由用户决定。 保存工作流前先询问,发布工作流或提交问题前再询问一次。两项操作都会使用用户的 GitHub 账户。
任务所需、需要在 Mac 上使用的文件会通过 AirDrop 传输,并保存到
~/Downloads(参考:将文件从手机传到 Mac)。
如果屏幕在你操作期间发生变化(app_changed、出现横幅或有人正在使用手机),请停止操作,并重新读取屏幕后再继续原计划。如果技能与实时 API 不一致,技能很可能已经过时;请参阅
参考:升级。如果 iphone-use 本身存在故障或令人困惑的地方,请主动提出提交问题(参考:提交问题)。