mcpField
C
crewdroid

crewdroid

本地服务
github.com/namyunsu开发工具01 天前更新

关于 crewdroid

crewdroid 是面向开发者和 AI Agent 的无界面 Android 设备实验室,可在多个模拟器上测试应用。它在不同网络和时序条件下运行流程,并检查服务端数据中的并发错误;CLI 命令也可作为 MCP 工具和 Agent 技能使用。

主要功能

  1. 01启动多种配置的 Android 模拟器集群
  2. 02设置各设备的网络状态
  3. 03重放多设备场景
  4. 04检查服务端数据中的并发错误
  5. 05查看屏幕与 Android 诊断信息
  6. 06将 CLI 命令作为 MCP 工具提供

适用场景

  1. 01在重试时复现重复或丢失的上传
  2. 02测试网络中断期间的应用流程
  3. 03检查并发编辑导致的更新丢失
  4. 04跨 Android 版本和屏幕排查崩溃

MCP 相关

stdio MCP 服务暴露与 CLI 相同的功能,包括设备管理、场景运行、诊断和判定。它还提供包含命令步骤的 Agent 技能。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"namyunsu-crewdroid": {
"command": "npx",
"args": [
"-y",
"crewdroid"
]
}
}
}
启动命令npx -y crewdroid

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmcrewdroid0.2.0

工具

14

收录的工具列表 · 更新于 今天

此工具无需参数。

详细介绍

crewdroid

npm MCP Registry license

面向 AI Agent 的无头 Android 设备实验室。 通过一条命令启动一组不同型号的 Galaxy 模拟器,按各自的计划切断每台设备的网络,以不同时间安排重放相同的用户流程,然后检查服务端数据,判断是否存在并发错误——记录重复、缺失或被覆盖。没有窗口,也无需点击:每一步都是带有 --json 和退出码的 CLI 命令;这些命令同时也是 MCP 工具和 Agent 技能。

npx crewdroid up --count 3        # 3 devices: s24ultra/API 34, fold5/API 34, flip7/API 36 — booted in ~7 s each
npx crewdroid run scenarios/photo-upload.json --seed 1   # multi-user flow + network chaos + judge, exit 1 on a bug

3 台模拟的 Galaxy 设备(不同屏幕和 Android 版本)并排运行相同的离线优先流程

为什么不直接使用 Android Emulator?

原生模拟器是一部带窗口、由人工操作的手机。crewdroid 是由程序驱动的设备群。

Android Emulator / AVD Managercrewdroid
设备一个 AVD 对应一个窗口和一个磁盘映像基于同一基础映像创建 N 个只读克隆,支持不同屏幕(S/Fold/Flip/任意 WxH@dpi)和 API 级别,一条命令即可启动
交互在窗口中点击,读取屏幕截图每条命令都提供 --json 输出和退出码;screen 返回无障碍树,而非像素
启动冷启动需 31.6 秒从精简快照启动需 6.7 秒
磁盘24.7 GiB(3 个 AVD)6.99 GiB(3 个克隆,3 个 API 级别)
主机 RAM8.45 GB3.93 GB
空闲 CPU(100 % = 1 个核心)1000 %~600 %
网络Extended Controls 中的一个开关每台设备可按随机计划启用 airplane、nodata、slow、flaky,也可在上传过程中启用
多用户错误不支持run 在每台设备上以不同时间安排重复运行一个流程,然后由 judge 检查服务端数据:unique、count、noLostUpdate
设备状态GUI 面板env(GPS、电池、旋转、深色模式、字体、区域设置、GSM、SMS、通话)和 app(权限、深层链接、Doze、内存修剪、存储空间已满)——每个设置器都会读取回当前状态
折叠屏 / 翻盖屏需要折叠屏 AVD在任意克隆上使用 fold / unfold:应用会收到真正的配置变更
面向 AI Agent无可调用内容MCP 服务、AGENTS.md、7 个根据症状触发的技能(“应用崩溃”“深层链接无法打开”“同步重复创建了一行”)

数据在一台 Windows 11 PC(Ryzen 7 5700X、64 GB、WHPX)上测得,使用 3 台设备,并与 3 个原生 google_apis AVD 对比。原始 JSON 和测量方法见 docs/measurements/。

按设计,这里没有同步屏障。真正的并发错误来自重试、离线队列和延迟编辑相互重叠——而不是在完全相同的毫秒按下按钮。crewdroid 为每台设备设置不同的延迟和网络计划,让操作自然重叠,然后从服务端读取真实数据(ADR 0002)。

60 秒快速体验

