把 HTTP API 声明为工具
声明式 HTTP 适合工具数量有限、请求形状稳定、可以用“method + path template + JSON Schema”准确描述的 REST API。它无需单独编写 Plugin,但不是通用 API 网关:复杂签名、分页编排、重试、响应归一或多步事务更适合专门的 Plugin。
适用与不适用
Section titled “适用与不适用”适合:
- 少量 GET/POST/PUT/DELETE 操作;
- 路径参数和剩余 query/body 能直接从 arguments 映射;
- 单个认证头即可满足上游认证;
- 希望工具立即进入
~help、SK scope、Search 和 MCP 投影。
不适合:
- 需要 AWS 风格签名、复杂 OAuth、多阶段上传或自定义重试;
- 需要根据响应动态调用下一个 API;
- 上游 schema 经常变化,且已有标准 MCP server;
- 需要隐藏复杂的供应商错误与返回形状。此时应使用外部 Plugin或 MCP。
- 网关能访问 HTTPS endpoint;
- 当前 SK 对挂载路径有
register,且registerPaths允许; - 有上游凭证时,对
system/secret有admin; - 已确认每个操作的副作用、路径参数和输入 schema。
路径 register/call 与 authRef 的通用边界见权限、SK 与可见性和密钥、出站身份与安全边界。
1. 编写工具定义
Section titled “1. 编写工具定义”创建 crm-tools.json:
[ { "name": "get_customer", "description": "按客户 ID 读取客户资料", "method": "GET", "pathTemplate": "/customers/{id}", "effect": "read", "inputSchema": { "type": "object", "additionalProperties": false, "properties": { "id": { "type": "string", "minLength": 1 }, "include": { "type": "string" } }, "required": ["id"] } }, { "name": "update_customer", "description": "更新客户资料", "method": "PUT", "pathTemplate": "/customers/{id}", "effect": "write", "inputSchema": { "type": "object", "additionalProperties": false, "properties": { "id": { "type": "string", "minLength": 1 }, "displayName": { "type": "string" } }, "required": ["id", "displayName"] } }]映射规则是确定的:{id} 从 arguments 取值并做 URL 编码;GET/DELETE 的剩余参数进入 query;POST/PUT 的剩余参数成为 JSON body。缺少路径参数时返回 invalid_argument。
effect 可显式设为 read、write 或 destructive。未提供时 GET 推导为 read,其他 method 推导为 write;删除、发送、发布等高风险动作建议明确写 destructive,不要只依赖 method 推导。
2. 保存凭证并挂载
Section titled “2. 保存凭证并挂载”tb secret set --name crm-api-token < crm.token
tb tool mount tools/crm \ --kind http \ --endpoint https://api.example.com/v1 \ --tools-file crm-tools.json \ --auth-ref crm-api-token \ --description "客户资料 API"默认认证头是 Authorization: Bearer <secret>。上游若要求原始 API key:
tb tool mount tools/crm \ --kind http \ --endpoint https://api.example.com/v1 \ --tools-file crm-tools.json \ --auth-ref crm-api-token \ --auth-header X-API-Key \ --auth-scheme ''3. 发现与调用
Section titled “3. 发现与调用”tb help tools/crmtb help tools/crm/get_customer --json
tb call tools/crm/get_customer '{"id":"cus_123","include":"contacts"}'
tb call tools/crm \ --tool update_customer \ --args '{"id":"cus_123","displayName":"Example"}'生产验收优先调用 read-only 工具。写操作先使用测试资源,并确认调用 SK 只有必要路径的 read,call;call 控制能否执行工具,工具自己的 effect 是给调用方判断风险的元数据,不替代授权。
- 节点和工具级
~help正确显示 description、effect 和 inputSchema; - 路径参数经过编码后到达正确 endpoint;
- GET 剩余参数成为 query,PUT/POST 剩余参数成为 JSON body;
- 上游 2xx JSON 或文本被正确返回;
- 删除当前 SK 的
call后调用得到 403,删除read后路径表现为 404; tb secret ls只显示 secret 名称和更新时间,不回显 token。
客户端和 Agent 应按从 ~help 到调用读取工具级 schema,而不是把这份示例工具表当成运行时契约。
| 现象 | 原因与处理 |
|---|---|
invalid_argument 缺少路径参数 |
pathTemplate 中的占位名与 arguments/schema 不一致 |
| 工具能调用但参数到了错误位置 | 重新检查 method:GET/DELETE 剩余参数进 query,POST/PUT 进 JSON body |
| 401/403 来自上游 | auth header/scheme 不符合上游,或 Secret 已失效;不要把本地 SK 透传 |
unavailable 提到 authRef |
SecretStore 不可用或引用不存在;修复主密钥/引用,不要匿名重试 |
| 上游返回 4xx/5xx 后只见统一错误 | HTTP provider 会归一传输错误;需要保留供应商业务细节时写 Plugin |
| 注册时拒绝 URL | 生产默认只允许 HTTPS;不要为公网目标开启全局不安全 HTTP |
| schema 与真实 API 漂移 | 更新 tools file 后重新挂载/更新节点,并以新节点 ~help 验证 |
tb tool rm tools/crmtb tree tools --depth 2节点删除不会删除 crm-api-token。确认不再被其他节点引用后:
tb secret rm crm-api-token变更工具表时,低风险做法是先挂到新路径(例如 tools/crm-v2),完成 help/schema/read-only 调用和受限 SK 验收,再切换调用方并卸载旧路径。这样比原地替换后再排查安全得多。