FlashZ/adb-mcp
GitHub: FlashZ/adb-mcp
围绕 Android Debug Bridge 的 MCP 服务器,提供 90 个结构化输出的工具,让 AI agent 无需手动复制粘贴终端命令即可直接驱动 Android 设备进行自动化操作。
Stars: 0 | Forks: 0
# adb-mcp
**一个围绕 Android Debug Bridge 的全面、结构化输出的 [MCP](https://modelcontextprotocol.io) 服务器。**
赋予 AI agent(Claude Code 或任何 MCP 客户端)直接、一流的控制权来操作
Android 设备——启动应用、驱动 UI、捕获日志和截图、推送/拉取
文件、设置端口转发——使得工作流变为:
```
agent → launch_package() → capture_screen() → tap_element("Send") → logcat_dump() → pull() → analyse()
```
……**无需复制/粘贴 shell 输出**,并且**没有不受限制的 `adb shell` 工具**(该
逃生舱是可选的,且默认关闭)。
涵盖 9 个分组的 **90 个工具**。每个工具都返回结构化的 JSON——绝不是原始的终端文本。
## 为什么使用它
通常的循环是:你输入 `adb shell …`,复制输出,粘贴给 AI,它进行
推理,告诉你下一个命令,你再输入它。adb-mcp 将其折叠为 agent 自行调用的工具。它是为移动端逆向工程/QA 自动化而构建的,但
适用于任何 adb 任务。
## 设计原则
- **幂等、命名的操作** —— `force_stop(pkg)`、`reverse_port(...)` —— 而不是
`execute_any_shell_command()`。
- **结构化输出** —— `{"pid": 8421, "status": "running"}`,而不是一大段文本。
- **作用域受限,而非全能** —— 默认没有通用 shell。`run_shell` 仅作为
显式开启项(`ADB_MCP_ALLOW_SHELL=1`)存在。破坏性工具(`delete_file`、
`clear_app_data`、`uninstall`)都有明确的命名,并且 `delete_file` 会拒绝受保护的
根目录(`/`、`/system`、`/data`、……)。
- **感知多设备** —— 每个设备工具都接受一个可选的 `serial`;`get_devices`
会标记 `is_usb`,以便你区分 USB 手机与
网络/模拟器目标(例如 WSA)。
## 安装
```
pip install -e . # from a clone
# 或者,发布后:
# pip install adb-mcp
```
需要 Python ≥ 3.10 以及你机器上的 Android platform-tools (`adb`)。
`adb` 会从 `ANDROID_HOME`、默认 SDK 位置、scoop 或 `PATH` 中
自动检测;
可通过 `ADB_PATH` 覆盖。
## 在 MCP 客户端中注册
**Claude Code**(位于你项目中的 `.mcp.json`,或使用 `claude mcp add`):
```
{
"mcpServers": {
"adb": {
"command": "python",
"args": ["-m", "adb_mcp.server"],
"env": {
"ADB_SERIAL": "RFCWC17BKJY", // optional default device
"ADB_MCP_ALLOW_SHELL": "0" // set "1" to enable run_shell
}
}
}
}
```
```
claude mcp add adb -- python -m adb_mcp.server
```
示例配置位于 [`examples/mcp.json`](examples/mcp.json)。
## 配置
| 环境变量 | 含义 |
|---|---|
| `ADB_PATH` | `adb` 的路径(如果未设置则自动检测)。 |
| `ANDROID_HOME` / `ANDROID_SDK_ROOT` | 用于 adb 自动检测的 SDK 根目录。 |
| `ADB_SERIAL` | 默认设备序列号。USB 手机:`RFCWC17BKJY`;WSA/模拟器:`127.0.0.1:58526`。 |
| `ADB_MCP_ALLOW_SHELL` | `1`/`true` 启用可选的 `run_shell` 逃生舱(默认关闭)。 |
每个面向设备的工具也接受一个 `serial` 参数以便在每次调用时覆盖,并且你
可以在运行时使用 `set_default_device` 切换会话默认值。
## 工具参考 (90)
### 设备 (15)
`get_devices` · `get_state` · `adb_version` · `get_device_properties` · `get_screen_info`
· `get_battery` · `connect` · `disconnect` · `wait_for_device` · `reboot`
· `set_default_device` · `get_default_device` · `root_adb` · `unroot_adb` · `remount`
### 应用 (16)
`list_packages` · `launch_package` · `launch_activity` · `force_stop` · `kill_background`
· `clear_app_data` · `app_status` · `get_current_activity` · `get_package_info`
· `install_apk` · `uninstall` · `grant_permission` · `revoke_permission`
· `set_package_enabled` · `start_service` · `send_broadcast`
### 输入 (12)
`tap` · `long_press` · `swipe` · `drag` · `text` · `keyevent` · `press_home`
· `press_back` · `press_recents` · `press_power` · `press_enter` · `wake_and_unlock`
### UI 自动化 (3)
`dump_ui` · `find_elements` · `tap_element` — 解析实时视图层级
(uiautomator) 并通过文本 / resource-id / content-description 点击元素,而不是
靠猜测像素坐标。
### 日志 (8)
`logcat_start` · `logcat_stop` · `logcat_dump` · `logcat_filter` · `logcat_clear`
· `get_crash_log` · `get_anr_traces` · `capture_bugreport` — 后台捕获并
解析记录为 `{time, pid, tid, level, tag, message}`。
### 媒体 (5)
`capture_screen` (内联 PNG) · `capture_screen_to_file` · `capture_screen_base64`
· `record_screen_start` · `record_screen_stop`
### 文件 (9)
`list_files` · `file_exists` · `stat_file` · `pull` · `push` · `read_file`
· `write_file` · `make_dir` · `delete_file` — `read_file`/`write_file`/`list_files`
针对已 root 的设备(WSA/Magisk)支持 `as_root` (`su -c …`)。
### 网络 (11)
`forward_port` · `reverse_port` · `list_forwards` · `list_reverses` · `remove_forward`
· `remove_reverse` · `clear_forwards` · `get_ip_address` · `set_wifi` · `set_mobile_data`
· `set_airplane_mode` — `reverse_port` 将设备端口映射到你的 PC(本地 API/CDN 垫片)。
### 系统 (11)
`get_prop` · `set_prop` · `get_setting` · `put_setting` · `list_processes` · `get_meminfo`
· `get_top` · `get_uptime` · `dumpsys` (限定于指定的服务) · `list_services`
· `run_shell` (可选开启)
## 示例:调查应用内操作
```
launch_package("com.geargames.homeworld")
capture_screen() # observe
tap_element(text="Fleet") # navigate via the view hierarchy
logcat_start(clear=True)
tap_element(text="Send") # trigger
logcat_dump(tags=["Unity","libc"]) # structured records
pull("/sdcard/Android/data/com.game/files/save.db", "dumps/save.db")
```
## 本地服务器/垫片工作流
```
reverse_port(device_port=7071, host_port=7071) # app's localhost:7071 -> your PC shim
reverse_port(device_port=7072, host_port=7072)
launch_package("com.geargames.homeworld")
logcat_filter(tags=["Curl","PlayFab"])
```
## 开发
```
pip install -e ".[dev]"
pytest -q # device-free smoke tests (imports, registration, parsers)
ruff check .
```
CI 在 Python 3.10–3.12 上运行相同的测试。
## 安全性
MCP 服务器执行本地命令,并且可以触及文件、日志和设备,因此
当 agent 链式调用其工具时,过于宽松的服务器会变得危险。adb-mcp 进行了
刻意的范围限制:
- **没有始终开启的任意 shell。** `run_shell` 是唯一的通用 shell 工具,并且
除非设置了 `ADB_MCP_ALLOW_SHELL=1`,否则它是关闭的。
- **防注入强化。** `adb shell` 通过设备的 `sh` 拼接其参数,
因此每个列表形式的命令都会在一个中心位置进行 `shlex.quote` 处理 —— 像
`"; rm -rf /sdcard"` 这样的 payload 在包名或 `dumpsys` 参数中只会变成一个字面量参数,
绝不会成为第二条命令。已由测试覆盖。
- **数量少且受保护的变更工具** —— `write_file`、`delete_file` (拒绝 `/`、`/system`、
`/data`、……)、`clear_app_data`、`uninstall`、`install_apk`、`set_prop`、`put_setting`、
以及 `set_*` 网络开关。
将其指向你拥有并信任的设备,每个目标设备运行一个服务器(使用
`ADB_SERIAL`/`serial`),除非你确实需要,否则请保持 `ADB_MCP_ALLOW_SHELL` 关闭。
完整模型请参阅 [SECURITY.md](SECURITY.md)。
## 许可证
MIT — 详见 [LICENSE](LICENSE)。
标签:AI代理, Android Debug Bridge, MCP服务, 移动开发, 移动运维, 逆向工具