docs+release: MCP.md 工具参考与部署指南;0.2.0
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
9506490ce2
commit
de683fe9c2
7 files changed
+193
-11
No files matched your search
+138
@@ -0,0 +1,138 @@
|
||||
# ppclock-mcp · MCP 服务器参考(v0.2.0)
|
||||
|
||||
> 面向 agent 挂载与部署的工具级参考。SDK 签名见 `docs/sdk/API.md`,协议细节见 `docs/protocol.md`。
|
||||
|
||||
## 一句话
|
||||
|
||||
ppclock-mcp 是跑在**蓝牙物理所在机器**上的单层 MCP 服务器:13 个工具覆盖对时 / 模式 /
|
||||
切换 / 传图 / 模板 / 倒计时 / 日历文字 / 休眠 / 刷屏 / raw 逃生舱,agent 经 stdio 或
|
||||
streamable HTTP 直接驱动 4.2" 墨水屏设备。
|
||||
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
pip install -e ".[mcp]" # 追加依赖:mcp>=1.10,<2
|
||||
```
|
||||
|
||||
要求:Python ≥ 3.10、本机蓝牙适配器(bleak)。服务器与被控设备在同一台蓝牙主机上;
|
||||
不需要互联网。
|
||||
|
||||
## 启动
|
||||
|
||||
入口为 console script `ppclock-mcp`(`python -m ppclock.mcp_server` 不受支持)。
|
||||
|
||||
```bash
|
||||
# stdio —— 本机 agent 直挂
|
||||
ppclock-mcp --mac AA:BB:CC:DD:EE:FF
|
||||
|
||||
# streamable HTTP —— 局域网 agent 平台远程调用
|
||||
PPCLOCK_MCP_TOKEN=<token> ppclock-mcp --transport http --host 0.0.0.0 --port 8972
|
||||
```
|
||||
|
||||
启动参数:
|
||||
|
||||
| 参数 | 默认 | 说明 |
|
||||
|---|---|---|
|
||||
| `--transport` | `stdio` | `stdio` / `http` |
|
||||
| `--host` | `127.0.0.1` | HTTP 绑定地址;绑非回环地址**必须**设 `PPCLOCK_MCP_TOKEN`,否则拒绝启动 |
|
||||
| `--port` | `8972` | HTTP 端口 |
|
||||
| `--mac` | 无 | 设备 MAC;缺省自动扫描 `NRF-` 前缀并记住实际地址 |
|
||||
| `--connect-timeout` | `90.0` | 守候连接秒数(覆盖设备 30-60s 广播窗口) |
|
||||
| `--idle-timeout` | `300.0` | 空闲断开秒数;`0` = 每次调用独立连接 |
|
||||
|
||||
环境变量:`PPCLOCK_MCP_TOKEN` —— HTTP 模式 Bearer 鉴权令牌(仅 HTTP 使用;stdio 无鉴权,
|
||||
信任本机进程)。
|
||||
|
||||
## Agent 挂载示例
|
||||
|
||||
```bash
|
||||
# Claude Code(stdio)
|
||||
claude mcp add ppclock -- ppclock-mcp --mac AA:BB:CC:DD:EE:FF
|
||||
```
|
||||
|
||||
streamable HTTP 端点为 `http://<host>:8972/mcp`,请求头携带
|
||||
`Authorization: Bearer <PPCLOCK_MCP_TOKEN>`;token 不符返回 401。HTTP 为无状态模式
|
||||
(`stateless_http`),无需会话保持。
|
||||
|
||||
## 13 工具参考
|
||||
|
||||
全部工具 async,返回统一契约(见下节)。参数与行为逐字对齐 `src/ppclock/mcp_tools.py`。
|
||||
|
||||
| 工具 | 参数 | 说明 |
|
||||
|---|---|---|
|
||||
| `scan_devices` | `timeout: float = 5.0` | 扫描附近 NRF- 前缀墨水屏设备,返回 `[{name,address,rssi}]` |
|
||||
| `device_status` | 无 | 查询连接状态/绑定 MAC/设备 ID/空闲秒数 |
|
||||
| `set_time` | `tz: float = 8.0` | 对时;tz 为时区偏移(默认 8=北京时间) |
|
||||
| `set_mode` | `mode: str` | 切换显示模式:`clock1-3`/`calendar1-3`/`image0-3`/`tricolor`/`mono` |
|
||||
| `toggle` | `name: str` | 单字节切换:`invert`/`font`/`rotate180`/`hour_format`/`clock_color` |
|
||||
| `upload_image` | `source: str, slot: int = 0, algo: str = "atkinson", mono: bool = False, threshold/diffusion/brightness/contrast/saturation/rotate: float\|None = None` | 传图到指定槽位。`source` = 服务器路径或 base64(可带 data URI 前缀);`algo` ∈ `none/floydsteinberg/atkinson/bayer/stucki/jarvis`;6 个可选 adjust 参数:`threshold`/`diffusion`/`brightness`/`contrast`/`saturation`/`rotate`(仅显式传入时生效) |
|
||||
| `render_template` | `name: str, payload: dict\|None = None, slot: int = 0, algo: str = "atkinson"` | 本地渲染模板并上传:`schedule`/`businesscard`/`memo`/`course`/`qrcode`/`custom` |
|
||||
| `countdown` | `date: str, mode: str = "clock", prefix: str\|None = None` | 倒计时;`date` 为 ISO `YYYY-MM-DD`;`mode` = `clock`/`calendar` |
|
||||
| `countdown_off` | 无 | 关闭倒计时 |
|
||||
| `calendar_text` | `text: str` | 设置日历中文文字并切到日历模式一 |
|
||||
| `set_sleep` | `on: bool, start_h: int, end_h: int` | 设置休眠时段(0-23 时) |
|
||||
| `clear_screen` | 无 | 刷屏(EPD 清屏) |
|
||||
| `raw_send` | `data_hex: str, channel: str = "alt"` | 逃生舱:直发十六进制字节串;`channel` = `rxtx`/`epd`/`alt` |
|
||||
|
||||
`device_status` 返回字段:`connected` / `mac` / `device_id`(尽力而为,失败省略)/
|
||||
`idle_seconds` / `connect_count` / `connect_timeout` / `idle_timeout`。
|
||||
|
||||
## 输出契约与错误码
|
||||
|
||||
与 CLI `--json` 同构的统一契约:
|
||||
|
||||
```json
|
||||
成功 {"ok": true, "tool": "<name>", "data": {...}}
|
||||
失败 {"ok": false, "tool": "<name>", "error": {"code", "message", "hint"?}}
|
||||
```
|
||||
|
||||
错误码(5 种):
|
||||
|
||||
| code | 触发 | hint |
|
||||
|---|---|---|
|
||||
| `CONNECT_TIMEOUT` | 守候窗口内未连上设备 | 设备长睡眠、广播窗口 30-60s;调大 `--connect-timeout` 或稍后重试 |
|
||||
| `DEVICE_NOT_FOUND` | 扫描未发现设备 | 未发现 NRF- 前缀设备;确认设备在位且未处于深睡 |
|
||||
| `BLE_ERROR` | 其他传输层错误 | 无 hint |
|
||||
| `INVALID_PARAM` | 参数校验失败(非法 base64/非图片/非法日期/非法 hex 等) | 无 hint,message 给出具体原因 |
|
||||
| `INTERNAL` | 工具层兜底未分类异常 | 无 hint,message 为 `类型: 详情` |
|
||||
|
||||
`hint` 仅对 `CONNECT_TIMEOUT` / `DEVICE_NOT_FOUND` 出现,语义是给 agent 的可执行恢复建议
|
||||
(调参重试 / 检查设备),不是给人看的错误描述。
|
||||
|
||||
## 连接行为(方案 C:按需连接 + 空闲保持)
|
||||
|
||||
- **守候窗口**:首次操作发起连接,守候 `--connect-timeout` 秒(默认 90s,覆盖设备
|
||||
30-60s 广播窗口);设备在深睡中也能等到其广播。
|
||||
- **空闲超时**:操作完成后保持连接;空闲 `--idle-timeout` 秒(默认 300s)自动断开让
|
||||
设备回睡眠。`--idle-timeout 0` 退化为每次调用独立连接。
|
||||
- **串行**:所有设备操作经一把锁串行执行(BLE 适配器独占),并发调用自动排队,不会
|
||||
互相打断。
|
||||
- **重连一次**:操作中连接丢失(TransportError)→ 断开重连并重试一次,再失败才向上
|
||||
返回错误。
|
||||
|
||||
## Windows 部署(蓝牙所在机)
|
||||
|
||||
```powershell
|
||||
python -m venv .venv
|
||||
.venv\Scripts\pip install -e ".[mcp]"
|
||||
setx PPCLOCK_MCP_TOKEN "<token>" # 或按服务方式注入环境变量
|
||||
.venv\Scripts\ppclock-mcp --transport http --host 0.0.0.0 --port 8972
|
||||
```
|
||||
|
||||
- 防火墙放行 **8972/tcp**,仅对局域网段开放(勿暴露公网;token 是唯一防线)。
|
||||
- 不动既有 **8971** bridge 与其他服务:8972 为独立端口、独立进程。
|
||||
- `--mac` 建议显式指定设备地址,避免自动扫描误绑其他 `NRF-` 设备。
|
||||
|
||||
## 不暴露的能力
|
||||
|
||||
以下 SDK 能力**有意不**注册为 MCP 工具:
|
||||
|
||||
| 能力 | 原因 |
|
||||
|---|---|
|
||||
| OTA 固件升级(`ota`) | 高危写闪存,agent 误调用可砖机;只走 CLI 显式 `--yes` 授权路径 |
|
||||
| 激活(`activate`/`activate_auto`) | 一次性出厂级操作,日常 agent 场景不需要;保留在 SDK/CLI |
|
||||
| LUT 校准(`lut`) | 面板厂商级调试参数,误刷影响显示质量 |
|
||||
| WiFi 配置(`wifi`) | 本固件为 no-op(固件证据),暴露只会误导 agent |
|
||||
| 轮播(`rotation`) | 本固件为 no-op(固件证据),同上 |
|
||||
|
||||
需要这些能力时按 `docs/sdk/API.md` 走 SDK/CLI,不经 MCP 面。
|
||||
Reference in new issue
Block a user