Skip to content

About

Mobile automation MCP and CLI with Android WebView CDP and reusable flow execution. Based on mobile-next/mobile-mcp.

Resources

Code of conduct

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

mobile-cli-allinone

由 xue-ding-e 维护的移动设备自动化工具。以 CLI 的 run / eval 为主要脚本入口,提供原生界面操作、Android WebView CDP 调试和 JSON 流程重放;另提供 MCP 服务供支持 MCP 的客户端使用。

仓库已从 mobile-mcp-allinone 更名为 mobile-cli-allinone,多平台源码与线性历史已推送到本仓库;以下链接和克隆示例使用当前名称。npm 包名 @xue-ding-e/mobile-mcp-allinone、MCP registry ID io.github.xue-ding-e/mobile-mcp-allinone 和 mcp-server-mobile 命令暂保持兼容,不表示发布了新包。

不同平台有不同的驱动和能力,不能把 Android 命令直接套到其他平台。下表描述当前源码接入情况,不代表已在所有系统、设备和版本上完成真机验收。

平台支持与边界

目标 CLI MCP 所需驱动与限制
Android 真机 / 模拟器 已接入原生操作、脚本、流程、WebView 已接入 ADB;设备须在线并授权。WebView 需应用开启调试
HarmonyOS / OpenHarmony HDC 目标 已接入原生操作、脚本、原生流程 已接入设备发现、原生操作和原生流程 HDC、设备调试授权以及设备侧 UITest / bm / aa 等命令;不是 Android ADB
iOS 真机 已接入原生操作、脚本、原生流程(--platform ios) 已接入 go-ios、设备信任/开发配置、WebDriverAgent(WDA);iOS 17+ 还需 tunnel
iOS Simulator 已接入 Simctl / WDA(--platform ios-simulator);CLI 截图直接使用 Simctl 已接入 mobilecli / agent macOS / Xcode / 已启动的模拟器;CLI 与 MCP 驱动不同,不能在 Windows / Linux 本机运行 simctl
  • Android 专属:wv-*、脚本 wv、WebView 流程和 CLI 录屏。没有 iOS Safari / WKWebView 或 HarmonyOS WebView CDP 接入。
  • HarmonyOS 支持控件读取、点击/双击/长按/滑动、文字输入、截图、应用启动/停止、签名 HAP 安装/卸载、文件传输与电源操作。长按时长由 UITest 决定,不支持自定义 duration;url、设置方向、录屏尚不支持。读取方向根据截图尺寸判断。
  • HDC install 仅接受 .hap,不会把 APK 当 HAP 安装。卓易通等兼容环境里的 APK 导入和手机端安装需要单独处理。
  • 默认 iOS 真机 go-ios 路径的 WDA 使用本机 localhost:8100,iOS 17+ tunnel 检查使用 60105。操作前必须确认该端口对应选定设备。CLI 模拟器不使用该共享端口,UI 控制必须提供独占 Runner 的显式绑定。
  • CLI 模拟器的 install / launch / shot 不需要 WDA。shot 从显式 simulator UUID 写入本次独占的临时 PNG,读取并校验头部和尺寸后清理;它不依赖部分 simctl 版本行为不一致的 - stdout 输出,不选择 booted 默认设备,也不会启动或查询共享 WDA。尺寸/元素读取与点击等 UI 控制需要 --simulator-wda-config;缺失或身份不符时直接失败。Windows 应通过 SSH 在 Mac 上运行 CLI,工具没有内置远程 simctl 传输。
  • MCP 的设备发现隔离不同驱动的失败;Android / HarmonyOS / iOS 真机的原生操作不要求先安装模拟器用的 mobilecli。MCP 录屏和崩溃报告仍使用 mobilecli,HarmonyOS 不支持这些工具。
  • CLI iOS 不支持 connect、wake、power-state、keep-awake、文件传输和录屏。WDA 按键仅支持 HOME、VOLUME_UP、VOLUME_DOWN、ENTER,不能照搬 Android 的 BACK。CLI 与 MCP 的模拟器驱动分别为 Simctl / WDA 与 mobilecli / agent。

