docs: add MCP debugging summary

This commit is contained in:
OpenClaw Agent
2026-03-14 13:28:02 +08:00
commit ebaf325222

View File

@@ -0,0 +1,126 @@
# MCP 调试记录Tao-Memory-Server / RikkaHub / Lucky
> 目标:解决移动端 MCP 客户端MOMERYPRO / RikkaHub连接异常-32000 / Connection closed并完成握手与工具调用。
> 项目路径:`/root/.openclaw/workspace/tao_mcp_go`
> 反向代理Lucky
> 服务端口5001
---
## 一、现象与症状
- 客户端能发起 `GET /mcp/sse``POST /mcp/message`,但出现:
- `-32000: Connection closed`
- POST 进入后端但 10~30s 超时后断开
- initialize 反复重试,未进入 tools/list
---
## 二、关键问题定位 & 解决方案
### 1) JSONRPC initialize 返回格式不被客户端认可
**现象**initialize 请求到了,但客户端无后续动作(反复初始化)。
**解决**
- `MCPResponse.Result` 改为 `any`,允许返回 protocolVersion/capabilities 等结构。
- 增加 initialize 返回:
- `protocolVersion`
- `capabilities.tools/resources/prompts`
- `serverInfo`
### 2) CORS 预检/响应问题导致移动端丢弃响应
**现象**OPTIONS 或 POST 可能被丢弃,客户端视为连接失败。
**解决**
- `requireAuth` 中放行 `OPTIONS`,返回 200 + 允许头
- `MessageHandler` 每次响应前统一设置:
- `Access-Control-Allow-Origin: *`
- `Access-Control-Allow-Methods: GET, POST, OPTIONS`
- `Access-Control-Allow-Headers: Content-Type, Authorization`
### 3) SSE 端点返回错误导致路径拼接异常
**现象**:客户端生成 /mcp/mcp 或 /mcp/https://…
**解决**
- 增加 `TAO_ENDPOINT_STYLE=message`SSE 发送 `event: endpoint``message?token=...`
### 4) Lucky 反代缓冲导致 SSE 首包/POST 响应丢失
**现象**SSE 未及时下发 endpointPOST 处理后客户端超时。
**解决**
- SSE 头加入:`X-Accel-Buffering: no`
- SSE 建立后立即 `Flush()`
- 心跳从 15s 调整为 5s
### 5) 协议版本不匹配导致客户端拒绝
**现象**:客户端请求协议 20250618服务端返回 20241105握手失败。
**解决**
- initialize 返回 `protocolVersion: 2025-06-18`
### 6) 识别 notifications/initialized
**现象**:握手成功后仍死循环。
**解决**
- 增加对 `notifications/initialized` 的处理与日志
### 7) POST 返回体被 Lucky 缓冲 / Chunked 不一致
**现象**POST 返回体被代理吞掉或不及时转发。
**尝试**
- 强制设置 `Content-Length`
- 禁用缓冲 `X-Accel-Buffering: no`
- 取消 `Connection: close`
> 此阶段仍存在“initialize 循环”问题,最终采用异步 SSE 方案解决。
---
## 三、终极解决方案:异步 SSE 通道模式MCP 正式规范)
**核心思路**
- POST 只作为“投递箱”,立即返回 `202 Accepted`
- 所有 JSONRPC 结果通过 SSE `event: message` 下发
**关键实现**
- `SSEHandler`:建立 `token -> chan` 的映射,并在 `select` 中写入 `event: message`
- `MessageHandler`:读取 JSON 后立即 202异步 `dispatchMCP()` 处理
- `dispatchMCP()`:根据 method 生成响应,写入对应 token 的 SSE 通道
**日志验证**
- `[SSE Connect]` → SSE 已连
- `[MCP POST]` → POST 到达
- `[MCP Response] sent via SSE` → 回复已通过 SSE 下发
- `[MCP Notify] initialized` → 客户端确认握手完成
- `tools/list` 成功返回
---
## 四、最终生效状态(已验证)
日志证据显示握手完成:
- initialize → notifications/initialized → tools/list
- 全流程通过 SSE message 传输
---
## 五、关键配置(供后续复盘)
- 服务:`tao-mcp-go.service`
- 端口5001
- 反代Lucky
- SSE URL`https://mcp.good.xx.kg/mcp/sse?token=...`
- Message URL`https://mcp.good.xx.kg/mcp/message?token=...`
---
## 六、建议后续工作
1. 清理调试日志POST body / SSE connect
2. 增加 tools/call 执行日志
3. 在 README 中补充“异步 SSE 模式说明”
4. 如需兼容同步模式,建议单独开新路由避免混用
---
> 本文档用于存档,建议上传到仓库 `docs/` 目录。