启动一组不同型号的设备(无头运行,屏幕上不会出现任何内容):

$ crewdroid up --count 3 --json
[
  { "serial": "emulator-5580", "profile": "s24ultra",   "api": 34, "screen": "1080x2340@450", "bootSeconds": 6.4, "readySeconds": 42.1 },
  { "serial": "emulator-5582", "profile": "fold5-main", "api": 34, "screen": "1812x2176@420", "bootSeconds": 6.7, "readySeconds": 41.8 },
  { "serial": "emulator-5584", "profile": "flip7-main", "api": 36, "screen": "1080x2520@480", "bootSeconds": 3.1, "readySeconds": 39.9 }
]

在上传过程中切断一台设备的数据连接,并让另一台设备进入不稳定网络状态:

$ crewdroid net emulator-5580 nodata
$ crewdroid net emulator-5582 flaky

针对存在竞争条件的服务端运行多用户场景(在捆绑的示例服务端中设置 BUGGY=1),并查看判定结果:

$ crewdroid run scenarios/photo-upload.json --seed 1
...
VIOLATION uploads unique(key): duplicate key="u13-1" (2 rows)
VIOLATION uploads count(acks): missing 1 of 48 expected key values
VIOLATION writes noLostUpdate(id,baseVersion): lost update: 3 writes to id="r2" all based on baseVersion=4; all but one were overwritten
FAIL: 5 violations            # exit code 1

对修复后的服务端运行相同场景 → OK: 3 rules, 0 violations,退出码为 0。判定规则是一个 JSON 文件,因此同样的检查也可以用于你自己的 API 导出数据。

无需截图,直接询问屏幕上显示了什么:

$ crewdroid screen emulator-5580 --json
{ "focused": "dev.crewdroid.probe/.ProbeActivity",
  "tree": [ { "cls": "TextView", "text": "outbox: 1 pending", "bounds": [32,180,620,230], "clickable": false, "depth": 3 }, ... ] }

专为 Agent 构建

  • 每条命令都可由机器读取:--json;失败时返回非零退出码;每次设置后都会读回;输入无效时,在任何 adb 调用前清晰报错。
  • MCP 服务:crewdroid mcp 通过 stdio 暴露 devices、up、down、net、env、app、fold、triage、screen、perf、apk、judge、hammer、run——与 CLI 调用的是同一组函数,没有第二套实现。
  • 技能位于 .agents/skills/(由 Claude Code、Cursor、Gemini CLI、Copilot、Codex 读取):crewdroid、android-triage、android-screen、android-permissions-intents、android-apk、android-perf、android-offline-concurrency。每项都是一份简短操作指南,包含 Agent 可根据其输出采取行动的精确命令。
  • AGENTS.md 包含 Agent 必须遵守的规则(adb 只能针对 emulator-<port> 执行;一次只运行一个任务;绝不使用屏障),另有供 Claude Code 使用的 CLAUDE.md。
  • 适用于共享机器:绝不会触碰连接到同一台 PC 的 USB 手机;克隆实例为只读;down 只会终止 crew-*。
{ "mcpServers": { "crewdroid": { "command": "npx", "args": ["-y", "crewdroid", "mcp"] } } }
claude plugin marketplace add namyunsu/crewdroid && claude plugin install crewdroid@crewdroid

Cursor:安装 MCP 服务 · Codex / Gemini CLI / Copilot:技能和 AGENTS.md 会从仓库中自动读取。

可发现的问题

Bug 类别crewdroid 如何复现捕获问题的规则
重试后重复上传(缺少幂等性)flaky 网络会丢弃响应,应用的发件箱会使用相同的密钥重试unique(key)
记录丢失(重启 / 飞行模式时发件箱数据丢失)保存期间启用 airplane,应用离线重启,然后重新连接count(acks)
更新丢失(两位用户编辑同一行,最后写入者胜出)设备在不同时间读取同一版本,然后都执行 PUTnoLostUpdate(id,baseVersion)
上传期间折叠发件箱排空期间执行 fold / unfold:应用必须在配置更改后正常运行,且只上传一次unique + count
仅在某个 Android 版本或屏幕上发生崩溃 / ANR一次运行中混合使用 API 31/34/36 和 S/Fold/Flip 配置;triage 会读取崩溃缓冲区、ANR 和退出原因—

捆绑的示例应用(Kotlin、离线发件箱,probe-app/)和示例服务(sample/server/,通过 BUGGY=1 开关控制)让上表中的每个问题都能在笔记本电脑上复现。