从源码安装

使用 Node.js 22 或更高版本以及 npm。各平台工具需要另行准备,不随此仓库自动完成设备授权、WDA 签名或 Xcode 配置。

git clone https://github.com/xue-ding-e/mobile-cli-allinone.git
cd mobile-cli-allinone
npm ci
npm run build
node lib/cli.js help

以上是本仓库源码安装方式,不假定 npm 包已经发布。修改 TypeScript 源码后重新执行 npm run build。

构建后也可把本地 checkout 安装到一个独立目录,使用新 CLI 别名(不修改全局安装):

npm install --prefix /path/to/local-install --ignore-scripts /path/to/mobile-cli-allinone
/path/to/local-install/node_modules/.bin/mobile-cli-allinone help

将路径替换成实际绝对路径;Windows 使用对应的 .cmd 垫片。此别名映射到 lib/cli.js;旧 mcp-server-mobile 仍映射到 lib/index.js。本地安装示例不表示新版已发布到 npm。

所有主机均可用 node lib/cli.js 启动 CLI。在 Windows PowerShell 中也可使用仓库垫片:

.\mobile.ps1 help
.\mobile.ps1 devices --all

CLI 的目标平台由驱动决定;能启动 Node.js 不代表主机具备目标平台的完整工具链。

平台前置条件

  • Android:安装 Android SDK Platform Tools,让 adb 可用,或设置 ANDROID_HOME 指向 SDK。手机开启调试并确认主机授权;模拟器先启动并确保出现在 adb devices 中。无线连接需要设备端预先配置,CLI 不代替配对和授权。
  • HarmonyOS:安装适合主机的 HDC。可通过 MOBILE_HDC_PATH 指定可执行文件完整路径;未设置时,Windows 会尝试 HiSuite 的固定路径,随后回退到 PATH 中的 hdc。设备需支持相应 UITest 等命令并已授权。USB 标识和无线 host:port 是独立连接目标。
  • iOS 真机:准备 go-ios,命令默认名为 ios,或以 GO_IOS_PATH 指定路径。先完成设备信任及所需开发配置、WDA 安装/运行、到本机 8100 的端口转发;iOS 17+ 还需运行 tunnel。程序检查这些前置状态,不会自动替你签名或部署 WDA。不同主机与 iOS 版本组合需自行验收。
  • iOS Simulator:需要 macOS、Xcode 和已启动(Booted)的模拟器。CLI 用 xcrun simctl 发现和管理应用,UI 操作还需预先建立并绑定独占 WDA Runner;CLI 不会启动、安装或签名 Runner。MCP 则使用 mobilewright 依赖提供的 mobilecli,可用 MOBILECLI_PATH 指定二进制路径,首次原生操作可能检测并安装模拟器 agent。不要将 mobilecli 的跨平台二进制名称理解为 Windows 可运行 iOS Simulator。

CLI 快速开始

示例中的设备 ID 和包名必须替换为自己的目标。建议先查看设备和界面,再执行会改变应用状态的命令。

node lib/cli.js devices --platform android --all
node lib/cli.js use ANDROID_SERIAL --platform android --pkg com.example.app
node lib/cli.js state
node lib/cli.js screen-size
node lib/cli.js elements
node lib/cli.js shot ./screen.png

capabilities --platform android|harmony|ios|ios-simulator 可查看各平台静态能力和依赖(命令中选择一个平台值);它不检查驱动安装、WDA 状态或设备是否就绪。

use 将默认设备、平台和包名写入当前用户的 ~/.mobile-cli/state.json。命令行 --device / --platform / --pkg 可以覆盖默认值;自动选取唯一在线设备也会更新状态。多设备操作应显式传参,运行前用 state 核对旧状态。

