Skip to main content
Glama
zalazp
by zalazp
README.md
# adb-sms MCP

通过 ADB 读取 Android **短信验证码**,供 Cursor Agent 配合 **chrome-devtools** 完成 Web 短信登录。

> **设计原则**:手机号由用户在 `devices.json` 里配置;adb 只负责识别设备 serial + 读短信 OTP。

## 工作原理

```
USB 连接手机(adb devices → serial)
        │
        ├─ devices.json[serial].phone_numbers  →  Web 填手机号
        │
        └─ adb 读短信 inbox                    →  adb_wait_for_otp 拿验证码
```

## 项目结构

```
mcp-adb-sms/
├── server.py              # MCP 服务入口
├── adb_client.py          # ADB 设备 / 短信读取
├── sms_parser.py          # 短信与 OTP 解析
├── test_local.py          # 本地自检(不启动 MCP)
├── requirements.txt
├── devices.json.example   # 手机号配置模板(提交到 git)
├── devices.json           # 本地配置(git 忽略,需自行创建)
└── README.md
```

## 前置条件

1. Android 手机开启 **USB 调试** 并授权电脑
2. `adb devices` 显示 `device`(非 `unauthorized`)
3. Python **3.10+**(推荐 3.12)
4. [Android platform-tools](https://developer.android.com/tools/releases/platform-tools)(含 `adb`)

## 安装

```powershell
git clone https://github.com/zalazp/mcp-adb-sms.git
cd mcp-adb-sms
py -3.12 -m pip install -r requirements.txt
```

### 配置手机号(必填)

手机号**不由 adb 读取**,请自行写入 `devices.json`:

```powershell
copy devices.json.example devices.json
```

1. 运行 `adb devices`,记下 serial(例如 `10AD410LNF000PX`)
2. 以 serial 为 key,填入该手机的**全部**手机号

```json
{
  "10AD410LNF000PX": {
    "phone_numbers": [
      "18300000000",
      "19100000000"
    ]
  }
}
```

## Cursor 配置

编辑 `%USERPROFILE%\.cursor\mcp.json`:

```json
{
  "mcpServers": {
    "adb-sms": {
      "command": "D:\\Python312\\python.exe",
      "args": [
        "-3.12",
        "E:\\path\\to\\mcp-adb-sms\\server.py"
      ],
      "env": {
        "ADB_PATH": "D:\\RJAZ\\Sdk\\platform-tools\\adb.exe"
      }
    }
  }
}
```

| 字段            | 说明                                              |
| --------------- | ------------------------------------------------- |
| command         | Python **3.10+**(推荐 3.12)的绝对路径           |
| `args` 中的路径 | 改成 clone 目录下 `server.py` 的**绝对路径**      |
| `ADB_PATH`      | 本机 `adb.exe` 绝对路径;已在 PATH 中可写 `"adb"` |

保存后 **重启 Cursor**,MCP 面板中 `adb-sms` 应变绿。

## 本地自检

```powershell
cd mcp-adb-sms
$env:ADB_PATH="D:\RJAZ\Sdk\platform-tools\adb.exe"
D:\Python312\python.exe test_local.py
```

正常输出示例:

```json
{
  "adb_exists": true,
  "devices": [{ "serial": "10AD410LNF000PX", "state": "device" }],
  "sms_readable": true,
  "sim_numbers": [
    { "number": "18300000000", "available": true },
    { "number": "19100000000", "available": true }
  ],
  "device_profile": { "source": "devices.json" }
}
```

若 `recommendations` 提示缺少配置,按上文创建 `devices.json`。

## MCP 工具

| 工具                       | 说明                                            |
| -------------------------- | ----------------------------------------------- |
| `adb_health_check`         | 诊断 adb、短信可读性、`devices.json` 是否已配置 |
| `adb_list_devices`         | 列出已连接 ADB 设备                             |
| `adb_get_sim_numbers`      | 从 `devices.json` 读取当前 serial 的手机号      |
| `adb_read_recent_sms`      | 读取最近 N 条短信                               |
| `adb_wait_for_otp`         | Web 点击发送验证码后,轮询等待新 OTP            |
| `adb_grant_sms_permission` | Android 11+ 尝试授权 shell 读 SMS               |
| `adb_shell`                | 受限 adb shell(白名单命令)                    |

### Agent 典型流程(短信登录)

```
1. adb_health_check()
2. adb_get_sim_numbers()              ← 从 devices.json 取手机号
3. chrome-devtools: 打开登录页、填号、勾选协议
4. chrome-devtools: 滑块验证码(失败则人工完成)
5. chrome-devtools: 点击「发送验证码」
6. adb_wait_for_otp(timeout=90, sender_filter="Midea|美的")
7. chrome-devtools: 填入验证码并登录
```

## 短信读不到时

```powershell
adb shell appops set com.android.shell READ_SMS allow
```

或在 Agent 中调用 `adb_grant_sms_permission`,再执行 `adb_health_check`。

仍失败时,MCP 会尝试 `dumpsys notification` 降级读取通知栏短信(精度较低)。

### adb_read_recent_sms 返回 0 条(空数组)

| 原因 | 处理 |
|------|------|
| **MCP 未 Reload** | 修改 `server.py` / `adb_client.py` 后,Cursor → **MCP 面板 → adb-sms → Reload**(或重启 Cursor) |
| **vivo 不支持 `--limit`** | 已修复:改为 Python 侧截取;旧进程仍会返回 0 |
| **body 含逗号解析截断** | 已修复 `sms_parser.py`;Reload 后 OTP 提取才正常 |
| **vivo 验证码未入库** | 通知栏先到且打码 `******`;需用户在手机点「复制验证码」 |

**本地自检(不经过 MCP 进程)**

```powershell
cd E:\PTaas\mcp-adb-sms
python test_parser.py
python test_local.py
```

期望:`sms_sample_count` ≥ 1。本地 OK 但 MCP 仍 0 → 一定是 **未 Reload MCP**。

## 安全说明

- 仅读取 **USB 连接的本机设备** 短信
- 不持久化短信内容到磁盘
- `devices.json` 含手机号,已在 `.gitignore` 中,**请勿提交到公开仓库**
- `adb_shell` 仅允许 content / dumpsys / getprop 等白名单命令
- 仅限本人设备或已授权测试场景