-
Notifications
You must be signed in to change notification settings - Fork 902
feat: add mcp-router plugin #2409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
新增 mcp-router 插件实现 MCP 工具调用动态路由功能变更概述新功能
配置调整
依赖更新
文档更新
变更统计
变更文件
💡 小贴士与 lingma-agents 交流的方式📜 直接回复评论
📜 在代码行处标记
📜 在讨论中提问
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #2409 +/- ##
===========================================
+ Coverage 35.91% 46.02% +10.11%
===========================================
Files 69 81 +12
Lines 11576 13020 +1444
===========================================
+ Hits 4157 5993 +1836
+ Misses 7104 6681 -423
- Partials 315 346 +31 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔎 代码评审报告
🎯 评审意见概览
| 严重度 | 数量 | 说明 |
|---|---|---|
| 🔴 Blocker | 0 | 阻断性问题,需立即修复。例如:系统崩溃、关键功能不可用或严重安全漏洞。 |
| 🟠 Critical | 1 | 严重问题,高优先级修复。例如:核心功能异常或性能瓶颈影响用户体验。 |
| 🟡 Major | 1 | 主要问题,建议修复。例如:非核心功能缺陷或代码维护性较差。 |
| 🟢 Minor | 0 | 次要问题,酬情优化。例如:代码格式不规范或注释缺失。 |
总计: 2 个问题
📋 评审意见详情
💡 代码实现建议
以下是文件级别的代码建议,聚焦于代码的可读性、可维护性和潜在问题。
🔹 plugins/wasm-go/mcp-filters/mcp-router/main.go (2 💬)
- 增强配置解析时的字段校验 (L54-L65)
- 完善请求处理失败时的错误处理 (L104-L126)
🚀 架构设计建议
以下是对代码架构和设计的综合分析,聚焦于跨文件交互、系统一致性和潜在优化空间。
🔍1. 遍历服务器配置列表可能导致性能问题
在 ProcessRequest 函数中,每次请求都会遍历整个 servers 配置列表以查找匹配的服务器名称。如果配置包含大量服务器条目,这会导致 O(n) 的时间复杂度,可能在高并发场景下显著增加处理延迟。建议将 servers 配置转换为以 name 为键的 map 结构,实现 O(1) 的查找效率,从而提升性能。
📌 关键代码
for _, server := range routerConfig.Servers {
if server.Name == serverName {
targetServer = &server
break
}
}在高负载或服务器配置数量较多时,可能导致请求处理延迟增加,影响系统吞吐量。
🔍2. 缺乏核心路由逻辑的单元测试
该 PR 中未包含针对路由核心逻辑的单元测试,例如验证服务器名称匹配、请求头修改、请求体参数修改等关键操作的正确性。缺乏测试可能导致潜在逻辑漏洞未被发现,尤其是在配置变更或边界条件(如无效工具名称格式、未匹配的服务器名称)下。
核心路由逻辑未经过充分验证,可能在生产环境中出现路由错误、请求体参数未正确修改或请求路由到错误服务器等问题,导致服务不可用或数据不一致。
🔍3. 依赖管理引入冗余间接依赖
在 go.mod 文件中,多个依赖被标记为 // indirect(例如 github.com/davecgh/go-spew、github.com/stretchr/testify 等),但部分依赖可能并非真正间接使用。例如,github.com/stretchr/testify 可能未被直接引用,但被标记为间接依赖,这可能引入冗余的依赖项。建议检查并清理未被直接使用的间接依赖,以减少依赖树复杂性和潜在版本冲突风险。
📌 关键代码
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/frankban/quicktest v1.14.6 // indirect
github.com/google/go-cmp v0.6.0 // indirect
冗余的依赖可能增加构建时间、二进制体积,或引入不必要的安全漏洞和版本兼容性问题。
审查详情
📒 文件清单 (5 个文件)
✅ 新增: 5 个文件
✅ 新增文件:
plugins/wasm-go/mcp-filters/mcp-router/README.mdplugins/wasm-go/mcp-filters/mcp-router/README_ZH.mdplugins/wasm-go/mcp-filters/mcp-router/go.modplugins/wasm-go/mcp-filters/mcp-router/go.sumplugins/wasm-go/mcp-filters/mcp-router/main.go
💡 小贴士
与 lingma-agents 交流的方式
📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:
-
在当前代码中添加详细的注释说明。
-
请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。
📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:
-
@lingma-agents 分析这个方法的性能瓶颈并提供优化建议。
-
@lingma-agents 对这个方法生成优化代码。
📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:
-
@lingma-agents 请总结上述讨论并提出解决方案。
-
@lingma-agents 请根据讨论内容生成优化代码。
cr7258
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🐉 LGTM
CH3CHO
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
按我的理解,这个插件要想工作的话,还需要配上一个 tools/list 的聚合插件?
还有这个插件是会被打包到 all-in-one 里,还是作为一个独立插件进行发布呢?
CH3CHO
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
想请教一下mcp-router应该配合mcp-server的toolSet聚合来自不同mcp的tool,但是代码里面判断了如果toolSet不为空,那么不会进行opts.ToolRegistry.RegisterTool注册,导致在tool/list的时候会走到 Tool %s/%s not found in global registry for composed server |
我可能没表达清楚,我没有直接使用higress,而是用了wasm-go的插件,计划是在单个openapi后端服务的sidecar 注入 这个插件,将openapi 转成 mcp。然后在网关使用mcp-router进行路由和聚合多个mcp server 并选择 tool。 |
Ⅰ. Describe what this PR did
Summary
This pull request introduces a new Wasm-Go plugin,
mcp-router, which enables dynamic routing for MCP (Model Context Protocol)tools/callrequests. This is a key component for enabling tool composition from multiple backend MCP servers, allowing a single gateway endpoint to act as an aggregator for a diverse set of tools.Background
Currently, an MCP Server instance is typically mapped to a single backend service. This one-to-one relationship makes it difficult to create a unified MCP endpoint that exposes tools from various independent services. To address this limitation and provide a more flexible tool-calling experience for AI agents, we need a mechanism to route tool calls to their appropriate backend servers dynamically.
Solution
The
mcp-routerplugin acts as an intelligent filter for MCP traffic. Its primary responsibilities are:Parsing Tool Names: It intercepts
tools/callrequests and inspects thenameparameter. It's designed to recognize a composite tool name format:server-name/tool-name.Dynamic Rerouting: Based on the extracted
server-name, the plugin looks up a pre-configured routing table to find the correct domain and path for the target backend MCP server. It then modifies the:authorityand:pathheaders of the request to reroute it accordingly.Request Body Rewriting: After determining the correct route, the plugin rewrites the request body, stripping the
server-name/prefix from the tool name. This ensures that the backend MCP server receives a standardtools/callrequest with a tool name it can understand.This approach, combined with the
toolSetfeature in themcp-serverplugin, allows users to define a single API endpoint that lists tools from multiple sources, and thismcp-routerensures that calls to those tools are correctly delivered to their respective backends.Example Scenario: Combining
mcp-serverandmcp-routerTo achieve a complete tool aggregation solution,
mcp-routerworks in tandem with themcp-serverplugin'stoolSetfeature.1. Configure the
mcp-serverwith atoolSetFirst, you create a new route (e.g.,
/mcp-toolsets/my-tool-a) and apply anmcp-serverplugin configuration that defines atoolSet. ThistoolSetaggregates tools from different servers.When a
tools/listrequest is sent to this endpoint, it will return a combined list of tools, with their names prefixed by their original server name:Request to
toolSetendpoint:Response from
toolSetendpoint:{ "jsonrpc": "2.0", "id": 1, "result": { "tools": [ { "name": "random-user-server/get-user", ... }, { "name": "rest-amap-server/maps-geo", ... } ] } }2. Configure the
mcp-routerNext, you apply the
mcp-routerplugin globally or on a relevant route to handle the subsequenttools/callrequests.3. Making a
tools/callRequestWhen the client (e.g., an AI Agent) wants to call a tool from the list, it sends a
tools/callrequest to thetoolSetendpoint.The
mcp-routerintercepts this request, sees therest-amap-server/prefix, and automatically reroutes the request tomcp.example.com/mcp-servers/mcp-rest-amap-server, ensuring the call reaches the correct backend.Ⅱ. Does this pull request fix one issue?
Ⅲ. Why don't you add test cases (unit test/integration test)?
Ⅳ. Describe how to verify it
Ⅴ. Special notes for reviews