iPhone Control MCP Server
Use the iPhone Control MCP server to inspect and control a real USB-connected iPhone through MCP tools.
Check connection/WDA readiness, lock state, foreground app, and screen size.
Take screenshots, optionally zooming into a region; screenshot pixels map directly to tap coordinates.
List on-screen text elements and tap them by exact/partial text or by coordinates.
Perform swipes, long presses, text input including Chinese, and submit with Enter.
Press hardware buttons: Home, volume up/down, and lock.
List installed apps, launch apps by bundle ID or display name, and terminate apps.
Open URLs or URL schemes using the system default handler.
Controls a real iPhone running iOS, enabling screenshots, taps, swipes, text entry, hardware buttons, UI element inspection, app launch/termination, and URL opening via WebDriverAgent with a CoreDevice HID fallback.
Sends optional Telegram notifications for failures such as re-signing problems, the phone going offline, or a passcode being required after reboot.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@iPhone Control MCP Server Open the Clock app, start the stopwatch, and send me a screenshot."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
We recommend iphone-control instead of this project. It is the successor to iphone-control-toolkit: one Rust binary instead of a container of separate tools, runs on Linux or macOS, supports iPhone and iPad, and keeps the MCP tools compatible, so existing prompts and clients keep working.
Early release, tested on aniPhone 15 Pro Max (iOS 27.0.1) with an x86_64 Debian host. Other models, iOS 17–26 and arm64 hosts have not been tested yet — reports are welcome.
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-toolkit puts it all in one Docker container on Linux. It builds go-ios, pymobiledevice3, plumesign and WebDriverAgent from pinned sources, keeps them running, and exposes the phone to Claude Code or any MCP client.
Claude Code / any MCP client
│ MCP over stdio (docker exec)
▼
┌──────────── Docker container on Linux ────────────┐
│ MCP server ─┬─ WebDriverAgent (primary) │
│ └─ CoreDevice HID (fallback) │
│ supervisor: reconnect · restart · re-sign · alert │
└───────────────────────┬────────────────────────────┘
│ USB
iPhoneRelated MCP server: mcp-ios
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 buttons by name, launch and close apps, open URLs
Automatic fallback: when WebDriverAgent is down, screenshots, taps, swipes and keys switch to Apple's CoreDevice HID service (iOS 27+, no signing needed)
Runs unattended: recovers from replugging, phone reboots, tunnel drops 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 phone goes offline, or a passcode is needed after a reboot
Optional auto-unlock: the phone can lock normally; every passcode digit is verified, and a wrong passcode disables auto-unlock after one attempt
Live viewer:
iphonectl vieweropens a desktop window with the phone's screen (up to ~25 fps over USB) that you control with mouse and keyboard, while the agent keeps workingOptional WebView debugging: Safari tabs and inspectable WebViews (Capacitor, Cordova, your own
WKWebView) are exposed over the Chrome DevTools Protocol, so tools can read the DOM and console directly instead of going through screenshotsDiagnostics:
iphonectl doctorchecks every layer from USB to WebDriverAgent and tells you how to fix each failure
Quick Start
You need a Linux host with Docker (Compose v2.24+), an iPhone on iOS 17+ connected by a data USB cable, and a free Apple ID (use a dedicated one, not your main account).
git clone https://github.com/Derrors/iphone-control-toolkit.git
cd iphone-control-toolkit
bin/iphonectl setup # guided setup; safe to re-run
bin/iphonectl mcp install # register with Claude Codesetup pulls ghcr.io/derrors/iphone-control-toolkit, then walks you through pairing, Developer Mode, mounting the developer disk image, signing in to your Apple ID, and signing and installing WebDriverAgent. Steps that are already done are skipped.
Open a new Claude Code session and ask, for example:
Open the Clock app, switch to the stopwatch, and show me a screenshot.
Other MCP clients: the server speaks stdio throughdocker exec and opens no network port.
{ "mcpServers": { "iphone": { "command": "docker", "args": ["exec", "-i", "iphone-control-toolkit", "/opt/ictl/mcp-server.sh"] } } }To build the image from source instead of pulling it, set IMAGE=iphone-control-toolkit:local in .env.
MCP Tools
Tool | Description |
| Connection, lock state, foreground app, screen size |
| Screenshot scaled to points; pass |
| Elements with text and their center coordinates |
| Tap by coordinates or by element name |
| Swipe, long-press |
| Type into the focused field |
|
|
| Manage apps by name or bundle ID |
| Open a URL or URL scheme |
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.
Live Viewer
bin/iphonectl viewerA window on the host shows the phone's screen live, streamed from WebDriverAgent's MJPEG server, and passes your input on to the phone. It runs next to the MCP server and shares its WebDriverAgent session, so you can watch the agent work or take over.
Input | On the phone |
Click / hold | Tap / long press |
Drag, mouse wheel | Swipe, scroll |
Keyboard | Types into the focused field |
Esc, right click, ⌂ Home | Home button |
✕ Close app | Ends the foreground app, like swiping it away in the app switcher |
iOS ignores system gestures that do not come from a finger, such as the swipe up from the bottom edge, so the window has buttons for them. Resize it freely. Options such as frame rate and resolution: iphonectl viewer --help.
It needs Python 3.11+ with Tk and Pillow on the host: sudo apt install python3-tk python3-pil.imagetk (Debian/Ubuntu) or sudo pacman -S tk python-pillow (Arch).
If the phone is plugged into a headless host, run the viewer on your desktop from a checkout of this repository:
ssh -N -L 8100:127.0.0.1:8100 -L 9100:127.0.0.1:9100 your-host &
PYTHONPATH=src python3 -m iphone_viewerDebugging WebViews
This is off by default. Set CDP_PORT=9222 in .env and run iphonectl up, and the container serves the phone's Safari tabs and inspectable WebViews over the Chrome DevTools Protocol on 127.0.0.1:9222: curl 127.0.0.1:9222/json lists them, and anything that speaks CDP can attach to read the DOM, run JavaScript, or follow console output and network requests. For hybrid apps that is faster and more precise than the element tree or screenshots.
While it is on, any process on the host can read and script the phone's Safari tabs, including sites you are logged in to. The bridge has no authentication and does not check where a request comes from, so turn it on only while you need it and only on a host you trust.
On the phone, turn on Settings → Apps → Safari → Advanced → Web Inspector.
Your app's
WKWebViewmust be inspectable (isInspectable = true, iOS 16.4+). Safari is always inspectable.
Capacitor apps built without Xcode (for example with xtool): Capacitor only makes the WebView inspectable in debug builds, which it detects through a CAPACITOR_DEBUG Info.plist key that only Xcode's build settings fill in. Set it explicitly in capacitor.config.ts, for development builds only:
ios: { webContentsDebuggingEnabled: !isReleaseBuild },iphonectl doctor reports how many pages are inspectable. Both the bridge and the live stream listen on 127.0.0.1 only and have no authentication, like WebDriverAgent itself; set MJPEG_PORT=0 in .env to turn the stream off. To reach them from another machine, use SSH port forwarding rather than binding them to other interfaces.
Everyday Commands
Command | What it does |
| Container status and recent supervisor log |
| Layer-by-layer health check with a fix for each failure |
| Live view of the screen, controlled with mouse and keyboard |
| Logs: |
| Re-sign WebDriverAgent if it expires soon (or now) |
| Sign in to the Apple ID again when the session expires |
| Turn auto-unlock on or off |
| Upgrade to the latest image |
Settings live in .env (created from .env.example): proxy, Telegram / Bark, data directory owner. All state lives in data/ — pairing records, the Apple ID session and signing key, certificates and the passcode. Back it up; never commit or share it.
Documentation
Design | Architecture: components, the two control paths, supervisor and re-signing |
Operations | |
Development | Development guide: tests, upgrading pinned upstream versions |
Licensing | THIRD_PARTY.md: bundled components, versions and licenses |
The detailed docs are in Chinese for now.
Limitations
One phone per host; don't connect two instances to the same phone
Free Apple ID profiles last 7 days. Re-signing is automatic, but an expired Apple ID session needs
iphonectl loginAfter the phone reboots, you must enter the passcode once on the phone to allow UI automation — iOS requires this
Elements hidden behind a popup may still be listed, because visibility is judged by position
System gestures (home indicator swipe, Control Center, Notification Center) cannot be injected from outside; use the Home button, closing apps by bundle ID, and URL schemes instead
This toolkit 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 you own.
Contributing
Bug reports and suggestions are welcome in Issues; please include the output of iphonectl doctor with your UDID removed. Pull requests are welcome too — see the development guide.
License
MIT for this project's code. The container image also includes upstream components under other licenses, including GPL-3.0; each release attaches their complete corresponding source. See THIRD_PARTY.md.
Available Tools
13 toolsiphone_launch_appA
启动 App 并切到前台。app 可以是 Bundle ID,也可以是显示名(如「设置」「微信」)。
Inputs: app (required).
iphone_list_appsA
列出已安装的 App(名字和 Bundle ID)。include_system=True 时列出系统 App。
Inputs: include_system.
iphone_list_elementsA
列出屏幕上带文字的界面元素:类型、标签、中心点坐标、尺寸。
filter: 只返回标签/名字/值里包含该文字的元素(不区分大小写)。 注意:按坐标判断是否在屏幕内,被弹窗遮住的元素也可能列出来,不确定时截图核对。
Inputs: limit, filter.
iphone_long_pressC
长按屏幕坐标(点)。
Inputs: x (required), y (required), seconds.
iphone_open_urlB
用系统默认方式打开链接或 URL Scheme(网页会在 Safari 打开)。
Inputs: url (required).
iphone_press_buttonA
按硬件键:home(回主屏幕)、volume_up、volume_down、lock(锁屏;配置了密码时之后的操作会自动解锁)。
Inputs: button (required).
iphone_screenshotA
截取当前屏幕。图像已缩放到点尺寸,像素坐标可直接用于点击和滑动。
看不清小图标、小字时,传 x/y/width/height(点)放大这块区域:从原始高清截图裁剪, 小区域再额外放大。返回文字里有放大倍数,图中坐标换算回屏幕点:x + 像素/倍数。
Inputs: x, y, width, height.
iphone_statusA
查看连接状态:WDA 是否就绪、是否锁屏、当前前台 App、屏幕尺寸。
Inputs: no named parameters.
iphone_swipeB
从一点滑到另一点(点坐标)。向上滑看下面的内容:from_y 大、to_y 小。
Inputs: to_x (required), to_y (required), from_x (required), from_y (required), +1 more.
iphone_tapC
点击屏幕坐标(点)。
Inputs: x (required), y (required).
iphone_tap_elementA
按文字点击元素:先找标签/名字完全相同的,找不到再找包含该文字的。
index: 匹配到多个时点第几个(从 0 开始,顺序同 iphone_list_elements)。
Inputs: text (required), index.
iphone_terminate_appB
结束 App 进程。app 可以是 Bundle ID 或显示名。
Inputs: app (required).
iphone_type_textA
在当前获得焦点的输入框里输入文字(支持中文)。需要先点中输入框。submit=True 时末尾按回车。
Inputs: text (required), submit.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 13 tools
Each tool targets a distinct action: status, element listing, coordinate tap, text-based tap, long press, swipe, text input, hardware buttons, app listing/launch/terminate, URL open, and screenshot. The only near-pair, iphone_tap vs iphone_tap_element, is clearly differentiated (coordinate vs label matching) in the descriptions. No two tools appear to do the same thing.
All tools share a consistent iphone_ prefix in snake_case with verb_noun structure (iphone_tap_element, iphone_launch_app, iphone_press_button). Minor deviations are iphone_status and iphone_screenshot, which are noun-only rather than verb-based, but the overall pattern is highly predictable.
13 tools is well within the ideal 3-15 range and each tool covers a necessary UI-automation primitive. The set is neither padded nor thin for a device-control server.
The surface covers status, discovery, gesture input, text entry, hardware keys, app lifecycle, URL opening, and screenshots, which spans the core UI-automation loop. Minor gaps remain, such as long-press-by-element (only coordinate-based), double-tap, and explicit wait/scroll-to-element helpers, but agents can work around these via coordinates and swipe.
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.
Drive real devices from your AI Coding tool. Embed a client SDK (Unity, Godot, Flutter, iOS/macOS, Android, React Native, Web) in your app, then capture screenshots, traverse the UI tree, inject taps and key events, and run automated test tasks on the physical device over a secure relay.
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
- AlicenseBqualityBmaintenanceDrives a physical iPhone or iPad over Appium and WebDriverAgent (XCUITest) from a Mac, letting an agent inspect the screen, tap, type, swipe, launch apps, and run Shortcuts. Safe-by-default access modes, app allowlists, and elicitation-gated destructive operations keep admin actions behind explicit approval.659 npmMIT
- 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