Files
auto_control/doc/MCP.md
T
butubb 24d57d3b96 docs: doc/ 全量重整——按现状重写并建立文档索引;项目统一更名 auto_control
背景:文档长期落后于代码(Tab 数、任务类型、接口示例等多处与现状不符),
且信息分散重复。这次按当前代码状态逐篇重写,并建立统一的文档体系。

新增
- doc/README.md:文档总索引(文档地图 / 推荐阅读路径 / **文档维护约定**)
- doc/DATA_MODEL.md:数据模型(7 张模型表 + 5 张非模型表、迁移机制、app_meta 键、
  数据目录、备份覆盖清单与双向自检)
- doc/AI_CONSOLE.md:AI 控制台机制(会话与 SSE、经验库/动作库蒸馏与召回、巡检、
  Markdown 渲染、推理链、token 统计、故障排查)

重写(按现状,去掉过时与重复)
- README.md:7 个 Tab、18 种步骤、设备生命周期、调度/窗口语义、常见问题;修掉
  「6 个 Tab / 分组为顶级 Tab」等过时内容与损坏的目录树
- doc/ARCHITECTURE.md:补启动装配顺序(import 期副作用、A~G 七阶段)、线程与锁清单、
  设备状态机、调度全链路、前端结构与实时通道、设计决策、**已知缺陷与踩坑清单**、扩展点
- doc/API.md:按蓝图重建「接口总索引」(107 条路由含鉴权)+ 分域详细说明 +
  非 JSON 响应汇总 + 错误分支速查
- doc/TASK_DEV.md:18 种步骤全表(参数/默认值/语义)、容器与公共参数、
  选择器与 XPath 序号语义、抓取器建议规则、新增任务类型骨架
- doc/DEPLOY.md:容器入口 start.sh 三件事、发布流程与检查清单、备份覆盖红线、
  按现象分类的故障排查
- doc/DEVELOPMENT.md:流程/红线/本地开发/**测试与写测试的约定**/配置速查/文档同步
- doc/MCP.md:19 个工具的参数级清单、坐标空间、写门控三连、安全与审计
- doc/MCP_DESIGN.md、doc/AI_TASK_GEN.md:标注设计 vs 实现现状,补交叉链接
- doc/backlog/TODO.md:新增「已知缺陷」小节(含复现与影响)+ 已完成留档
- .env.example:按代码实际读取的键重写(补 USB/DISCOVERY/MCP/AGENT,删死配置)

其它
- 项目名统一 auto_control:README/文档/scripts/pack.py 产物名;代码内的
  doc 章节引用(templates/admin/monitor.html)同步更新
- 校验:16 篇文档 156 条相对链接全部可解析;文档中的关键数字与代码核对一致
  (19 个 MCP 工具 / 18 种步骤 / 12 张备份表 / 1 种任务类型)
2026-09-10 22:19:18 +08:00

11 KiB
Raw Blame History

MCP 手机控制手册(MCP.md)

多模态 AI(DeepSeek / Claude 等)通过 MCP(Model Context Protocol) 操作 Android 手机的统一出口。平台自带的「AI 控制台」(mcp_agent/)与外部 MCP 客户端使用的都是这一批工具。

本文 = 使用手册(工具清单 / 用法 / 接入)。设计取舍与演进见 MCP_DESIGN.md;AI 控制台的会话/经验/动作机制见 AI_CONSOLE.md。


1. 架构与边界

