ios-control-mcp
Provides tools to control a real iPhone running iOS, including capturing screenshots, tapping and swiping, typing text, pressing hardware buttons, opening and listing apps, and waiting between operations.
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., "@ios-control-mcpopen the Settings app on my iPhone and take 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.
ios-control-mcp
Control a real iPhone from an MCP client on macOS. Capture screenshots, tap and swipe, type text, press buttons, and open apps through Apple's CoreDevice services, using pymobiledevice3.
The server runs locally over stdio. It uses on-demand screenshots rather than a continuous mirror, and requires no companion iOS app. USB is preferred; Wi-Fi is available after pairing and enabling wireless connections.
Status: beta. Device services can change between iOS releases. Automated tests cover protocol handling and mocked device behavior; they do not establish compatibility with every iPhone or iOS version. See the hardware validation checklist before relying on a new setup.
Requirements
macOS, including the built-in
/usr/bin/sipsimage converter.Python 3.10 or newer. CI targets Python 3.10, 3.12, and 3.13.
An iPhone with iOS 17 or newer, paired with this Mac, unlocked, and with Developer Mode enabled under Settings → Privacy & Security.
Working developer services on the device. Depending on iOS and the host setup, developer disk image preparation may be necessary; consult the upstream device setup documentation.
The iOS version is a transport prerequisite, not a promise that all tools work on every supported OS release. Linux and Windows device control are not supported by this project.
Related MCP server: iphone-mcp
Install
git clone https://github.com/als0m3/ios-control-mcp.git
cd ios-control-mcp
python3 -m venv .venv
.venv/bin/python -m pip install --upgrade pip
.venv/bin/python -m pip install .Connect the iPhone with a cable, unlock it, and accept the trust prompt if shown. Enable Developer Mode and complete any restart or confirmation requested by iOS.
Connect an MCP client
Add a stdio server to your client's MCP configuration, using the absolute path to the installed executable:
{
"mcpServers": {
"ios-control": {
"command": "/absolute/path/to/ios-control-mcp/.venv/bin/ios-control-mcp",
"args": [],
"env": {
"IOS_CONTROL_TRANSPORT": "usb"
}
}
}
}Configuration formats differ between clients; some also require "type": "stdio".
Restart or reload the client after editing its configuration. The equivalent
module entry point is .venv/bin/python -m ios_control_mcp.
Start with iphone_status, then iphone_screenshot. The process waits for
newline-delimited JSON-RPC input when launched directly in a terminal; it does
not open a window or provide an interactive command prompt.
Tools
All coordinates are normalized, from 0.0 to 1.0: the top-left corner is
(0, 0) and the center is (0.5, 0.5). Measure against a recent screenshot.
Pixel coordinates, incorrect types, unknown arguments, and values outside the
published limits are rejected before any device operation.
Tool | Arguments | Behavior |
| None | iOS version, build, model, available transports, tunnel state; omits the device name and UDID |
|
| Returns a JPEG resized to the requested width; falls back to PNG if conversion fails |
| Required | Touch and release; contact lasts at least 100 ms |
| Required | Interpolated drag; requested duration excludes contact and flush delays |
| Required | Printable ASCII, tab, and newline using a US keyboard mapping; rejects unsupported characters before typing |
| Required |
|
| Required | Exact bundle ID, exact display name, or unique partial name; ambiguous matches are rejected |
| Optional | Lists app names and bundle IDs; filter matches either field |
|
| Waits before the next operation |
Example arguments:
{"x": 0.5, "y": 0.5}{"x": 0.5, "y": 0.75, "x1": 0.5, "y1": 0.25, "ms": 400}{"app": "com.apple.Preferences"}A swipe beginning at the bottom edge can trigger the Home gesture. For scrolling
inside an app, start at y < 0.9. Keyboard layout, orientation, lock state, and
system dialogs can affect input. Newline may submit a form; tab may move focus.
Opening an app does not request termination of an already running instance. Allow time for launch animations, then take another screenshot to verify the result. A successful tool response confirms the request completed, not that the screen reached the intended state.
Device selection and configuration
Environment variable | Meaning |
| Select one specific device. If it is absent, the call fails instead of controlling another device. |
|
|
| Base device-call timeout in seconds, from 1 to 300; default 60. Typing and swiping add a bounded duration allowance. |
With multiple devices attached, set IOS_CONTROL_UDID. With one device, the
server remembers its selection until restart. Keep actual UDIDs in local client
configuration, not in committed files or public issue reports.
Requests run sequentially. Screenshots and app listing can reconnect and retry once after a connection failure. Input and app launching are never automatically replayed. A timeout or connection error may mean an action partially completed; inspect the screen before retrying it. Client cancellation notifications are not processed during an in-flight call; configured timeouts bound device operations.
Wi-Fi
With only the intended iPhone attached by USB, enable wireless connections:
.venv/bin/python -m pymobiledevice3 lockdown wifi-connections onKeep the Mac and iPhone on the same trusted network. Unset
IOS_CONTROL_TRANSPORT for USB preference with network fallback, or set it to
wifi to require a network connection. The phone must remain unlocked and
reachable. To disable wireless connections, reconnect over USB and run the
command with off instead of on.
Privacy and security
This server can read the visible screen and send input to the foreground app. Only connect trusted MCP clients and keep their tool approval controls enabled for consequential actions. Screenshots can include messages, credentials, and other private content; the MCP client may send tool results to its model provider.
The server has no telemetry or HTTP listener. It sends tool results over local stdio and communicates with the paired device. Image conversion uses temporary files removed when conversion finishes normally; abrupt process termination can leave files behind. The dependency manages pairing records and may download developer support assets. Client logs and dependency diagnostics can contain private information. See SECURITY.md before sharing a report.
Troubleshooting
Symptom | What to check |
No iPhone found | Cable, unlock state, trust pairing, and Developer Mode. For Wi-Fi, check wireless pairing and the network. |
Selected device unavailable | Check |
Multiple devices found | Set |
Developer service or tunnel error | Confirm developer services are ready, check upstream setup requirements, and restart the client after fixing the connection. |
Input completes but nothing changes | Confirm focus, normalized coordinates, keyboard layout, and absence of a blocking system dialog. |
Typing rejects text | Use printable ASCII, tab, or newline. Unsupported text is rejected as a whole. |
App name is ambiguous | Use the exact bundle ID returned by |
Device action times out | Inspect the current screen before retrying; the action may already have partly completed. |
Client cannot start the server | Check its absolute executable path and environment variables. Inspect stderr locally; redact before sharing. |
Development
See CONTRIBUTING.md for setup and checks, architecture for the transport design, and CHANGELOG.md for behavior changes.
License
The code in this repository is licensed under the MIT License. Dependencies retain their own licenses. In particular, pymobiledevice3 is GPL-3.0-or-later; the MIT license here does not relicense that dependency. Review third-party license obligations when redistributing a combined package.
This is an independent project, not affiliated with or endorsed by Apple.
This server cannot be deployed
Maintenance
Related MCP Connectors
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.
Securely control paired computers with ReMCP.
Securely control computers you explicitly pair through files, terminals, processes, screenshots, desktop UI/input, clipboard, browser automation, diagnostics, and document tools.
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables MCP clients to control macOS via accessibility and screen recording, providing tools to list apps, observe UI, click, type, press keys, and scroll.MIT
- AlicenseNot gradedqualityCmaintenanceControl a real, physical iPhone from an MCP client, enabling tapping, swiping, typing, reading messages, and navigating apps via Apple's UI-automation channel.7 npmMIT
- AlicenseNot gradedqualityAmaintenanceExposes native iPhone device services and UI automation through MCP, enabling agents to inspect and control trusted iPhones via a unified interface.2GPL 3.0
- AlicenseNot gradedqualityBmaintenanceEnables MCP hosts to observe and operate macOS apps by reading accessible controls, entering text, clicking, scrolling, capturing screenshots, and performing on-device OCR, with background app control and explicit human authorization.3MIT