内容
<img width="16%" height="16%" align="right" alt="image" src="https://github.com/user-attachments/assets/0f30244d-6fde-4310-9d4f-cb63bac07082" />
# ADB-MCP — AI 控制的安卓设备通过 ADB
**.NET Framework 4.8.1 / C#** [模型上下文协议](https://modelcontextprotocol.io) 服务器,给予
LLM 对安卓设备通过 ADB 的完全控制:它可以**看到**屏幕(结构化的 UI 层次结构 +
抽样帧),**操作**屏幕(点击,输入,滑动,按键,启动应用,发送短信,拨打电话),并可以**实时监控**
通过 scrcpy 镜像 — 所有这些都作为输入的 MCP 工具,并围绕危险操作添加了安全层。
附带的是一个**独立的桌面镜像应用**(WinForms),用于手动控制手机。
按照 *通过 ADB-MCP 实现 AI 控制安卓设备* 的可行性简报进行构建。控制平面是成熟的、
现成的部分;这里的新颖之处在于 **混合层次结构优先感知**,**屏幕镜像平面**,
以及 **权限模型**(确认门 + shell 允许列表),它可以让代理拥有的手机保持安全。
> **状态:** 已在摩托罗拉 moto g82 5G(Android 13)上通过无线 ADB 证明有效。MCP 服务器已经驱动了
> 完整的观察→决策→操作循环:读取 UI 层次结构,编写和发送 Messenger 消息(基于元素的点击 + 文本注入),
> 以及搜索联系人来拨打真正的电话。
---
## 您获得什么
| 平面 | 它在这里的工作方式 |
|-------|-------------------|
| **控制** | `adb` 执行器封装为 MCP 工具:`tap`,`type_text`,`swipe`,`press_key`,`open_app`,`send_sms`,`shell`。当流处于活动状态时,输入通过 **控制套接字** 路由,而不是启动 `adb shell input` — 延迟获胜。 |
| **感知** | **层次结构优先**(`get_state`:便宜,结构化,精确的点击中心)带有 **抽样帧**(`get_screenshot`)仅在模糊时。帧来自 **实时 scrcpy H.264 流** 当运行时,否则来自 screencap。 |
| **镜像 / 流** | `start_stream` 打开 scrcpy 自己的 **H.264 视频 + 控制套接字**(低延迟帧 + 一个连接上的输入)。`start_mirror` 运行 scrcpy 窗口供人类观察者。 |
| **权限** | 不可逆操作(SMS)是 **确认门控**;原始 `shell` 工具是 **允许列表保护**("已加载的武器" 状态)。 |
| **桌面应用** | `AdbMcp.App` — 一个 WinForms 窗口,镜像屏幕(screencap 循环),将鼠标点击转换为点击 / 拖动转换为滑动,注入按键和文本,并有一个点击返回 / 首页 / 最近使用 / 电源 / 唤醒的按钮,以及一个内置的无线 **配对** 行。 |
### 工具(17)
`list_devices` · `get_state` · `get_screenshot` · `get_notifications` · `tap` · `type_text` · `swipe` ·
`press_key` · `open_app` · `send_sms` · `shell` · `start_mirror` · `stop_mirror` · `wait` ·
`start_stream` · `stop_stream` · `stream_status`
运行 `adb-mcp-server --list-tools` 以打印完整的 JSON 模式。
---
## 架构
```
MCP 客户端(LLM)
│ JSON-RPC 2.0 通过标准输入/输出(换行符分隔)
▼
┌─────────────────────────── adb-mcp-server(net481) ───────────────────────────┐
│ McpServer ──► ToolRegistry ──► 14 个输入工具 │
│ │ │
│ ┌──────────────┬────────────────┬──┴───────────┬────────────────┐ │
│ ▼ ▼ ▼ ▼ ▼ │
│ AdbClient UiHierarchy FrameProcessor ShellPolicy ScrcpyMirror │
│ (二进制- (uiautomator (缩放 + (允许列表) (人类窗口) │
│ 安全 adb) 解析+解析) JPEG 编码) │
└───────────────────────────────────┬────────────────────────────────────────────┘
▼
adb ──► 安卓设备 / 模拟器
```
源代码布局:
```
src/AdbMcp.Core/ 类库 — 所有逻辑
Adb/ AdbClient, UiHierarchy, DeviceQueries, Perception, InputEncoding, AndroidKeys
Mcp/ McpServer(JSON-RPC), ToolRegistry, Tooling(ITool/ToolResult/Schema), DefaultTools
Tools/ PerceptionTools, ActuatorTools, SystemTools
Imaging/ FrameProcessor, Nv12Converter, IVideoDecoder(System.Drawing)
Scrcpy/ ScrcpyProtocol(控制消息 + 视频头编码器), ScrcpyVideoStream(解复用),
ScrcpyControlClient, ScrcpySession, ScrcpyFrameSource, StreamManager, ScrcpyMirror
Mf/ MediaFoundationH264Decoder + COM 互操作(Windows 自带 H.264 解码)
Safety/ ShellPolicy
Config/ ServerConfig
src/AdbMcp.Server/ 控制台可执行文件 — 参数解析,配置,标准输入/输出线路(adb-mcp-server.exe)
src/AdbMcp.App/ WinForms 桌面镜像 — Adb.cs(adb 包装器),MainForm.cs(实时镜像 + 输入 + 配对)
tests/AdbMcp.Tests/ 离线自测试框架(75 个断言,不需要设备)
```
---
## 先决条件
1. **Windows + .NET Framework 4.8.1** (目标包;Visual Studio 2022 或 .NET SDK 构建它)。
2. **现代 `adb`** 来自 [Android SDK 平台工具](https://developer.android.com/tools/releases/platform-tools)。
> ⚠️ 一些 Windows 安装程序中附带的 `adb.exe`(`C:\Windows\adb.exe`)可能是一个 **2011 年的旧版本 v1.0.26**
> 它在 `adb devices` 上挂起并且缺少 `exec-out`。安装当前平台工具并指向它。
3. **具有启用 USB 调试的设备**(USB,或通过 `adb tcpip 5555` + `adb connect <ip>` 无线)。
4. *(可选)* **[scrcpy](https://github.com/Genymobile/scrcpy)** 用于镜像窗口(`start_mirror`)和低延迟流(`start_stream`)。流需要一个与 `scrcpyServerVersion` 匹配的 **`scrcpy-server` JAR**(默认 2.4)- 在 `scrcpy.exe` 旁边自动检测,或在配置中设置 `scrcpyServerJar`。
5. *(Windows,自动)* Media Foundation 提供实时流帧的内置 H.264 解码器 - 无需安装。
使用 `adb-mcp-server --test-decoder` 验证它。
---
## 构建
```powershell
# 从存储库根目录
dotnet build -c Release # 构建 Core + Server + App + Tests
# 服务器:src\AdbMcp.Server\bin\Release\net481\adb-mcp-server.exe
# 应用: src\AdbMcp.App\bin\Release\net481\AdbMcp.App.exe
```
或在 Visual Studio 2022 中打开 `AdbMcp.sln` 并构建。
### 运行测试
```powershell
dotnet run --project tests\AdbMcp.Tests -c Release
# -> Passed: 75 Failed: 0 (不需要设备)
```
---
## 运行
```powershell
# 验证工具链并查看连接的设备(不启动服务器):
adb-mcp-server --self-check --adb C:\platform-tools\adb.exe
# 启动 MCP 服务器(在标准输入/输出上进行 JSON-RPC;客户端为您启动):
adb-mcp-server --adb C:\platform-tools\adb.exe
```
通过 MCP 客户端(例如 Claude Desktop / Claude Code)连接它 - 请参阅
[`mcp-config.example.json`](mcp-config.example.json):
```json
{
"mcpServers": {
"adb-android": {
"command": "C:\\Users\\admin\\Desktop\\ADB-MCP\\src\\AdbMcp.Server\\bin\\Release\\net481\\adb-mcp-server.exe",
"args": ["--adb", "C:\\Program Files (x86)\\Android\\android-sdk\\platform-tools\\adb.exe"],
"env": { "ANDROID_ADB_SERVER_PORT": "5860" }
}
}
}
```
> 上面的 `env.ANDROID_ADB_SERVER_PORT` 在此机器上 **不是装饰性的** - 请参阅
> [无线设置和 adb 服务器端口](#无线设置和adb服务器端口)。省略目标 `--device`
> 让服务器自动选择单个连接的手机,因此它在无线 ADB 端口旋转时存活。
### CLI 选项
| 标志 | 含义 |
|------|---------|
| `--config <file>` | 加载 JSON 配置(请参阅 [`config/adbmcp.config.sample.json`](config/adbmcp.config.sample.json))。 |
| `--adb <path>` | 现代 adb 可执行文件的路径。 |
| `--scrcpy <path>` | scrcpy 的路径。 |
| `--device <serial>` | 目标特定设备(默认:自动选择单个连接的设备)。 |
| `--max-frame-dim <px>` / `--jpeg-quality <n>` | 抽样帧大小 / 质量。 |
| `--auto-confirm` | **危险** - 禁用确认门控(仅限测试设备)。 |
| `--allow-unlisted-shell` | 允许非允许列表 shell 命令在 `confirm=true` 时运行。 |
| `--self-check` / `--list-tools` / `--help` | 诊断;不启动服务器。 |
配置优先级:**默认值 → 配置文件 → `ADB_MCP_*` 环境变量 → CLI 标志**。
`stdout` 保留用于 JSON-RPC 流;**所有日志都输出到 stderr**。
---
## 桌面镜像应用 (`AdbMcp.App`)
一个独立的 WinForms 窗口,用于手动控制手机 - 方便设置、调试和观察代理的操作。
```powershell
dotnet build -c Release src\AdbMcp.App\AdbMcp.App.csproj
# 启动(继承专用的 adb 端口;请参见下文):
$env:ANDROID_ADB_SERVER_PORT = "5860"
.\src\AdbMcp.App\bin\Release\net481\AdbMcp.App.exe
```
- **实时镜像** 通过 `screencap` 循环以可选择的帧率(“今天有效”的感知路径)。
- **点击 = 点击**,**拖动 = 滑动**,键盘按键通过(`Esc`→返回,`Enter`,`Backspace`→删除),以及一个
文本框,注入整个字符串。
- **硬件按钮:** 返回 / 首页 / 最近使用 / 电源 / 唤醒。
- **配对行:** 输入配对 `host:port` + 代码并单击 **配对** 以执行无线配对,无需终端。
---
## 无线设置和 adb 服务器端口
### 配对(一次性)
Android 11+ 无线调试需要 **一次性配对** 才能使 `adb connect` 生效。配对代码
**在 ~60 秒内过期** 并且其端口每次对话框重新打开时都会旋转,因此请在一个快速步骤中完成 -
要么使用应用的 **配对** 行,要么使用带有打开的配对对话框的命令:
```powershell
& "C:\Program Files (x86)\Android\android-sdk\platform-tools\adb.exe" -P 5860 pair 192.168.0.212:<PAIR_PORT> <CODE>
```
配对后持久存在于重启后。之后您只需要 `connect`(无需代码):
```powershell
.\connect-phone.ps1 <CONNECT_PORT> # 从主无线调试屏幕读取端口
```
### ⚠️ adb 服务器端口(端口 5037 冲突)
adb 的默认服务器端口是 **5037**。在此机器上,该端口由 **traccar** GPS 跟踪服务
(Java Windows 服务)占用,因此不是 adb - 因此每个连接到 5037 的 adb 客户端 **都会无限期挂起**。解决方法是非破坏性的:运行 adb 在其 **自己的专用服务器端口** 上,并将 traccar 留空。
- 这里的一切都使用 **端口 5860**:MCP 配置设置 `ANDROID_ADB_SERVER_PORT=5860`,桌面应用内置
`-P 5860`,并且 [`connect-phone.ps1`](connect-phone.ps1) 指向它。
- 如果您转移到没有此冲突的机器,请删除环境变量 / `-P`,默认的 5037 端口工作正常。
```powershell
# 在专用端口上启动干净的 adb 服务器并确认它立即响应:
$env:ANDROID_ADB_SERVER_PORT = "5860"
& "C:\Program Files (x86)\Android\android-sdk\platform-tools\adb.exe" -P 5860 devices
```
---
## MVP 证明:“发送消息”
简报中的终极目标 - *打开消息,找到联系人,编写,确认,发送* - 映射到:
1. `get_state` → 读取屏幕,找到撰写字段和控件,通过文本/ ID。
2. `open_app` / `tap` → 导航到对话。
3. `tap`(字段)→ `type_text` → 编写。
4. `send_sms` **不** `confirm` → 返回预览,无操作。
5. `send_sms` **和** `confirm:true` → 通过意图编写并按下发送。
`send_sms` 还直接执行编写-然后点击发送的操作,这是简报
建议的可靠路径,而不是 OEM 脆弱的 `service call isms`。
---
## 安全性和权限模型
具有 `shell` + `input` + `send_sms` 的代理有效地 **拥有手机**。此服务器内置了简报的姿态:
- **确认门控。** `send_sms` 拒绝在没有 `confirm:true` 的情况下操作 - 而是预览。扩展相同的模式到任何新的不可逆转的动词。
- **Shell 允许列表。** `shell` 仅运行与配置的正则表达式允许列表匹配的命令(默认情况下仅限读取检查 + 标准输入执行器)。除非操作员显式启用 `allowUnlistedShellWithConfirm`。 **绝不向不受信任的提示公开原始 shell。**
- **提示注入是实时威胁。** 屏幕内容(通知,网页)可以尝试操纵代理。 **在测试设备上隔离到 ** 进行任何不受信任的工作负载。
- **绑定本地,拥有设备。** USB 调试是攻击面;仅针对您控制的设备,并公开自动化作者身份,其中消息到达第三方。
---
## 感知策略(为什么保持便宜)
- **`get_state` 首先。** uiautomator 层次结构是结构化、精确且便宜的 - 它提供每个元素的
文本,ID,content-desc 和点击中心。根据 **文本/资源 ID** 而不是原始 x,y,因此操作在分辨率和布局更改后存活下来。
- **`get_screenshot` 仅在不明确时。** 帧缩放到最大边缘并编码为 JPEG 以控制令牌。仅在无法通过层次结构描述的画布/游戏/照片内容时采样。
---
## 屏幕镜像平面和低延迟流(新构建)
这是简报中引出的部分 - 而且已经构建:
- **`start_stream`** 将 scrcpy-server JAR 推入 `adb forward` 设备上的本地端口,
启动服务器通过 `app_process`,并连接 **两个套接字**:
- 一个 **视频套接字** 携带 H.264,经解复用(设备元数据处理,编解码器元数据,每个帧的 PTS/标志/长度头)并解码为 RGB,通过 Windows **Media Foundation** H.264 MFT
(`MediaFoundationH264Decoder` + 测试过的 [`Nv12Converter`](src/AdbMcp.Core/Imaging/Nv12Converter.cs))以及
[`Nv12Converter`](src/AdbMcp.Core/Imaging/Nv12Converter.cs);
- 一个 **控制套接字** 用于输入 - 流期间,`tap`/`type_text`/`swipe`/`press_key` 成为几十字节
字节通过保持打开的连接而不是每个操作启动 `adb shell input`。
- **`get_screenshot`** 在流式传输时采样实时解码帧(`source: auto`),否则使用 screencap。
- 一切 **优雅降级**:没有流,输入通过 `adb shell`,而帧通过 screencap;解码器
不可用,帧通过 screencap,而控制通道仍然承载输入。
**验证状态。** 字节流协议(控制消息,视频解复用)和 NV12 颜色数学单元测试(75 个断言)。Media Foundation 互操作在 Windows 上通过 `--test-decoder`
(MFT 创建和输入/输出类型协商成功)进行验证。完整的端到端流式传输 - 服务器握手通过
解码帧 - 对物理设备进行验证,因为它需要实时 H.264 源和匹配的 `scrcpy-server` JAR。
```powershell
adb-mcp-server --test-decoder # 探查 H.264 解码器互操作(不需要设备)
```
---
## 已知限制
- 需要现代的 `adb`;古老的捆绑 Windows 构建(`C:\Windows\adb.exe`,2011 年 v1.0.26)将挂起。
- **端口 5037 可能被占用** 另一个服务(此处:traccar)- 在 `ANDROID_ADB_SERVER_PORT` / `-P` 或其他 adb 调用挂起。参见 [无线设置](#wireless-setup--the-adb-server-port)。
- 无线配对代码 **在 ~60 秒内过期** 并且配对端口在对话框重新打开时旋转 - 在一个快速步骤中配对(应用配对行
或单个命令),然后仅 `connect`。
- scrcpy 协议 **版本特定** - `scrcpy-server` JAR 必须与 `scrcpyServerVersion` 匹配。
- `send_sms` 通过在层次结构中找到它来按下发送控制 - 在常见消息应用中很强大,但
重度自定义的 OEM 应用可能需要 `get_state` + 显式 `tap`。
- 端到端流媒体在设备验证待定(互操作和编解码器已测试;实时流需要硬件)。
- 无线 ADB 在睡眠/漫游时可能会断开 - 如果设备消失,请使用 `adb connect <ip>` 重新连接。
## 许可
作为 Tester Present 合作伙伴提供即用。范围仅限您拥有和控制的设备。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器