- 新增 4.1 生产环境对接现状(MCP 入口、ensure 换签、握手流程) - operation scope(id=2) 当前绑定 24 个工具;移除未绑定的 agent.count - xiaoqu-ai scope(id=3) 当前绑定 12 个工具;代理域工具改为实际可用映射 - 开发顺序改为按 4.1 清单对照核验
11 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.1 生产环境对接现状(2026-09-16 在 prod svc 库核验)
| 项 | 生产实际值 |
|---|---|
| MCP 入口 | https://agent.ququclean.com/mcp(Streamable HTTP,POST) |
| Token 换取 | POST https://agent.ququclean.com/api/open/token/ensure,header X-Open-Key |
| 本系统 scope | xiaoqu-ai(scope id=3,名称「小趣CRM」),服务端固定,禁止模型或客户端选择 |
| 服务密钥 | CRM 专用服务密钥已绑定 xiaoqu-ai(同时绑了 sync/operation/test 四域);密钥未绑 scope 时 ensure 返回 403 |
作用域注意:生产共有 4 个作用域——test(id=1,全量)、operation(id=2,运营app)、xiaoqu-ai(id=3,本系统)、sync(id=4,数据同步)。各域绑定独立维护,与 dev 种子数据不一致,核对以 prod svc 库 agent_scope / scope_tool 为准。
xiaoqu-ai scope 当前绑定的工具(12 个):
- 站点/物业/设备:
district.list.query(4)、district.detail.get(5)、property.list.query(6)、property.detail.query(7)、hardware.list.query(14)、hardware.detail.query(15) - 商城订单:
mall.order.list.query(9)、mall.order.detail.query(10)、mall.order.logistics.query(11) - 合同:
contract.list.query(12)、contract.detail.query(13) - 自检:
integration.context.get(19)
未绑定到 xiaoqu-ai 的工具:agent.count(1)、agent.list.query(2)、agent.detail.query(3)(代理域工具,CRM 首期未开通)、sys.ping(8)、*.changes.list(16-18)、contracts.current.batch_get(25)(后两类为 sync 专用)、全部仓库工具(20-24,26) 与送货/装机工单工具(27-30)。如 CRM 后续需要仓库/工单能力,须先评审再在管理后台补绑。
Token 换取与 MCP 握手流程:
- Gateway 持
X-Open-Key调 ensure:{"mobile":"<企业账号手机号>","scopeCode":"xiaoqu-ai"}→ 返回xqak_...(长期有效,幂等,created=false 表示复用已有) POST /mcp发initialize,从响应头取mcp-session-id- 发
notifications/initialized,之后tools/list/tools/call必须带Mcp-Session-Id头 Authorization: Bearer xqak_...(Bearer 前缀只拼一次)
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。生产 xiaoqu-ai scope(id=3)已存在并已绑定工具,实际可用映射如下(2026-09-16 核验):
| Gateway 本地工具 | MCP 工具 | 状态 |
|---|---|---|
xiaoqu.property_list |
property.list.query |
已绑定,可启用 |
xiaoqu.property_detail |
property.detail.query |
已绑定,可启用 |
xiaoqu.district_list |
district.list.query |
已绑定,可启用 |
xiaoqu.district_detail |
district.detail.get |
已绑定,可启用 |
xiaoqu.hardware_list |
hardware.list.query |
已绑定,可启用 |
xiaoqu.hardware_detail |
hardware.detail.query |
已绑定,可启用 |
xiaoqu.mall_order_list |
mall.order.list.query |
已绑定,可启用 |
xiaoqu.mall_order_detail |
mall.order.detail.query |
已绑定,可启用 |
xiaoqu.mall_order_logistics |
mall.order.logistics.query |
已绑定,可启用 |
xiaoqu.contract_list |
contract.list.query |
已绑定,可启用 |
xiaoqu.contract_detail |
contract.detail.query |
已绑定,可启用 |
勘误(2026-09-16):原候选清单中的
agent.count/agent.list.query属代理商域工具,未绑定到xiaoqu-aiscope,已移除;如需代理数据须先在管理后台补绑并评审数据范围。仓库与送货/装机工单工具(20-30)也尚未绑定到本 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 和工具绑定(prod 已于 2026-09-16 核验,见 4.1 节,首期 10 项只读工具已绑定;新环境上线时按 4.1 清单对照)。 - 增加 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。
- 不在首期接入写工具或副作用自动重试。