@brooswit/thatch

中文文档
0.9.0发布于 2026/10/07MITTypeScriptES Module构建来源已验证近 30 天下载 2973

Elysia 插件: 中央的 HTTP MCP 服务器, 并带有命名的连接和将消息推入 Claude 代码会话的通道

中文使用文档
文档目录7 节
  1. 用 Claude 代码接收频道消息
  2. 为什么送货类型不是 void
  3. API 密码
  4. 幸存服务器重启( LIBS-7)
  5. 遗留物 stdio 发现回落
  6. 层
  7. 脚本

@brooswit/thatch (英语)

中央HTTP MCP服务器,作为 爱莉西亚 插件 。 许多 Claude 代码会话通过 URL 连接到一个服务器;服务器按名称处理,可以将消息推入一个活的会话.

import { Elysia } from "elysia";
import { thatch, z } from "@brooswit/thatch";

const { plugin, mcp } = thatch({
  tools: {
    status: { description: "Fleet status", input: {}, handler: (_a, c) => `hello ${c.id}` },
  },
});

const app = new Elysia().use(plugin).listen(3000);

// every client is accepted and gets a UUID; it holds all its request headers.
mcp.on("connect", (c) => console.log("connected", c.id, c.headers["x-workspace"]));

// address by a header predicate, then push into that session — from anywhere
const c = mcp.connections.find((c) => c.headers["x-workspace"] === "epic/KAN-39");
const d = await c?.send({ content: "PR #296 approved", meta: { key: "KAN-39" } });
//  d: { claim: "C2" }  — a connected session's stream took it
//     { claim: "refused", reason: "not-connected" | "no-channel-stream" | "bad-meta" | "closed-mid-send" }

Claude代码连接到:

claude mcp add --transport http fleet http://localhost:3000/mcp --header "x-workspace: epic/KAN-39"

用 Claude 代码接收频道消息

推车 notifications/claude/channel。关于届会 提交 克劳德代码必须选择:

  • 发射 互动 (无) claude -p与 --channels server:<name>,比如说. claude --mcp-config mcp.json --channels server:thatch。一个被推动的帧会获得许可 提示用户接受; 无头 -p 没有接受者并跳过频道.
  • 在克劳德.艾 团队/企业中,频道通知为 org(默认关闭)和 org 必须启用它们; 控制台账户默认打开.

test/live/channel-render.md 是一种旁证。 离服务器而去的是 包含在自动套房中;这最后的一首是交互式的.

为什么送货类型不是 void

推入会话可能会以 MCP SDK 隐藏的方式失败: 在其通知流没有被附加时可以注册连接,在这种情况下, SDK 悄悄地放下了帧. thatch 大声拒绝no-channel-stream)和仅索赔 C2 当一个溪流实际上在那里 承载帧. C3 (输入记录)和 C4 (模型读出) 是不可见的, 所以这里没有API 假装给他们.

API 密码

  • thatch({ tools?, auth?, path?, history?, serverInfo?, resurrectSessions? }) → { plugin, mcp }。每个客户端都被接受并指定一个UUID。 门连接到 auth(req) => boolean (default accept all);它没有识别——一个被接受的客户端仍然获得UUID并持有其信头.
  • instructions (可选字符串)作为 MCP 服务器指令初始化时返回到每个客户端. Claude Code将其添加到模型的上下文中,因此每个呼叫者应该遵循的行为(例如如何在聊天中回复)会在这里一次,而不是在每个代理的设定中.
  • mcp.connections数字 : list(), (中文(简体) ), get(id), (中文(简体) ), has(id), (中文(简体) ), count(), (中文(简体) ), find(pred), (中文(简体) ), filter(pred)。 。 。 .
  • mcp.send(id, frame), (中文(简体) ), mcp.sendMany(ids, frame), (中文(简体) ), mcp.sendAll(frame, { where? })。 。 。 .
  • mcp.on/once/off 页:1 connect 编号 : disconnect。断开的原因是 closed, (中文(简体) ), error,或 stale。 。 。 .
  • 收获 (单位:千美元)reap),默认情况下:没有DELETE而死亡的客户端从不关闭其传输,因此切片会自己关闭,释放 disconnect 有理无据 stale。一旦它的通知流下降 detachGraceMs (默认为60s),此后没有提出请求,或者有一次从未打开过流的会话没有请求 idleMs (默认为10分). 一个开通的流或任何请求都保持会话活性,一个返回的收割客户端得到404,这是MCP重新初始化的信号. 给它 thatch({ reap: { detachGraceMs, idleMs, intervalMs } }),或将其关闭 reap: false。 。 。 .
  • 会话复活 (单位:千美元)resurrectSessions,默认关闭):见下文“重新启动服务器”.
  • A 类 Connection 携带 id, (中文(简体) ), headers (他们), connectedAt方法 send(frame) 编号 : close()没有内在的历史, lastSeenAt或准备旗——签署 send 事件和按键,无论你喜欢 send 结果告诉你,如果一个框架不能降落.
  • import { FakeConnection } from "@brooswit/thatch/testing" 测试.

幸存服务器重启( LIBS-7)

