Files
qianbian/docs/superpowers/specs/2026-07-30-ppclock-mcp-design.md
T

125 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ppclock-mcp 设计:AI-native MCP 服务器(单层部署)
日期:2026-07-30 · 状态:已批准(用户免审,直接进入实现)
## 目标
把 ppclock SDK 的设备能力包装成 **MCP 服务器**,直接部署在蓝牙物理所在的
Windows 服务器上(单层,不经 bridge),供各 agent 平台调用。
- 传图、不同状态显示、时间核对等高层能力,AI-native 工具语义
- Windows 先行实测;Linux 保持代码兼容(bleak 跨平台),暂不实测
- Windows 部署与联调由 worker 与熠管家协作完成,用户不参与过程
## 架构
```
agent 平台(Claude Code/Desktop/其他)
│ stdio(本机 agent) 或 streamable HTTP(局域网 agent,bearer token)
▼
ppclock-mcp(运行在蓝牙所在服务器,单层,无 bridge)
├─ mcp_server.py FastMCP 装配:工具注册、传输启动、HTTP 鉴权、CLI 参数
├─ device_manager.py 连接管理器(方案 C)
└─ tools.py 高层工具薄包装:参数校验 + 统一输出契约
▼
ppclock SDK(via_local,bleak;Windows=WinRT / Linux=BlueZ)→ BLE → NRF- 设备
```
**SDK 零改动**:MCP 层只是 SDK 的消费者。
### 连接管理(方案 C:按需连接 + 空闲保持)
- 一把 `asyncio.Lock` 串行所有设备操作(BLE 适配器独占,先到先得)
- 首次操作守候连接:扫描/连接超时默认 90s(覆盖设备 30–60s 广播窗口)
- 操作完成后保持连接;空闲超过 `--idle-timeout`(默认 300s)自动断开,
设备恢复睡眠省电
- 操作中连接丢失 → 自动重连并重试**一次**,再失败才报错
- 配置退化:`--idle-timeout 0` = 每次独立连接;很大值 ≈ 常驻连接
### 传输与鉴权
- 官方 `mcp` Python 包(FastMCP),一份实现双模:`--transport stdio|http`
- HTTP = streamable HTTP,默认 `--host 127.0.0.1 --port 8972`(避开 bridge 8971)
- 鉴权:环境变量 `PPCLOCK_MCP_TOKEN`;绑非回环地址时**必须**设置,
请求头 `Authorization: Bearer <token>`,不符即 401
- stdio 模式无鉴权(进程隔离即边界)
### 安装形态
- 本仓库内:`pyproject.toml` 增加 optional extra `mcp = ["mcp>=1.2"]`
- 新入口脚本:`ppclock-mcp = ppclock.mcp_server:main`
- 基础 SDK 依赖不增加
## 工具面(13 个)
| 工具 | 参数 | 说明 |
|---|---|---|
| `scan_devices` | `timeout=5.0` | 扫描 NRF- 设备 → `[{name,address,rssi}]` |
| `device_status` | — | 连接状态/绑定 MAC/设备 ID(连接中时)/空闲秒数 |
| `set_time` | `tz=8.0` | 对时(默认北京) |
| `set_mode` | `mode` | clock1-3/calendar1-3/image0-3/tricolor/mono |
| `toggle` | `name` | invert/font/rotate180/hour_format/clock_color |
| `upload_image` | `source, slot=0, algo="atkinson", mono=false, **adjust` | source = 服务器本地路径 **或** base64(可带 data URI 前缀);返回 `{bytes_bw,bytes_red,small,slot}` |
| `render_template` | `name, payload, slot=0, algo="atkinson"` | 6 模板本地渲染上传 |
| `countdown` | `date, mode="clock", prefix=None` | date 为 ISO `YYYY-MM-DD` |
| `countdown_off` | — | 关闭倒计时 |
| `calendar_text` | `text` | 日历中文文字并切日历模式一 |
| `set_sleep` | `on, start_h, end_h` | 休眠时段(0–23) |
| `clear_screen` | — | 刷屏 |
| `raw_send` | `data_hex, channel="alt"` | 逃生舱直发(hex 字符串) |
不暴露:OTA、激活、LUT、WiFi、轮播(高危或本固件 no-op)。
### 输出契约(与 CLI `--json` 一致)
成功 `{"ok": true, "tool": <name>, "data": {...}}`;
失败 `{"ok": false, "tool": <name>, "error": {"code", "message", "hint"}}`。
错误码小集合:`INVALID_PARAM` / `DEVICE_NOT_FOUND` / `CONNECT_TIMEOUT` /
`BLE_ERROR` / `DEVICE_DISCONNECTED` / `INTERNAL`。`DEVICE_NOT_FOUND` 与
`CONNECT_TIMEOUT` 的 hint 说明设备睡眠与守候窗口机制。
## 数据流(典型)
1. agent 调 `upload_image(base64…)` → tools 校验/解码 → manager 取锁
2. 无连接 → `PPClient.via_local(mac)` 守候连接(≤90s)
3. SDK 图像管线(裁剪 400×300→抖动→双平面打包)→ BLE 分块上传 → 返回字节统计
4. 刷新空闲计时器;锁释放;空闲 300s 后自动断开
mac 解析顺序:工具参数 > 启动 `--mac` > 自动扫描首个 NRF-(并记住)。
## 测试
- **单元**(无硬件):
- device_manager:fake transport 注入,覆盖串行锁、空闲超时断开、
掉线重连重试一次、守候超时错误
- tools:参数校验、base64/路径两种图源、错误契约形状
- **MCP 协议层**:FastMCP 内存 ClientSession 端到端调工具(fake transport)
- **Windows 实测**(熠管家协助):scan → set_time → upload_image → set_mode
目视确认上屏;HTTP 模式 token 鉴权正/反例;stdio 模式本机 agent 挂载
- **Linux**:仅保证导入与单元测试通过(bleak 分支兼容),不做硬件测试
## 部署(Windows,熠管家协作)
1. 服务器准备 Python ≥3.10 venv;源码部署(git clone 或拷贝)
2. `pip install -e ".[mcp]"`(注意 bleak WinRT 后端,无需额外系统组件)
3. 设 `PPCLOCK_MCP_TOKEN`;启动
`ppclock-mcp --transport http --host 0.0.0.0 --port 8972 --mac AA:BB:…`
4. 防火墙放行 8972(仅局域网);**不动**既有服务与 8971 bridge
5. 测试期手动启动即可;稳定后再议是否注册为 Windows 服务(超出本期范围)
熠管家协作边界:worker 提供部署脚本/步骤与验证清单;熠管家提供 Windows
访问与执行;用户不参与。
## 文档与版本
- 版本 0.2.0;CHANGELOG、README(MCP 段)、llms.txt、docs/sdk/API.md 同步
- 新增 docs/sdk/MCP.md:工具参考 + agent 挂载示例(stdio/HTTP 双例)
## 明确不做(YAGNI)
- 图片 URL 拉取(保持离线;agent 可自行下载后走 base64)
- 多设备并发(单适配器串行已够;mac 参数可切换设备)
- MCP resources/prompts(本期只 tools)
- Windows 服务化、Linux 硬件实测(后续迭代)