# @brooswit/thatch 中文文档

规范地址：https://npmcn.com/package/%40brooswit/thatch/

版本：0\.9\.0
npm 元数据更新时间：2026-10-07T15:33:51.186Z
中文译文更新时间：2026-11-08T16:13:39.876Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40brooswit/thatch
原文对照：https://npmcn.com/package/%40brooswit/thatch/?lang=original
项目主页：https://github.com/brooswit-factory/thatch#readme
源码仓库：https://github.com/brooswit-factory/thatch

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：79.4 kB，23 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：2 个
- peer 依赖：elysia \>=1\.4
- 首次发布：2026-08-24T17:06:02.706Z
- 最新版本发布：2026-10-07T15:33:50.827Z
- 近 30 天下载量：2973（2026-10-09 至 2026-11-07，npm 官方下载统计）
- 已发布版本数：7（近 12 个月 7 个）

## 中文简介

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

## 安装

```sh
npm install @brooswit/thatch
```

也可以使用：`pnpm add @brooswit/thatch`、`yarn add @brooswit/thatch`、`bun add @brooswit/thatch`

## README

# @brooswit/thatch (英语)

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

```ts
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中继器,请在转发请求前拨打共享帮助器:

```ts
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 发现规格](https://modelcontextprotocol.io/specification/2026-07-28/server/discover) 财务报告和审定财务报表 [stdio 后向兼容性](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports)。 。 。 .

## 层

`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 是什么？

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 和提交记录判断。

