Skip to content

About

Control a real USB-connected iPhone from Linux (no Mac, no paid developer account) and expose it to AI agents as MCP tools

Topics

Resources

Contributing

Security policy

Stars

40 stars

Watchers

1 watching

Forks

Repository files navigation

iphone-control: Let AI agents operate a real iPhone

Let an AI agent operate a real iPhone or iPad plugged into a Linux machine or a Mac — one Rust binary, no Xcode, no paid developer account, no jailbreak.

Release iOS Platform: Linux | macOS MCP Rust License M8ven verified

🚀 Quick Start  ·  📖 Docs  ·  📦 Releases  ·  🐛 Issues  ·  🌐 简体中文


Claude Code on the left calls iphone_launch_app and iphone_tap_element; on the right, the iPhone shows the Clock stopwatch running

Asking Claude Code to “open Clock, switch to the stopwatch and start it”. Left: Claude Code’s tool calls (first part only). Right: the phone afterwards.

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.

Architecture: an MCP client talks to iphone-control mcp over stdio, which talks to the daemon over a Unix socket; the daemon drives the iPhone or iPad over USB through WebDriverAgent, with CoreDevice HID as fallback

Features

One binary, 17 MCP tools, fewer round trips, runs unattended, HID fallback, doctor and alerts

  • 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_batch runs up to 20 steps in one call
  • Automatic 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: doctor checks 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 an Apple Silicon Mac or a Linux machine.

macOS or Linux, one command (upstream example; for a fork, use the installer asset from its own signed release)

curl -fsSLo iphone-control-install.sh https://github.com/Derrors/iphone-control/releases/latest/download/install.sh && sh iphone-control-install.sh

It downloads the release for your machine, verifies the Ed25519 release manifest and archive SHA-256 (Python 3 and OpenSSL 3 required), installs iphone-control into ~/.local/bin and runs the daemon as a per-user service that starts at login (launchd on macOS, systemd on Linux). Run it as your regular user. Use iphone-control update to upgrade this managed service. Running sh iphone-control-install.sh --uninstall removes it and keeps your data.

Upstream v0.2.0 predates the signed installer. To install that release or migrate an existing script installation, follow the v0.2.0 instructions.

Or with a package manager

# macOS or Linux (Homebrew)
brew install derrors/tap/iphone-control && brew services start iphone-control

# Debian 12+ / Ubuntu 22.04+: the .deb from Releases (amd64 or arm64), pulls in usbmuxd
sudo apt install ./iphone-control_<version>_amd64.deb && systemctl --user enable --now iphone-control

On Linux the system usbmuxd is needed (sudo apt install usbmuxd; the .deb brings it). On an Intel Mac, build from source.

Then, on every system

Connect the phone with the cable and run:

iphone-control

The first time, it walks you through setup in the terminal, one step at a time: language, proxy, the background service, pairing, Developer Mode, Apple ID, signing and installing WebDriverAgent, the optional auto-unlock and notifications, and registering with Claude Code and Codex. Do what it asks on the phone. Steps already done are skipped; afterwards, iphone-control just shows the status.