要求

  • Android SDK,包含命令行工具和版本不低于 36.4 的模拟器(ANDROID_SDK_ROOT 或 ANDROID_HOME 必须指向该 SDK,或必须存在 ~/.crewdroid/android-sdk)。尚未安装 SDK?运行 npx crewdroid setup --yes,即可安装 JDK 17(仅供 sdkmanager 使用)、命令行工具、platform-tools、模拟器和 google_atd 镜像(--images 34,31,36,--dry-run 会先列出大小);crewdroid 会下载主机 CPU 所需的 google_atd 镜像(x86_64,或 Apple Silicon / ARM Linux 上的 arm64-v8a;API 31/34/36,每个约 0.9 GB),并使用 slim 缩减镜像
  • Node >= 22
  • Windows 10/11 x64、Apple Silicon 上的 macOS,或 Linux x64/arm64
  • 硬件加速:WHPX(Windows)、Hypervisor.framework(macOS)或 KVM(Linux,/dev/kvm);setup 会报告 emulator -accel-check 的结果
  • macOS/Linux:slim 会跳过 NTFS 稀疏化 / 压缩步骤(快照清零和过期覆盖层清理仍会执行);RAM 数值为进程 RSS(共享页面不会拆分)

命令

每个命令都接受 --json,失败时以非零状态码退出。

命令功能
crewdroid up --count N [--profiles a,b] [--screen WxH[@dpi],...] [--profiles-file f.json]启动 N 台模拟器,使用 Galaxy 配置或自定义屏幕(任意尺寸,例如 --screen 3840x2160@320)
crewdroid down关闭所有 crew-* 模拟器
crewdroid net <serial> airplane|nodata|slow|flaky|online设置一台设备的网络状态
crewdroid fold <serial> / unfold <serial>在 Fold/Flip 配置上切换封面屏和主屏
crewdroid run <scenario.json> [--seed N]运行多设备场景,然后检查服务端数据
crewdroid judge --rules <file> --source <url|file>检查 unique / count / noLostUpdate 规则
crewdroid hammer --url <base>无需设备即可对服务端施加并发负载
crewdroid slim / prepare / identity缩减磁盘占用、构建基础 AVD、使设备各不相同
crewdroid measure --up N测量磁盘、RAM、启动时间和空闲 CPU
crewdroid triage / screen / perf / apkAndroid 诊断,见下文
crewdroid env <serial> <what> [args]设备环境:位置、电池、旋转、深色模式、字体、区域设置、移动网络、SMS、通话(见 Environment)
crewdroid app <serial> <pkg> <what> [args]应用控制:权限、深层链接 / App Links、清除数据、备份 / 恢复、资源压力(见 App control)
crewdroid shot / tap / type / swipe / key无需 mobile-mcp 即可截图和输入(见 Screenshots and input)
crewdroid mcp通过 stdio MCP 服务向 Agent 提供上述功能

截图和输入

命令功能
crewdroid shot <serial> [file.png]将 exec-out screencap -p 输出到 file.png(默认 ./crewdroid-<serial>-<yyyymmdd-HHMMSS>.png);打印路径、宽 x 高和 blackRelaunch(先恢复 API 31 黑屏,与 screen 相同)。MCP 工具会将 PNG 作为图像内容返回,并附带一行文本。
crewdroid tap <serial> <x> <y> | --text <T> | --id <resource-id> [--index N]在指定坐标点击,或点击 screen 树中与文本 / content-desc 或 resource-id(完整匹配或匹配 :id/ 后的部分)相符元素的中心:先精确匹配,再进行不区分大小写的包含匹配。没有匹配项,或未指定 --index(从 0 开始)但存在多个匹配项时,以状态码 1 退出并列出候选项(文本、id、边界)。
crewdroid type <serial> <text> [--into <text|id>]执行 input text(空格、引号、&、% 会进行转义);--into 会先点击字段。仅支持 ASCII,见下文。
crewdroid swipe <serial> up|down|left|right [--times N] | swipe <serial> x1 y1 x2 y2 [ms]沿当前屏幕中央 50 % 区域的指定方向滑动(up 会向下滚动内容)。
crewdroid key <serial> back|home|enter|delete|tab|menu|KEYCODE_*执行 input keyevent;随后打印当前聚焦的窗口。

