跳转到内容

挂载 MCP 与 MCP 客户端投影

tool-bridge 同时出现在 MCP 链路的两端,但两端解决的问题不同:

方向 入口 作用
MCP → tool-bridge 挂载一个 kind: mcp 节点 把上游 MCP 工具纳入 HTBP 树、SK 权限和统一发现
MCP client → tool-bridge https://tb.example.com/~mcp 把当前 SK 可见的 HTBP 能力动态投影成 MCP server

不要把这两件事混写成“开启 MCP”。前者需要上游 URL 和可能的上游凭证;后者需要给 MCP 客户端一把 tool-bridge scoped SK。

适合已经有 Streamable HTTP MCP server,希望让 HTTP Agent、CLI、Dashboard 和 MCP 客户端共享同一棵受权树的场景。

不适合只有本地 stdio 进程且没有 HTTP 入口的情况;tool-bridge 的声明式 MCP 节点需要可访问的 HTTP URL。也不要把任意不可信 URL交给生产网关:上游默认要求 HTTPS,本地 HTTP 需要显式开发开关。

  • 对目标挂载路径拥有 readcallregister
  • registerPaths 允许该路径;
  • 有凭证时,对 system/secret 拥有 admin
  • 网关能访问上游 URL;
  • OAuth 场景已规划 canonical origin 和 redirect URI。

挂载权限与上游凭证边界见权限、SK 与可见性密钥、出站身份与安全边界

Terminal window
tb tool mount tools/docs \
--kind mcp \
--url https://mcp.example.com/mcp \
--description "文档检索 MCP"

挂载后先发现,不要先猜工具名:

Terminal window
tb help tools/docs
# 将 search 替换为上一条 ~help 返回的真实工具名
TOOL_NAME=search
tb help "tools/docs/$TOOL_NAME" --json
tb call tools/docs --tool "$TOOL_NAME" --args '{}'

节点级 ~help 是索引;工具级 ~help 才包含完整输入 schema。普通工具也可直接调用:

Terminal window
tb call "tools/docs/$TOOL_NAME" '{"query":"tool-bridge"}'

先把凭证写进 SecretStore,再挂载引用:

Terminal window
tb secret set --name docs-mcp-token < token.txt
tb tool mount tools/docs \
--kind mcp \
--url https://mcp.example.com/mcp \
--auth-ref docs-mcp-token

默认注入 Authorization: Bearer <secret>。只有上游明确要求其他头名或 scheme 时才覆盖:

Terminal window
tb tool mount tools/custom \
--kind mcp \
--url https://mcp.example.com/mcp \
--auth-ref custom-token \
--auth-header X-API-Key \
--auth-scheme ''

不要用 --header 放密钥;静态 header 属于可读节点配置。authRef 解析失败时网关会 fail closed,而不是匿名访问上游。

Terminal window
tb tool mount tools/oauth-mcp \
--kind mcp \
--url https://mcp.example.com/mcp \
--auth oauth
tb tool auth tools/oauth-mcp

如果上游只接受 loopback callback,可按当前 CLI 帮助尝试:

Terminal window
tb tool auth tools/oauth-mcp --local

OAuth discovery、授权与 token 交换发生在网关边界内。不要把 access/refresh token 复制进 providerConfig,也不要用不同域名交替完成授权与调用。

  1. tb help <node> 能列出工具;
  2. tb help <node>/<tool> --json 返回有效 schema;
  3. 当前 SK 有 call 时能完成一次无破坏性调用;
  4. 去掉 call 但保留 read 的测试 SK 能看见帮助、调用得到 403;
  5. 去掉 read 的测试 SK 对节点得到 404。

上游工具 discovery 可能被缓存;需要确认上游刚变更的工具表时,以当前节点 ~help 支持的刷新方式和对应版本说明为准,不要承诺静态刷新时延。

给客户端配置 HTTP endpoint 和专用最小权限 SK:

URL: https://tb.example.com/~mcp
Authorization: Bearer <scoped-tool-bridge-sk>

tools/list 不是固定清单。它会按本次 Bearer 身份,从树中投影可见且可调用的工具,并包含 tb_helptb_list_nodes;宿主启用全局 Search 时才包含 tb_search。投影工具名经过 MCP-safe 编码,客户端应使用 tools/list 返回的名称,不能从 HTBP path 自行拼接。

/~mcp 是无状态适配器:每次请求都重新使用当前 Bearer 身份,不依赖网关 isolate 中保存的 MCP session。它复用同一权限与 provider 行为,不是第二套旁路 API。

现象 处理
挂载时拒绝 http:// 生产上游应改为 HTTPS;仅本地测试可由部署者显式开启不安全 HTTP
unavailable 且提到 authRef Secret 不存在、主密钥不可用或引用名错误;检查 tb secret ls,不要降级匿名
节点有帮助但调用 403 当前 SK 有 read 没有 call
工具名和 MCP 客户端里不同 入站投影会编码名称;以 MCP tools/list 为准
tb_search 不存在 宿主没有启用全局 Search;这是可选 capability,不是 MCP 故障
OAuth 回调失败 检查 canonical origin、上游 redirect allowlist,并按 CLI 提示判断是否使用 --local
上游业务错误返回 HTTP 200 MCP 的 isError 可是工具结果,不等同于 HTBP 传输错误;读取返回 content
Terminal window
tb tool rm tools/docs
tb tree tools --depth 2

卸载节点不会删除其 SecretStore 凭证。确认没有其他节点使用后,再执行 tb secret rm <name>。对于 OAuth 节点,先停止业务流量、卸载节点,再在必要时到上游撤销授权;不要只删本地引用却保留无法审计的上游 token。

MCP 客户端侧回滚只需移除 ~mcp endpoint 或吊销该客户端专用 SK,不影响树上上游 MCP 节点。