- 人工智能
- AI Agent
- MCP 服务
- GUI 自动化
- 移动开发
- 测试
【免费下载链接】mobile-mcp
Model Context Protocol Server for Mobile Automation and Scraping (iOS, Android, Emulators, Simulators and Real Devices)
mobile-mcp是一个面向移动自动化与数据采集的 Model Context Protocol(MCP)Server,它让 LLM/Agent 通过统一的mobile_*工具集直接驱动 iOS/Android 模拟器、模拟器和真机。本篇文章以仓库中 test/prompt-android-emulator.md 这份**验收测试 Prompt(Acceptance Test Prompt)**为主体,逐行拆解它如何对一个 Android 模拟器上的完整用户旅程进行端到端验证,并对照 src/server.ts、src/mobile-device.ts、test/validate-response.js 等源码,说明每一步背后对应的 MCP 工具、底层调用链与 Agent 应遵循的操作范式。读完本文,你将掌握:如何读懂并复现这类"全流程 Agent 验收测试"、如何约定严格的 JSON 输出契约、以及如何用 accessibility-first 的思维方式在真实设备上完成"启动应用 → 断言前台 → 导航 → 输入 → 滑动 → 校验"的自动化闭环。
一、这份文档是什么:一份驱动 Agent 执行设备测试的验收 Prompt
test/prompt-android-emulator.md是一份完整的验收测试指令,它的读者不是人类工程师,而是一个正在接受测试的 AI Agent。其结构非常典型,分为两个部分:
- 输出契约(Output Contract):前 6 行严格规定了 Agent 的最终响应格式,要求返回一个 JSON 对象,包含
pass、error(可选)、steps三个字段,并且整段响应"只能"是该 JSON——不允许前置摘要、不允许后置评论、不允许 Markdown 代码围栏,要求响应的第一个字符是{,最后一个字符是}。 - 测试场景(
<test>块):第 8~31 行以命令式自然语言描述了 15 个环环相扣的验收步骤,覆盖设备唯一性断言、应用安装/启动/终止、前台应用断言、HOME 键导航、截图落盘与校验、屏幕元素断言、文本输入、滑动操作等。
这份文档与同目录的 test/prompt-ios-simulator.md 构成一对平台对称的验收用例:后者针对 iOS 模拟器(维基百科取词、备忘录 App 添加提醒、NASA 每日一图截图讲解),前者针对 Android 模拟器。二者共享完全相同的 JSON 输出契约,说明这是项目为"Agent 能否正确、稳定地操控移动设备"设计的一套可机检的自动化评估体系。
二、JSON 输出契约:为什么 Agent 的回答必须"只含一个 JSON"
文档前 6 行是整个测试能否被机器判定的基石。Agent 的最终响应必须满足:
- 顶层是一个 JSON 对象;
pass:布尔值,测试全部通过为true,失败为false;error:仅当失败时给出的人类可读问题描述;steps:字符串数组,记录 Agent 为达成任务所执行的每一步,并且必须在步骤中提及使用了哪些 MCP 工具。
这个契约并非空话,仓库里 test/validate-response.js 就是它的"裁判"。该脚本读取标准输入(fs.readFileSync(0, "utf8")),然后:
- 用
findMatchingBrace做带字符串转义感知的花括号配对,找出文本中所有候选 JSON 对象(test/validate-response.js); - 用
findLastJsonObject取最后一个能够成功解析的 JSON 对象——这样设计是因为"Agent 偶尔会把结论包在散文或代码围栏里",脚本会宽容地只取最后的合法 JSON(test/validate-response.js); - 最后校验
response.pass === true且steps是数组,否则以非零退出码报错(test/validate-response.js)。
从源码可见,"只输出 JSON"这条纪律是为了让验证逻辑足够简单、无歧义、可自动化,而宽容解析则是为了在实际运行中减少因格式小瑕疵导致的误判。这一点对任何想要构建"LLM 作为测试执行者"流水线的团队都有直接借鉴价值。
三、测试前置:为什么必须"只有一个 Android 模拟器"
测试第 1 步要求断言当前只连接了一个 Android 模拟器。这是一个环境不变量(environment invariant):后续所有操作都基于"唯一设备"这一前提,避免 Agent 因多设备而选错deviceId。
在 mobile-mcp 中,这一步对应mobile_list_available_devices工具。从 src/server.ts 起注册了该工具,其底层经由Mobilecli类的getDevices()执行mobilecli devices命令(src/mobilecli.ts),返回结构化的设备列表,其中每个设备包含id、name、platform(android/ios)、type(real/emulator/simulator)、version、state(online/offline)。getDevices还支持--platform、--type、--include-offline过滤参数,Agent 可以用它们精确筛选"唯一的、android、emulator、online"的设备。
与之呼应,仓库的 Playwright 设备测试在 test/android.ts 中做了完全相同的环境前置:AndroidDeviceManager.getConnectedDevices()得到设备列表,devices.length === 1才运行测试,否则test.skip跳过。这印证了"单设备前置"是 Android 设备自动化测试的一致约定。
四、应用管理链路:list → terminate → launch → foreground 断言
测试第 2~6 步构成一条完整的应用生命周期验证链:
- 列出已安装应用,断言
com.mobilenext.playground已安装; - 若该应用正在运行,先终止它;
- 启动
com.mobilenext.playground; - 断言该应用位于前台;
- 按 HOME 键;
- 断言它不再位于前台,而是回到了桌面启动器。
4.1 对应 MCP 工具
这条链路在 mobile-mcp 中一一对应四个工具:
| 测试步骤 | MCP 工具 | 参数 | 底层命令 |
|---|---|---|---|
| 列出已安装应用 | mobile_list_apps | device | apps list |
| 终止运行中的应用 | mobile_terminate_app | device,packageName | apps terminate |
| 启动应用 | mobile_launch_app | device,packageName,locale? | apps launch |
| 查询前台应用 | mobile_get_foreground_app | device | apps foreground |
其中mobile_launch_app支持可选locale参数(逗号分隔的 BCP 47 标签,如fr-FR,en-GB),用于以指定语言环境启动应用(src/server.ts)。
4.2 源码级验证
这些工具最终都由MobileDevice类(实现Robot接口)转发给 mobilecli 二进制:
listApps()调用mobilecli apps list --device <id>,并把响应中appName || packageName统一成InstalledApp(src/mobile-device.ts);launchApp()构造apps launch <package> [--locale <locale>](src/mobile-device.ts);terminateApp()构造apps terminate <package>(src/mobile-device.ts);getForegroundApp()解析apps foreground的 JSON 响应,返回packageName与appName(src/mobile-device.ts)。
MobileDevice.runCommand会把--device <deviceId>追加到每个命令尾部(src/mobile-device.ts),所以 MCP 工具层的device参数贯穿了所有调用。
HOME 键操作对应mobile_press_button工具,button支持BACK(仅 Android)、HOME、VOLUME_UP/DOWN、ENTER以及一组 Android TV 专用按键(src/server.ts),底层由pressButton()调用io button <button>(src/mobile-device.ts)。
同源测试 test/android.ts 也做了同样的 launch/terminate 断言:launchApp("com.android.chrome")后listRunningProcesses()应包含该包名,terminateApp后应不再包含。这证明"启动 → 校验进程存在 → 终止 → 校验进程消失"是仓库自带的官方验证范式。
五、截图链路:落盘、PNG 有效性、分辨率与文件体积校验
测试第 7~9 步要求:
- 再次启动应用并保存截图到
delete-me.png; - 断言
delete-me.png在本地磁盘上创建成功,且是合法的 PNG,尺寸至少 512×512 像素、体积至少 50KB; - 删除
delete-me.png。
5.1 工具与参数
- 落盘截图对应
mobile_save_screenshot,核心参数:saveTo(必须以.png、.jpg或.jpeg结尾)、maxSize(最长边像素上限,等比缩放)、scale(0.0~1.0 缩放系数,与maxSize互斥,maxSize优先)。saveTo的扩展名决定了输出格式:.png输出 PNG,其余输出 JPEG(src/server.ts)。调用前会经validateFileExtension与validateOutputPath双重校验(src/server.ts)。 - 内存截图对应
mobile_take_screenshot,它默认以 JPEG(质量 75)返回,默认maxSize为 1024(DEFAULT_SCREENSHOT_MAX_SIZE,src/server.ts),并会额外返回一段"截图尺寸 → 屏幕坐标"的映射说明文本,帮助 Agent 把截图里看到的坐标换算成可点击的屏幕坐标(src/server.ts)。
5.2 底层实现
MobileDevice.getScreenshot()构造mobilecli screenshot --device <id> --format <fmt> --output -,支持--quality(JPEG 质量)、--max-size、--scale,通过executeCommandBuffer以 Buffer 方式接收二进制数据(src/mobile-device.ts,src/mobilecli.ts)。
PNG 合法性校验在本仓库中有专门实现:测试 test/android.ts 用new PNG(screenshot)解析截图,断言其getDimensions()恰好等于getScreenSize()返回的屏幕尺寸——即截图必须是"合法且与屏幕同尺寸"的 PNG。仓库根目录还有对应的 src/png.ts 与 src/jpeg.ts 模块,分别负责 PNG 尺寸解析与 JPEG 尺寸解析,正是mobile_take_screenshot校验返回图片尺寸的依据(src/server.ts)。
对于"删除文件"这类本地文件操作,MCP 工具集没有提供专门的删除工具,Agent 通常通过宿主环境的文件系统能力完成,这与文档中"delete-me.png 是临时产物、测试后应清理"的意图一致。
六、视觉断言:用截图确认"一红一绿两部手机"的界面
测试第 10 步要求截取一张截图,并断言屏幕顶部有一张"看起来像两部手机、一红一绿"的图片。这是典型的"视觉内容断言"场景——普通的 accessibility tree 无法表达图片的视觉语义(颜色、图形),必须回退到mobile_take_screenshot。
仓库 skills/mobile-automation/SKILL.md 对这一点有明确指引:
优先调用
mobile_list_elements_on_screen(返回带标签与坐标的 accessibility tree,更快、更便宜、更可靠);只有当元素缺失或需要视觉确认(游戏、Canvas 绘制的 UI、图片内容)时才回退到mobile_take_screenshot。
这与 README 中"Accessibility-first——从原生 accessibility tree 驱动应用,无视觉模型、无图像 token,仅在必要时回退截图+坐标"的设计哲学完全一致(README.md)。因此第 10 步恰好示范了"何时必须用视觉而非结构"的边界条件:涉及图片色彩与形状的内容,mobile_list_elements_on_screen无法回答,Agent 必须读取截图并描述画面。
七、元素交互链路:Basic UI、Toggle、BACK 导航与输入框
测试第 11~15 步是最核心的 UI 交互验证:
- 点击Basic UI按钮,断言屏幕上出现名为Toggle的元素;
- 按 BACK 返回主菜单,再次点击Basic UI;
- 断言可见:标签为Text Field的文本输入框、Password密码框、Multiline text多行文本框;
- 点击第一个文本输入框并输入Hello World,重新列出元素并断言输入已生效;
- 向上滑动,断言Text Field不再可见,但出现了一个日期选择器(date selector)。
7.1 工具映射
| 测试步骤 | MCP 工具 | 关键参数 |
|---|---|---|
| 点击 Basic UI | mobile_click_on_screen_at_coordinates | x,y或ref |
| 断言元素存在 | mobile_list_elements_on_screen | format(text/json) |
| 按 BACK | mobile_press_button | button: "BACK" |
| 输入文字 | mobile_type_keys | text,submit |
| 向上滑动 | mobile_swipe_on_screen | direction: "up", 可选x/y/distance |
7.2 点击:ref 优先于坐标
mobile_click_on_screen_at_coordinates支持两种目标:元素 ref(来自最近一次mobile_list_elements_on_screen,形如@e5)或绝对坐标x/y。文档语义上ref优先于坐标——传入ref时直接调用tapByRef,否则要求x、y必须同时提供(src/server.ts)。底层tap()会把坐标Math.round成整数,因为 mobilecli 拒绝小数坐标(src/mobile-device.ts)。SKILL.md 还专门提醒:点击元素包围盒的中心,而不是左上角(skills/mobile-automation/SKILL.md)。
7.3 元素列表与断言
mobile_list_elements_on_screen返回带ref、坐标、显示文本或无障碍标签的元素列表,format参数支持 text(默认,每元素一行紧凑输出)与 json 两种格式(src/server.ts)。底层getElementsOnScreen()解析mobilecli dump ui的 JSON,并通过flattenUIElement把嵌套的 accessibility tree递归扁平化为平面元素数组(src/mobile-device.ts,src/mobile-device.ts)。每个ScreenElement携带type、label、text、name、value、identifier、rect、ref、focused、selected、checked、enabled等字段,足以为"标签为 Text Field / Password / Multiline text 的输入框"这类断言提供结构化依据。
注意工具描述中的一条纪律:"ref 与坐标只要屏幕不变就保持有效;仅在导航或布局变化后重新列出元素"(src/server.ts)。这正好对应第 11 步"点击 Basic UI 后必须重新 list 元素才能断言 Toggle"的流程——每次界面变化后都要刷新元素快照。
7.4 文本输入:先聚焦,再输入,后验证
第 14 步"点击第一个文本输入框 → 输入 Hello World → 重新列出元素断言已输入"完整遵循了 SKILL.md 的输入范式:先点击输入框、确认其获得焦点,再mobile_type_keys(skills/mobile-automation/SKILL.md)。mobile_type_keys的text参数传入待输入文本,submit为布尔值,置true时输入后自动追加 ENTER 键(src/server.ts)。输入框元素本身带有focused字段,可用于确认焦点状态。
7.5 滑动与"元素不再可见"的断言
第 15 步要求向上滑动后Text Field 不再可见、取而代之出现日期选择器。mobile_swipe_on_screen的direction支持up/down/left/right;若不传起点坐标则默认从屏幕中心开始,distance默认为 400 像素(iOS)或屏幕短边的 30%(Android)(src/server.ts)。底层MobileDevice.swipe()以屏幕中心为中点、400 像素为默认距离计算起止点并调用io swipe x1,y1,x2,y2(src/mobile-device.ts);带起点的swipeFromCoordinate()则从给定坐标沿方向移动指定距离(src/mobile-device.ts)。
"向上滑动 → 断言旧元素消失、新元素出现"是一个经典的滚动校验模式:Agent 必须在滑动后再次mobile_list_elements_on_screen,通过重新抓取元素快照来证明界面确实发生了变化——这正是 SKILL.md 强调的"每次操作后都要验证"(Verify after every action)原则:移动端 UI 有动画,期望元素未出现时应短暂等待再检查,而不是盲目点击(skills/mobile-automation/SKILL.md)。
八、批量编排:mobile_batch_commands 与多步流程加速
值得注意的是,本仓库为"填表、多步流程"提供了专门的批量工具mobile_batch_commands:一次调用内按顺序执行多个工具(如 click、type、click、type),steps数组中每个元素包含name与arguments;device参数自动应用到每个步骤(除非该步骤自带);stopOnError默认true(失败即停);listElementsAtEnd可在最后自动追加一次元素列举并附上结果(src/server.ts)。
从实现看,批量执行直接调用注册在toolCallbacksMap 里的回调函数,绕过 MCP 传输层(src/server.ts),并且禁止嵌套mobile_batch_commands、禁止在批量内使用mobile_take_screenshot(因为它的返回是图片,无法在批量文本输出中呈现,须改用mobile_save_screenshot,src/server.ts)。这套设计在验收测试文档所描述的场景中非常实用——例如第 11~15 步的"点击 → 断言 → 返回 → 点击 → 输入"序列,Agent 完全可以在条件允许时用一次mobile_batch_commands完成编排,再单独用listElementsAtEnd: true拿到最终界面快照。
九、在本地复现与运行:测试基础设施
虽然test/prompt-android-emulator.md是给 Agent 的 Prompt,但仓库提供了完整的本地测试骨架,帮助你理解这套验收测试的运行环境:
- playwright.config.ts 把 Playwright 仅用作测试运行器(不启动浏览器),
testDir指向./test、testMatch: "*.ts",workers: 1且fullyParallel: false——因为设备测试会真实改变设备状态,必须串行执行;timeout: 60_000是因为设备操作包含多处数秒等待(playwright.config.ts)。 - test/android.ts 是同一能力的 Playwright 断言实现:屏幕尺寸、截图 PNG 校验、列应用、打开 URL、列元素、sendKeys 与 tap、启动/终止、横竖屏切换,均要求恰好一台 Android 设备(
test.skip(!hasOneAndroidDevice, ...))。 - test/validate-response.js 负责对 Agent 的 JSON 响应做机检。
对照可见:文档描述的验收流程与test/android.ts的测试矩阵高度同构——getScreenSize/getScreenshot/listApps/getElementsOnScreen/sendKeys/tap/launchApp/terminateApp正是验收 Prompt 每一步所依赖的能力。换句话说,这份 Prompt 是"用自然语言包装起来的、由 LLM 驱动的端到端测试",而 Playwright 测试是"同一份验收标准的过程式实现",两者互为镜像。
十、对 Agent 开发者的实战启示
综合全文,从这份验收测试文档中可以提炼出在移动自动化 Agent 开发中直接可复用的四条规范:
- 输出契约先行:凡是"Agent 作为测试执行者"的场景,都应像本文档一样先定义严格的 JSON 契约(
pass/error/steps),并配套 test/validate-response.js 这类宽容但严谨的解析校验器,做到"失败可定位、步骤可追溯"。 - 环境不变量前置:所有操作开始前先断言设备唯一性(
mobile_list_available_devices),从根源上消除多设备歧义;这与 test/android.ts 的devices.length === 1检查一致。 - Accessibility-first,视觉兜底:默认用
mobile_list_elements_on_screen获取结构化的 accessibility tree(带 ref 与坐标),只有遇到图片色彩/形状等结构无法表达的内容(如"一红一绿两部手机")才切换mobile_take_screenshot。 - 操作后必验证:每一次点击、滑动、输入之后都要重新 list 元素或截图,确认界面如预期变化后再进入下一步;App 生命周期操作(launch/terminate/前台断言/HOME 返回)要与 UI 断言穿插进行,构成完整的闭环。
这份验收测试文档本身就是移动自动化 Agent 能力的一次"全链路体检",而 mobile-mcp 的工具集与源码让这份体检的每一个环节都有了可查证、可复现的实现支撑。
- 人工智能
- AI Agent
- MCP 服务
- GUI 自动化
- 移动开发
- 测试
【免费下载链接】mobile-mcp
Model Context Protocol Server for Mobile Automation and Scraping (iOS, Android, Emulators, Simulators and Real Devices)
相关推荐
Baserow MCP 端点手动测试全指南:从连接客户端到验证工具清单
Baserow MCP 端点手动测试全指南:从连接客户端到验证工具清单 Baserow 通过 Model Context Protocol(MCP)向 Clau
后端前端数据库低代码工作流自动化浏览器自动化测试革命:AI驱动的一站式端到端验证平台
浏览器自动化测试革命:AI驱动的一站式端到端验证平台 还在为繁琐的浏览器测试而烦恼?每次发布前都要手动检查性能、SEO、可访问性?browser tools m
人工智能AI Agent浏览器控制开发工具最完整MCP客户端测试指南:从手动验证到自动化全流程实践
最完整MCP客户端测试指南:从手动验证到自动化全流程实践 你还在为MCP客户端测试效率低下而烦恼?本文将系统介绍MCP(Model Context Protoc
教程文档人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考