AI 控制台 / 外部 MCP 客户端
        │  Streamable HTTP(http://<host>:8033/mcp)
        ▼
MCP Server(mcp_server/mcp_server.py)        ← 19 个 de_* 工具
        │  平台 HTTP API(登录 + CSRF)  或  轻量 adb/u2 直连
        ▼
auto_control 平台(:18050)                    ← 设备池 / 任务 / 看屏
        │  adb / uiautomator2 / uiautodev / OCR
        ▼
Android 设备(IP:5555)
  • 轻量通道直连(adb monkey 开 App、u2 输入、本地 OCR)不绕平台,省时间省 token
  • 坐标换算、UI 吸附、剪贴板注入等细节全部在 Server 层消化,模型只给"意图"
  • 只暴露设备层能力:平台级的任务增改/分组/设备池/APK/备份等 REST 只给 Web 前端用,未做成 MCP 工具(补齐规划见 AI_TASK_GEN.md §9)

2. 运行与配置

生产跑在 220 的 python-app 容器内(scripts/start.sh 自动拉起),端点 http://192.168.20.220:8033/mcp。

# 本机手动启动
MCP_ALLOW_WRITE=1 MCP_PLATFORM_USER=admin MCP_PLATFORM_PASS=<平台密码> \
  MCP_AUDIT_FILE=data/mcp_audit.log python -m mcp_server.mcp_server
环境变量 默认 说明
MCP_PLATFORM_URL http://127.0.0.1:18050 平台地址
MCP_PLATFORM_USER / MCP_PLATFORM_PASS admin / 空(start.sh 兜底 admin123) 平台登录凭据。改过 admin 密码必须同步,否则登录失败
MCP_ALLOW_WRITE 0(start.sh 内强制 1) 写门控:=1 才允许点击/输入/开关 App(只读工具不受限)
MCP_ALLOWED_SERIALS 空 设备白名单(逗号分隔)。非空 = 只允许列出的 serial;为空时只校验 serial 非空,不按平台设备池过滤(语义缺口见 backlog)
MCP_HTTP_HOST / MCP_HTTP_PORT 0.0.0.0 / 8033 监听
MCP_SCREENSHOT_WIDTH 540 截图返回宽度上限(模型看到的坐标系)
MCP_JPEG_QUALITY 70 截图 JPEG 质量
MCP_AUDIT_FILE /var/log/mcp/audit.log(容器兜底 /tmp/mcp_audit.log) 审计日志路径
MCP_PLATFORM_TIMEOUT 30 平台请求超时(秒)
MCP_ENABLED 1 只被 scripts/start.sh 消费:=0 则不后台拉起 MCP

mcp_server/config.py 只读进程环境变量,不读 .env;scripts/supervise.sh 不拉起 MCP(容器场景由 start.sh 负责)。


3. 坐标空间(重要)

  • de_screenshot 返回 ≤540px 宽的 JPEG(display 空间),同时给出 native_size(设备原生分辨率)与 screen_state
  • de_tap / de_swipe 的坐标一律用 de_screenshot 返回图像的坐标系,Server 按比例换算成原生坐标
  • 必须先截图再点击:Server 需要最近一次截图来建立坐标空间,否则报 invalid_param「请先对该设备执行 de_screenshot」
  • de_tap 带自动吸附:落点若在某个可点击元素内,实际点该元素中心 → 坐标只需大致对准;返回 snapped / label 便于核对

4. 工具清单(19 个)

统一返回约定:

{"ok": true,  "data": { … }}
{"ok": false, "error": {"code": "device_busy", "message": "设备正在执行任务…"}}

错误码:invalid_param · device_not_allowed · write_disabled · device_busy · platform_unavailable · device_offline · text_not_found。

4.1 设备与状态(只读)

工具 参数 返回 / 说明
de_list_devices — [{serial, model, online, task_job, worker_status, foreground_app}]。开局第一步
de_foreground_app serial {foreground_app} 当前前台包名(dumpsys,MIUI 焦点为空时兜底)
de_list_tasks — 平台任务计划 [{id,name,task_type,enabled,schedule}](只读)

4.2 观察屏幕(只读)

工具 参数 返回 / 说明
de_screenshot serial {image:{type:"image",data:<base64>,mimeType:"image/jpeg"}, width, height, native_size, screen_state}。多模态模型直接看图
de_ui_tree serial, limit(150,1-300) {count, elements:[{text,id,desc,class,clickable,bounds}]},可点击元素排前;limit 控 token
de_ocr serial {count, texts:[{text,score}]}(≤100 条)。UI 树拿不到的图片/WebView 文字用它
de_read_clipboard serial {clipboard}
de_list_apps serial, keyword("") {count, packages} 第三方已装包名(pm list packages -3,≤200)

4.3 点击与滑动(写操作)

工具 参数 说明
de_tap_text serial, text(≤100 字符) 推荐:按屏幕可见文字点击。原生控件走 UI 树,WebView/图片文字自动 OCR 兜底;找不到 → text_not_found
de_tap_element serial, by(text/id/desc/text_contains/desc_contains), value, index(1) 按元素属性点击,无需坐标;多命中用 index
de_tap serial, x, y 坐标点击(截图坐标系 + 自动吸附)。纯图形目标才用
de_swipe serial, x1,y1,x2,y2, duration(0.2) 滑动(长按 = 同点起止 + duration≥1)
de_press_key serial, key back / home / recent / menu / power / volume_up / volume_down / enter / delete / search / camera

4.4 输入与剪贴板(写操作)

工具 参数 说明
de_type_text serial, text 向当前输入框输入(支持中文,直设 EditText,不依赖剪贴板)
de_set_clipboard serial, text 写入设备剪贴板(ClipInject 通道 + 读回验证)

4.5 App 管理(写操作,走 adb 直连不建 u2 会话)

工具 参数 说明
de_open_app serial, package adb monkey 直启(最快路径,无需知道 activity)
de_stop_app serial, package am force-stop

4.6 亮屏 / 熄屏(写操作)

工具 参数 说明
de_wake serial 亮屏并解锁(熄屏时先调它再截图)
de_sleep serial 熄屏(会中断正在运行的任务,慎用)

后两组分别经 direct_ops(adb)与平台 POST /api/device/screen_all 实现,不在 MCP 进程内建 u2 会话。

4.7 写操作门控(三连)

所有写工具在执行前依次检查:

  1. _check_write() —— MCP_ALLOW_WRITE=1?否则 write_disabled
  2. _check_serial() —— serial 非空 / 在白名单内?否则 device_not_allowed
  3. _ensure_device_free() —— 设备 worker_status 不是 running/connecting?否则 device_busy(AI 不与任务抢设备)

设备状态查询有 5 秒缓存;查询本身异常时放行(不阻塞),由平台侧兜底。


5. 推荐使用模式

  1. de_list_devices 确认目标设备在线
  2. de_screenshot 看图理解当前界面(图像会在下一回合送达模型)
  3. 点击定位优先级:
    • 目标有可见文字 → de_tap_text(一次调用完成"找到并点击",最可靠)
    • 文字有歧义/多候选 → de_ui_tree 确认后用 de_tap_element(可用 text_contains 模糊匹配)
    • 纯图形目标 → de_tap 坐标(无需精算,会自动吸附)
  4. 输入文字:先点中输入框,再 de_type_text
  5. 每步验证:关键操作后再 de_screenshot——界面变了 = 成功;没变 = 未命中 → 换 de_tap_text/de_tap_element 重新定位,不要重复点同一坐标
  6. 收尾:用中文总结做了什么、当前状态、注意事项
  7. 效率:界面未变时不重复截图/点击;连续 6 步无进展就停止并总结

6. 安全与审计

机制 说明
写门控 MCP_ALLOW_WRITE=0(默认)时所有写操作被拒,只读可用
任务互斥 写操作前检查设备是否在跑任务,忙则 device_busy
平台会话 platform_client 内部登录(MCP_PLATFORM_USER/PASS)、会话失效自动重登、POST 自动带 X-CSRF-Token;平台凭据不暴露给客户端
白名单 MCP_ALLOWED_SERIALS 非空时限制可操作 serial
审计 每次调用(含只读)写一行 JSON 到 MCP_AUDIT_FILE:{ts, tool, serial, args 摘要, result 摘要}
红线 任何工具都不执行 adb kill-server / adb disconnect
端点鉴权 ⚠️ MCP HTTP 端点自身没有 token/账号校验,只做出站登录 → 必须靠网络隔离(同机/内网),不要直接暴露公网

7. 客户端接入示例

import asyncio
from fastmcp import Client

async def main():
    async with Client("http://192.168.20.220:8033/mcp", timeout=30) as c:
        devs = await c.call_tool("de_list_devices", {})
        serial = devs.data["data"][0]["serial"]          # 第一台设备
        shot = await c.call_tool("de_screenshot", {"serial": serial})
        img = shot.data["data"]["image"]                 # base64 JPEG(给多模态模型看)
        await c.call_tool("de_tap_text", {"serial": serial, "text": "搜索"})

asyncio.run(main())

给外部数字员工的使用约定与红线,另见 staffdeck/KNOWLEDGE_BASE.md。


8. AI 控制台(内置 Agent)

Web 的「AI 控制台」Tab 内建 Agent(mcp_agent/,OpenAI 兼容模型)用的就是本 Server 的同一批工具:

  • 流式输出 + 每步 MCP 调用实时展示(含截图缩略)
  • 多轮会话(同会话保留上下文)
  • 自进化记忆:经验库(任务配方)+ 动作库(命名动作),相似任务自动注入参考
  • 模型与 Key 在控制台右上角 ⚙ 配置(存平台 app_meta)

依赖提示:AI 控制台依赖本 MCP Server(默认 http://127.0.0.1:8033/mcp)。未启动时平台会把 SDK 的含糊报错映射成明确文案「MCP server(8033) 不可达 …」。


维护约定:新增 / 修改 / 删除任何一个 MCP 工具或相关配置,必须同步更新本文与 MCP_DESIGN.md(doc 同步红线)。