[v2] 服务器端钩子,用于订阅/监听资源订阅(按 URI 添加/删除)

作者: j0hanz创建于 2026年9月17日更新于 2026年9月18日

filesystem-mcp (一个通过受保护文件系统的 MCP 服务器,使用 fs.watch 监视文件)是一个很好的示例。为了恢复缺失的信号,它在 SDK 之前和下面解析了网络协议本身:

  • HTTP (src/transport/http.ts#L153-L237):在将请求传递给 toNodeHandler 之前,路由会自己读取 req.body,检查它是否是结构上有效的 subscriptions/listen(使用 specTypeSchemas.SubscriptionsListenRequest 进行验证),如果它会将观察器数量推到配置的上限,则会早期拒绝,并为每个请求的 URI 启动一个观察器,并在 res'close' 事件上释放这些观察器 - 只有在 "此流结束后" 在 SDK 外部可以观察到的信号。
  • stdio (src/transport/stdio.ts#L222-L334):没有请求/响应边界可用于钩子,因此代码将 serveStdio 在调用者提供的 StdioServerTransport 上安装的 onmessage 回调包装起来,并包装 send 也包装了(result/error 回复是唯一可从 SDK 外部观察到的信号,即确认或拒绝监听的信号,因此可以从中释放租用)。请求被按顺序队列和接受,因此两个监听命名为同一个 URI 无法竞争观察器注册的引用计数,而 notifications/cancelled 通过 JSON-RPC 请求 ID 与挂起或正在运行的监听进行匹配。

内容来源: modelcontextprotocol/typescript-sdk