iphone-control
This MCP server lets an AI agent observe and operate a real iPhone/iPad over USB, with WebDriverAgent and CoreDevice HID fallback.
Inspect device/service status, capture screenshots (including region zoom), and list UI elements.
Tap by coordinates or text, long-press, swipe, type text (including Chinese), and press hardware buttons.
List, launch, and terminate apps, and open URLs or URL schemes.
Wait for text to appear and run batches of up to 20 actions with optional post-action screenshots/elements.
List connected devices and select which iPhone/iPad to control.
Integrates with Apple ID and Apple's CoreDevice HID service to sign and re-sign WebDriverAgent, manage Apple ID sessions, and provide fallback device control when WebDriverAgent is unavailable.
Enables AI agents to operate a real iPhone running iOS 17+ with screenshots, taps, swipes, long-presses, text input, hardware buttons, UI element inspection, app launch/termination, URL opening, and batch actions.
Sends alert notifications through Telegram when WebDriverAgent re-signing fails, the Apple ID session expires, the phone goes offline, or a passcode is required after a reboot.
Overview
AI agents can drive browsers and desktops, but a real iPhone is harder: Apple's automation tools need a Mac and Xcode, and the open-source alternatives come as separate pieces that each need their own setup, signing and babysitting.
iphone-control does it all in one Rust binary on Linux or macOS, built on idevice, Impactor and WebDriverAgent. A long-running daemon owns the phone — tunnel, HID session, WebDriverAgent session — and exposes it to Claude Code or any MCP client. It succeeds iphone-control-toolkit and keeps its MCP tools compatible.
Related MCP server: iphone-use
Features
See and touch the screen: screenshots with region zoom, tap, swipe, long-press, text input (including Chinese), hardware buttons
Work with UI elements: read the element tree, tap by text (on a part not covered by floating bars or the keyboard), launch and close apps, open URLs, wait for text to appear
Fewer round trips: any action can return the resulting screen once it has settled, flagging pages still loading and blocking alerts;
iphone_batchruns up to 20 steps in one callAutomatic fallback: when WebDriverAgent is down, screenshots, taps, swipes and keys switch to Apple's CoreDevice HID service (iOS 27+)
Runs unattended: recovers from replugging, phone reboots and WebDriverAgent crashes; re-signs WebDriverAgent with a free Apple ID before the 7-day profile expires
Alerts: Telegram or Bark notifications when re-signing fails, the Apple ID session expires, the phone goes offline, or a passcode is needed after a reboot
Optional auto-unlock: every passcode digit is verified, and a wrong passcode disables auto-unlock after one attempt
Diagnostics:
doctorchecks every layer from USB to WebDriverAgent and tells you how to fix each failure
Quick Start
You need an iPhone or iPad on iOS 17+ connected by a data cable, a free Apple ID (use a dedicated one), and a Linux host with Docker or an Apple Silicon Mac.
Linux (Docker)
git clone https://github.com/Derrors/iphone-control.git && cd iphone-control
cp .env.example .env # optional: proxy, notifications
docker compose up -d --build # the first build takes a few minutes
docker exec -it iphone-control iphone-control setup # guided setup; safe to re-run
claude mcp add iphone -s user -- docker exec -i iphone-control iphone-control mcpmacOS (Docker can't pass USB through on a Mac, so run the binary directly)
V=v0.1.5 # latest release
curl -fsSL https://github.com/Derrors/iphone-control/releases/download/$V/iphone-control-$V-macos-arm64.tar.gz | tar xz
mkdir -p ~/.local/bin && install -m 755 iphone-control-$V-macos-arm64/iphone-control ~/.local/bin/
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zprofile && source ~/.zprofile
iphone-control daemon # keep this terminal open
iphone-control setup # in a second terminal
iphone-control mcp-config # prints the `claude mcp add` command to runsetup walks you through pairing, Developer Mode, Apple ID sign-in and installing WebDriverAgent; do what it asks on the phone. Then open a new Claude Code session and ask, for example, “Open Clock, switch to the stopwatch and start it.”
More: step-by-step guide · prebuilt image · binary / source · macOS guide · other MCP clients.
MCP Tools
Tool | Description |
| Connection, lock state, foreground app, screen size |
| Screenshot scaled to points; pass |
| Elements with text and their center coordinates; filter by text or type |
| Tap by coordinates or by element text |
| Swipe (returns once the list stops), long-press |
| Type into the focused field; reads it back and fixes dropped characters |
|
|
| Manage apps by name or bundle ID |
| Open a URL or URL scheme |
| Wait until some text appears instead of polling with screenshots |
| Run up to 20 steps in one call, stopping at the first error |
| Every iPhone/iPad on USB; marks the one being controlled |
| Switch to another device, or back to automatic choice |
IPHONE_CONTROL_DEV_TOOLS=1 adds six opt-in developer tools: logs, crash reports, installing and removing apps, and two for Web Inspector (list web pages, run JavaScript in them). They are off by default; read the security notes before turning them on.
Action tools accept then: "elements" | "screenshot" to return the screen after the action. Screenshot pixels are tap coordinates, so the agent can tap what it sees. Games, maps and video players draw their own UI and have no element tree — use screenshots and coordinates there. Full parameters: docs/tools.md.
Tool texts, results, CLI output and logs are in Simplified Chinese by default; set IPHONE_CONTROL_LANG=en for English (configuration).
Everyday Commands
Run them as docker exec -it iphone-control iphone-control <command>, or directly for a source install and on macOS.
Command | What it does |
| The long-running daemon: the container's entry point; on a source install or macOS you start it yourself |
| The MCP server; your AI client starts it |
| Daemon state, time left on the signing profile, recent log |
| Layer-by-layer health check with a fix for each failure |
| Guided setup; re-run any time |
| Sign in to the Apple ID again when the session expires |
| Sign and install WebDriverAgent now |
| Re-sign WebDriverAgent if it expires soon (or now) |
| Turn auto-unlock on or off for a device (passcodes are kept per device) |
| Turn auto-unlock back on after it was disabled |
| List connected devices / switch which one is controlled |
| Send test notifications |
| Print the command that registers the MCP server |
| Expose WebDriverAgent on 127.0.0.1 for other tools; stop it when done |
| Watch the screen live in a browser and tap, swipe and type on it, on 127.0.0.1:8200; stop it when done |
All commands and options: CLI reference.
Upgrade with git pull && docker compose up -d --build (or docker compose pull && docker compose up -d --no-build for the prebuilt image); for the binary and macOS, see Source / binary and macOS. Read the upgrade notes in the changelog first. Settings live in .env — see configuration. All state lives in data/: pairing records, the Apple ID session and signing key, and the passcode if auto-unlock is on. Back it up; never commit or share it.
Documentation
Guide | What is it · Limitations · Getting started · AI clients · Tools |
Usage | Configuration · CLI · Several devices · Notifications · Auto-unlock |
Deployment | |
Problems | FAQ · Troubleshooting · Issues |
Security | SECURITY.md: what is stored, who can reach it, reporting vulnerabilities |
Development | |
Licensing | THIRD_PARTY.md: vendored components, versions and licenses |
The architecture and design documents are in Chinese for now.
This tool can fully control your phone. An agent may tap payment, delete or send buttons — keep tool-call confirmation on in your MCP client. Not affiliated with Apple; use it only with devices and accounts you own. ReadSECURITY.md before enabling auto-unlock.
Contributing
Issues and pull requests are welcome — see the contributing guide.
License
MIT. Third-party components: THIRD_PARTY.md.
Available Tools
17 toolsiphone_batchADestructive
按顺序执行几步操作,一次调用完成(最多 20 步),某一步出错就停下,说明停在第几步、后面几步没执行。
steps 每项是 {"tool": 工具名, 其余是该工具的参数},可用:iphone_tap、iphone_tap_element、iphone_long_press、iphone_swipe、iphone_type_text、iphone_press_button、iphone_launch_app、iphone_terminate_app、iphone_open_url、iphone_wait_for,以及 {"tool": "wait", "seconds": 秒数}(不超过 5)。iphone_tap_element 没点到也会停下。执行前先检查全部参数,有错一步都不执行。
何时用:结果确定的连续操作(按键、逐级点菜单、填表),每步省一轮往返。每步的结果不确定(点了以后不知道会跳到哪)时,还是一步步来。then 在全部做完(或停下)后返回一次界面。
返回:一行结果文字,例如「1. iphone_launch_app → 已启动 com.apple.Preferences(每步一行)」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: steps (required), then, then_filter, then_region, +2 more.
iphone_launch_appAIdempotent
启动 App 并切到前台。app 是显示名时按已安装的 App 查找,找不到会报错,提示用 iphone_list_apps 查看。
何时用:打开某个 App。要直接进网页或 App 里的某个页面用 iphone_open_url。想从首页重新开始(而不是回到上次的页面),先用 iphone_terminate_app 结束它再启动。
行为:App 已在后台运行时只切回前台,停在上次的页面;没在运行就冷启动。等 App 真的到前台才返回(最多约 8 秒);被系统弹窗(如权限请求)挡住或启动慢时,结果里会说明。需要 WDA。
返回:一行结果文字,例如「已启动 com.apple.Preferences」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: app (required), then, then_filter, then_region, +1 more.
iphone_list_appsARead-only
列出已安装的 App,每行一个:显示名和 Bundle ID。
何时用:iphone_launch_app、iphone_terminate_app 报「找不到名为…的 App」时,查准确的名字或 Bundle ID。默认只列用户装的 App;设置、相机等系统 App 要 include_system=true(要多花几秒)。结果有缓存。只读。
Inputs: include_system.
iphone_list_devicesARead-only
列出 USB 上接着的全部 iPhone/iPad,每行一台:设备名、型号、iOS 版本、UDID,标出正在控制哪台、有没有设自动解锁密码。
何时用:接着多台设备、要确认操作落在哪台,或切换前查设备名和 UDID。同一时间只控制一台,其他工具都作用在正在控制的那台上。只读。
Inputs: no named parameters.
iphone_list_elementsARead-only
列出屏幕上带文字的界面元素,每行一个:类型、标签、名字、值、中心点坐标、尺寸(点)。
何时用:找按钮、输入框、列表项的文字和位置,比截图快、省上下文;找到后用 iphone_tap_element 按文字点。游戏、地图等没有元素树的界面这里是空的,改用 iphone_screenshot。
注意:按坐标判断是否在屏幕内,被弹窗遮住的元素也可能列出来,不确定时截图核对。需要 WDA。只读:不改变界面,但配置了锁屏密码时会先解锁。
Inputs: limit, filter.
iphone_long_pressADestructive
在屏幕坐标(点)上单指按住 seconds 秒再抬起,手指不移动。
何时用:要长按才出现的操作,例如主屏图标的快捷菜单、消息或图片的上下文菜单、选中文字。普通点击用 iphone_tap 或 iphone_tap_element;要移动手指(滚动、拖滑块)用 iphone_swipe。
行为:只按一次。按得太短(不到约 0.5 秒)系统可能当成普通点击。长按弹出的菜单不会自己消失,下一步先看屏幕(或直接带 then=screenshot)。需要 WDA。
返回:一行结果文字,例如「已长按 (200,400) 1 秒」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: x (required), y (required), then, seconds, +3 more.
iphone_open_urlA
用系统默认方式打开网址或 URL Scheme:http/https 网页在 Safari 打开,URL Scheme 打开对应的 App。
何时用:直接进入某个网页或 App 里的某个页面,比启动 App 再一级级点快。只想打开 App 用 iphone_launch_app。
行为:有的 URL Scheme 系统会先弹窗问要不要打开,带 then=screenshot 确认。需要 WDA。
返回:一行结果文字,例如「已打开 https://example.com」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: url (required), then, then_filter, then_region, +1 more.
iphone_press_buttonA
按硬件键:home(回主屏幕)、volume_up、volume_down、lock(锁屏)。
何时用:离开当前 App 回主屏幕用 home(App 留在后台,要彻底关掉用 iphone_terminate_app);调音量;锁屏。锁屏后配置了密码的话,下一个操作会先自动解锁。
行为:系统弹窗挡着时按 home 不会生效,这时不按,并提示先点弹窗上的按钮。按 home 会等主屏真的到前台再返回。
返回:一行结果文字,例如「已按 home」。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: button (required), then, then_filter, then_region, +1 more.
iphone_screenshotARead-only
截取当前屏幕,返回 JPEG 图像和一行说明。图像已缩放到点尺寸,图中像素坐标可直接用于 iphone_tap、iphone_swipe。
看不清小图标、小字时,传 x/y/width/height(点,四个要一起给)放大这块区域:从原始高清截图裁剪,小区域再额外放大。返回文字里有放大倍数,图中坐标换算回屏幕点:x + 像素/倍数。
何时用:游戏、地图、图片等没有元素树的界面,或要确认画面效果时。只想知道有哪些按钮、文字,iphone_list_elements 更快更省上下文。操作后要看结果时,优先给操作工具带 then=screenshot。WDA 不可用时改用 CoreDevice 截图(iOS 27 起,说明里注明「HID」)。只读:不改变界面,但配置了锁屏密码时会先解锁。
Inputs: x, y, width, height.
iphone_select_deviceAIdempotent
改为控制另一台设备,之后所有工具都作用在它上面,守护进程重启后还记得。device 是 UDID 或设备名(设备名包含这段文字且只有一台也行),auto 表示取消选定、改回自动选(正在控制的那台断开才换)。
何时用:接着多台设备、要操作的不是正在控制的那台。先用 iphone_list_devices 看有哪几台。
行为:切换后要在新设备上拉起 WDA(10~60 秒),期间读界面、按名字点击等用不了,先用 iphone_status 确认就绪;这台从没装过 WDA 时起不来,要请用户运行 iphone-control setup。自动解锁按设备分开存密码,新设备没设就不会自动解锁。设了 IPHONE_UDID 时不能切换。
返回:一行结果文字,例如「已切换到 Derrors 的 iPad(iPad11,1 iOS 26.6.1,00008020-…)」。
Inputs: device (required).
iphone_statusARead-only
查看手机和服务的状态:WDA(WebDriverAgent)是否就绪、是否锁屏、能否自动解锁、当前前台 App 的 Bundle ID、屏幕尺寸(点)、守护进程状态。
何时用:开始操作前确认手机可用;操作报错、怀疑 WDA 掉线或手机锁屏时排查。WDA 不可用时会说明哪些功能受影响(读元素、按名字点击、启动 App、输入中文)。只读,不改变手机状态。
Inputs: no named parameters.
iphone_swipeA
单指从 (from_x, from_y) 按下,用 seconds 秒移到 (to_x, to_y) 后抬起(坐标单位是点)。
何时用:滚动列表或页面、左右翻页、拖动滑块。向上滑看下面的内容:from_y 大、to_y 小(例如 y 从 700 滑到 300);向左滑看右边的内容:from_x 大、to_x 小。点击用 iphone_tap,原地按住用 iphone_long_press。
行为:seconds 越小滑得越快,快滑会带惯性多滚一段;要精确移动(滑块)把 seconds 调到 1 秒左右。滑完会等列表停止滚动(最多 2.5 秒)再返回,还在滚就在结果里说明。WDA 不可用时改用 CoreDevice HID(iOS 27 起)。
返回:一行结果文字,例如「已滑动 (215,700) → (215,300)」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: to_x (required), to_y (required), from_x (required), from_y (required), +5 more.
iphone_tapADestructive
点击屏幕上的一个坐标(单位是点,与 iphone_screenshot 全屏图的像素一致,左上角为原点)。
何时用:目标没有文字(图标、图片)、在游戏或地图里,或 iphone_list_elements 里找不到它时。带文字的按钮、列表项优先用 iphone_tap_element,界面布局变了也点得准。按住用 iphone_long_press,滚动用 iphone_swipe。
行为:单指按下约 0.05 秒后抬起,点一次。不检查坐标上是什么,点之前先截图确认位置。WDA 不可用时改用 CoreDevice HID(iOS 27 起;结果里注明「经 HID」)。
返回:一行结果文字,例如「已点击 (120,300)」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: x (required), y (required), then, then_filter, +2 more.
iphone_tap_elementADestructive
按文字点击界面元素:先找标签/名字与 text 完全相同的,找不到再找包含 text 的。中心被悬浮栏、键盘等盖住时改点没被盖住的部分,整个被盖住就不点。
何时用:按钮、列表项、标签页等带文字的元素,优先用它而不是按坐标点。不确定文字怎么写时先 iphone_list_elements。没有文字的图标、游戏、地图用 iphone_tap。
行为:没找到、index 超出匹配个数或整个被盖住时不点,返回原因(不算出错;在 iphone_batch 里会让批量停下)。需要 WDA。
返回:一行结果文字,例如「已点击 Button "通用"」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: text (required), then, index, then_filter, +2 more.
iphone_terminate_appADestructiveIdempotent
强制结束 App 进程,相当于在多任务界面里把它划掉。app 是显示名时按已安装的 App 查找,找不到会报错。
何时用:App 卡住或状态不对,或者想让下次 iphone_launch_app 从首页冷启动。只想离开 App 用 iphone_press_button 按 home,App 留在后台。
行为:App 里没保存的输入、正在播放的内容会丢失。App 本来没在运行也不报错。结束的是前台 App 时会回到主屏幕。需要 WDA。
返回:一行结果文字,例如「已结束 com.apple.Preferences」。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: app (required), then, then_filter, then_region, +1 more.
iphone_type_textA
在当前获得焦点的输入框里输入文字(支持中文),从光标处输入,不会清空原有内容。submit=true 时末尾按回车。
何时用:搜索框、表单、聊天框等。要先点中输入框让键盘弹出;屏幕上没有键盘时报错,什么都不输。回车可能会发送消息或提交表单,发送前先向用户确认。
行为:输完会读回输入框核对,少了结尾几个字会自动补上;对不上就报错,也不按回车。WDA 不可用时改用 HID(iOS 27 起),只能输入美式键盘上的英文和符号。
返回:一行结果文字,例如「已输入 4 个字符,并按了回车」。不带 then 时,如果系统弹窗挡着屏幕,结果里会提醒(这时操作落在了弹窗上)。传 then=elements 或 then=screenshot 会等界面稳定后附上操作后的元素列表或截图,省一次单独的调用。配置了锁屏密码时会先自动解锁。
Inputs: text (required), then, submit, then_filter, +2 more.
iphone_wait_forARead-only
等包含某段文字的界面元素出现(例如页面加载完、搜索结果出来、弹窗出现),出现就立即返回找到的元素和用时;超时报错。
何时用:操作后要等加载时代替反复截图轮询,每 0.3 秒查一次,不占上下文。输入框里的字不算(刚输入的搜索词不会被当成结果)。需要 WDA。只读:不改变界面,但配置了锁屏密码时会先解锁。
Inputs: text (required), timeout.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 17 tools
Every tool targets a distinct action or resource, and the descriptions explicitly cross-reference each other (tap vs tap_element vs long_press vs swipe; screenshot vs list_elements vs wait_for; list_devices vs select_device vs status). The only meta-tool, iphone_batch, is clearly scoped as a sequential executor of an enumerated subset of the other tools.
All 17 tools use a uniform snake_case `iphone_` prefix with verb-first naming (tap, tap_element, long_press, swipe, type_text, launch_app, terminate_app, open_url, press_button, wait_for, select_device, list_*). The few noun-only names (status, screenshot, batch) are conventional and still readable within the same prefix scheme.
17 tools is slightly above the ideal 3-15 band, but each one covers a genuinely distinct primitive of iOS automation (gesture, query, app lifecycle, device management). No filler tools, though the surface could be trimmed by folding batch or wait_for into others.
Core lifecycle is well covered: device discovery/selection, status, element and screenshot inspection, all main gestures, text input, app launch/terminate, hardware keys, URL opening, and waiting. Gaps remain for pinch/zoom multi-touch gestures, clipboard access, and explicit alert/permission handling, which agents would occasionally need but can mostly work around.
Maintenance
Related MCP Connectors
Let your AI agent control real iPhones: screenshots, tap, swipe, type and open apps.
Cloud iPhones and Macs with Xcode for AI agents: build, run and test iOS apps, use the screen.
Let AI agents control Android and iOS devices on Mobilerun Cloud: screen, input, apps, workflows.
Cloud iPhone Simulators for AI agents: build the Xcode project, read the screen, tap by label, test.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to control real iPhones and simulators on macOS, allowing for UI interaction, testing, and automation.65 npm95MIT
- FlicenseAqualityAmaintenanceControl a real iPhone or iOS Simulator through a macOS daemon and XCTest runner over USB or Wi-Fi: read screen text, tap, type, swipe, inspect logs and replay flows with explicit outcomes. Browser sandbox: use readonly to inspect 12 preloaded flows without a phone. Reuse an existing sandbox from MCP Deployments, or delete it before starting another. Device control needs your Mac and iPhone.643472-
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to operate a real iPhone from a Mac by reading the screen over USB and sending taps, swipes, typing, and app launches over Bluetooth, with every action returning a fresh screenshot so the agent can verify its work. Runs as a local MCP server, so agents can test iOS apps on physical devices and automate everyday phone tasks.43 npm10MIT
- AlicenseNot gradedqualityBmaintenanceFree, open-source Mac app and MCP server that lets AI agents take screenshots, tap, swipe, type and launch apps on a real iPhone. Includes owner-approved clients, an activity log and pause controls; supports USB and Wi-Fi after pairing.12Apache 2.0