Hotdry.

Article

用 Goose 的 MCP 热插拔机制构建沙箱化自定义工具链

基于 Goose 的 MCP Server 架构,拆解插件生命周期、沙箱隔离与热插拔实现,给出可直接落地的超时、重启与权限白名单参数。

2025-12-12ai-systems

把 AI-agent 做成 “可扩展操作系统” 的关键,是让用户像装 App 一样装工具,且随时插拔、不崩主进程。Block 开源的 Rust 版 Goose 给出的答案是:把插件翻译成 MCP Server,用进程级生命周期管理实现热插拔,用白名单 + WASM 做沙箱。本文拆给你看:从发现、加载、 capability 协商到崩溃重启,每一步都有可直接落地的参数。

一、Goose 的 “插件” 到底是什么

Goose 主进程完全用 Rust 写成,只干四件事:

  1. 调度 LLM 请求;
  2. 维护一个 MCP Client Router;
  3. 守护所有子进程(即 MCP Server);
  4. 把 stdout/sse 回来的 JSON-RPC 结果喂给 LLM。

因此,“写插件”=“写一个 MCP Server”,语言不限:官方仓库里既有 Node 也有 Python 例子,只要实现 MCP Specificationtools/listtools/call 两组方法即可。Goose 在运行时把它当黑盒子 spawn,用完即走,天然隔离。

二、热插拔生命周期:五条命令就能复现

  1. 发现
    用户通过 UI 或 CLI 输入扩展名,Goose 先去本地 $GOOSE_REGISTRY/json/<name>.json 查元数据;若无,则回退到远程 registry。元数据里唯一必填的是启动命令:["npx", "@mcp/github"]"wasm://./figma.wasm"

  2. 拉取 & 校验
    如果指定了 checksum,Goose 用 sha256 校验;若走 WASM,还会验证 runtime 版本兼容性(wasmtime >= 17.0)。

  3. spawn + capability 协商
    Goose 以 RUST_LOG=mcp=debug 启动子进程,先发送 mcp.initialize,子进程返回 capabilities.tools.list=true 即表示 “我能提供工具”。这一步失败直接回滚,不会写入配置。

  4. 注册到 Router
    成功后,把 <tool_name, server_id> 写进内存哈希表;LLM 后续看到 tools/github.create_issue 就会路由到对应子进程。

  5. 崩溃重启 & 卸载
    子进程退出码非 0 视为 crash。Goose 立即重启,连续 5 次失败则永久卸载,并写 $GOOSE_DATA/crashes/<id>.log 供排查。用户可手动 goose ext reload <id> 清零计数器。

以上五步全部在 1 秒内完成,用户侧感知就是 “点一下开关→工具列表里出现新工具”。

三、沙箱隔离三板斧

维度 默认策略 可调参数
网络 仅允许 localhost:8000–9000 GOOSE_MCP_ALLOW_NET=host:port,host:port
文件 只读工作区,写操作需显式声明 `{

ai-systems