
1. 移动端自动化的真正痛点在哪里做过移动端自动化的朋友应该都有体会这个领域最让人头疼的从来不是写脚本本身而是连接这件事。你写了一堆 Appium 脚本跑起来发现设备掉了你搭好了 WebDriverAgent结果签名过期了你想让 AI 帮你操作一下手机发现根本没有一个统一的接口能让模型看见屏幕上的元素。mobile-mcp 这个项目本质上就是在解决这个最后一公里的问题——它把 iOS 和 Android 设备的操作能力通过 MCPModel Context Protocol协议暴露出来让任何支持 MCP 的 AI 客户端都能直接操控真机。说白了mobile-mcp 就是一个翻译层。左边是 iOS 的 XCUITest 和 Android 的 ADB/UIAutomator右边是 MCP 协议定义的标准工具调用接口。中间这层翻译做好了Claude、Cursor、各种 AI Agent 框架就能像调用本地函数一样去点击手机屏幕、滑动列表、输入文字、截屏分析。这跟 playwright-mcp 让 AI 操控浏览器的思路是一脉相承的只不过战场从浏览器换到了移动端。这个项目适合谁三类人值得重点关注一是做移动端自动化测试的工程师你们可以用它来快速搭建 AI 驱动的测试流程二是搞 AI Agent 开发的开发者你们需要一个可靠的移动端操作接口三是对 MCP 协议感兴趣、想找一个完整实战项目来学习的技术爱好者。不管你是哪一类理解 mobile-mcp 的架构设计和实操细节都能帮你少走很多弯路。2. mobile-mcp 的架构设计与核心思路拆解2.1 为什么是 MCP 而不是自定义 API很多人第一反应是我直接写个 HTTP 接口不就行了为什么要用 MCP这个问题我在刚开始接触时也想过。答案其实很简单——生态。MCP 是 Anthropic 推动的一个开放协议标准它的核心价值在于一次实现到处调用。你按照 MCP 协议暴露了工具那么所有支持 MCP 的客户端Claude Desktop、Cursor、Windsurf、各种 Agent 框架都能直接接入不需要你为每个客户端单独写适配层。对比一下传统方案如果你自己定义 REST API那 Claude 要接你的 API 得写一套适配Cursor 要接又得写一套每个客户端的工具描述格式还不一样。MCP 把这些标准化了——工具名称、参数 schema、返回值格式全部统一。这就像 USB-C 接口的意义不是它比专用接口性能更好而是它让所有设备都能用同一根线。另一个关键考量是上下文管理。MCP 协议天然支持流式返回和资源管理AI 模型可以在一次对话中连续调用多个工具根据上一步的结果决定下一步操作。这对于移动端自动化来说太重要了——你不可能预先知道每个步骤的结果必须让模型根据屏幕反馈动态决策。2.2 iOS 和 Android 两条技术路线的取舍mobile-mcp 在底层实现上iOS 和 Android 走的是完全不同的技术路线这个设计决策值得仔细说说。iOS 这边核心依赖是WebDriverAgent简称 WDA。WDA 是 Facebook 开源的一个测试框架它利用 XCUITest 框架在设备上运行一个 HTTP 服务器接收外部指令并转化为 XCUITest 操作。mobile-mcp 通过 WDA 的 REST API 来操控 iOS 设备。为什么不用 libimobiledevice 那套因为 libimobiledevice 只能做设备级别的操作安装应用、获取设备信息没法做 UI 级别的精细控制。你要点击屏幕上某个特定按钮必须走 XCUITest 这条路。Android 这边就简单多了直接走ADB UIAutomator。ADB 负责设备连接和基础操作安装、启动、截屏UIAutomator 负责 UI 元素定位和操作。Android 的开放性是它的优势——你不需要像 iOS 那样折腾签名和开发者模式插上 USB 打开调试就能用。但 Android 的碎片化也是真实存在的问题不同厂商的 ROM 对 UIAutomator 的支持程度参差不齐这个后面会详细讲。这里有个容易踩的坑很多人以为 iOS 自动化必须用 Mac其实 mobile-mcp 的服务端确实需要 macOS 来运行 WDA但 MCP 客户端可以在任何机器上。也就是说你可以在 Windows 上写代码通过局域网连接到 Mac 上的 mobile-mcp 服务。2.3 工具集设计暴露哪些能力给 AImobile-mcp 暴露给 AI 的工具集设计得相当克制没有追求大而全而是聚焦在最核心的操作上。我梳理了一下主要工具类别工具类别具体功能对应底层实现设备管理列出设备、获取设备信息iOS: ideviceinfo / Android: adb devices应用管理安装、卸载、启动、停止应用iOS: WDA API / Android: adb shell amUI 交互点击、长按、滑动、输入文字iOS: WDA / Android: UIAutomator元素定位获取 UI 树、查找元素iOS: WDA source / Android: dump hierarchy屏幕操作截屏、录屏iOS: WDA screenshot / Android: adb screencap系统操作返回、Home、音量、旋转iOS: WDA / Android: adb shell input这个设计的好处是每个工具都有明确的语义AI 模型很容易理解什么时候该用哪个工具。比如模型看到点击登录按钮这个任务它会先调用获取 UI 树找到按钮的坐标或选择器然后调用点击工具执行操作。这个流程跟人类操作手机的逻辑是一致的。2.4 通信层stdio 还是 SSEMCP 协议支持多种传输方式mobile-mcp 主要用的是stdio标准输入输出。这意味着 MCP 客户端会启动 mobile-mcp 作为一个子进程通过标准输入输出进行通信。这种方式的优点是简单、无需网络配置、安全性好不暴露端口。缺点是不支持远程调用——你的 MCP 客户端和 mobile-mcp 必须在同一台机器上。如果你需要远程使用可以考虑 SSEServer-Sent Events模式mobile-mcp 也支持。但这种模式下你需要自己处理网络暴露带来的安全问题。我的建议是除非有明确的远程需求否则优先用 stdio 模式省心。3. 环境搭建与核心细节实操3.1 iOS 环境从零到能跑通iOS 这边的环境搭建是最容易劝退人的环节我把完整流程和踩坑点都列出来。第一步安装 Xcode 和命令行工具从 App Store 安装 Xcode然后执行xcode-select --install sudo xcode-select -s /Applications/Xcode.app/Contents/Developer验证安装xcodebuild -version能输出版本号就说明没问题。第二步部署 WebDriverAgent这一步是最容易出问题的。WDA 需要签名才能在真机上运行。你需要一个 Apple Developer 账号免费的也行但免费账号签名 7 天过期需要重新签。# 克隆 WDA 仓库 git clone https://github.com/appium/WebDriverAgent.git cd WebDriverAgent # 用 Xcode 打开项目 open WebDriverAgent.xcodeproj在 Xcode 中你需要做几件事选择 WebDriverAgentRunner target在 Signing Capabilities 中设置你的 Team修改 Bundle Identifier 为一个唯一的字符串比如 com.yourname.wda选择你的真机设备作为 target然后按 CmdU 运行测试WDA 会被安装到设备上并启动。如果一切正常你会在 Xcode 控制台看到设备 IP 和端口号通常是 8100。第三步端口转发WDA 运行在设备的 8100 端口上你需要把它转发到 Mac 本地# 用 iproxy来自 libimobiledevice iproxy 8100 8100 # 或者用 tidevice国内开发者常用的工具 tidevice relay 8100 8100验证curl http://localhost:8100/status应该返回 JSON 格式的设备状态信息。第四步安装 mobile-mcp# 如果用 npm npm install -g mobile-mcp # 或者从源码构建 git clone https://github.com/mobile-next/mobile-mcp.git cd mobile-mcp npm install npm run build第五步配置 MCP 客户端以 Claude Desktop 为例编辑配置文件macOS 路径是~/Library/Application Support/Claude/claude_desktop_config.json{ mcpServers: { mobile-mcp: { command: node, args: [/path/to/mobile-mcp/dist/index.js], env: { DEVICE_TYPE: ios } } } }重启 Claude Desktop你应该能在工具列表里看到 mobile-mcp 提供的工具。3.2 Android 环境相对简单但仍有坑Android 的环境搭建比 iOS 简单不少但也不是没有坑。第一步安装 Android SDK 和 ADB如果你已经装了 Android StudioADB 通常在~/Library/Android/sdk/platform-tools/macOS或%LOCALAPPDATA%\Android\Sdk\platform-tools\Windows。把这个路径加到系统 PATH 里。# 验证 adb version第二步开启设备调试在 Android 设备上进入设置 → 关于手机 → 连续点击版本号7 次开启开发者模式返回设置 → 开发者选项 → 开启USB 调试用 USB 连接电脑设备上会弹出授权对话框勾选始终允许验证adb devices应该能看到你的设备。第三步安装 UIAutomator 服务mobile-mcp 需要 UIAutomator 来获取 UI 层级信息。有些设备自带有些需要手动安装# 检查是否已安装 adb shell pm list packages | grep uiautomator # 如果没有安装 Android SDK 自带的版本 adb install /path/to/android-sdk/tools/lib/uiautomator.jar实际上现代 Android 设备通常不需要单独安装 UIAutomatoradb shell uiautomator dump命令可以直接使用。如果遇到权限问题试试adb root仅限模拟器或已 root 的设备。第四步配置 mobile-mcp跟 iOS 类似只是在环境变量里指定 Android{ mcpServers: { mobile-mcp: { command: node, args: [/path/to/mobile-mcp/dist/index.js], env: { DEVICE_TYPE: android, ANDROID_HOME: /Users/yourname/Library/Android/sdk } } } }3.3 设备连接方式的选择USB 连接和无线连接各有优劣我整理了一个对比连接方式优点缺点适用场景USB稳定、延迟低、无需额外配置线缆限制、设备数量受限开发调试、单设备测试无线ADB自由移动、支持多设备需要初始 USB 配对、网络不稳定时掉线演示、多设备并行无线iOS同上WDA 需要额外配置、稳定性较差特定场景Android 无线调试的配置需要 Android 11# 先用 USB 连接开启无线调试 adb tcpip 5555 # 查看设备 IP adb shell ip addr show wlan0 # 断开 USB无线连接 adb connect 192.168.1.100:5555iOS 无线调试就麻烦多了需要 WDA 支持而且稳定性一直是个问题。我的建议是 iOS 尽量用 USBAndroid 可以尝试无线。3.4 实操心得那些文档里不会写的东西关于 iOS 签名免费开发者账号签名的 WDA 只有 7 天有效期过期后需要重新用 Xcode 运行一次。如果你要长期使用建议花 99 美元买个开发者账号签名有效期一年。另外用xcodebuild命令行签名比用 Xcode GUI 更稳定不容易出现无法验证的问题。关于 Android 碎片化小米、华为、OPPO 等厂商的 ROM 对 UIAutomator 的支持有差异。我遇到过小米设备上uiautomator dump返回空文件的情况解决方案是关闭 MIUI 优化开发者选项里或者改用adb shell dumpsys window来获取窗口信息。华为设备则可能需要在开发者选项里额外开启仅充电模式下允许 ADB 调试。关于端口冲突WDA 默认用 8100 端口如果你同时跑多个 iOS 设备需要给每个设备分配不同端口。iproxy 8101 8100这样转发然后在 mobile-mcp 配置里指定端口。4. 完整实操流程让 AI 帮你操作手机4.1 一个完整的自动化场景假设我们要让 AI 完成一个任务打开微信找到某个联系人发送一条消息。这个场景涵盖了启动应用、UI 定位、文本输入、点击操作等核心环节。第一步确认设备连接在 MCP 客户端里先调用list_devices工具。返回结果应该包含你的设备信息{ devices: [ { id: ABCD1234-5678-90EF-GHIJ-KLMNOPQRSTUV, name: iPhone 15 Pro, platform: ios, status: connected } ] }如果设备列表为空检查 USB 连接、WDA 是否运行、端口转发是否正常。第二步启动目标应用调用launch_app工具传入微信的 Bundle IDiOS 是com.tencent.xinAndroid 是com.tencent.mm{ bundleId: com.tencent.xin }这一步底层执行的是xcrun simctl launch或adb shell am start。启动后建议等 2-3 秒让应用完全加载。第三步获取 UI 层级调用get_ui_hierarchy工具返回的是一棵 XML 树iOS或 JSON 树Android。这棵树包含了屏幕上所有可见元素的属性类型、文本、坐标、是否可点击等。XCUIElementTypeApplication name微信 XCUIElementTypeWindow XCUIElementTypeOther XCUIElementTypeButton name搜索 x320 y88 width44 height44/ XCUIElementTypeTable XCUIElementTypeCell name文件传输助手 x0 y200 width390 height72/ /XCUIElementTypeTable /XCUIElementTypeOther /XCUIElementTypeWindow /XCUIElementTypeApplicationAI 模型会解析这棵树找到目标元素。比如要点击搜索按钮它会提取出坐标 (320, 88) 或者用 name 属性来定位。第四步执行点击操作调用tap工具{ x: 342, y: 110 }注意坐标是元素中心点不是左上角。计算方式x width/2, y height/2。第五步输入文字点击搜索框后调用type_text工具{ text: 文件传输助手 }iOS 上这个操作通过 WDA 的/wda/keys接口实现Android 上通过adb shell input text实现。注意中文输入在 Android 上可能有问题因为adb shell input text不支持 Unicode。解决方案是用 ADBKeyBoard 这个输入法或者用adb shell am broadcast发送广播。第六步验证结果再次调用get_ui_hierarchy确认搜索结果出现了目标联系人。然后点击联系人进入聊天界面输入消息内容点击发送。整个流程下来AI 模型会调用 8-10 次工具每次调用之间它会根据返回结果决定下一步。这就是 MCP 协议的价值——它让 AI 有了感知-决策-执行的闭环能力。4.2 参数计算与选择过程在实际操作中有几个参数需要特别注意截图压缩率mobile-mcp 返回的截图默认是 PNG 格式一张 1080P 的截图可能有 2-3MB。如果频繁截屏会消耗大量 token。建议在配置里开启 JPEG 压缩质量设为 70-80这样截图大小能降到 200-300KB对 AI 识别影响不大。UI 树深度有些应用的 UI 层级非常深比如嵌套了十几层 ViewGroup完整的 UI 树可能有几千行。mobile-mcp 支持设置最大深度建议设为 10-15 层既能覆盖大部分元素又不会让 token 爆炸。操作间隔AI 连续调用工具时如果间隔太短设备可能来不及响应。建议在 mobile-mcp 配置里设置ACTION_DELAY为 500-1000ms。这个值太小会导致操作丢失太大又会影响效率。超时设置获取 UI 树和截屏操作可能耗时较长特别是在低端设备上。建议把超时设为 10-15 秒避免因为超时导致整个流程失败。4.3 实操现场记录一次完整的调试过程让我记录一次真实的调试过程展示遇到问题时的排查思路。目标让 AI 在 Android 设备上打开设置进入关于手机读取 Android 版本号。第一次尝试AI 调用launch_app启动设置应用然后调用get_ui_hierarchy。返回的 UI 树是空的。排查手动执行adb shell uiautomator dump /sdcard/ui.xml然后adb pull /sdcard/ui.xml发现文件内容是空的。这说明 UIAutomator 服务没有正常工作。解决检查发现是设备的 MIUI 优化导致的。在开发者选项里关闭MIUI 优化重启设备问题解决。第二次尝试UI 树正常返回了但 AI 找不到关于手机这个选项。查看 UI 树发现这个选项在 ScrollView 里当前屏幕没有显示出来。解决AI 需要先执行滑动操作。调用swipe工具从屏幕底部向上滑动。滑动后再获取 UI 树就能找到目标元素了。第三次尝试找到了关于手机元素点击后进入新页面。但 AI 读取到的版本号是13而实际版本是13.0.5。排查查看 UI 树发现版本号被拆分成了两个 TextViewAI 只读取了第一个。解决调整 AI 的提示词让它读取完整的 UI 树并合并相邻的文本节点。或者在 mobile-mcp 层面做处理把相邻的文本节点合并。这个过程展示了移动端自动化的典型挑战环境问题、UI 动态性、数据解析。每一个环节都可能出问题需要耐心排查。5. 常见问题与排查技巧实录5.1 连接类问题速查表问题现象可能原因排查步骤解决方案设备列表为空USB 连接问题adb devices或idevice_id -l换线、换端口、重启 ADB 服务WDA 启动失败签名问题查看 Xcode 控制台报错重新签名、检查 Bundle ID 唯一性端口转发失败iproxy 未运行lsof -i :8100启动 iproxy 或 tidevice设备显示 unauthorized未授权调试设备屏幕上的授权对话框勾选始终允许、撤销授权重试连接频繁断开无线信号不稳定检查网络延迟改用 USB 连接5.2 UI 操作类问题元素定位不到最常见的原因是 UI 树没有及时更新。应用界面切换后需要等待一段时间再获取 UI 树。建议在每次操作后加 1-2 秒延迟。另外有些元素是动态生成的比如列表项需要先滑动到可见区域才能定位。点击无效可能是坐标计算错误或者元素被遮挡。iOS 上可以用 WDA 的/wda/element/{id}/click接口直接点击元素比坐标点击更可靠。Android 上可以用adb shell input tap但要注意坐标是相对于屏幕的不是相对于应用的。输入中文乱码Android 的adb shell input text不支持 Unicode。解决方案有三个一是安装 ADBKeyBoard 输入法通过广播发送中文二是用adb shell am broadcast -a ADB_INPUT_TEXT --es msg 中文三是用 UIAutomator 的setText方法需要写 Java 代码。滑动不灵敏adb shell input swipe的持续时间参数很关键。默认是 300ms对于长距离滑动可能太快。建议设为 500-800ms。iOS 上 WDA 的/wda/dragfromtoforduration接口也需要调整 duration 参数。5.3 性能与稳定性问题截图太慢iOS 上 WDA 截屏走的是 XCUITest 的 API本身就比较慢。优化方法是降低截图频率只在必要时截屏。Android 上adb exec-out screencap -p比adb shell screencap快很多因为避免了文件写入和读取。UI 树太大前面提到过设置最大深度。另外可以过滤掉不可见元素和装饰性元素只保留可交互的元素。mobile-mcp 支持配置过滤规则。内存泄漏长时间运行后WDA 或 UIAutomator 服务可能内存泄漏。建议定期重启服务或者设置自动重启策略。iOS 上可以用xcodebuild test-without-building重新启动 WDA。5.4 独家避坑技巧技巧一用 accessibility id 而不是坐标。坐标点击最大的问题是屏幕分辨率变化或 UI 布局调整后就失效了。accessibility id 是元素的唯一标识更稳定。在 iOS 上对应accessibilityIdentifierAndroid 上对应content-desc或resource-id。技巧二处理弹窗和权限对话框。应用启动时经常弹出权限请求或更新提示这些弹窗会遮挡目标元素。建议在启动应用后先检查是否有弹窗有的话先处理掉。可以写一个通用的弹窗处理函数检测常见的弹窗类型并自动关闭。技巧三用录屏辅助调试。当自动化流程失败时光看日志很难定位问题。建议开启录屏回放操作过程。iOS 上用xcrun simctl io booted recordVideoAndroid 上用adb shell screenrecord。技巧四建立元素库。对于频繁操作的元素建立一个元素库记录它们的定位方式。这样 AI 不需要每次都解析完整的 UI 树直接查库就行能大幅提升效率。技巧五处理 WebView 和 Hybrid 应用。很多应用的核心页面是 WebViewUIAutomator 和 XCUITest 对 WebView 的支持有限。解决方案是切换到 WebView 上下文Android 上用adb shell cat /proc/net/unix | grep webview找到 socket或者用图像识别的方式定位元素。6. 进阶玩法与扩展思路6.1 结合视觉模型做图像识别mobile-mcp 返回的截图可以直接喂给视觉模型比如 GPT-4V、Claude 3 Vision让模型看懂屏幕内容。这在处理游戏、Canvas 绘制、自定义控件等场景下特别有用因为这些场景下 UI 树拿不到有效信息。具体做法是截屏 → 传给视觉模型 → 模型返回目标元素的坐标 → 调用 tap 工具点击。这个流程比传统的图像模板匹配灵活得多不需要预先准备模板图片。6.2 多设备并行操作mobile-mcp 支持同时连接多个设备。你可以让 AI 同时在 iOS 和 Android 上执行相同的操作对比结果。这在兼容性测试中非常有用。配置方式是在 MCP 客户端里启动多个 mobile-mcp 实例每个实例连接不同的设备。或者用 mobile-mcp 的多设备模式在工具调用时指定设备 ID。6.3 与 CI/CD 流水线集成把 mobile-mcp 集成到 CI/CD 里可以实现自动化的冒烟测试。每次代码提交后自动在真机上跑一遍核心流程发现问题及时报警。集成方式有两种一是用 MCP 客户端比如 Claude API作为执行引擎在 CI 脚本里调用二是直接用 mobile-mcp 的底层 API绕过 MCP 协议。前者更灵活后者更稳定。6.4 自定义工具扩展mobile-mcp 的工具集是可以扩展的。如果你有特殊需求比如需要操作蓝牙、NFC、传感器等可以自己写工具实现然后注册到 mobile-mcp 里。扩展方式是继承 mobile-mcp 的 Tool 基类实现execute方法然后在工具注册表里添加。具体可以参考项目源码里的src/tools/目录。7. 我个人在实际操作中的体会折腾 mobile-mcp 这段时间最大的感受是移动端自动化的核心难点从来不是技术本身而是环境的不可控性。同样的脚本在你的机器上跑得好好的换一台设备就可能各种报错。iOS 的签名、Android 的碎片化、网络的不稳定每一个都是潜在的坑。我的建议是如果你要长期使用 mobile-mcp一定要做好三件事第一建立完善的环境检查流程每次使用前先跑一遍健康检查第二准备好备用设备主力设备出问题时能快速切换第三记录所有踩过的坑和解决方案形成自己的知识库。另外不要指望 AI 能 100% 正确地完成所有操作。移动端 UI 的动态性太强了AI 也会有判断失误的时候。实际使用中我通常会让 AI 处理 80% 的常规操作剩下 20% 的复杂场景还是人工介入。这样既能享受 AI 带来的效率提升又能保证关键流程的可靠性。最后分享一个小技巧如果你在 iOS 上遇到 WDA 频繁掉线的问题试试用tidevice代替iproxy做端口转发。tidevice 是国内开发者写的一个工具对 iOS 设备的兼容性更好而且支持自动重连。安装方式很简单pip install tidevice然后用tidevice relay 8100 8100就能替代 iproxy 了。这个工具还支持查看设备日志、安装应用等功能比 libimobiledevice 那套工具链好用不少。