Then open a new Claude Code or Codex session and ask, for example, “Open Clock, switch to the stopwatch and start it.” Or run iphone-control viewer for the control page in the browser (http://127.0.0.1:8200; log in with the link iphone-control viewer token prints), where you can act on the live screen and hand tasks to a local Claude Code or Codex; it works from the local network and other machines too, see Viewer and Remote Use.

More: step-by-step guide · build from source · macOS guide · other MCP clients.

MCP Tools

Tool Description
iphone_status Connection, lock state, foreground app, screen size
iphone_screenshot Screenshot scaled to points; pass x/y/width/height to zoom into a region
iphone_list_elements Elements with text and their center coordinates; filter by text or type
iphone_tap / iphone_tap_element Tap by coordinates or by element text
iphone_swipe / iphone_long_press Swipe (returns once the list stops), long-press
iphone_type_text Type into the focused field; reads it back and fixes dropped characters
iphone_press_button home, volume_up, volume_down, lock
iphone_list_apps / iphone_launch_app / iphone_terminate_app Manage apps by name or bundle ID
iphone_open_url Open a URL or URL scheme
iphone_wait_for Wait until some text appears instead of polling with screenshots
iphone_batch Run up to 20 steps in one call, stopping at the first error
iphone_list_devices Every iPhone/iPad on USB; marks the one being controlled
iphone_select_device 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

Command What it does
(none) The first time, the setup guide; after that, the status (and starts the service if it isn't running)
setup [--reconfigure] Run the setup guide again; --reconfigure redoes one part (language, proxy, service, Apple ID, phone, auto-unlock, notifications, MCP registration)
service install|uninstall|start|stop|restart|status The background service (launchd on macOS, systemd user unit on Linux)
daemon The long-running daemon; the service runs it, or start it by hand
mcp [--url <viewer>] The MCP server; your AI client starts it. With --url it bridges to another machine's viewer
status Daemon state, time left on the signing profile, recent log
doctor Layer-by-layer health check with a fix for each failure
login Sign in to the Apple ID again when the session expires
sign Sign and install WebDriverAgent now
resign [--force] Re-sign WebDriverAgent if it expires soon (or now)
passcode set|clear Turn auto-unlock on or off for a device (passcodes are kept per device)
unlock-reset Turn auto-unlock back on after it was disabled
devices / select <UDID|name|auto> List connected devices / switch which one is controlled
notify-test [event] Send test notifications
mcp-config Print the command that registers the MCP server
wda-bridge [--port] Expose WebDriverAgent on 127.0.0.1 for other tools; stop it when done
viewer [--port] [--lan] Control page on 127.0.0.1:8200, behind a login (viewer token shows the token and a link; read-only tokens too): live screen you can tap, swipe and type on, device panel, and AI tasks run by a local Claude Code or Codex. --lan opens it to the local network (HTTPS), and MCP over HTTP is on the same port (/mcp)
task run [--url <viewer>] -- <command> AI tasks for other agent platforms; with --url the phone is on another machine. task list, pause, approve… follow and control tasks
viewer token [add <name> [--read-only]|list|show <name>|remove <name>] The viewer's login tokens: show the owner's, or add named and read-only ones
service viewer install|uninstall|start|stop|restart Run the viewer as a background service of its own
update check|apply|policy Check for, install, or set the policy for updates
completions <shell> Bash, Zsh or Fish completion script

All commands and options: CLI reference.

Run iphone-control update to check for a stable release. When an upgrade is available, it uses the signed update for a managed service, Homebrew for a tap installation, or apt for a Debian package. It reports when you're up to date. Source installations follow the source upgrade instructions.

To check versions, open About & updates in Viewer or run iphone-control update check --json. Managed services can opt in to signed patches while idle with iphone-control update policy auto-patch. Use iphone-control update policy notify to return to checks only. Read the upgrade notes before upgrading.

Uninstall with sh iphone-control-install.sh --uninstall, brew uninstall iphone-control or sudo apt remove iphone-control; your data stays. Settings live in ~/.config/iphone-control/env: the guide writes it, and after editing it by hand run iphone-control service restart — see configuration. All state lives in ~/.local/share/iphone-control: 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 Install · Build from source · macOS · Data and backups
Problems FAQ · Troubleshooting · Issues
Security SECURITY.md: what is stored, who can reach it, reporting vulnerabilities
Development Contributing · Architecture · Decisions · Changelog
Licensing THIRD_PARTY.md: vendored components, versions and licenses

The architecture and design documents are in Chinese for now.

Warning

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. Read SECURITY.md before enabling auto-unlock.

Contributing

Issues and pull requests are welcome — see the contributing guide.

License

MIT. Third-party components: THIRD_PARTY.md.

About

Control a real USB-connected iPhone from Linux (no Mac, no paid developer account) and expose it to AI agents as MCP tools

Topics

Resources

Contributing

Security policy

Stars

40 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages