嵌入现有应用
@tool-bridge/sdk 把 tool-bridge 作为库嵌入你的应用。你可以注册本地 Tool/Context,把 fetch 接到现有 HTTP 宿主,或通过 connect() 把本地能力反向挂到远程网关。
它适合已有 Node 22+ 应用、需要调用进程内函数或自定义存储的开发者。它不适合希望“安装后自动获得完整托管 gateway”的场景:SDK 不会自动替你提供持久数据库、对象存储、Search、设备网关通道或完整内置 Plugin catalog。
当前发布包以 Node 22 为目标,并直接依赖 node:os、Node ws 和 process.env。虽然 HTTP 表面使用标准 Request / Response,它目前不是可直接嵌入 Cloudflare Workers 的通用包;Workers 请使用标准 Cloudflare gateway。
- Node.js 22+;
- 熟悉
Request/ResponseFetch API; - 一套生产 StateStore 方案;
- Admin SK 与可选 SecretStore 加密密钥;
- 如果对外暴露 HTTP,准备 TLS、域名和宿主生命周期管理。
下面的 Node 示例使用 Hono 的 Node server adapter:
npm install @tool-bridge/sdk @hono/node-server2. 创建实例并注册本地工具
Section titled “2. 创建实例并注册本地工具”import { serve } from '@hono/node-server'import { createToolBridge, MemoryStateStore } from '@tool-bridge/sdk'
const adminSk = process.env.TB_BOOTSTRAP_ADMIN_SKif (!adminSk) throw new Error('TB_BOOTSTRAP_ADMIN_SK is required')
const tb = createToolBridge({ state: new MemoryStateStore(), adminSk, encryptionKey: process.env.TB_SECRET_ENCRYPTION_KEY,})
tb.registerTool( 'tools/echo', { List: () => [ { name: 'echo', description: '原样返回 text', inputSchema: { type: 'object', properties: { text: { type: 'string' } }, required: ['text'], additionalProperties: false, }, }, ], Call: (_name, args) => ({ content: { echoed: args.text } }), }, { description: '本地 echo 工具' },)
serve({ fetch: (request) => tb.fetch(request), port: 8787,})registerTool 的 List 是运行时 ~help 与 JSON Schema 的来源;Call 执行实际工具。也可以传入 OperationRegistry,通过 Zod 统一生成 schema 与校验。
3. 验证 HTTP 表面
Section titled “3. 验证 HTTP 表面”在另一个终端先读取节点级工具索引:
curl \ -H "Authorization: Bearer $TB_BOOTSTRAP_ADMIN_SK" \ -H "Accept: application/json" \ http://127.0.0.1:8787/tools/echo/~help这一层会列出 echo,但为控制上下文大小不会返回完整 schema。继续读取工具级帮助:
curl \ -H "Authorization: Bearer $TB_BOOTSTRAP_ADMIN_SK" \ -H "Accept: application/json" \ http://127.0.0.1:8787/tools/echo/echo/~help再使用信封调用:
curl -X POST \ -H "Authorization: Bearer $TB_BOOTSTRAP_ADMIN_SK" \ -H "Content-Type: application/json" \ -d '{"tool":"echo","arguments":{"text":"hello"}}' \ http://127.0.0.1:8787/tools/echo- 节点级
~help返回echo索引,工具级~help返回真实 input schema; - 合法调用返回
{ "echoed": "hello" }对应内容; - 缺少
text或加入未知字段时按 schema 被拒绝; - 未携带有效 SK 时无法访问受保护路径。
完成示例后应签发受限 SK,并用它重复 help/call。不要让业务调用长期使用 bootstrap Admin SK。
4. 注入生产依赖
Section titled “4. 注入生产依赖”createToolBridge 的关键配置:
| 配置 | 作用 | 缺省行为 |
|---|---|---|
state |
树、SK、manifest 的权威状态 | 必填 |
objects |
Context 对象存储 | 未提供时,对应对象 provider 不可用 |
secrets |
自定义 SecretStore | 未提供时使用基于 state 的加密实现 |
encryptionKey |
默认 SecretStore 主密钥 | 也可从 TB_SECRET_ENCRYPTION_KEY 读取;皆无则 Secret 写入不可用 |
adminSk |
首次 bootstrap SK | 也可从 TB_BOOTSTRAP_ADMIN_SK 读取;首次引导两者皆无则拒绝 |
remoteAllowlist |
Federation host 后缀白名单 | 空或缺省时拒绝所有 remote |
maxHops |
Federation Via 跳数上限 | 当前默认 4 |
pluginBindings / pluginCatalog |
进程内 Plugin 代码与 descriptor | 不自动装配;两者需要同源 |
如果只给 pluginBindings 不给 catalog,运行时代码存在但无法按 export 解析;只给 catalog 不给 binding,则能选择却不能调用。标准宿主从 @tool-bridge/plugins 同源装配两者,自定义宿主也应保持这个不变量。
当前公开 ToolBridgeConfig 没有 SearchIndex 注入字段,因此 SDK 实例不提供 ~search。需要 Search 时使用标准 Node server 或完整 Cloudflare gateway,并以根 ~describe 验收;不要向 SDK 传入一个类型未声明、运行时也不会装配的 search 字段。
5. 注册 Context
Section titled “5. 注册 Context”使用 registerContext(path, provider, meta) 注册本地 Context。Provider 至少实现读取所需动词;是否有 Put、Patch、Delete、Search 或 Subscribe 取决于你提供的方法。
客户端应从 Context 路径的 ~help 读取实际命令和 schema,从同一路径的 ~describe 读取可选 capability。公共文档不应静态宣称某个自定义 Context 可写或可搜索。
如果 Context 返回大型内容,可以配合 ObjectStore 和短期 $ref;签名、有效期与访问边界由宿主实现负责。
6. 反向连接远程网关
Section titled “6. 反向连接远程网关”本地实例可以把已经注册的 Tool/Context 上报到远程 tool-bridge:
const connection = tb.connect( 'https://tb.example.com', process.env.TB_DEVICE_SK!, { deviceId: 'my-service-01' },)
const mountPath = await connection.readyconsole.log(`mounted at ${mountPath}`)
// 应用退出时:connection.close()await connection.closed长驻服务必须显式使用稳定 deviceId,否则断线重连无法可靠恢复同一个 online 节点。远端 SK 需要 register scope 和相应 registerPaths,详见接入本地设备与服务与权限、SK 与可见性。
SDK 的 connect() 上报注册节点,不内置 CLI 的 shell/fs 执行器。需要暴露 shell 或文件时使用 tb connect,并配置显式白名单。
Cloudflare Workers 边界
Section titled “Cloudflare Workers 边界”不要因为 SDK 暴露 tb.fetch(Request) 就把 Node 发布包直接接到 Workers export。当前单一入口按 Node 22 构建,connect() 也使用只能在 Node 握手中注入 Authorization header 的 WebSocket 客户端。
如果目标是 Cloudflare Workers,使用一键模板或源码部署。它们已经装配 KV/R2、设备 Durable Object、Assets,以及源码形态中的 D1 Search。
第一次请求时报缺 Admin SK
Section titled “第一次请求时报缺 Admin SK”SDK 在首次 fetch/connect 前执行 bootstrap。显式传 adminSk 或安全注入 TB_BOOTSTRAP_ADMIN_SK;不要在共享环境随机生成并打印最高权限凭证。
secret set 返回 unavailable
Section titled “secret set 返回 unavailable”没有自定义 secrets,也没有提供合法 encryption key。注入 TB_SECRET_ENCRYPTION_KEY 后重新启动并验证;已有密文还需要原加密根。
本地工具能调用,远程连接后找不到
Section titled “本地工具能调用,远程连接后找不到”确保在 connect() 前调用 registerTool/registerContext,设备 SK 的 registerPaths 覆盖目标 mountPath,并等待 connection.ready。远程身份看到的最终路径和工具仍以远程 ~help 为准。
以为 SDK 自动包含所有 integration
Section titled “以为 SDK 自动包含所有 integration”SDK 默认不装配完整 built-in catalog。需要自行同源提供 pluginCatalog 和 pluginBindings,或改用标准 Node/Cloudflare 宿主。
- 用受限 SK替代业务 Admin 调用;
- 阅读从
~help到调用验证自定义 schema; - 对外运行前完成生产上线检查清单;
- 需要反向连接时进入接入本地设备与服务。