HarmonyOS 示例:

node lib/cli.js devices --platform harmony --all
node lib/cli.js use HDC_TARGET --platform harmony
node lib/cli.js elements
node lib/cli.js launch com.example.app --ability EntryAbility
node lib/cli.js tap-text "设置"
node lib/cli.js shot ./harmony-screen.png

已配置无线调试的 HDC 目标可使用 connect HOST:PORT --platform harmony。keep-awake 300、keep-awake restore 以及 file-send LOCAL REMOTE / file-recv REMOTE LOCAL 是 HarmonyOS 专用扩展;wake / power-state 同时支持 Android 和 HarmonyOS。文件发送和电源设置会修改目标设备。

iOS 真机示例(已完成 go-ios / WDA / tunnel 前置配置):

node lib/cli.js capabilities --platform ios
node lib/cli.js devices --platform ios
node lib/cli.js use IOS_UDID --platform ios
node lib/cli.js elements
node lib/cli.js shot ./ios-screen.png

iOS Simulator 示例(仅 macOS,已启动模拟器):

node lib/cli.js devices --platform ios-simulator --all
node lib/cli.js launch com.example.app --platform ios-simulator --device SIMULATOR_UUID
node lib/cli.js shot /absolute/screen.png --platform ios-simulator --device SIMULATOR_UUID
node lib/cli.js wda-status --platform ios-simulator --device SIMULATOR_UUID --simulator-wda-config /private/simulator-wda.json
node lib/cli.js eval "return await robot.getScreenSize()" --platform ios-simulator --device SIMULATOR_UUID --simulator-wda-config /private/simulator-wda.json

--all 可显示未启动的模拟器,不代表它可以立即执行操作。CLI 不会自动创建/启动模拟器,也不会创建 iOS 无线连接或部署 WDA。模拟器安装使用适配模拟器的 .app,也支持顶层包含 .app 的 .zip;不能将真机 IPA 当作模拟器应用通用安装。

Simulator 的独占 WDA 绑定

--simulator-wda-config 只接受显式 --platform ios-simulator --device <完整 UUID>。私有 JSON 的 schemaVersion 为 1,simulatorUuid 必须与命令一致,wdaOrigin 为独占数字 loopback HTTP origin,须显式端口且不能使用共享 8100。配置不写入全局默认,也不适用于物理 iOS 的 --ios-config。

runner 必填 bundleId(以 .xctrunner 结尾)、pid、processStart(实际 ps -p PID -o lstart=)、executableSha256、wdaProductBundleIdentifier 和 codeFiles。每项代码包含安装 bundle 内的 relativePath 与小写 sha256;应从本次独占构建枚举完整 Mach-O 清单并安装回读。至少包含 XCTest 主执行文件和 WebDriverAgentLib.framework/WebDriverAgentLib,两项还须提供实际加载的绝对 mappedPath。XCTest 可从该构建的 DerivedData 加载 framework,所以同时核对安装和实际映射的字节。不要把配置、运行路径或设备身份提交到公共源码。

每条 WDA HTTP 请求(包括 session 清理)前,CLI 使用 lsof 核对端口唯一 listener、ps 核对 PID/启动时间/执行文件,并把进程关联到指定 UUID 的 simctl get_app_container;随后核对安装代码与实际加载代码哈希。HTTP /status 的 ready、build product 与 /wda/device/info 的 isSimulator 仅作补充检查;device info 的 vendor UUID 不能当作 simulator UUID。任一检查失败均拒绝请求,不接管新 Runner、不自动恢复。

Simulator wda-status 包含上述本机取证以及 /status、/wda/device/info 两个只读请求;run/eval 的 robot.captureScreen() 在自己创建的一个 session 内读取尺寸与元素,PNG 仍走显式 UUID 的原生截图。坐标使用 WDA points,截图尺寸为像素。检查与 HTTP 之间不是原子绑定;静态回执、进程存活或一次 ready 均不能代替实际 UI 验证。

