跳转到内容

嵌入现有应用

@tool-bridge/sdk 把 tool-bridge 作为库嵌入你的应用。你可以注册本地 Tool/Context,把 fetch 接到现有 HTTP 宿主,或通过 connect() 把本地能力反向挂到远程网关。

它适合已有 Node 22+ 应用、需要调用进程内函数或自定义存储的开发者。它不适合希望“安装后自动获得完整托管 gateway”的场景:SDK 不会自动替你提供持久数据库、对象存储、Search、设备网关通道或完整内置 Plugin catalog。

当前发布包以 Node 22 为目标,并直接依赖 node:os、Node wsprocess.env。虽然 HTTP 表面使用标准 Request / Response,它目前不是可直接嵌入 Cloudflare Workers 的通用包;Workers 请使用标准 Cloudflare gateway。

  • Node.js 22+;
  • 熟悉 Request / Response Fetch API;
  • 一套生产 StateStore 方案;
  • Admin SK 与可选 SecretStore 加密密钥;
  • 如果对外暴露 HTTP,准备 TLS、域名和宿主生命周期管理。

下面的 Node 示例使用 Hono 的 Node server adapter:

Terminal window
npm install @tool-bridge/sdk @hono/node-server
import { serve } from '@hono/node-server'
import { createToolBridge, MemoryStateStore } from '@tool-bridge/sdk'
const adminSk = process.env.TB_BOOTSTRAP_ADMIN_SK
if (!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,
})

registerToolList 是运行时 ~help 与 JSON Schema 的来源;Call 执行实际工具。也可以传入 OperationRegistry,通过 Zod 统一生成 schema 与校验。

在另一个终端先读取节点级工具索引:

Terminal window
curl \
-H "Authorization: Bearer $TB_BOOTSTRAP_ADMIN_SK" \
-H "Accept: application/json" \
http://127.0.0.1:8787/tools/echo/~help

这一层会列出 echo,但为控制上下文大小不会返回完整 schema。继续读取工具级帮助:

Terminal window
curl \
-H "Authorization: Bearer $TB_BOOTSTRAP_ADMIN_SK" \
-H "Accept: application/json" \
http://127.0.0.1:8787/tools/echo/echo/~help

再使用信封调用:

Terminal window
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。

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 字段。

使用 registerContext(path, provider, meta) 注册本地 Context。Provider 至少实现读取所需动词;是否有 Put、Patch、Delete、Search 或 Subscribe 取决于你提供的方法。

客户端应从 Context 路径的 ~help 读取实际命令和 schema,从同一路径的 ~describe 读取可选 capability。公共文档不应静态宣称某个自定义 Context 可写或可搜索。

如果 Context 返回大型内容,可以配合 ObjectStore 和短期 $ref;签名、有效期与访问边界由宿主实现负责。

本地实例可以把已经注册的 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.ready
console.log(`mounted at ${mountPath}`)
// 应用退出时:
connection.close()
await connection.closed

长驻服务必须显式使用稳定 deviceId,否则断线重连无法可靠恢复同一个 online 节点。远端 SK 需要 register scope 和相应 registerPaths,详见接入本地设备与服务权限、SK 与可见性

SDK 的 connect() 上报注册节点,不内置 CLI 的 shell/fs 执行器。需要暴露 shell 或文件时使用 tb connect,并配置显式白名单。

不要因为 SDK 暴露 tb.fetch(Request) 就把 Node 发布包直接接到 Workers export。当前单一入口按 Node 22 构建,connect() 也使用只能在 Node 握手中注入 Authorization header 的 WebSocket 客户端。

如果目标是 Cloudflare Workers,使用一键模板源码部署。它们已经装配 KV/R2、设备 Durable Object、Assets,以及源码形态中的 D1 Search。

SDK 在首次 fetch/connect 前执行 bootstrap。显式传 adminSk 或安全注入 TB_BOOTSTRAP_ADMIN_SK;不要在共享环境随机生成并打印最高权限凭证。

没有自定义 secrets,也没有提供合法 encryption key。注入 TB_SECRET_ENCRYPTION_KEY 后重新启动并验证;已有密文还需要原加密根。

本地工具能调用,远程连接后找不到

Section titled “本地工具能调用,远程连接后找不到”

确保在 connect() 前调用 registerTool/registerContext,设备 SK 的 registerPaths 覆盖目标 mountPath,并等待 connection.ready。远程身份看到的最终路径和工具仍以远程 ~help 为准。

SDK 默认不装配完整 built-in catalog。需要自行同源提供 pluginCatalogpluginBindings,或改用标准 Node/Cloudflare 宿主。