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服务, 移动开发, 移动运维, 逆向工具