思源笔记 MCP 接入 Hermes-Agent 完整排查总结

思源笔记 MCP 接入 Hermes-Agent 完整排查总结

__

最终目标

在 fnOS + 1Panel 环境下,通过 supergateway 将思源笔记 MCP 服务暴露给 Hermes-Agent,实现 AI 自动读写思源笔记。

最终环境配置

项目

fnOS 宿主机 IP

192.168.5.224

Docker 网络

1panel-network

思源笔记容器名

1Panel-siyuan-cdZB

MCP 容器名

siyuan-mcp

supergateway 端口

9000

SSE 端点

http://192.168.5.224:9000/siyuan-mcp

MCP 包

siyuan-mcp@latest(替换了原 siyuan-mcp-server)

踩坑记录(按时间顺序)

坑一:误判 npm warn 为下载失败

​supergateway​ 日志中出现:

text

npm warn exec The following package was not found and will be installed: siyuan-mcp-server@1.0.3

起初以为是下载失败,实际上这只是 npx​ 的正常提示——包不存在时会自动安装,该信息并非报错,真正的错误在后续输出中才能看到。

坑二:初始选择的 MCP 包维护状态不明确

最初使用 siyuan-mcp-server​(作者 k13768),该包环境变量名文档不清晰(SIYUAN_API_TOKEN​ / SIYUAN_API_URL​ 是否被正确读取无法确认),且维护状态不明。后切换为 siyuan-mcp@latest​,环境变量调整为:

text

SIYUAN_HOST: 1Panel-siyuan-cdZB
SIYUAN_PORT: "6806"
SIYUAN_TOKEN: 思源笔记apitoken

坑三:对 1Panel Compose 变量替换机制的误解

1Panel MCP 模板的 compose 文件中,command​ 使用了 ${COMMAND}​、${SSE_PATH}​ 等变量,这些变量由 1Panel ​在启动时从界面配置渲染​,并非容器运行时的环境变量。因此,在 environment​ 块中定义这些变量是无效的。

​${COMMAND}​ 被替换为 npx -y siyuan-mcp@latest​ 整体字符串后传入 supergateway​ 的 --stdio​ 参数——虽然形式上是一个整体,但 supergateway​ 内部会用 shell 解析该字符串,所以能正常执行。

这个机制本身是正常的,并非问题所在。 后续排查发现配置文件无异常,1Panel 的渲染和替换逻辑符合预期。

坑四:--streamableHttpPath​ 为空导致端点不可用(无效诊断)

在排查过程中,发现 compose 中 ${STREAMABLE_HTTP_PATH}​ 变量值为空,导致 supergateway​ 日志中未显示 streamable HTTP 端点信息,curl​ 访问 /siyuan-mcp/http​ 返回 404。最初怀疑是配置未正确渲染,但这个方向实际上是​无效诊断​:

  • 当 --outputTransport​ 为 sse​ 时,--streamableHttpPath​ 参数本身就不会生效,日志不显示是正常行为。

  • ​curl​ 返回 404 也是正常的——服务只开放了 SSE 端点,没有 HTTP 端点。

  • 配置文件没有问题,1Panel 也没有渲染错误。 这块纯属诊断方向走偏,浪费了时间。

坑五(根本原因):MCP transport 协议不匹配

这是整个排查过程中最隐蔽、也是最终被定位到的问题。MCP 的 HTTP 传输存在两种模式:

协议

说明

适用场景

Streamable HTTP

MCP 新版协议(2025-03-26+),单连接完成所有通信

大多数新版 MCP 服务

SSE

传统协议,SSE 长连接 + 独立 POST 请求

老版 / 中文社区 MCP 服务

​supergateway​ 暴露的是传统 SSE 端点,而 Hermes 通过 mcp add​ 或界面添加 MCP 时,​默认使用 Streamable HTTP​。两者握手方式不匹配,导致连接建立后立刻被服务端关闭,报 Session terminated​。

而 Hermes 界面未暴露 transport​ 这一底层配置项,需要通过对话让 Hermes 将配置写入 config.yaml​。

最终解决方案

在 Hermes 的 config.yaml​ 中为思源 MCP 服务​显式指定 transport: sse​:

yaml

mcp_servers:
  siyuan:
    url: "http://192.168.5.224:9000/siyuan-mcp"
    transport: sse        # 🔑 关键:指定传统 SSE 协议
    timeout: 180
    connect_timeout: 30

通过对话让 Hermes 自动写入该配置后,连接成功:

text

✓ Connected (113ms)
✓ Tools discovered: 52

经验总结

  1. ​MCP 协议有新旧两种 transport​:接入前先确认服务端用的是 Streamable HTTP 还是 SSE。不匹配会导致连上即断,且报错不明显(如 Session terminated​),容易误判为网络或认证问题。

  2. ​supergateway​ 包裹的 stdio MCP 服务默认走 SSE​:而 Hermes 等新版 Agent 默认使用 Streamable HTTP。两者对接时,​必须在 Hermes 侧手动指定 transport: sse​。

  3. ​诊断时注意区分“现象”和“根因”​:比如 --streamableHttpPath​ 为空时 curl​ 返回 404,在 SSE 模式下这是正常行为,不是问题。不要被无关现象牵着走,先用协议握手测试确认 MCP 服务本身是否正常(手动 echo '{"jsonrpc":"2.0",...}' | npx ...​ 能快速验证),再排查接入层。

  4. ​选包优先看维护状态​:社区同类包质量参差不齐,优先选择文档清晰、环境变量说明明确的包,能省去大量不必要的排查时间。