可选 iOS Wi-Fi CLI 配置

--ios-config 选择已经完成信任配对的 Wi-Fi 入口;不传该参数时仍保留原 go-ios / WDA 路径。该配置只用于 CLI,不改变 MCP 和 Simulator 的驱动。工具不会自动配对、生成配对记录、启动 WDA、构建或签名应用。

准备 Python 3.11 或更新版本,在所选 Python 环境安装可选依赖:

python -m pip install -r scripts/ios-wifi-bridge/requirements.txt

该入口固定依赖 pymobiledevice3 11.32.0,其许可证为 GPL-3.0-or-later;它是使用者单独安装的可选运行依赖,不属于本仓库 Apache-2.0 许可证覆盖的第三方代码。所附 Python 文件是调用该依赖的自研适配,不包含该依赖源码或设备配对数据。默认 go-ios 路径不要求安装此 Python 依赖。

在仓库外创建私有 JSON,例如 private-ios.json;下列全部为占位符,必须替换成自己的已配对设备和已运行 WDA 的地址:

{
  "device": {
    "udid": "YOUR_PAIRED_IPHONE_UDID",
    "wdaUrl": "http://YOUR_WDA_HOST:8100",
    "lastWifiHost": "YOUR_PAIRED_IPHONE_HOST"
  },
  "pythonRelative": "./YOUR_PYTHON_RUNTIME/python.exe"
}

pythonRelative 相对于该 JSON 所在目录解析;macOS/Linux 可使用自己的 Python 可执行文件路径。配对记录由使用者预先保存在所选运行用户的 ~/.pymobiledevice3/,不得提交 JSON、配对记录或 Python 环境。命令优先复用 JSON 同目录完整的 identity_probe.py / device.py / install_wifi.py 脚本组;缺少任一文件时统一使用仓库随附的 scripts/ios-wifi-bridge/,不混用两组脚本。脚本执行仍检查真实设备 UDID,不会退回 USB 或另一台手机。UI 前身份检查仅读取配对 TCP lockdown,不创建开发者隧道、RSD 或 XCTest 服务;应用启动和安装仍通过相应受控开发接口完成。

每条设备命令都显式传相同的 --device 和 --ios-config:

node lib/cli.js devices --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json
node lib/cli.js probe --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json
node lib/cli.js wda-status --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json
node lib/cli.js elements --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json
node lib/cli.js shot ./ios-screen.png --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json

可再传 --wda-url http://YOUR_WDA_HOST:8100 核对目标;它必须与私有 JSON 中配置的 HTTP(S) origin 完全相同,不接受另一个地址,也不接受凭据、路径、query 或 fragment。Wi-Fi 设备身份验证成功只证明认证传输可用,UI 操作还要求 WDA 就绪。

wda-status 在认证设备后仅执行一次只读 GET /status,输出实际 endpoint、HTTP 状态、原始响应(最多 64KiB,含 truncated 标记)、解析结果或错误、耗时及网络错误原因。HTTP 200 不等于就绪:当前只接受无 HTTP / WebDriver 协议错误且 value.ready === true 的响应,其余结果 ok: false 并返回失败退出码。大响应不重复输出完整 parsed JSON,错误文本同样限长。该命令不会创建 WDA session 或执行点击;连接错误不代表应用渲染或整个平台功能已验收失败。

批量读取 iOS 界面时,在 run / eval 中调用 await robot.captureScreen(),返回 {size, elements, screenshot},其中截图为 Buffer,应通过脚本的文件接口保存。三项读取使用本次创建的同一个 WDA session,按官方路由访问 source?format=json 和 screenshot,完成或失败后清理本次 session;不会接管已有 session。单独的 getScreenSize()、getElementsOnScreen()、getScreenshot() 仍可分别使用。共享 session 只约束读取的会话身份,不表示三次操作发生在同一绘制帧。

