Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58e51e96a9 |
@@ -0,0 +1,153 @@
|
|||||||
|
# xiaoqu-ai 接入 xiaoqu-mcp 详细设计
|
||||||
|
|
||||||
|
## 1. 目标与边界
|
||||||
|
|
||||||
|
本文是 [`xiaoqu 多产品 Agent 统一接入 xiaoqu-mcp 总体设计`](./xiaoqu-mcp-multi-product-agent-design.md) 的 xiaoqu-ai 落地设计。
|
||||||
|
|
||||||
|
xiaoqu-ai 的 iOS、Android、Web 共用一套服务端 MCP 接入,不在三个客户端分别实现 MCP Client:
|
||||||
|
|
||||||
|
```text
|
||||||
|
iOS / Android / Web
|
||||||
|
│ 产品登录 Token
|
||||||
|
▼
|
||||||
|
xiaoqu-ai Gateway / Agent Runtime
|
||||||
|
│ 用户 MCP Token(仅服务端持有)
|
||||||
|
▼
|
||||||
|
xiaoqu-agent-service /mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
项目目录:
|
||||||
|
|
||||||
|
- iOS、Web、Gateway、Agent Service:`/Users/tonylai/xiaoquai/xiaoqu-ai`
|
||||||
|
- Android:`/Users/tonylai/jiaxk/xiaoqu-ai-android`
|
||||||
|
|
||||||
|
## 2. 当前代码依据
|
||||||
|
|
||||||
|
| 端/服务 | 当前入口 | 结论 |
|
||||||
|
|---|---|---|
|
||||||
|
| iOS 销售助手 | `ios/Sources/XiaoquCRM/Features/SalesAgent/SalesAgentClient.swift` | 继续调用 `/api/v1/sales-agent/*` REST/SSE |
|
||||||
|
| iOS 管理助手 | `ios/Sources/XiaoquCRM/Features/AI/Networking/ManagerAgentClient.swift` | 继续调用服务端 Agent,不新增 MCP Token |
|
||||||
|
| Android | `app/src/main/java/com/xiaoquai/crm/data/remote/WebSocketManager.kt`、`ApiService.kt` | 继续走 Gateway WebSocket/REST,`TokenManager` 只保存产品 Token |
|
||||||
|
| Web | `web/src/hooks/use-agent-chat.ts` | 继续调用 `/api/v1/agents/{id}/invoke` |
|
||||||
|
| Gateway | `gateway/internal/agent/tools.go`、`gateway/internal/handler/runtime_tool_invoke_handlers.go` | 已有统一 ToolExecutor、数据范围校验和运行时工具入口 |
|
||||||
|
| Agent Service | `agent-service/agent_service/tools/runtime_gateway_tools.py` | 已使用当前用户 JWT调用 Gateway runtime catalog/tool invoke |
|
||||||
|
|
||||||
|
iOS 的 `ClawBridge.swift` 是独立端侧 Agent 模式,不属于本次服务端 xiaoqu-mcp 接入,不修改其 Keychain、MCP 配置或 Token。
|
||||||
|
|
||||||
|
## 3. 统一接入点
|
||||||
|
|
||||||
|
MCP 适配器放在 Gateway 的工具执行层,三端最终复用同一实现:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Web / Android Agent 请求 ──► Gateway AgentRuntime ─┐
|
||||||
|
├─► Gateway ToolExecutor
|
||||||
|
iOS Sales Agent ──► agent-service │ │
|
||||||
|
└─ runtime_gateway_tools ───────┘ ▼
|
||||||
|
xiaoqu-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
这样保留现有客户端和 Agent 编排,只把新的远程工具接入集中在 Gateway。Agent Service 继续转发已验证的用户 JWT,不自行持有第二份 xiaoqu-mcp Token 缓存。
|
||||||
|
|
||||||
|
## 4. Gateway 变更
|
||||||
|
|
||||||
|
### 4.1 配置
|
||||||
|
|
||||||
|
在 Gateway 启动配置中增加:
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `XQ_MCP_ENABLED` | `false` | 是否启用 xiaoqu-mcp 工具 |
|
||||||
|
| `XQ_MCP_URL` | unset | xiaoqu-mcp 内网地址 |
|
||||||
|
| `XQ_MCP_OPEN_KEY` | unset | Token 初始化凭证 |
|
||||||
|
| `XQ_MCP_SCOPE_CODE` | unset | xiaoqu-ai 固定 scope;启用前必须在管理后台确认 |
|
||||||
|
| `XQ_MCP_TIMEOUT_SECONDS` | `10` | MCP 请求超时 |
|
||||||
|
|
||||||
|
启用时 URL、Open Key 和 scope 必填。Open Key 只来自部署 Secret,不写入 YAML、客户端配置或仓库。
|
||||||
|
|
||||||
|
### 4.2 最小模块
|
||||||
|
|
||||||
|
新增 `gateway/internal/connector/xiaoqumcp/`:
|
||||||
|
|
||||||
|
- `token_provider.go`
|
||||||
|
- 输入 Gateway 已验证的 `tenantID`、`userID`。
|
||||||
|
- 从用户资料存储取得可信 mobile/email 并调用 `ensure`。
|
||||||
|
- 按租户、用户和 scope 缓存 Token;401 时只刷新当前用户一次。
|
||||||
|
- `client.go`
|
||||||
|
- 管理 MCP JSON-RPC、Session ID、Bearer Header、超时和错误映射。
|
||||||
|
- 按租户、用户和 scope 隔离 Session。
|
||||||
|
|
||||||
|
使用 Go 标准 HTTP Client 和项目现有错误/日志设施,不增加 MCP 框架依赖。
|
||||||
|
|
||||||
|
### 4.3 ToolExecutor 接入
|
||||||
|
|
||||||
|
在 `gateway/internal/agent/tools.go` 注册稳定的本地工具名,由 Handler 调用 `xiaoqumcp.Client`。不得把远端 `tools/list` 原样注册给模型。
|
||||||
|
|
||||||
|
首期只接只读工具。候选映射以 xiaoqu-mcp 当前工具为基础,但必须先为 xiaoqu-ai 创建并审核独立 scope:
|
||||||
|
|
||||||
|
| Gateway 本地工具 | MCP 工具 | 状态 |
|
||||||
|
|---|---|---|
|
||||||
|
| `xiaoqu.agent_count` | `agent.count` | scope 绑定后启用 |
|
||||||
|
| `xiaoqu.agent_list` | `agent.list.query` | scope 绑定后启用 |
|
||||||
|
| `xiaoqu.property_list` | `property.list.query` | scope 绑定后启用 |
|
||||||
|
|
||||||
|
每个工具继续使用现有 `RequiredDataScope`、Agent Capability 绑定和参数 schema。MCP 返回结果先做字段白名单投影,再进入模型上下文、卡片渲染和 `chat_tool_logs`。
|
||||||
|
|
||||||
|
## 5. 用户与权限流程
|
||||||
|
|
||||||
|
```text
|
||||||
|
产品登录 Token
|
||||||
|
→ Gateway middleware 得到 userID / tenantID / role
|
||||||
|
→ Agent Capability + RequiredDataScope 校验
|
||||||
|
→ 可信用户资料解析 mobile/email
|
||||||
|
→ token_provider.ensure(scopeCode)
|
||||||
|
→ mcp_client.tools/call
|
||||||
|
→ xiaoqu-mcp 再校验 Token scope 与数据权限
|
||||||
|
```
|
||||||
|
|
||||||
|
`agent.InvokeRequest` 已携带 `UserID`、`TenantID`、`UserJWT` 和 `UserRole`。MCP Handler 必须使用这些可信字段,不接受模型参数覆盖身份或 scope。
|
||||||
|
|
||||||
|
Agent Service 的 `runtime_gateway_tools.py` 继续转发入站用户 JWT;无 JWT 时保持 fail-closed,不允许自签或使用公共用户身份。
|
||||||
|
|
||||||
|
## 6. 客户端影响
|
||||||
|
|
||||||
|
| 客户端 | 变更 |
|
||||||
|
|---|---|
|
||||||
|
| iOS | 无 MCP 网络层变更;继续消费现有 REST/SSE、确认卡和工具结果 |
|
||||||
|
| Android | 无 MCP 网络层变更;Gateway Token 仍由现有 `TokenManager` 管理 |
|
||||||
|
| Web | 无 MCP 网络层变更;继续调用 Agent invoke API 并渲染返回结果 |
|
||||||
|
|
||||||
|
如果新工具需要专用展示,只扩展现有服务端响应投影和客户端卡片 schema;不得因此向客户端下发 MCP Token、Session ID 或原始 Header。
|
||||||
|
|
||||||
|
## 7. 错误与生命周期
|
||||||
|
|
||||||
|
- 用户切换或产品会话失效时,当前用户的 MCP Token 缓存和 Session 一并失效。
|
||||||
|
- MCP 401:清理当前用户缓存,重新 `ensure` 并重连一次。
|
||||||
|
- MCP 403:返回权限不足,不刷新 Token。
|
||||||
|
- MCP 超时或不可用:返回现有稳定工具错误,不回退公共 Token 或数据库直连。
|
||||||
|
- 只读请求最多重试一次;写工具不在首期范围。
|
||||||
|
- 日志和 `chat_tool_logs` 只记录工具名、状态、耗时与脱敏错误,不记录 Token、Header、mobile/email 或未投影原始结果。
|
||||||
|
|
||||||
|
## 8. 开发顺序
|
||||||
|
|
||||||
|
1. 在目标环境创建或确认 xiaoqu-ai 独立 scope,并绑定首期只读工具。
|
||||||
|
2. 增加 Gateway 配置与启动校验。
|
||||||
|
3. 实现 `token_provider.go` 和 `client.go`,覆盖 Token、Session、超时和错误映射测试。
|
||||||
|
4. 在 ToolExecutor 注册固定工具并复用现有 DataScope 校验。
|
||||||
|
5. 验证 Agent Service runtime gateway 路径仍只转发用户 JWT。
|
||||||
|
6. 分别用 iOS、Android、Web 完成同用户、跨用户和跨租户联调。
|
||||||
|
|
||||||
|
## 9. 项目验收
|
||||||
|
|
||||||
|
- 同一用户在 iOS、Android、Web 调用同一工具时,结果契约和数据权限一致。
|
||||||
|
- 三端请求、存储、日志中均无 MCP Token、Session ID 或 `X-Open-Key`。
|
||||||
|
- Web/Android Gateway Agent 与 iOS Sales Agent 最终调用同一个 Gateway MCP Handler。
|
||||||
|
- 用户 A/B、不同租户和 scope 的 Token 缓存与 MCP Session 完全隔离。
|
||||||
|
- 无本地 Capability、无 RequiredDataScope 或无 MCP scope 时均不能调用。
|
||||||
|
- MCP 401 只刷新当前用户;MCP 不可用不影响未启用该 Capability 的原有 Agent 功能。
|
||||||
|
|
||||||
|
## 10. 当前不做
|
||||||
|
|
||||||
|
- 不为 iOS、Android、Web 分别实现 MCP Client。
|
||||||
|
- 不改造 iOS ClawBridge。
|
||||||
|
- 不把远端全部工具动态暴露给 Agent。
|
||||||
|
- 不在首期接入写工具或副作用自动重试。
|
||||||
@@ -1,232 +0,0 @@
|
|||||||
# xiaoqu 多端 Agent 统一接入 xiaoqu-mcp 开发设计
|
|
||||||
|
|
||||||
## 1. 设计结论
|
|
||||||
|
|
||||||
xiaoqu-ai 的 iOS、Android、Web **共用一套 Agent/MCP 接入链路**:
|
|
||||||
|
|
||||||
```text
|
|
||||||
iOS / Android / Web
|
|
||||||
│ 产品登录 Token
|
|
||||||
▼
|
|
||||||
xiaoqu-ai Gateway / Agent Runtime
|
|
||||||
│ 用户 MCP Token(仅服务端持有)
|
|
||||||
▼
|
|
||||||
xiaoqu-agent-service /mcp
|
|
||||||
```
|
|
||||||
|
|
||||||
运营项目是另一套产品和 Agent 编排服务,因此保留自己的入口,但复用同一个
|
|
||||||
xiaoqu-mcp 服务、Token 原语、工具契约、权限和审计规则:
|
|
||||||
|
|
||||||
```text
|
|
||||||
运营 iOS / Android
|
|
||||||
│ 产品登录 Token
|
|
||||||
▼
|
|
||||||
ops-assistant-service
|
|
||||||
│ 用户 MCP Token(仅服务端持有)
|
|
||||||
▼
|
|
||||||
xiaoqu-agent-service /mcp
|
|
||||||
```
|
|
||||||
|
|
||||||
共同的是服务能力和协议,不是 Swift/Kotlin UI 代码。客户端不实现 MCP Client,
|
|
||||||
不保存 MCP Token,也不接触 `X-Open-Key`。
|
|
||||||
|
|
||||||
### 1.1 范围
|
|
||||||
|
|
||||||
| 产品 | 客户端 | 项目目录 |
|
|
||||||
|---|---|---|
|
|
||||||
| xiaoqu-ai | iOS、Web、服务端 Agent | `/Users/tonylai/xiaoquai/xiaoqu-ai` |
|
|
||||||
| xiaoqu-ai | Android | `/Users/tonylai/jiaxk/xiaoqu-ai-android` |
|
|
||||||
| xiaoqu-operations-ai | iOS、Android、服务端 Agent | `/Users/tonylai/jiaxk/xiaoqu-operations-ai` |
|
|
||||||
| xiaoqu-mcp | MCP 服务、Token、权限、审计 | 当前仓库 `xiaoqu-agent-service` |
|
|
||||||
|
|
||||||
### 1.2 明确不做
|
|
||||||
|
|
||||||
- 不为 iOS、Android、Web 分别实现 MCP Client。
|
|
||||||
- 不提供面向 App/Web 的 MCP Token 换取接口。
|
|
||||||
- 不把固定 MCP Token、`X-Open-Key` 写入 App、浏览器配置、prompt 或 Git。
|
|
||||||
- 不让客户端、Planner 或模型提交 `user_id`、手机号、邮箱、租户或 scope 作为授权依据。
|
|
||||||
- 不改造现有 iOS ClawBridge;它是独立的端侧 Agent 模式,不属于本次 xiaoqu-mcp 接入链路。
|
|
||||||
|
|
||||||
## 2. 当前代码依据
|
|
||||||
|
|
||||||
| 项目/端 | 当前入口 | 结论 |
|
|
||||||
|---|---|---|
|
|
||||||
| xiaoqu-ai iOS | `ios/Sources/XiaoquCRM/Features/SalesAgent/SalesAgentClient.swift`、`Features/AI/Networking/ManagerAgentClient.swift` | 已通过 Agent REST/SSE 调用,继续复用 |
|
|
||||||
| xiaoqu-ai Android | `app/src/main/java/com/xiaoquai/crm/data/remote/WebSocketManager.kt`、`ApiService.kt` | 已通过 Gateway WebSocket/REST 调用,继续复用 |
|
|
||||||
| xiaoqu-ai Web | `web/src/hooks/use-agent-chat.ts` | 已调用 Gateway `/api/v1/agents/{id}/invoke`,继续复用 |
|
|
||||||
| xiaoqu-ai Agent | `agent-service`、`gateway` | 增加服务端 MCP Client 和用户 Token Provider |
|
|
||||||
| 运营 iOS/Android | `ios`、`android` | 已调用 `ops-assistant-service` REST/WebSocket,继续复用 |
|
|
||||||
| 运营 Agent | `services/ops-assistant-service` | 在 Executor 工具适配层增加 MCP Client |
|
|
||||||
|
|
||||||
xiaoqu-ai iOS 的 `ClawBridge.swift` 当前具备端侧 MCP 能力,但 Android 和 Web 没有。
|
|
||||||
为了让三端真正共用一套,本次不把新的 xiaoqu MCP Token 接入 ClawBridge,统一走服务端 Agent。
|
|
||||||
|
|
||||||
## 3. 统一架构
|
|
||||||
|
|
||||||
```text
|
|
||||||
┌─────────────────────────────────────────────────────┐
|
|
||||||
│ xiaoqu-ai │
|
|
||||||
│ iOS ─┐ │
|
|
||||||
│ Android ──► Gateway ──► Agent Runtime ──┐ │
|
|
||||||
│ Web ─┘ │ │
|
|
||||||
└────────────────────────────────────────┼────────────┘
|
|
||||||
│ MCP
|
|
||||||
┌────────────────────────────────────────┼────────────┐
|
|
||||||
│ xiaoqu-operations-ai │ │
|
|
||||||
│ iOS ─┐ │ │
|
|
||||||
│ Android ──► ops-assistant-service ─────┤ │
|
|
||||||
└────────────────────────────────────────┼────────────┘
|
|
||||||
▼
|
|
||||||
xiaoqu-agent-service
|
|
||||||
Token + Scope + Tool
|
|
||||||
行级权限 + Audit
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3.1 职责
|
|
||||||
|
|
||||||
| 层 | 职责 |
|
|
||||||
|---|---|
|
|
||||||
| iOS/Android/Web | 登录、会话 UI、流式展示、确认交互;只携带产品登录凭证 |
|
|
||||||
| 产品 Gateway | 验证登录态,注入可信用户/租户上下文,代理 Agent 请求 |
|
|
||||||
| 产品 Agent Runtime | 编排 Agent、维护 capability allowlist、获取用户 MCP Token、调用 MCP |
|
|
||||||
| xiaoqu-agent-service | 校验 MCP Token、过滤工具、执行行级权限、查询业务数据、记录审计 |
|
|
||||||
|
|
||||||
## 4. 认证与 Token
|
|
||||||
|
|
||||||
### 4.1 三类凭证
|
|
||||||
|
|
||||||
| 凭证 | 使用者 | 用途 |
|
|
||||||
|---|---|---|
|
|
||||||
| 产品登录 Token | iOS/Android/Web → 产品 Gateway | 证明当前产品用户身份 |
|
|
||||||
| `X-Open-Key` | 产品 Agent Runtime → `/api/open/token/ensure` | 服务间获取用户 MCP Token |
|
|
||||||
| 用户 MCP Token `xqak_*` | 产品 Agent Runtime → `/mcp` | 绑定 MCP 用户、scope、权限和审计 |
|
|
||||||
|
|
||||||
`X-Open-Key` 和 MCP Token 均只存在于受信任服务端。
|
|
||||||
|
|
||||||
### 4.2 用户映射
|
|
||||||
|
|
||||||
1. Gateway 验证产品登录 Token。
|
|
||||||
2. Agent Runtime 从可信上下文取得产品用户、租户和数据范围。
|
|
||||||
3. Agent Runtime 从受信任用户资料源取得手机号/邮箱。
|
|
||||||
4. Agent Runtime 用固定 `scopeCode` 调用 `POST /api/open/token/ensure`。
|
|
||||||
5. xiaoqu-agent-service 返回该 MCP 用户对应的 Token。
|
|
||||||
6. Agent Runtime 使用此 Token 调用 `/mcp`。
|
|
||||||
|
|
||||||
禁止接受客户端或模型传入的手机号、邮箱、`user_id`、`tenant_id`、`scopeCode`
|
|
||||||
覆盖可信上下文。scope 由服务端配置固定,启用前与管理后台实际配置核对。
|
|
||||||
|
|
||||||
### 4.3 服务端缓存与生命周期
|
|
||||||
|
|
||||||
- 缓存键至少包含:产品、租户、产品用户 ID、scope。
|
|
||||||
- 切换账号或退出登录时,产品会话失效;不得让新用户复用旧用户 MCP Session。
|
|
||||||
- MCP 返回 401 时,只清除当前用户缓存并重新 `ensure` 一次。
|
|
||||||
- 只读调用可在重连后重试一次;有副作用调用不得自动重放。
|
|
||||||
- 日志仅记录用户 ID、scope、工具名、状态和耗时,不记录凭证明文或手机号/邮箱明文。
|
|
||||||
|
|
||||||
## 5. xiaoqu-mcp 契约
|
|
||||||
|
|
||||||
### 5.1 `POST /api/open/token/ensure`
|
|
||||||
|
|
||||||
认证:`X-Open-Key: <server-only-key>`。
|
|
||||||
|
|
||||||
请求:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"mobile": "<trusted-user-mobile>",
|
|
||||||
"email": "<trusted-user-email>",
|
|
||||||
"scopeCode": "<server-configured-scope>"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- `mobile`、`email` 至少一个,手机号优先。
|
|
||||||
- 现有有效 Token:解密 `key_cipher` 返回同一明文。
|
|
||||||
- 历史无密文 Token:禁用旧 Token,自动签发新 Token。
|
|
||||||
- 不存在有效 Token:创建长期 Token;回收通过禁用实现。
|
|
||||||
- 响应和审计不得记录 Token 明文。
|
|
||||||
|
|
||||||
错误语义:`400` 参数/scope 错误,`401` Open Key 无效,`403` Open API 未启用,
|
|
||||||
`404` 用户不存在或不属于允许的企业账号。
|
|
||||||
|
|
||||||
### 5.2 `POST /mcp`
|
|
||||||
|
|
||||||
```http
|
|
||||||
Authorization: Bearer <user-mcp-token>
|
|
||||||
Content-Type: application/json
|
|
||||||
Accept: application/json, text/event-stream
|
|
||||||
```
|
|
||||||
|
|
||||||
调用顺序:`initialize` → `notifications/initialized` → `tools/list` → `tools/call`。
|
|
||||||
初始化响应包含 Session ID 时,后续请求携带 `Mcp-Session-Id`。
|
|
||||||
|
|
||||||
权限同时在两个位置收口:
|
|
||||||
|
|
||||||
```text
|
|
||||||
产品 Agent capability allowlist
|
|
||||||
∩ MCP Token scope
|
|
||||||
∩ 当前用户/租户/行级数据范围
|
|
||||||
```
|
|
||||||
|
|
||||||
`tools/list` 按 scope 过滤;`tools/call` 再次强制校验,不能只依赖提示词或隐藏菜单。
|
|
||||||
|
|
||||||
## 6. 最小变更清单
|
|
||||||
|
|
||||||
### 6.1 xiaoqu-agent-service
|
|
||||||
|
|
||||||
`ensure`、Token 密文、Bearer 鉴权、scope 和审计已交付,保持协议兼容;本轮主要配合
|
|
||||||
两个 Agent Runtime 联调,不为客户端增加新接口。
|
|
||||||
|
|
||||||
### 6.2 xiaoqu-ai
|
|
||||||
|
|
||||||
| 层 | 变更 |
|
|
||||||
|---|---|
|
|
||||||
| Gateway/Agent Runtime | 增加用户 MCP Token Provider 和 MCP HTTP Client;接入现有工具适配层 |
|
|
||||||
| iOS | 保持现有 Agent REST/SSE 调用;不修改 Keychain 和 ClawBridge 的 MCP Token |
|
|
||||||
| Android | 保持现有 Gateway REST/WebSocket 调用;`TokenManager` 只保存产品 Token |
|
|
||||||
| Web | 保持现有 `/agents/{id}/invoke` 等 Agent API;浏览器不感知 MCP |
|
|
||||||
|
|
||||||
### 6.3 xiaoqu-operations-ai
|
|
||||||
|
|
||||||
在现有 `Router → Planner → Executor → Answer` 中,只修改 Executor 工具适配层:
|
|
||||||
|
|
||||||
```text
|
|
||||||
validate capability
|
|
||||||
→ trusted user context
|
|
||||||
→ MCP Token Provider
|
|
||||||
→ MCP tools/call
|
|
||||||
→ result projection
|
|
||||||
→ execution trace / Answer
|
|
||||||
```
|
|
||||||
|
|
||||||
具体设置见 `xiaoqu-mcp-integration-setup.md`。
|
|
||||||
|
|
||||||
## 7. 开发顺序
|
|
||||||
|
|
||||||
| # | 工作 | 完成标准 |
|
|
||||||
|---|---|---|
|
|
||||||
| 1 | 确认两个产品的用户映射和实际 scopeCode | 不依赖客户端身份字段,scope 已在管理后台存在 |
|
|
||||||
| 2 | xiaoqu-ai Agent Runtime 接入 Token Provider + MCP Client | iOS/Android/Web 调同一 Agent 能力并得到一致结果 |
|
|
||||||
| 3 | ops-assistant-service 接入 Token Provider + MCP Client | 运营 iOS/Android 经同一服务端链路成功 |
|
|
||||||
| 4 | 多端与跨用户安全回归 | 无 Token 泄露、串号、越权或副作用自动重放 |
|
|
||||||
|
|
||||||
## 8. 验收标准
|
|
||||||
|
|
||||||
- xiaoqu-ai 同一用户在 iOS、Android、Web 调用同一能力,工具结果和数据权限一致。
|
|
||||||
- 三端请求只出现产品登录 Token,不出现 MCP Token 或 `X-Open-Key`。
|
|
||||||
- 用户 A/B、不同租户、不同 scope 的 MCP Session 和缓存完全隔离。
|
|
||||||
- 运营 iOS/Android 经 `ops-assistant-service` 调用,客户端同样不持有 MCP Token。
|
|
||||||
- 无 scope 时 Planner/Executor 不能调用;绕过 `tools/list` 直接 `tools/call` 仍被服务端拒绝并审计。
|
|
||||||
- MCP 401 只刷新当前用户;有副作用调用不自动重放。
|
|
||||||
- Token 不进入 prompt、工具参数、trace、普通日志、崩溃信息和 Git。
|
|
||||||
|
|
||||||
## 9. 风险与回退
|
|
||||||
|
|
||||||
| 风险 | 应对 |
|
|
||||||
|---|---|
|
|
||||||
| 产品用户与 MCP 用户映射错误 | 只用 Gateway 可信身份查询手机号/邮箱;联调覆盖同名和缺失用户 |
|
|
||||||
| 服务端缓存串用户 | 复合缓存键;登录切换和并发测试 |
|
|
||||||
| 两个 Agent Runtime 暴露不同工具 | 各自维护明确 allowlist,并用同一 MCP schema 做契约测试 |
|
|
||||||
| MCP 不可用 | Agent 返回稳定的工具不可用错误,不回退公共 Token 或数据库直连 |
|
|
||||||
|
|
||||||
回退只关闭各 Agent Runtime 的 MCP capability 开关,iOS、Android、Web 继续使用原有
|
|
||||||
Agent 功能;不得回退为客户端共享固定 Token。
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
# xiaoqu-operations-ai 接入 xiaoqu-mcp 开发设置
|
|
||||||
|
|
||||||
## 1. 目标
|
|
||||||
|
|
||||||
让 `ops-assistant-service` 作为运营项目唯一 MCP Client 调用
|
|
||||||
`xiaoqu_mcp_service`,同时服务运营 iOS、Android。保持现有:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Router → Planner → Executor → Answer
|
|
||||||
```
|
|
||||||
|
|
||||||
每次调用使用当前已验证用户对应的 MCP Token,不把 MCP Token 放进提示词、Planner 输出、工具参数或普通日志。
|
|
||||||
|
|
||||||
客户端边界:
|
|
||||||
|
|
||||||
| 端 | 调用入口 | MCP Token |
|
|
||||||
|---|---|---|
|
|
||||||
| 运营 iOS | `ops-assistant-service` REST/WebSocket | 不下发 |
|
|
||||||
| 运营 Android | `ops-assistant-service` REST/WebSocket | 不下发 |
|
|
||||||
|
|
||||||
客户端只持产品登录凭证;`ops-assistant-service` 从已验证身份映射用户后,服务端获取并使用 MCP Token。
|
|
||||||
|
|
||||||
## 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。
|
|
||||||
- 业务后端必须从已验证用户会话查询手机号/邮箱,不能信任客户端或模型传入的身份字段。
|
|
||||||
- 首次创建返回 Token 明文;xiaoqu-mcp 同时保存 SHA-256 哈希和 AES-GCM 加密密文(密钥由 `app.token-cipher-key` 派生)。
|
|
||||||
- 已存在 Token 解密回传明文(二次获取),重复调用幂等复用同一把 Token;历史无密文 Token 自动轮换(禁用旧把、签发新把)。
|
|
||||||
- Token 密文解密失败必须报错;不得回退到哈希值或公共 Token。
|
|
||||||
|
|
||||||
## 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`,首次签发返回明文;后续直接复用本地持久化 token。
|
|
||||||
- 不接受 `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 缓存;如需远端立即失效,走服务端管理端吊销能力。
|
|
||||||
- 日志只记录用户 ID、工具名、scope 和错误码,不记录 Token、Authorization Header 或手机号/邮箱明文。
|
|
||||||
- `tools/list` 仅用于校验远端能力;真正可调用集合以本地 allowlist 为准。
|
|
||||||
|
|
||||||
## 6. 开发顺序
|
|
||||||
|
|
||||||
1. 先确认 xiaoqu-mcp 的 `ensure` 契约和 Token 密文落库;运营链路不依赖 xiaoqu-ai 业务后端门面。
|
|
||||||
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 权限。
|
|
||||||
- 不在本次首期引入写工具;写工具需另行设计审批、幂等和补偿协议。
|
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
# xiaoqu 多产品 Agent 统一接入 xiaoqu-mcp 总体设计
|
||||||
|
|
||||||
|
## 1. 设计结论
|
||||||
|
|
||||||
|
xiaoqu-ai 与 xiaoqu-operations-ai 共用 xiaoqu-mcp 的服务能力、Token 原语、工具协议、权限模型和审计规则,但保留各自的 Agent Runtime:
|
||||||
|
|
||||||
|
```text
|
||||||
|
xiaoqu-ai iOS / Android / Web
|
||||||
|
│ 产品登录 Token
|
||||||
|
▼
|
||||||
|
xiaoqu-ai Gateway / Agent Runtime ───┐
|
||||||
|
│ 用户 MCP Token(仅服务端持有)
|
||||||
|
xiaoqu-operations-ai iOS / Android │
|
||||||
|
│ 产品登录 Token │
|
||||||
|
▼ │
|
||||||
|
ops-assistant-service ───────────────┤
|
||||||
|
▼
|
||||||
|
xiaoqu-agent-service /mcp
|
||||||
|
Token + Scope + Tool
|
||||||
|
行级权限 + Audit
|
||||||
|
```
|
||||||
|
|
||||||
|
共同的是后端协议,不是 Swift、Kotlin 或 Web UI 代码。任何客户端都不实现本次 xiaoqu-mcp Client,不保存用户 MCP Token,也不接触 `X-Open-Key`。
|
||||||
|
|
||||||
|
## 2. 范围与文档分工
|
||||||
|
|
||||||
|
| 层级 | 项目 | 项目目录 | 文档 |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 总体 | xiaoqu-mcp | 当前仓库 `xiaoqu-agent-service` | 本文 |
|
||||||
|
| 详细设计 | xiaoqu-ai iOS、Android、Web、服务端 Agent | `/Users/tonylai/xiaoquai/xiaoqu-ai`、`/Users/tonylai/jiaxk/xiaoqu-ai-android` | [`xiaoqu-ai-mcp-integration-design.md`](./xiaoqu-ai-mcp-integration-design.md) |
|
||||||
|
| 详细设计 | xiaoqu-operations-ai iOS、Android、服务端 Agent | `/Users/tonylai/jiaxk/xiaoqu-operations-ai` | [`xiaoqu-operations-ai-mcp-integration-design.md`](./xiaoqu-operations-ai-mcp-integration-design.md) |
|
||||||
|
|
||||||
|
本文只定义两个产品必须共同遵守的架构和安全契约。项目代码落点、配置、Capability 映射和项目级验收只写在对应详细设计中。
|
||||||
|
|
||||||
|
## 3. 统一职责
|
||||||
|
|
||||||
|
| 层 | 职责 |
|
||||||
|
|---|---|
|
||||||
|
| iOS / Android / Web | 登录、会话 UI、流式展示和确认交互;只携带产品登录凭证 |
|
||||||
|
| 产品 Gateway | 验证登录态,建立可信用户、租户和数据范围上下文 |
|
||||||
|
| 产品 Agent Runtime | 编排 Agent,维护本地 Capability allowlist,获取用户 MCP Token 并调用 MCP |
|
||||||
|
| xiaoqu-agent-service | 校验 MCP Token,按 scope 过滤工具,执行用户/租户/行级权限并记录审计 |
|
||||||
|
|
||||||
|
两个产品可以暴露不同的 Capability 集合,但都必须通过同一套 MCP 鉴权和工具契约执行。运营项目不得直接调用 xiaoqu-ai Agent,也不得复制或直连 xiaoqu-mcp 数据库。
|
||||||
|
|
||||||
|
## 4. 认证与 Token 契约
|
||||||
|
|
||||||
|
### 4.1 三类凭证
|
||||||
|
|
||||||
|
| 凭证 | 使用链路 | 用途 |
|
||||||
|
|---|---|---|
|
||||||
|
| 产品登录 Token | 客户端 → 产品 Gateway | 证明当前产品用户身份 |
|
||||||
|
| `X-Open-Key` | 产品 Agent Runtime → `/api/open/token/ensure` | 服务间获取指定用户的 MCP Token |
|
||||||
|
| 用户 MCP Token `xqak_*` | 产品 Agent Runtime → `/mcp` | 绑定 MCP 用户、scope、权限和审计 |
|
||||||
|
|
||||||
|
`X-Open-Key` 和用户 MCP Token 只能存在于受信任服务端,不得进入客户端、prompt、模型输出、工具参数、普通日志或 Git。
|
||||||
|
|
||||||
|
### 4.2 用户映射
|
||||||
|
|
||||||
|
1. Gateway 验证产品登录 Token。
|
||||||
|
2. Agent Runtime 从可信上下文取得产品用户、租户和数据范围。
|
||||||
|
3. Agent Runtime 从受信任用户资料源取得手机号或邮箱。
|
||||||
|
4. Agent Runtime 使用服务端固定的 `scopeCode` 调用 `POST /api/open/token/ensure`。
|
||||||
|
5. xiaoqu-agent-service 返回该 MCP 用户对应的 Token。
|
||||||
|
6. Agent Runtime 使用该 Token 调用 `/mcp`。
|
||||||
|
|
||||||
|
客户端、Planner 和模型不得提供或覆盖 `user_id`、手机号、邮箱、租户、数据范围或 `scopeCode`。每个产品启用前必须核对管理后台中的真实 scope 和工具绑定。
|
||||||
|
|
||||||
|
### 4.3 `POST /api/open/token/ensure`
|
||||||
|
|
||||||
|
认证:`X-Open-Key: <server-only-key>`。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mobile": "<trusted-user-mobile>",
|
||||||
|
"email": "<trusted-user-email>",
|
||||||
|
"scopeCode": "<server-configured-scope>"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `mobile`、`email` 至少一个,手机号优先。
|
||||||
|
- 已有有效 Token:解密 `key_cipher` 并返回同一明文。
|
||||||
|
- 历史无密文 Token:禁用旧 Token 并自动签发新 Token。
|
||||||
|
- 不存在有效 Token:创建长期 Token;回收通过禁用实现。
|
||||||
|
- 密文解密失败必须报错,不得回退哈希值或公共 Token。
|
||||||
|
|
||||||
|
错误语义:`400` 参数或 scope 错误,`401` Open Key 无效,`403` Open API 未启用,`404` 用户不存在或不属于允许的企业账号。
|
||||||
|
|
||||||
|
## 5. MCP 协议与权限
|
||||||
|
|
||||||
|
调用入口:`POST /mcp`。
|
||||||
|
|
||||||
|
```http
|
||||||
|
Authorization: Bearer <user-mcp-token>
|
||||||
|
Content-Type: application/json
|
||||||
|
Accept: application/json, text/event-stream
|
||||||
|
```
|
||||||
|
|
||||||
|
调用顺序:`initialize` → `notifications/initialized` → `tools/list` → `tools/call`。初始化响应包含 Session ID 时,后续请求携带 `Mcp-Session-Id`。
|
||||||
|
|
||||||
|
最终可执行能力为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
产品 Agent capability allowlist
|
||||||
|
∩ MCP Token scope
|
||||||
|
∩ 当前用户权限
|
||||||
|
∩ 当前租户/数据范围
|
||||||
|
```
|
||||||
|
|
||||||
|
`tools/list` 必须按 Token scope 过滤,`tools/call` 必须再次强制校验。不得仅依赖提示词、本地隐藏菜单或 Planner 输出做授权。
|
||||||
|
|
||||||
|
## 6. 生命周期与错误处理
|
||||||
|
|
||||||
|
- 缓存键至少包含产品、租户、产品用户 ID 和 scope。
|
||||||
|
- 登录用户变化或退出登录时,旧用户的 Token 缓存和 MCP Session 必须失效。
|
||||||
|
- MCP 返回 401 时,只清理当前用户缓存并重新 `ensure` 一次。
|
||||||
|
- 只读调用可在重新连接后重试一次;有副作用调用不得自动重放。
|
||||||
|
- MCP 不可用时返回稳定的工具不可用错误,不得回退公共 Token 或数据库直连。
|
||||||
|
- 日志只记录用户 ID、scope、工具名、状态和耗时,不记录凭证明文或手机号/邮箱明文。
|
||||||
|
|
||||||
|
## 7. 联调顺序
|
||||||
|
|
||||||
|
| # | 工作 | 完成标准 |
|
||||||
|
|---|---|---|
|
||||||
|
| 1 | 确认两个产品的用户映射与实际 scope | scope 已存在并绑定所需工具,不依赖客户端身份字段 |
|
||||||
|
| 2 | 完成 xiaoqu-ai 服务端接入 | iOS、Android、Web 经同一服务端适配器调用 |
|
||||||
|
| 3 | 完成 xiaoqu-operations-ai 服务端接入 | 运营 iOS、Android 经 ops-assistant-service 调用 |
|
||||||
|
| 4 | 跨用户、跨租户和跨产品回归 | 无 Token 泄露、串号、越权或副作用自动重放 |
|
||||||
|
|
||||||
|
## 8. 总体验收与回退
|
||||||
|
|
||||||
|
- 所有客户端请求只出现产品登录 Token,不出现用户 MCP Token 或 `X-Open-Key`。
|
||||||
|
- 用户 A/B、不同租户、不同 scope 的 Token 缓存和 MCP Session 完全隔离。
|
||||||
|
- 绕过 `tools/list` 直接调用 `tools/call` 仍会被服务端拒绝并审计。
|
||||||
|
- 两个产品的本地 allowlist 可以不同,但同名 MCP 工具的请求和响应契约一致。
|
||||||
|
- 任一产品回退时,只关闭该 Agent Runtime 的 MCP Capability 开关;客户端继续使用原有 Agent 功能。
|
||||||
|
- 禁止回退为客户端共享固定 Token、公共服务端 Token 或数据库直连。
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
# xiaoqu-operations-ai 接入 xiaoqu-mcp 详细设计
|
||||||
|
|
||||||
|
## 1. 目标与边界
|
||||||
|
|
||||||
|
本文是 [`xiaoqu 多产品 Agent 统一接入 xiaoqu-mcp 总体设计`](./xiaoqu-mcp-multi-product-agent-design.md) 的运营项目落地设计。
|
||||||
|
|
||||||
|
`ops-assistant-service` 是运营项目唯一 MCP Client,同时服务运营 iOS 和 Android,并保留现有编排:
|
||||||
|
|
||||||
|
```text
|
||||||
|
运营 iOS / Android
|
||||||
|
│ 产品登录 Token
|
||||||
|
▼
|
||||||
|
Router → Planner → Executor → Answer
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
xiaoqu-mcp
|
||||||
|
```
|
||||||
|
|
||||||
|
客户端不新增 MCP 代码。项目目录:`/Users/tonylai/jiaxk/xiaoqu-operations-ai`。
|
||||||
|
|
||||||
|
## 2. 当前代码依据
|
||||||
|
|
||||||
|
- `services/ops-assistant-service` 是 FastAPI + Python 3.12 服务。
|
||||||
|
- 当前依赖中没有 MCP SDK,也没有 `tools/list` / `tools/call` 客户端。
|
||||||
|
- `src/ops_assistant_service/capability_registry.py` 维护静态 `CAPABILITY_REGISTRY`。
|
||||||
|
- `src/ops_assistant_service/executor.py` 当前执行 `customer_issues.*`、`smartclean.query` 等本地 Capability。
|
||||||
|
- 用户身份来自 Gateway JWT,并通过 `ops_identity_mappings` 解析租户、用户和 `scope_tags`。
|
||||||
|
- 最小接入点是 Executor 的工具适配层,不新增第二套编排器。
|
||||||
|
|
||||||
|
## 3. 配置设计
|
||||||
|
|
||||||
|
在 `src/ops_assistant_service/config.py` 的 `Settings` 中增加以下 `OPS_ASSISTANT_` 配置:
|
||||||
|
|
||||||
|
| 变量 | 默认值 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `XQ_MCP_ENABLED` | `false` | 是否启用 MCP Capability |
|
||||||
|
| `XQ_MCP_URL` | unset | xiaoqu-mcp 内网地址 |
|
||||||
|
| `XQ_MCP_OPEN_KEY` | unset | Token 初始化凭证,类型使用 `SecretStr` |
|
||||||
|
| `XQ_MCP_SCOPE_CODE` | `operation` | 服务端固定 scope,禁止由 Planner 或客户端选择 |
|
||||||
|
| `XQ_MCP_TIMEOUT_SECONDS` | `10` | MCP 请求超时 |
|
||||||
|
|
||||||
|
启用时必须同时提供 URL、Open Key 和 scope。`operation` 已存在于 dev 种子,其他环境启用前仍需核对实际 scope 和工具绑定;生产配置不得写入仓库。
|
||||||
|
|
||||||
|
## 4. 最小模块
|
||||||
|
|
||||||
|
只新增两个模块:
|
||||||
|
|
||||||
|
- `src/ops_assistant_service/mcp_client.py`
|
||||||
|
- 使用现有 `httpx` 完成 JSON-RPC、Session ID、Bearer Header、超时和错误映射。
|
||||||
|
- 按租户、`user_id` 和 scope 隔离 MCP Session。
|
||||||
|
- `src/ops_assistant_service/mcp_token_provider.py`
|
||||||
|
- 接收已验证的 `SharedIdentity`。
|
||||||
|
- 从受信任用户资料源取得 mobile/email 并调用 `ensure`。
|
||||||
|
- 按租户、`user_id` 和 scope 缓存 Token;401 时只刷新当前用户一次。
|
||||||
|
- 不接受客户端或 Planner 传入的身份字段作为覆盖参数。
|
||||||
|
|
||||||
|
不引入通用 MCP 框架、不新增 Agent,也不直连 xiaoqu-mcp 数据库。
|
||||||
|
|
||||||
|
## 5. 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 在调用前执行本地 Capability、用户 `scope_tags`、租户/DataScope 校验;xiaoqu-mcp 再执行 Token scope 和服务端数据权限校验。
|
||||||
|
|
||||||
|
远端结果经过字段白名单投影后再进入 Answer。Token、Authorization Header 和未授权字段不得进入 execution trace。
|
||||||
|
|
||||||
|
## 6. Executor 接入
|
||||||
|
|
||||||
|
在 `executor.py` 增加 MCP 只读分支:
|
||||||
|
|
||||||
|
```text
|
||||||
|
validate_tool_input
|
||||||
|
→ 校验本地 Capability 和参数白名单
|
||||||
|
→ 读取 SharedIdentity / DataScope
|
||||||
|
→ mcp_token_provider 获取当前用户 Token
|
||||||
|
→ mcp_client 调用 tools/call
|
||||||
|
→ 结果字段投影
|
||||||
|
→ 现有 execution_trace / Answer
|
||||||
|
```
|
||||||
|
|
||||||
|
现有 `customer_issues.*` 和 `smartclean.query` 保持不变。MCP 不可用时返回稳定的 `TOOL_UNAVAILABLE`,不得回退公共 Token 或数据库直连。
|
||||||
|
|
||||||
|
## 7. 开发顺序
|
||||||
|
|
||||||
|
1. 核对目标环境中的 `operation` scope、工具绑定和用户资料映射。
|
||||||
|
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。
|
||||||
|
|
||||||
|
## 8. 项目验收
|
||||||
|
|
||||||
|
- 运营 iOS、Android 继续只调用 `ops-assistant-service`,客户端无 MCP Token。
|
||||||
|
- 用户 A/B、不同租户和 scope 的 Token 与 MCP Session 不互用。
|
||||||
|
- Planner 不能选择未注册的远程工具,Executor 不能绕过 `scope_tags` 和 DataScope。
|
||||||
|
- `tools/list`、`tools/call` 使用同一用户 Session 和 Bearer Token。
|
||||||
|
- MCP 401 只刷新当前用户;只读请求最多重试一次。
|
||||||
|
- 测试、日志、trace、配置和 Git 历史中均无凭证明文。
|
||||||
|
|
||||||
|
## 9. 当前不做
|
||||||
|
|
||||||
|
- 不把 MCP Client 放进运营 iOS 或 Android。
|
||||||
|
- 不动态注册全部远程工具。
|
||||||
|
- 不在首期引入写工具;写工具需另行设计审批、幂等和补偿协议。
|
||||||
|
- 不复制 xiaoqu-mcp 数据库,不调用 xiaoqu-ai Agent 代查数据。
|
||||||
Reference in New Issue
Block a user