Skip to main content
Glama

iPhone MCP

English · 简体中文

运行在电脑上的 MCP 服务,通过 Wi-Fi(默认)或 USB、CoreDevice 隧道和 RemoteXPC 开发者服务直接控制 iPhone。手机无需安装或后台运行 Actell,无需手机端 MCP、VPN、ESP32 或 WebDriverAgent。

当前面向 macOS、iOS 27+、Wi-Fi/USB、正向竖屏触控。已在拔掉 USB 后验证截图、点击、滑动、中文输入、Bonjour 发现及 TCP 中断后重连;长期稳定性仍待验收。不把协议请求成功视为界面操作成功。

安装

需要 uv、Python 3.13。uv sync 会按需安装 Python 并创建隔离环境。

git clone https://github.com/the-eric-kwok/iphone-mcp.git
cd iphone-mcp
uv sync --frozen
uv run --frozen iphone-mcp --help
uv run --frozen iphone-mcp devices

手机准备:

  1. 用数据线连接 Mac,解锁手机,在 Finder 或 Xcode 中完成信任配对。

  2. 在手机设置中启用开发者模式。

  3. 让匹配版本的 Xcode 完成设备准备,挂载 Personalized Developer Disk Image(DDI)。本项目不下载、挂载 DDI,不更改开发者模式或信任关系。

  4. 手机和 Mac 连接同一局域网,开启系统无线连接,然后拔掉数据线。关闭其他正在控制同一手机的任务,保持手机可操作。

# 首次准备:先通过 USB 完成信任,再显式开启系统无线连接。
uv run --frozen iphone-mcp devices --transport usb
uv run --frozen iphone-mcp prepare-wifi --udid <UDID>

# 拔掉数据线后验证 Wi-Fi。doctor 只连接和截图,随后释放,不发送输入或保存截图。
uv run --frozen iphone-mcp devices --transport wifi --udid <UDID>
uv run --frozen iphone-mcp doctor --udid <UDID> --transport wifi

# Bonjour 不可用时,可直接指定手机 IP。
uv run --frozen iphone-mcp doctor --udid <UDID> --host <手机IP>

prepare-wifi 只通过 USB 为指定的已配对设备设置系统 EnableWifiConnections,并读取确认;普通发现和连接不会自动修改此设置。准备完成后,手机仅运行系统服务,无需常驻 App。系统更新、重启或 DDI 状态变化后,可能需要重新在 Xcode 中准备开发者服务。

无线发现使用 macOS 系统 Bonjour,仅返回电脑已有身份能够认证的设备。macOS 的系统配对记录不能直接枚举时,传入已知 --udid 可以让系统查询对应记录,连接不依赖数据线。发现为空也需检查本地网络权限、Bonjour、局域网隔离和手机解锁状态。指定 --host 可跳过服务发现;.local 名称仍由系统 Bonjour 解析,连接始终校验所选 UDID 和配对身份。为避免误选插线虚拟网络,Wi-Fi 模式过滤链路本地、回环及组播地址,要求可用的局域网 IPv4 或非链路本地 IPv6 地址。

Wi-Fi 是默认连接方式;USB 必须显式传入 --transport usb。Wi-Fi 失败会报错,不自动回退 USB。

Related MCP server: open_phone

MCP 接入

使用 stdio,MCP 客户端负责启动进程,不需要手动常驻运行另一个 HTTP 服务。

{
  "mcpServers": {
    "iphone": {
      "command": "/opt/homebrew/bin/uv",
      "args": [
        "--directory", "/absolute/path/to/iphone-mcp",
        "run", "--frozen", "iphone-mcp", "serve"
      ]
    }
  }
}

配置模板见 examples/mcp.json。请替换 uv 和项目的绝对路径;/absolute/path/to/iphone-mcp 是占位路径。项目安装过程不会自动修改任何 MCP 客户端配置。

工具

工具

用途

list_devices

通过 transport=all/wifi/usb 发现设备,可按 udid 过滤;返回 items 和部分发现错误 errors

connect_device

指定 udid,默认 transport=wifi;可指定 host,或显式选 usb

device_status

读取本地会话状态,不隐式重连

screenshot

返回新鲜 JPEG、尺寸、方向和 frame_id

tap

根据截图像素坐标点击

drag

根据截图像素坐标拖动,时长 0.1~5 秒

home

返回主屏幕

list_apps

按名称或 Bundle ID 搜索应用

launch_app

启动或激活应用,不终止已有进程

type_text

设置手机剪贴板后粘贴,支持完整 Unicode 文本

wait

等待 0~10 秒,不阻塞停止操作

stop、disconnect_device

取消动作、作废排队请求、释放当前会话

list_devices() 每次调用刷新两种连接;list_devices(transport="wifi") 或 list_devices(transport="usb") 可单独查询,udid 可缩小范围。同一设备有两种可用路线时保留两条记录,使用 UDID 关联,避免掩盖实际连接方式。发现只读取设备身份,不启动控制会话;当前控制会话通过 device_status 查询。