应用启动和安装示例:

node lib/cli.js launch com.example.app --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json
node lib/cli.js install /PRIVATE_PATH/App.ipa --pkg com.example.app --platform ios --device YOUR_PAIRED_IPHONE_UDID --ios-config /PRIVATE_PATH/private-ios.json

launch 使用显式 bundle ID,install 必须另传 --pkg。安装前读取 IPA 中唯一主 App 的 Info.plist,核对 bundle 与版本;安装后通过真实设备 lookup 再核对相同身份和版本,不能把设备上已有的另一应用或旧版本当作本次安装成功。Wi-Fi profile 的 apps、stop、uninstall 明确不支持;应用编译、签名和 WDA 部署由外部工具完成。本节描述接口和前置条件,不表示任何原始应用页面、设备型号或 GUI 交互已经通过验收。

一次脚本完成多个步骤

run <script.js> 执行脚本文件;eval "<js>" 执行内联脚本。两者注入 robot、device、platform、sleep、flows、wv,以及平台专用的 adb / hdc。robot 的接口定义见 src/robot.ts。

node lib/cli.js eval "return await robot.getScreenSize()"
node lib/cli.js run ./inspect.js --platform android --device ANDROID_SERIAL

inspect.js 示例(脚本体可直接 await / return):

const size = await robot.getScreenSize();
const elements = await robot.getElementsOnScreen();
return { device, platform, size, elements: elements.slice(0, 10) };

脚本默认超时为 120 秒,可用 --timeout 30 调整。超时不是事务回滚,也不保证撤销已开始的设备动作。run / eval 在本机 Node.js 进程执行,不是安全沙箱;只运行你已审查、信任的脚本。

普通结果输出紧凑 JSON;help 输出文本,失败诊断输出到 stderr。截图命令将图片写入指定文件;自行编写脚本时,应显式保存二进制结果,不要依赖 JSON 输出携带图片。

原生命令与 Android WebView

常用原生命令:apps、launch、stop、install、uninstall、tap、longpress、doubletap、tap-text、swipe、key、button、shot、elements、screen-size、orientation。命令能否执行以平台支持矩阵为准;完整参数见 help 和 src/cli.ts。

WebView 只连接目标 Android 应用中已开启调试的页面,不会自动开启应用调试:

node lib/cli.js wv-pages --platform android --device ANDROID_SERIAL --pkg com.example.app
node lib/cli.js wv-outline --platform android --device ANDROID_SERIAL --pkg com.example.app
node lib/cli.js wv-style body --props color,font-size --platform android --device ANDROID_SERIAL --pkg com.example.app
node lib/cli.js wv-eval "document.title" --platform android --device ANDROID_SERIAL --pkg com.example.app

另有 wv-tap-text、wv-shot、wv-net。单命令自动连接并断开,脚本中的 wv 延迟到首次使用时连接。页面 JavaScript 受设备 WebView 引擎版本限制;老引擎可能不支持可选链等语法。网络记录、DOM、截图可能包含敏感信息。

JSON 流程重放

流程是步骤数组,原生步骤复用当前平台的 Robot。下面只记录一条说明并截图:

[
  { "op": "log", "note": "Capture current screen" },
  { "op": "screenshot", "saveTo": "./screen.png" }
]

将其保存为 inspect.json 后:

node lib/cli.js flow-run ./inspect.json --platform harmony --device HDC_TARGET
node lib/cli.js flow-list
node lib/cli.js flow-save inspect ./inspect.json

默认在失败步骤停止;--keep-going 会继续后续步骤,可能继续产生副作用,不等于回滚。支持步骤与参数见 src/flows.ts,WebView 步骤与断言仅适用于 Android。

具名流程默认存于仓库 flows/,也可通过 MOBILEMCP_FLOWS_DIR 指向个人目录。个人回放、截图和现场脚本建议放入已忽略的 ignore/;不要把私有账号、业务内容或凭据提交到公共流程。