每一个会话id一个道克服务器 都只在这个过程中发出生命。 之后a 重新启动(或任何取代进程的重新部署),这些id的每一个都不得而知 和默认的新进程答案 404 {"error":"unknown session"} 包括客户自己的背景 长生不老的溪流 频道推力需要降落。 根据 MCP 传输规格,一个客户端 得到404是应该重新 -initialize忘了旧的身份证. 这是否真的 自动发生完全取决于客户端在流下降时所做的, (中文(简体) ), 这里有一个混合的画面:

  • Claude代码的MCP客户端是SDK的 StreamableHTTPClientTransport当 独立通知流下降, 它重复相同的 GET, 使用相同的会话 ID 和页眉,使用指数回放——默认为两次,大约在1和1.5后, 然后,它静静地放弃,永远. 它在同一个地方打开了溪流: 对 之后 notifications/initialized 得到一个202。 后来成功的请求永远不会重开 这个.
  • 仅a 请求 (不是独立的 得到流 重新连接自己) 驱动一个满 客户端重新初始化——这就是打开新鲜流的原因. 所以没有 resurrectSessions,否则会话的频道在 打电话者碰巧用它做别的东西,此时404会强迫客户 通过完全重新启动 和新鲜的溪流.

thatch({ resurrectSessions: true }) 从服务器侧关闭部分空隙—— 页:1 独立流只能重新连接: 未识别 mcp-session-id 上场 以该精确的 id 而不是 404 键重新创建会话,但以 auth 钩子 接受新请求(拒绝仍然回答401),完全是一个新的连接 永不复活。 恢复的连接 headers 只来自要求 复活了它 旧的连接 不管它持有什么头条 都消失了 所以什么都没有 重复使用或猜测.

一个POST或DEELETE 在一个未识别的ID 仍然404s, 即使有这个. 这是 故意的,不是疏忽:因为SDK客户端在之后才重新打开它的流 其本身 initialize 握手,复活一个 POST 会使这个请求"成功"与 没有重新初始化——因此没有溪流重新开放。 会议将保持登记,但 永久耳聋,比起今天的404更糟糕. 只有GET是客户自己的流 从字面上说,试图回来,这就是一个案例 复活可以帮助而不削减 离开客户的自我康复路径。 所以,净效应是:

  • 在客户端自身重试窗口内完成的重启( 几秒钟, by) 默认 : Get 重试后附 没有客户端的更改 没有 重新初始化, 一旦重接, 就不会丢出推力 .
  • 一个需要更长时间的重启: 在新进程存在之前, Get 重试已经用尽, 因此,流在客户端下一个请求(POST/DELETE)之前会一直被死 驱动同样完全重新初始化 ~ 新鲜的溪道 今天存在,有或无此选项.

默认关闭,因为即使更窄的只有一条路通过标记 刚建成的SDK运输,因为已在A 调用者选择代号——使用运输内部(sessionId, (中文(简体) ), _initialized),而不是 运输的公共 API —— 以测试为主(test/unit/end-to-end.test.ts, (中文(简体) ), describe("session resurrection (LIBS-7)")因此,SDK升级 改变这些内部 而不是默默地停止生产.

遗留物 stdio 发现回落

server/discover 在MCP2026-07-28中被标准化. 更新的stdio客户 在遗产之前调查它 initialize 当他们收到JSON-RPC时握手倒地 -32601. Thatch 使用了遗留的会话 HTTP 生命周期; 它并不要求现代的无国籍人协议支持.

对于stdio-to-HTTP中继器,请在转发请求前拨打共享帮助器:

import { legacyStdioRelayAction } from "@brooswit/thatch";

const action = legacyStdioRelayAction(message, !!http.sessionId);
if (action.type === "reply") await stdio.send(action.message);
else if (action.type === "forward") await http.send(message);

帮助者只回答有效的 server/discover 要求,保存他们的身份证。 它无视 notifications/roots/list_changed 在 HTTP 会话存在之前 : 新鲜的启动会话很早就发出, 而服务器会话状态不需要无效 。 一旦召开届会,它通常会转发该通知。 所有其他信件均已转发。 下级 legacyStdioDiscoveryResponse(message) 仅供发现(答复或 undefined) (中文(简体) ).

无论是帮助者创建会话,排队消息,还是广告现代能力. 在 stdio 边界上处理此信息: HTTP 初始化守护符可能在其到达Titch 之前拒绝无会话消息 。 HTTP插件及其初始化规则不变.

见 MCP 发现规格 财务报告和审定财务报表 stdio 后向兼容性。 。 。 .

层

protocol (框架、交付、方法——纯)- registry (名称连接+历史)- channel (终止,诚实的索赔) plugin (Elysia挂载,每次连接一个MCP服务器)- testing。 。 。 .

脚本

bun run check        # generate load tests + typecheck + unit + load + coverage ≥90%
bun test test/unit
MCP_LIVE=1 bun test test/live   # against a real Claude Code session (opt-in)

版本与发布记录

@brooswit/thatch 共发布 7 个版本,首次发布于 2026/08/25;过去 12 个月发布了 7 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.9.0latest2026/10/071 个月前
0.8.02026/09/191 个月前
0.7.02026/09/191 个月前
0.6.32026/09/121 个月前
0.6.22026/09/121 个月前
0.6.12026/08/262 个月前

关于 @brooswit/thatch 的常见问题

@brooswit/thatch 是什么?

Elysia 插件: 中央的 HTTP MCP 服务器, 并带有命名的连接和将消息推入 Claude 代码会话的通道

如何安装 @brooswit/thatch?

在项目目录运行 npm install @brooswit/thatch,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:elysia(>=1.4)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@brooswit/thatch 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@brooswit/thatch 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@brooswit/thatch 可以商用吗?

@brooswit/thatch 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@brooswit/thatch 的下载量有多少?

根据 npm 官方下载统计,@brooswit/thatch 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,973 次,日均约 99 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@brooswit/thatch 还在维护吗?

最新版本 0.9.0 发布于 2026/10/07(1 个月前);至今共发布 7 个版本,其中过去 12 个月发布了 7 个;首次发布于 2026/08/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。