例如:connect_device(udid="…", transport="wifi", host="192.168.1.20");省略 host 时通过 Bonjour 寻找设备。状态中的 transport 和 host 表示实际选用的连接。

推荐顺序:list_devices → connect_device → screenshot → tap/drag/type_text → screenshot。

坐标属于返回图片,不是原始屏幕尺寸。默认截图最长边为 1600 像素,可以用 max_size 调整。输入必须携带最近的 frame_id;新截图、输入、停止、断线或超过 60 秒都会使旧引用失效。方向变化会拒绝坐标输入,首版不猜测横屏映射。截图引用用于绑定坐标,不能保证屏幕内容在两次调用之间未改变。

type_text 会替换手机剪贴板,不读取或保存原剪贴板,不自动回车;系统粘贴确认需要用户处理。返回 dispatched 只说明协议发送完成,必须重新截图确认实际效果。

架构

MCP 客户端
  └─ stdio MCP 服务
      └─ Controller:串行操作、截图引用、取消与不重放
          └─ CoreDeviceBackend
              ├─ Wi-Fi TCP Lockdown/USB Lockdown 配对身份
              ├─ DesktopTunnel:CoreDeviceProxy、进程内隧道、RSD
              ├─ ScreenCaptureService:按需获取 PNG,再压缩为 JPEG
              ├─ DisplayService:输入所需媒体会话、UDP 接收、RTCP 反馈
              ├─ UniversalHID/Indigo:触控、Home、粘贴按键
              └─ AppService/PasteboardService

常驻复用隧道和服务连接,输入第一次调用时才启动媒体通道。截图使用独立截图服务,不实现视频解码或返回旧视频缓存;这有利于首版验证和降低空闲解码开销,截图吞吐与延迟尚需真机测量。

每个 MCP 进程只连接一台设备,这是上游进程内网络栈的限制。同一设备的不同进程通过文件锁互斥;切换设备、连接方式或主机须先断开。锁不会约束 Xcode、Actell 或其他外部控制器。

停止只处理自己的触控、按键和媒体标识,不调用全局 stopAll。操作失败或超时时关闭当前会话,不自动重连并重放动作。输入已经发出但结果不明时,需要用户或 Agent 在新会话截图核对。物理断线时无法保证设备收到释放报告;本地清理与设备端实际释放须区分。

服务不监听 TCP 端口,不存储截图、输入文本或配对记录;依赖库使用电脑已有的配对身份。stdout 只承载 MCP,诊断写入 stderr。具备此 stdio 连接权限的客户端可以调用所有工具,没有额外逐次确认层。

验证

uv run --frozen ruff check .
uv run --frozen pytest -q
uv build

测试覆盖系统 Bonjour 的 TXT 解析与取消清理、无线身份匹配、禁止隐式 USB 回退、取消期间资源释放、无线断线唤醒、连接复用、坐标缩放、截图失效、方向变化、并发输入、取消、停止、未知结果不重放、按键释放、媒体定向停止、设备锁,以及真实子进程的 MCP 初始化、工具发现、参数校验和退出。

真机验收步骤见 docs/ACCEPTANCE.md。尚待验证持续媒体反馈、方向边界、输入期间的断线、实际关闭无线网络及设备端释放边界。Windows、Linux、横屏触控、自动 DDI 准备和视频流截图不在首版支持范围内。

代码与来源

文件

职责

src/iphone_mcp/bonjour.py

macOS 系统 DNS-SD 浏览、服务解析、TXT 与资源清理

src/iphone_mcp/connection.py

USB/Wi-Fi 发现、Lockdown、指定通道的 CoreDevice 隧道、显式无线准备

src/iphone_mcp/backend.py

CoreDevice 服务、媒体反馈与资源释放

src/iphone_mcp/controller.py

会话、串行调度、超时、取消、截图引用

src/iphone_mcp/model.py

图片压缩、坐标转换、输入验证

src/iphone_mcp/server.py

MCP 工具与标准图片结果

src/iphone_mcp/__main__.py

启动、设备枚举与只读诊断

采用 GPL-3.0-only,第三方来源见 THIRD_PARTY.md。协议能力依赖非公开开发者服务及匹配的 DDI,固定依赖版本与 uv.lock 一同维护。升级系统或依赖后应重新验收。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to control a physical iPhone from macOS through local phone tools, including USB capture, Bluetooth HID, and AssistiveTouch interactions. It also exposes relay tools for remote access over Streamable HTTP with optional OAuth.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables a macOS MCP client to control a real iPhone through CoreDevice services, including screenshots, normalized taps and swipes, text entry, hardware-button presses, and app launching or listing.
    11
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables 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.
    28 npm
    10
    MIT