MCP:另一种调用入口

CLI 使用 lib/cli.js;MCP 使用 lib/index.js。两者不是同一启动命令。构建后,在 MCP 客户端配置中填入本机绝对路径:

{
  "mcpServers": {
    "mobile-cli-allinone": {
      "command": "node",
      "args": ["/absolute/path/to/mobile-cli-allinone/lib/index.js"],
      "env": {
        "MOBILEMCP_DISABLE_TELEMETRY": "1"
      }
    }
  }
}

Windows 路径可写成 D:/path/to/mobile-cli-allinone/lib/index.js。默认使用 stdio。客户端可从 mobile_list_available_devices 开始,再按工具列表调用原生操作、截图、Android WebView 或流程工具;不要假定 CLI 与 MCP 的命令和驱动完全相同:MCP 没有 CLI 的 run / eval 命令,也没有独立的 HDC 文件传输、电源管理命令;原生流程可调用已支持的平台 Robot,WebView 流程仅 Android。

可选 HTTP SSE 模式:

node lib/index.js --listen localhost:3000

端点为 http://localhost:3000/mcp;这是 SSE transport,不是 Streamable HTTP。默认监听 localhost,当前实现仅允许一个活动 SSE 客户端。设置 MOBILEMCP_AUTH 后,客户端必须发送相应的 Authorization: Bearer …。未设置时没有认证;不要直接暴露到公网,也不要将 token 写进命令示例或仓库。

MCP 服务保留上游 PostHog 使用统计逻辑;设置 MOBILEMCP_DISABLE_TELEMETRY=1 可关闭,上述配置已关闭统计。

安全与验证范围

  • 仅操作你有权控制的设备。安装/卸载、输入、点击、URL、脚本、流程和测试都可能改变应用状态、发送消息或触发交易;执行前核对设备、应用和步骤。
  • 此工具不代替使用者或调用它的 agent 做授权判断。MCP 客户端应限制不受信任内容触发设备操作。
  • 不提交设备截图、调试日志、令牌、签名文件或个人流程;调试工具及端口只开放给可信主机。更多见 SECURITY.md。
  • 平台矩阵表示源码具备的接入路径。自动化测试、构建成功不等于真机验证;设备型号、OS 版本、中文输入、权限弹窗、应用兼容层、WDA 签名/tunnel 和无线连接需要在自己的环境单独验收。

开发检查:

npm run build
npm run lint
npx tsc --noEmit
npm run test:offline

test:offline 先构建,再仅运行十二个指定文件:PNG、Harmony、ADB 安装结果、原 CLI iOS 路由、WDA 错误处理、MCP 平台路由,以及 Wi-Fi CLI 身份约束、WDA 诊断、本地子进程集成、纯 lockdown 身份、IPA 安装身份与模拟器原生截图测试。它们不发现或操作真实设备;HTTP 仅连接 loopback。子进程集成测试使用本机 Python 运行合成脚本,没有 Python 时明确跳过该项。不要在不了解测试内容时直接运行 npm test:默认套件包含 Android / iOS / 模拟器测试,可能读取或改变已连接设备,部分测试在收集阶段就调用平台工具。

问题反馈:Issues。请附提交版本、主机系统、目标平台及脱敏复现信息,区分“源码已实现”“模拟测试通过”和“真机已验证”。

许可与来源

本项目基于 Mobile Next 的 mobile-mcp 开发,保留 Apache-2.0 许可证和适用的原始版权声明,详见 LICENSE。CHANGELOG.md 中早于本分支的版本记录属于上游历史。Android DeviceKit、mobilewright 等依赖保留各自的名称和来源。

About

Mobile automation MCP and CLI with Android WebView CDP and reusable flow execution. Based on mobile-next/mobile-mcp.

Resources

Code of conduct

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages