7.3 KiB
xiaoqu-ai 接入 xiaoqu-mcp 详细设计
1. 目标与边界
本文是 xiaoqu 多产品 Agent 统一接入 xiaoqu-mcp 总体设计 的 xiaoqu-ai 落地设计。
xiaoqu-ai 的 iOS、Android、Web 共用一套服务端 MCP 接入,不在三个客户端分别实现 MCP Client:
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 的工具执行层,三端最终复用同一实现:
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 时只刷新当前用户一次。
- 输入 Gateway 已验证的
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. 用户与权限流程
产品登录 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. 开发顺序
- 在目标环境创建或确认 xiaoqu-ai 独立 scope,并绑定首期只读工具。
- 增加 Gateway 配置与启动校验。
- 实现
token_provider.go和client.go,覆盖 Token、Session、超时和错误映射测试。 - 在 ToolExecutor 注册固定工具并复用现有 DataScope 校验。
- 验证 Agent Service runtime gateway 路径仍只转发用户 JWT。
- 分别用 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。
- 不在首期接入写工具或副作用自动重试。