Files
tao-memory-mcp/docs/mcp-debugging-summary.md
2026-03-14 13:28:02 +08:00

3.9 KiB
Raw Blame History

MCP 调试记录Tao-Memory-Server / RikkaHub / Lucky

目标:解决移动端 MCP 客户端MOMERYPRO / RikkaHub连接异常-32000 / Connection closed并完成握手与工具调用。 项目路径:/root/.openclaw/workspace/tao_mcp_go 反向代理Lucky 服务端口5001


一、现象与症状

  • 客户端能发起 GET /mcp/ssePOST /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=messageSSE 发送 event: endpointmessage?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 URLhttps://mcp.good.xx.kg/mcp/sse?token=...
  • Message URLhttps://mcp.good.xx.kg/mcp/message?token=...

六、建议后续工作

  1. 清理调试日志POST body / SSE connect
  2. 增加 tools/call 执行日志
  3. 在 README 中补充“异步 SSE 模式说明”
  4. 如需兼容同步模式,建议单独开新路由避免混用

本文档用于存档,建议上传到仓库 docs/ 目录。