屏幕范围之外的坐标会在发送任何内容之前以状态码 1 退出。不会输入非 ASCII 文本(例如韩文):type 会以状态码 1 退出并说明原因。input text 只能输入设备键盘映射中的字符;ATD 没有可用于设置剪贴板以便粘贴的 shell 命令(cmd clipboard 尚未实现),而 crewdroid 不会安装键盘应用;请通过你的应用传入此类文本(intent extra、测试钩子),或自行安装 ADBKeyboard 等 IME。探测应用提供了相应表单:--es check form(字段 id 为 name,按钮 Send -> CrewProbe FORM <text>;包含 3 个屏幕的滚动内容,其底部的 END 会记录 CrewProbe SCROLL END)。node scripts/check-input.mjs 会在 API 34 和 API 36 设备上运行所有这些测试。

诊断

只读命令(不会在设备上持续运行)。每条命令都支持 --json;这四条命令也都是 MCP 工具。

命令输出
crewdroid triage <serial> [--app <pkg>] [--heap out.hprof]crashes(logcat 崩溃缓冲区:包名、异常、应用中的顶部堆栈帧、时间)、anrs(ActivityManager 日志 + dumpsys activity exit-info)、anrTraces(/data/anr 标头,未获取 root 权限时为 "unreadable")、exits(退出原因)、recentLog(应用最近 200 行日志)、summary。--heap 会运行 am dumpheap 并拉取 hprof 文件。
crewdroid screen <serial> [--png file]当前焦点窗口(dumpsys window)和精简的 uiautomator 树 [{cls, text, desc, id, bounds, clickable, depth}]。仅当 testTagsAsResourceId = true 时,Compose testTag 才会显示为 id。在 API 31 上,如果应用重新启动后留下全黑屏幕(Android 12 模拟器缺陷,任何工具的 am start -S 都会触发),会先恢复屏幕(HOME + 恢复应用),并报告为 blackRelaunch,因此不会误判为应用缺陷。
crewdroid perf <serial> <pkg> [--activity .Main] [-- <am start extras>]冷启动(am force-stop、2 秒、am start -W;TotalTime 毫秒)、来自 dumpsys gfxinfo 的帧数 / 卡顿率 / p50-p90-p99,以及来自 dumpsys meminfo 的 PSS 总量 / Java / native 内存(KB)。ATD 镜像没有 GPU:请比较不同运行之间的帧数,不要与手机比较。
crewdroid apk <file.apk>仅在主机上运行(使用最新 build-tools 中的 aapt2):包名、版本、最低 / 目标 SDK、权限、导出的 Activity、深层链接过滤器。

探测应用提供了这些目标:adb -s emulator-5580 shell am start -n dev.crewdroid.probe/.ProbeActivity --es check crash|anr|jank(anr:点击按钮,然后在 10 秒内再次点击)。node scripts/check-triage.mjs 会在一台 API 34 设备上运行全部四项检查。

环境

crewdroid env <serial> <what> [args] [--json]。每个设置器都会回读状态;如果状态不符,会显示消息并以状态码 1 退出;无效值(battery 150、rotate 9、不是 emulator-<port> 格式的 serial)会在调用 adb 前以状态码 1 退出。另有一个 MCP 工具(env)。

