docs: doc/ 全量同步 dev 现状——API 目录补全(AI 控制台/系统备份/自动发现等)、去 STF 过时口径、补 generic_steps 与配置键速查;确立「功能/配置改动须同步文档」红线

- doc/API.md:补方法/路径标题,权限分层修正,新增 AI 控制台(/api/agent/*)、系统备份(/api/system/backup/*)、设备自动发现(/api/devices/discovery/*)、tap_text/summary/health/devices-apps 等整节端点,去 STF 残留
- doc/TASK_DEV.md:STF 时代描述清理;新增 §2.10 generic_steps(18 节点与必填/嵌套/静默跳过语义)、§2.11 自定义动作与单步测试、/api/jobs 盲存校验语义、resolve_serials/抢占语义、模板构造函数签名修正
- doc/DEPLOY.md:数据备份改为推荐「系统→数据备份」功能并说明重启生效目录,端口表 STF7100→MCP8033,补 start.sh 生产链路与 MCP_PLATFORM_PASS 同步,故障排查去 STF
- doc/MCP.md:加「现状边界」(平台级任务 CRUD 未 MCP 化,规划见 AI_TASK_GEN §9),busy/平台会话说明,MCP_ALLOWED_SERIALS 语义纠正
- doc/MCP_DESIGN.md:加实现现状对照、错误码、独立容器改演进备选、里程碑状态、API 映射表按实现重写
- doc/ARCHITECTURE.md:Tab/子分栏/线程模型/数据表/蓝图表去 STF,补 device_discovery/agent/system_backup/经验巡检等
- doc/DEVELOPMENT.md:新增 §5.6「改动必须同步文档」红线、§2.3 配置键速查、蓝图化新增 API 流程、文档索引补登记
- doc/STF_REMOVAL.md:加历史记录状态横幅
- doc/AI_TASK_GEN.md:新增 AI 建任务设计稿(含 §9 需转 MCP 工具分层)
This commit is contained in:
2026-09-09 16:05:56 +08:00
parent 470c76221e
commit fd829a6063
9 changed files with 1121 additions and 196 deletions
+49 -20
View File
@@ -1,6 +1,6 @@
# MCP 手机控制(Mobile Control MCP Server)设计文档
> 分支:dev:mcp | 状态:设计稿 | 日期:2026-09-04
> 分支:dev | 状态:设计稿/演进(实现现状以 doc/MCP.md 为准) | 日期:2026-09-04
## 1. 背景与目标
@@ -26,7 +26,7 @@
┌──────────────┐ MCP (Streamable HTTP / stdio) ┌──────────────────┐
│ 多模态 AI │ ────────────────────────────────▶ │ MCP Server │
│ Claude Desktop│ tools + image content block │ (220 独立进程) │
│ Claude Code │ ◀──────────────────────────────── │ mcp/ 包 │
│ Claude Code │ ◀──────────────────────────────── │ mcp_server/ 包 │
└──────────────┘ 截图图像 / JSON 结果 └────────┬─────────┘
│ 内部调用
▼
@@ -71,12 +71,14 @@
- 语言/运行时:Python 3.11(与平台一致)
- 框架:**FastMCP**(`fastmcp`,官方 SDK 之上,装饰器式 tools,自带 Streamable HTTP/stdio 双传输)
- 依赖:`fastmcp`、`httpx`、`Pillow`(图像处理)、`mcp[cli]`
- 依赖:`fastmcp`(requirements.txt 已含,>=2.0)、`httpx`、`Pillow`(图像处理)、`mcp[cli]`(**设计依赖,未落地**——当前 requirements 未含,仅 fastmcp)
- 日志:logging → 平台同款格式(时间/级别/模块)
### 5.2 进程与容器
- 独立容器 `mcp-server`(220 docker-compose 追加),image `python:3.11-slim`
> **实现现状**:当前 MCP 与 web_server **同容器**,由 `scripts/start.sh` 后台拉起(`MCP_ENABLED=1` 默认,=0 可关),监听 8033。下方独立容器方案为**演进备选**。
- 独立容器 `mcp-server`(220 docker-compose 追加),image `python:3.11-slim`(演进备选)
- 挂载:无数据挂载(无状态,配置走环境变量);网络 host 或独立端口(**候选:8033**,避免与 18050/18051 冲突)
- 独立于 auto_control 重启,互不阻塞;MCP Server 崩溃不影响平台,平台不可用时 MCP tools 返回明确错误
@@ -87,16 +89,29 @@
| `MCP_PLATFORM_URL` | `http://127.0.0.1:18050` | 平台地址 |
| `MCP_PLATFORM_USER` / `MCP_PLATFORM_PASS` | 空 | 平台登录账号(admin) |
| `MCP_ALLOW_WRITE` | `0` | 写操作总开关(0=只读感知,1=可操作) |
| `MCP_ALLOWED_SERIALS` | 空=全部 | 设备白名单(逗号分隔;为空时自动=设备池内设备) |
| `MCP_ALLOWED_SERIALS` | 空=全部 | 设备白名单(逗号分隔;为空时自动=设备池内设备)——**设计目标,代码未实现**(实现仅校验 serial 非空,见 §8.3 注) |
| `MCP_HTTP_HOST` | `0.0.0.0` | HTTP 监听地址 |
| `MCP_HTTP_PORT` | `8033` | HTTP 传输端口 |
| `MCP_PLATFORM_TIMEOUT` | `30` | 平台请求超时(秒) |
| `MCP_SCREENSHOT_WIDTH` | `540` | 截图宽度(等比缩放,控图像 token 成本) |
| `MCP_JPEG_QUALITY` | `70` | 截图 JPEG 质量 |
| `MCP_AUDIT_FILE` | `/var/log/mcp/audit.log` | 审计日志路径 |
> `MCP_ENABLED` 由 `scripts/start.sh` 消费(默认 1),非 MCP 进程内配置;`MCP_PLATFORM_PASS` 在 start.sh 兜底 `admin123`,改 admin 密码须同步(见 doc/MCP.md)。
## 6. Tools 规格
命名空间 `de_`(device)前缀避免与常见工具冲突。全部工具对**未配置白名单/离线设备**返回明确错误,不做静默跳过。
> **实现现状对照**(本节以下是设计规格;实际实现以 `mcp_server/` 与 [doc/MCP.md](MCP.md) 为准,主要差异):
> - `de_screen_state` **未独立实现**:并入 `de_screenshot` 返回的 `screen_state` 字段
> - 实际另有(设计稿未列):`de_tap_text` / `de_tap_element` / `de_stop_app` / `de_read_clipboard` / `de_foreground_app` / `de_list_apps` / `de_list_tasks`
> - `de_type_text` 实际签名 `(serial, text)`,走 u2 `EditText.set_text`(非设计稿的 ClipInject+paste 优先)
> - `de_tap` 坐标语义已是**截图坐标系、server 按比例换算原生**(非设计稿「原生像素、调用方自换算」)
> - `de_open_app` 是 **adb monkey 直启**(非 u2 `app_start`)
> - `de_find_and_tap` / `de_wait_until` / `de_get_task_state` **未实现**;语义点击由 `de_tap_text` / `de_tap_element` 承担
> - **平台级工具层未实现**:任务 CRUD/提交、分组/设备池/自定义动作/APK/备份等 REST 只给前端用,未 MCP 化;补齐规划见 [doc/AI_TASK_GEN.md](AI_TASK_GEN.md) §9——P0 只补 `list_task_types` / `list_groups` / `list_pool` + `submit_task`(校验不落库),**不暴露写 CRUD**,维持「AI 提案 → 人工确认」
### L1 感知层
#### `de_list_devices`
@@ -108,7 +123,7 @@
- 描述:截取设备当前屏幕(JPEG),返回 image content block;同时返回 `width/height/serial` 元信息
- 实现:平台 `/api/screen/thumb`(X-Screen-State 头复用判断亮熄屏);失败(离线/超时)→ 明确错误
- 图像规格:宽 ≤ `MCP_SCREENSHOT_WIDTH`(默认 540),质量 `MCP_JPEG_QUALITY`;**需保证图像方向正确**(设备可能横竖屏,含 EXIF 或由调用方按截图尺寸推断)
- 限制:截图频率 ≥ 1s/次(防 AI 疯狂截图),可配置
- 限制:截图频率 ≥ 1s/次(防 AI 疯狂截图),可配置(**未落地**:现状无频率限制)
#### `de_ui_tree(serial: str) -> str`
- 描述:获取当前界面元素树(扁平 JSON:resource-id/text/content-desc/class/bounds),供定位
@@ -158,7 +173,7 @@
### 工具返回约定
- 全部工具返回结构化 JSON:`{ok: true, data: ...}` 或 `{ok: false, error: {code, message}}`
- 错误码:`platform_unavailable` / `device_offline` / `device_not_allowed` / `invalid_param` / `write_disabled` / `busy`(设备被任务占用)
- 错误码:`platform_unavailable` / `device_offline` / `device_not_allowed` / `invalid_param` / `write_disabled` / `device_busy`(设备被任务占用,running/connecting 拒写) / `text_not_found`(de_tap_text 屏幕上无该文字)
- image 返回:`{ok:true, image: <content block>, width, height}`
## 7. 图像链路细节
@@ -174,14 +189,16 @@
1. **平台会话**:MCP Server 启动时用 `MCP_PLATFORM_USER/PASS` 登录平台拿会话(Cookie),会话失效自动重登;不向客户端暴露平台凭据
2. **写操作门控**:`MCP_ALLOW_WRITE=0`(默认)时 L2/L3 操作全部拒绝(`write_disabled`)——先部署只读,验证感知链路后再开写
3. **设备白名单**:`MCP_ALLOWED_SERIALS` 指定;为空时自动限制为**设备池 enabled 设备**(平台口径)
4. **占用互斥**:操作前查设备 `worker_status`——running/connecting 中拒绝操作(`busy`),避免 MCP 与任务打架
3. **设备白名单**:`MCP_ALLOWED_SERIALS` 指定;为空时自动限制为**设备池 enabled 设备**(平台口径)——**此为设计目标,当前代码未实现**:实现只校验 serial 非空,空名单不按设备池过滤(如需收紧请配置白名单)
4. **占用互斥**:写操作前查设备 `worker_status`——running/connecting 中拒绝(`device_busy`),避免 MCP 与任务打架(已实现,只读工具不受限)
5. **审计**:每次调用(含只读)写审计日志:`ts|tool|serial|args摘要|result`;落盘 `MCP_AUDIT_FILE`
6. **传输安全**:内网部署(host 网络 8033)默认无 TLS;若外网暴露需前置 TLS/网络隔离(平台红线:设备控制接口不进公网)
7. **无状态**:MCP Server 不存设备数据,全量透传平台
## 9. 部署(220 docker-compose 追加)
> **演进备选**:下方「独立 mcp-server 容器」为演进方案。**当前实现**=与 web_server 同容器,由 `scripts/start.sh` 后台拉起(`MCP_ENABLED=1` 默认、`MCP_ALLOW_WRITE=1`、`MCP_PLATFORM_PASS` 兜底 admin123),见 [doc/MCP.md](MCP.md) 与 DEPLOY §2.4。
```yaml
mcp-server:
container_name: mcp-server
@@ -190,7 +207,7 @@
working_dir: /app
volumes:
- "./mcp_server:/app"
command: sh -c "pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt && python -m mcp_server"
command: sh -c "pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt && python -m mcp_server.mcp_server"
environment:
- MCP_PLATFORM_URL=http://127.0.0.1:18050
- MCP_PLATFORM_USER=admin
@@ -219,6 +236,8 @@
| M2 | L3 语义层(find_and_tap/wait_until)+ 图像尺寸/性能调优 | AI 用自然语言指令(含中文输入)完成跨 3 步以上操作且自适应页面变化 |
| M3 | 生产化:安全加固复核、审计看板、部署脚本、接入文档、任务系统互斥回归 | 日常稳定使用 1 周无异常 |
> **实现状态备注**:M0/M1 已实现;M2 部分实现(`de_tap_text` / `de_tap_element` 已实现,`de_find_and_tap` / `de_wait_until` 未实现);M3 未验收。
## 11. 风险与开放问题
1. **AI 误操作**:模型点击错位/误触关键按钮(如删除)——缓解:L3 定位优先于裸坐标、写门控先行、审计可追溯;**不做**二次确认(破坏自动化体验),靠白名单+占用互斥兜底
@@ -230,15 +249,25 @@
## 12. 附录:平台 API 映射(MCP → 平台)
| MCP tool | 平台调用 |
| MCP tool | 实际平台调用(现状) |
|---|---|
| de_screenshot | GET /api/screen/thumb?serial= |
| de_tap / de_swipe / de_press_key | POST /api/screen/tap|swipe|key |
| de_type_text / de_set_clipboard | POST /api/tools/clipboard/set(ClipInject)+ u2 input |
| de_ui_tree | GET /api/uiauto/…(或 core 直连) |
| de_ocr | core.ocr(进程内或新只读端点) |
| de_list_devices | GET /api/status + /api/devices/pool |
| de_open_app | core device app_start(或任务层 open_app 动作) |
| de_screen_state | dumpsys(core.common._device_screen_state) |
| de_list_devices | GET /api/status |
| de_screenshot | GET /api/screen/thumb?serial=(X-Screen-State 头 → screen_state;另 GET /api/screen/size 取原生分辨率) |
| de_ui_tree | GET /api/uiauto/elements(uiautodev) |
| de_ocr | direct_ops.ocr:u2 截图 + core.ocr RapidOCR |
| de_tap | POST /api/screen/tap(snap=1 自动吸附) |
| de_swipe | POST /api/screen/swipe |
| de_press_key | POST /api/screen/key |
| de_tap_text | POST /api/screen/tap_text(UI 树子串匹配 → OCR 兜底) |
| de_tap_element | u2 元素直连(uiautomator2 `d(by=value).click()`,无平台端点) |
| de_type_text | u2 `EditText.set_text`(direct_ops.type_text,不走 ClipInject) |
| de_set_clipboard | core.clipboard_helper ClipInject 通道(inject_clipboard,读回验证) |
| de_read_clipboard | u2 `d.clipboard` |
| de_open_app | adb monkey 直启(direct_ops.open_app) |
| de_stop_app | adb `am force-stop`(direct_ops.stop_app) |
| de_foreground_app | adb `dumpsys window`(direct_ops.foreground_app,mCurrentFocus/mFocusedApp 兜底) |
| de_list_apps | adb `pm list packages -3`(direct_ops.list_apps) |
| de_wake / de_sleep | POST /api/device/screen_all(mode=on/off) |
| de_list_tasks | GET /api/jobs |
> 实现时对平台缺失的只读入口(如 ocr/open_app 的直连面)优先在平台加**只读端点**(复用现有权限体系),MCP 不越权直连设备。
> `de_screen_state` 无独立工具,已并入 `de_screenshot` 的 `screen_state` 字段;设计稿中 `de_find_and_tap`/`de_wait_until`/`de_get_task_state` 未实现,不在此表。现状中 MCP 直连面(u2/adb)不经平台 REST,但安全(白名单/写门控/busy/审计)仍在 MCP 工具层统一把关,绝不越权触碰平台红线。