📘 mcpgw 图解教程 · 目录 第一部分 · 宏观全景 01 / 15
第一部分 · 宏观全景

mcpgw 是什么

mcpgw 是一个用 Rust 写的智能 MCP(Model Context Protocol)网关。 它把 N 个上游 MCP server 聚合起来,但对客户端只暴露少量「元工具」—— 由网关在内部做工具检索与按需加载,避免「把上百个工具一次性塞给 LLM」导致的上下文爆炸与选错工具。

🔌 生活类比
把「上百个工具一次性塞给 LLM」想成把整座图书馆的书全堆到桌上——桌子塞满了,你也根本找不到要用的那本。 mcpgw 更像图书馆门口的检索台:你先说一句「我想做 X」,它只把相关的几本递给你; 需要细看时再帮你取来完整那一本;想借走时它替你去书库里把书拿出来。 LLM 始终只面对检索台这一个稳定窗口,而不是整面书墙。

它解决什么问题:工具爆炸

每个上游 MCP server 都会暴露一堆工具。把很多 server 聚合到一起,工具总数会迅速膨胀。 直接把这张长长的工具清单丢给模型,会同时引发三个麻烦:

维度没有网关(直接聚合全部工具)mcpgw(渐进式发现)
上下文占用上百个工具的 schema 全塞进 prompt,撑爆上下文窗口客户端始终只看到 3 个元工具,占用恒定
选择准确率候选越多,模型越容易选错工具先按查询检索,只把相关候选交给模型
prompt 缓存上游增删工具 → 工具数组变化 → 缓存失效工具数组永不变化 → 缓存稳定命中

它的解法:3 个元工具的渐进式发现

mcpgw 不把真实工具直接暴露出去,而是只暴露三个固定的「元工具」,让客户端按 检索 → 看详情 → 执行的节奏,分步把需要的工具「问」出来:

search_tools(query)
用自然语言查询,拿到相关工具候选
get_tool_details(name)
看清某个工具的完整入参 schema
call_tool(name, args)
带参数真正执行该上游工具
🔬 细节 / 代码对应
无论上游有多少工具、是否增减,客户端永远只看到这 3 个元工具。 下游 MCP 服务的 list_tools 恒定返回这 3 个,因此不需要list_changed 去改变模型可见的工具列表(上游变化只在网关内部触发重建检索索引)。
crates/downstream/src/lib.rs · GatewayServer::list_tools
// 客户端能看到的工具集合恒定为 3 个元工具
async fn list_tools(&self, _req, _ctx)
    -> Result<ListToolsResult, McpError> {
    Ok(ListToolsResult::with_all_items(meta_tools()))
}
// meta_tools() == [search_tools, get_tool_details, call_tool]
✅ 关键要点
💡 设计亮点
渐进式披露做在网关(server)侧,因此兼容所有 MCP 客户端、零改造; 又因为对外的工具数组永不变化,对 prompt 缓存友好。 这一选择背后还有现实考量:tools/list_changed 在协议里是可选能力,主流客户端运行中刷新并不可靠, 所以 mcpgw 不依赖它来改变可见工具列表(决策详见 docs/superpowers/specs/2026-06-08-mcpgw-progressive-discovery-design.md)。