最终目标

在 fnOS + 1Panel 环境下,通过 supergateway 将思源笔记 MCP 服务暴露给 Hermes-Agent,实现 AI 自动读写思源笔记。

最终环境配置

项目

fnOS 宿主机 IP

192.168.5.224

Docker 网络

1panel-network

思源笔记容器名

1Panel-siyuan-cdZB

MCP 容器名

siyuan-mcp

supergateway 端口

9000

SSE 端点

http://192.168.5.224:9000/siyuan-mcp

MCP 包

siyuan-mcp@latest(替换了原 siyuan-mcp-server)

踩坑记录(按时间顺序)

坑一:误判 npm warn 为下载失败

​supergateway​ 日志中出现:

npm warn exec The following package was not found and will be installed: siyuan-mcp-server@1.0.3

起初以为是下载失败,实际上这只是 npx​ 的正常提示——包不存在时会自动安装,该信息并非报错,真正的错误在后续输出中才能看到。

坑二:初始选择的 MCP 包维护状态不明确

最初使用 siyuan-mcp-server​(作者 k13768),该包环境变量名文档不清晰(SIYUAN_API_TOKEN​ / SIYUAN_API_URL​ 是否被正确读取无法确认),且维护状态不明。后切换为 siyuan-mcp@latest​,环境变量调整为:

SIYUAN_HOST: 1Panel-siyuan-cdZB
SIYUAN_PORT: "6806"
SIYUAN_TOKEN: 思源笔记apitoken

坑三:1Panel Compose 变量替换的认知偏差

1Panel MCP 模板的 compose 文件中,command​ 使用了 ${COMMAND}​、${SSE_PATH}​ 等变量,这些变量由 1Panel 在启动时从界面配置渲染,并非容器运行时的环境变量。因此,在 environment​ 块中定义这些变量是无效的。

​${COMMAND}​ 被替换为 npx -y siyuan-mcp@latest​ 整体字符串后传入 supergateway​ 的 --stdio​ 参数——虽然形式上是一个整体,但 supergateway​ 内部会用 shell 解析该字符串,所以能正常执行。

坑四:--streamableHttpPath​ 为空导致 HTTP 端点不可用

compose 中 ${STREAMABLE_HTTP_PATH}​ 变量值为空,导致 supergateway​ 未开启 streamable HTTP 端点,curl​ 访问 /siyuan-mcp/http​ 返回 404。多次尝试在 compose 中硬编码修改,但发现 1Panel 界面的「重建」操作并非总是重新加载 compose 文件,最终需要手动执行 docker compose down && up -d​ 才真正生效。

坑五(根本原因):MCP transport 协议不匹配

这是整个排查过程中最隐蔽的问题。MCP 的 HTTP 传输存在两种模式:

协议

说明

适用场景

Streamable HTTP

MCP 新版协议(2025-03-26+),单连接完成所有通信

大多数新版 MCP 服务

SSE

传统协议,SSE 长连接 + 独立 POST 请求

老版 / 中文社区 MCP 服务

​supergateway​ 暴露的是传统 SSE 端点,而 Hermes 通过 mcp add​ 或界面添加 MCP 时,默认使用 Streamable HTTP。两者握手方式不匹配,导致连接建立后立刻被服务端关闭,报 Session terminated​。

而 Hermes 界面未暴露 transport​ 这一底层配置项,需要通过对话让 Hermes 将配置写入 config.yaml​。

最终解决方案

在 Hermes 的 config.yaml​ 中为思源 MCP 服务显式指定 transport: sse:

mcp_servers:
  siyuan:
    url: "http://192.168.5.224:9000/siyuan-mcp"
    transport: sse        # 🔑 关键:指定传统 SSE 协议
    timeout: 180
    connect_timeout: 30

通过对话让 Hermes 自动写入该配置后,连接成功:

✓ Connected (113ms)
✓ Tools discovered: 52

经验总结

  1. MCP 协议有新旧两种 transport:接入前先确认服务端用的是 Streamable HTTP 还是 SSE。不匹配会导致连上即断,且报错不明显(如 Session terminated​),容易误判为网络或认证问题。

  2. ​supergateway​ 包裹的 stdio MCP 服务默认走 SSE:而 Hermes 等新版 Agent 默认使用 Streamable HTTP。两者对接时,必须在 Hermes 侧手动指定 transport: sse​。

  3. 1Panel 的「重建」不可全信:修改 compose 文件后,建议用 docker compose down && up -d​ 手动重建确认生效,并用 docker inspect​ 验证实际运行参数。

  4. 选包优先看维护状态:社区同类包质量参差不齐,优先选择文档清晰、环境变量说明明确的包,能省去大量不必要的排查时间。


主要改动:

  • 把“坑五”从“原因罗列”升级为“排查定位过程 + 根本原因”,逻辑更完整

  • 去掉了几处赘述(如多次重复的排查命令),保持简洁

  • 经验总结的表达更精炼,便于以后快速回顾

  • 补充了关键细节(如为什么 --stdio​ 整体字符串能生效、如何确认 1Panel 重建不生效)

你可以直接复制使用。如果有其他想调整的部分,随时告诉我。😊

飞牛 OS + 1Panel:Docker 数据目录迁移全记录 2026-06-11
Nginx Proxy Manager 升级后证书失效故障记录 2026-06-21

评论区