docs(mcp): 统一服务文档目录

This commit is contained in:
xqzp2026
2026-09-07 12:27:02 +09:30
parent 237a1f1c26
commit 12f69504e4
4 changed files with 170 additions and 3 deletions
@@ -67,7 +67,7 @@
| MCP Token 过期/401 | 清除当前用户 MCP Token,重新换取一次;同一请求不自动重放工具副作用 | | MCP Token 过期/401 | 清除当前用户 MCP Token,重新换取一次;同一请求不自动重放工具副作用 |
| accessToken 刷新 | 保留 MCP Token;若服务返回 401,再重新换取 | | accessToken 刷新 | 保留 MCP Token;若服务返回 401,再重新换取 |
| 切换账号 | 先断开旧 MCP Client,再加载新账号 Token 并建立新 Client | | 切换账号 | 先断开旧 MCP Client,再加载新账号 Token 并建立新 Client |
| 退出登录 | 销毁旧 Claw/MCP Client,删除当前账号本地 MCP Token;服务端撤销或等待短期过期 | | 退出登录 | 销毁旧 Claw/MCP Client,删除当前账号本地 MCP Token;当前永久 Token 不会自动失效,需要显式调用 revoke |
| 多账号 | Keychain key 必须包含稳定用户 ID,禁止所有账号共用 `mcpToken` | | 多账号 | Keychain key 必须包含稳定用户 ID,禁止所有账号共用 `mcpToken` |
~~建议 MCP Token 默认有效期 15 分钟,并提供换取接口;长期 AK 仅用于受控开发/管理场景。~~ ~~建议 MCP Token 默认有效期 15 分钟,并提供换取接口;长期 AK 仅用于受控开发/管理场景。~~
@@ -115,11 +115,32 @@
- 不存在则自动创建永久 Token,memo 标记 `open-api 自动签发(<scopeCode>)`。 - 不存在则自动创建永久 Token,memo 标记 `open-api 自动签发(<scopeCode>)`。
- 全程写 `audit_log`(`tool_name=open.token.ensure`、`client_type=open-api`,手机号/邮箱脱敏,不记录 Token)。 - 全程写 `audit_log`(`tool_name=open.token.ensure`、`client_type=open-api`,手机号/邮箱脱敏,不记录 Token)。
**关键约束与对策**:`created=false` 时拿不到明文。因此 xiaoqu-ai 业务后端必须在首次 `created=true` 时**自己持久化明文**(按 user_id 关联,加密存储),之后下发给本用户的客户端;若明文丢失,只能由管理员在后台禁用旧 Token 后再调 `ensure` 触发新建(或将来加 rotate 接口)。 **关键约束与对策**:`created=false` 时拿不到明文。因此 xiaoqu-ai 业务后端必须在首次 `created=true` 时**自己持久化明文**(按 user_id 关联,加密存储),之后下发给本用户的客户端。
**身份约束**:业务后端不得接受客户端或模型传入的 `user_id`、`mobile`、`email` 作为身份依据。必须先从已验证的 xiaoqu-ai `accessToken` 会话解析用户,再由业务后端查询该用户的手机号/邮箱并调用 `ensure`。`X-Open-Key` 只允许服务端保管。
### 4.1a Token 丢失与主动失效(建议补充)
当前 `ensure` 在 `created=false` 时不会返回明文,无法解决业务后端首次落库失败或 Token 泄露后的换发问题。建议增加两个服务间接口,均使用 `X-Open-Key` 鉴权:
`POST /api/open/token/rotate`
- 按用户和 `scopeCode` 禁用当前有效 Token,创建新 Token。
- 仅本次返回新 Token 明文;旧 Token 立即失效。
- 记录旧 Token、新 Token 前缀、用户和 scope,禁止记录 Token 明文。
- 具备幂等保护,避免并发换发产生多个有效 Token。
`POST /api/open/token/revoke`
- 按用户和 `scopeCode` 禁用当前 Token。
- 不返回 Token 明文;重复调用视为成功。
- 用于退出登录后的主动失效、设备解绑和安全事件处置。
在 `rotate/revoke` 尚未实现前,退出登录只能清理客户端本地凭证,不能声称服务端 Token 已失效;管理员后台禁用仍是唯一服务端回收方式。
### 4.1b xiaoqu-ai 业务后端门面(待 xiaoqu-ai 侧实现) ### 4.1b xiaoqu-ai 业务后端门面(待 xiaoqu-ai 侧实现)
iOS 面向的接口(建议沿用原设计):POST `/api/v1/mcp/session-token`,`Authorization: Bearer <xiaoqu-access-token>`。业务后端从登录态解析用户 → 取手机号/邮箱 → 调 `ensure` → 返回 `{token, expires_at, user_id}`。客户端身份字段(client、device_id)由业务后端自行记录,agent-service 不感知。 iOS 面向的接口(建议沿用原设计):POST `/api/v1/mcp/session-token`,`Authorization: Bearer <xiaoqu-access-token>`。业务后端从登录态解析用户 → 服务端查询手机号/邮箱 → 调 `ensure` → 返回 `{token, expires_at, user_id}`。不得使用请求体中的 `user_id/mobile/email` 覆盖登录态身份;客户端身份字段(client、device_id)由业务后端自行记录,agent-service 不感知。
### 4.2 POST `/mcp` ### 4.2 POST `/mcp`
@@ -0,0 +1,146 @@
# xiaoqu-operations-ai 接入 xiaoqu-mcp 开发设置
## 1. 目标
让 `ops-assistant-service` 通过服务端 MCP Client 调用
`xiaoqu_mcp_service`,保持现有:
```text
Router → Planner → Executor → Answer
```
每次调用使用当前已验证用户对应的 MCP Token,不把 MCP Token 放进提示词、Planner 输出、工具参数或普通日志。
## 2. 当前代码结论
- `ops-assistant-service` 是 FastAPI + Python 3.12 服务。
- 当前依赖中没有 MCP SDK,也没有 `tools/list` / `tools/call` 客户端。
- `Executor` 目前直接调用本地 capability:`customer_issues.*`、`smartclean.query`。
- 用户身份来自 Gateway JWT,并通过 `ops_identity_mappings` 解析租户、用户和 `scope_tags`。
- 当前最合适的接入点是 Executor 的工具适配层,不新增第二套编排器。
## 3. xiaoqu-mcp 服务契约
### 3.1 MCP 调用
- 地址:`POST <XQ_MCP_URL>/mcp`
- 认证:`Authorization: Bearer <xqak-token>`
- 初始化顺序:`initialize` → `notifications/initialized` → `tools/list` → `tools/call`
- 初始化后保存 `Mcp-Session-Id`。
- `tools/list` 已按 Token scope 过滤,`tools/call` 仍由服务端再次鉴权。
### 3.2 Token 初始化
服务间调用:`POST <XQ_MCP_URL>/api/open/token/ensure`
```http
X-Open-Key: <server-only-key>
Content-Type: application/json
```
请求体包含 `mobile` 或 `email`,以及固定的 `scopeCode`(首期建议 `operation`)。
约束:
- `X-Open-Key` 只能配置在受信任后端,不能下发 App。
- 业务后端必须从已验证用户会话查询手机号/邮箱,不能信任客户端或模型传入的身份字段。
- `created=true` 才返回 Token 明文;业务后端必须立即加密保存。
- `created=false` 不返回明文;Token 丢失前需先实现 rotate,退出登录需实现 revoke 才能立即失效。
## 4. 推荐实现
### 4.1 配置
在 `config.py` 增加以下 `OPS_ASSISTANT_` 配置:
| 变量 | 默认值 | 说明 |
|---|---|---|
| `XQ_MCP_ENABLED` | `false` | 是否启用 MCP capability |
| `XQ_MCP_URL` | unset | 例如 `http://xiaoqu-mcp:8088`,只存地址,不存用户 Token |
| `XQ_MCP_OPEN_KEY` | unset | 仅用于服务端 Token 初始化,使用 `SecretStr` |
| `XQ_MCP_SCOPE_CODE` | `operation` | 固定作用域,禁止由 Planner 或客户端选择 |
| `XQ_MCP_TIMEOUT_SECONDS` | `10` | MCP 请求超时 |
启用时必须同时提供 URL、Open Key 和 scope;生产环境禁止明文写入仓库。
### 4.2 新增最小模块
建议只增加两个模块:
- `src/ops_assistant_service/mcp_client.py`
- 管理 HTTP 请求、JSON-RPC、Session ID、Bearer Header、超时和错误映射。
- 进程内按 `user_id` 缓存 MCP Session;账号或 Token 变化时销毁。
- `src/ops_assistant_service/mcp_token_provider.py`
- 接收已验证的 `SharedIdentity`。
- 从受信任用户资料源取得 mobile/email。
- 调用 `ensure`,首次创建时加密持久化明文。
- 不接受 `user_id/mobile/email` 作为客户端覆盖参数。
不引入通用 MCP 框架、第二个 Agent 或数据库直连;现有 `httpx` 已足够完成首期只读接入。
### 4.3 Capability 映射
在 `capability_registry.py` 增加固定的本地 capability,禁止把远端 `tools/list` 原样暴露给 Planner:
| 本地 capability | MCP 工具 | 首期权限 |
|---|---|---|
| `xiaoqu.agent_count` | `agent.count` | read |
| `xiaoqu.agent_list` | `agent.list.query` | read |
| `xiaoqu.property_list` | `property.list.query` | read |
Planner 只能选择注册表中的名称和 schema。Executor 在调用前同时检查:
```text
应用允许 ∩ 用户 scope_tags ∩ 租户/数据范围
```
远端返回结果先经过字段白名单投影,再交给 Answer;Token、原始 Header 和未授权字段不得进入 trace。
### 4.4 Executor 接入点
在 `executor.py` 增加一个只读分支:
```text
validate_tool_input
→ 校验本地 capability 和参数白名单
→ 读取 SharedIdentity / DataScope
→ 获取当前用户 MCP Token
→ MCP tools/call
→ 结果投影
→ 现有 execution_trace / Answer 链路
```
现有 `customer_issues.*` 和 `smartclean.query` 保持不变。MCP 不可用时返回稳定的 `TOOL_UNAVAILABLE`,不得回退到公共 Token 或直接访问 xiaoqu-mcp 数据库。
## 5. 生命周期与安全
- 登录用户变化:先关闭旧 Session,再建立新用户 Session。
- MCP 返回 401:清理当前用户 Token,最多执行一次重新获取和重连;不自动重放副作用请求。
- 退出登录:清理本地/服务端 Token 缓存;实现 revoke 后再主动撤销远端 Token。
- 日志只记录用户 ID、工具名、scope 和错误码,不记录 Token、Authorization Header 或手机号/邮箱明文。
- `tools/list` 仅用于校验远端能力;真正可调用集合以本地 allowlist 为准。
## 6. 开发顺序
1. 先在 xiaoqu-ai 业务后端完成登录态到 `ensure` 的门面,并验证 Token 明文加密落库。
2. 增加 `Settings` 配置和启动校验。
3. 实现 `mcp_token_provider.py` 和 `mcp_client.py`,补充 JSON-RPC/Session 单元测试。
4. 增加 3 个只读 capability,并接入 Executor。
5. 增加用户隔离、scope 拒绝、401 重连、Token 脱敏和 MCP 不可用测试。
6. 先在 development/test 环境启用,完成联调后再进入 staging。
## 7. 验收标准
- 用户 A 的请求始终使用 A 的 MCP Token,用户 B 不能复用。
- A 无对应 scope 时,Planner/Executor 均不能调用该 MCP 工具。
- `tools/list`、`tools/call` 使用同一用户 Session 和 Bearer Token。
- 切换用户后旧 Session 不再发出请求。
- MCP 401 只刷新当前用户,且同一请求不重复执行副作用。
- 测试、日志、trace、配置文件和 Git 历史中均无 Token 明文。
## 8. 当前不做
- 不把 MCP Client 放进 iOS/Android 端。
- 不把全部远程工具动态注册给 Planner。
- 不复制 xiaoqu-mcp 数据库或绕过 MCP 权限。
- 不在本次首期引入写工具;写工具需另行设计审批、幂等和补偿协议。