What含义
geo <lon> <lat> [alt]GPS 定位(先经度)并开启位置服务。只有应用请求位置信息时,Android 才会收到定位结果,因此设置器无法因状态不符而失败:它只检查位置服务是否开启,并报告 Android 上次看到的定位结果(androidLastFix、delivered)。只有探测器的 ENV loc= 行(check=env)才能确认定位结果
`battery <0-100> [acunplugged]`
rotate <0-3>关闭自动旋转,固定旋转方向
sensor acceleration x:y:z加速度计数值
`dark onoff/font `
locale <pkg> <tags>应用级语言区域设置,例如 locale dev.crewdroid.probe ko-KR,en;仅适用于 API 33+(没有用于设置设备全局语言区域的 shell 命令)
`gsm data homeroaming
gsm signal <0-31> [--hold <sec>]信号强度;控制台会保持 15 s,--hold 会每隔 10 s 重新发送一次。没有回读机制(仅控制台确认)
sms <from> <text> / `call [acceptcancel]`
show回读设备上的上述所有状态

rotate 还会运行 wm fixed-to-user-rotation enabled:如果不这样做,在 API 36 镜像上,WindowManager 会在下次启动应用时恢复之前的旋转方向(revertOverride)。rotate 和 show 会从设置和 WindowManager 回读锁定状态。只有控制台返回 OK 才能确认 gsm signal(没有回读机制)。支持负数(env emulator-5580 geo -122.084 37.422)。ATD 没有 Messages 或 Dialer 应用:短信和电话只会更改电话状态并发送广播。探测器应用会记录它看到的内容:am start -n dev.crewdroid.probe/.ProbeActivity --es check env -> CrewProbe ENV dark=<bool> font=<scale> rot=<n> battery=<pct> loc=<lat>,<lon>|none(loc 需要位置权限:pm grant)。node scripts/check-env.mjs 会在 2 台设备上运行所有这些检查。

应用控制

crewdroid app <serial> <pkg> <what> [args] [--json]。设置操作会读回状态;如果状态不符,则显示消息并以状态码 1 退出。名称、分组或尺寸无效时,会在执行任何 adb 调用前以状态码 1 退出。也提供 MCP 工具(app)。

项目含义
`perm grantrevoke <perm…>/perm show [perm…]`
open <uri> [--pkg]am start -a VIEW -c BROWSABLE -d <uri>(--pkg:仅限此应用包)。没有应用能处理该 URI 时,以状态码 1 退出并显示 No Activity found(ATD 没有 Chrome)。运行中的应用只会将其任务调到前台,不会收到 URI:结果会显示 delivered: false;请先强制停止该应用
links show / links force <domain> / links resetApp Links(API 31+):pm get-app-links;set-app-links --package <pkg> 2 <domain>(无需联网即可批准);... 0 all
clearpm clear;使用 run-as 读回(适用于可调试应用),否则只能读取 pm 返回的 Success
backup / restore使用 com.android.localtransport/.LocalTransport 执行 bmgr(API 34 和 36 镜像中提供;若缺失,则以状态码 1 退出并说明原因)。传输服务会拒绝备份没有数据的应用。restore 使用最新的备份集
pressure doze / `standby <activeworking_set
pressure trim <level>am send-trim-memory(从 HIDDEN 到 COMPLETE)。设备上无法读回:只能读取 am 的确认信息。向前台进程设置后台级别,或目标进程未运行时,都会报错。探测程序会记录 CrewProbe TRIM <level>
pressure reset撤销 doze、电池拔出、待机分组(-> active)、bg-restrict 和 battery-saver
fill-storage <GB> / fill-storage free使用 fallocate 在 /data/local/tmp 中创建文件,并通过 df -k /data 读回;free 会删除该文件。镜像约有 5.8 GB 可用空间

探测应用配置了深层链接 crewdroid://probe/* 和 https://probe.crewdroid.example/*(autoVerify),并会记录 CrewProbe LINK <uri>。node scripts/check-app.mjs 会在 2 台设备上运行全部检查。

添加设备配置

配置是一个屏幕(宽 x 高、密度),启动后通过 wm size / wm density 应用,而不是单独的 AVD。在 profiles/galaxy.json 中添加一项:

{ "name": "s25", "model": "Galaxy S25", "width": 1080, "height": 2340, "density": 420, "minAndroid": "15", "minApi": 35 }

然后运行 crewdroid up --count 1 --profiles s25。minApi 决定设备使用哪个 Android 镜像。

无需编辑该文件即可使用任意尺寸:crewdroid up --count 2 --screen 1920x720@160,3840x2160@320(密度可选,会根据约 360dp 的短边推算),或使用 --profiles-file my.json(结构相同;参见 profiles/custom.example.json)。尺寸可以超过主机显示器范围——已测试至 7680x2160;参见 docs/measurements/size.md。

安全规则

  • 每次 adb 调用都会经过防护机制,只接受 emulator-<port> 序列号,因此绝不会操作同一台机器上的 USB 手机。
  • 模拟器以一个基础 AVD 的只读克隆形式运行:不会保存任何更改,down 只会移除 crew-* 实例。
  • 每台机器一次只能运行一个 crewdroid(up / down 会获取锁)。
  • SDK 路径只取自 ANDROID_SDK_ROOT / ANDROID_HOME;不会硬编码。

如何保持轻量

克隆一个基础 AVD(-read-only),将系统映像重写为稀疏格式并进行 NTFS 压缩,在快照前将 quickboot RAM 映像填零,使用 -lowram 并将客户机 RAM 设为 896 MB,关闭主机 Vulkan、音频和窗口。每个参数都经过逐一测量:docs/measurements/slim.md(磁盘)、ram.md(RAM)、features.md(各运行时功能的空闲开销——均不会添加守护进程)。

韩语文档:README.ko.md · 许可证:MIT

关键词:Android 模拟器、无头、多设备测试、并发测试、竞争条件、幂等性、更新丢失、离线优先同步、不稳定网络、Galaxy Fold Flip 配置文件、MCP 服务、AI Agent、Claude Code 插件、Agent 技能、移动 QA 自动化。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。