Skip to content

Feat support mcp registry api#13376

Merged
KomachiSion merged 1 commit intoalibaba:v3.0-developfrom
luoxiner:opt-mcp-management
May 16, 2025
Merged

Feat support mcp registry api#13376
KomachiSion merged 1 commit intoalibaba:v3.0-developfrom
luoxiner:opt-mcp-management

Conversation

@luoxiner
Copy link
Contributor

Please do not create a Pull Request without creating an issue first.

What is the purpose of the change

Feat support mcp registry api

Brief changelog

  • Add MCP regsitry api.
  • Support multi version mcp server.

Verifying this change

XXXX

Follow this checklist to help us incorporate your contribution quickly and easily:

  • Make sure there is a Github issue filed for the change (usually before you start working on it). Trivial changes like typos do not require a Github issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
  • Format the pull request title like [ISSUE #123] Fix UnknownException when host config not exist. Each commit in the pull request should have a meaningful subject line and body.
  • Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
  • Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add integration-test in test module.
  • Run mvn -B clean package apache-rat:check findbugs:findbugs -Dmaven.test.skip=true to make sure basic checks pass. Run mvn clean install -DskipITs to make sure unit-test pass. Run mvn clean test-compile failsafe:integration-test to make sure integration-test pass.

@github-actions
Copy link

Thanks for your this PR. 🙏
Please check again for your PR changes whether contains any usage/api/configuration change such as Add new API , Add new configuration, Change default value of configuration.
If so, please add or update documents(markdown type) in docs/next/ for repository nacos-group/nacos-group.github.io


感谢您提交的PR。 🙏
请再次查看您的PR内容,确认是否包含任何使用方式/API/配置参数的变更,如:新增API新增配置参数修改默认配置等操作。
如果是,请确保在提交之前,在仓库nacos-group/nacos-group.github.io中的docs/next/目录下添加或更新文档(markdown格式)。

@lingma-agents
Copy link

lingma-agents bot commented May 16, 2025

新增MCP注册API支持多版本管理及前端界面优化

变更文件

文件路径 变更说明
ai/​src/​main/​java/​com/​alibaba/​nacos/​ai/​constant/​Constants.java 添加MCP_REGISTRY_PATH路径常量和MCP_SERVER_VERSIONS_GROUP版本分组标识
ai/​src/​main/​java/​com/​alibaba/​nacos/​ai/​controller/​McpAdminController.java 控制器类名从McpController改为McpAdminController,新增版本参数支持
ai/​src/​main/​java/​com/​alibaba/​nacos/​ai/​controller/​McpRegistryController.java 实现/v0/servers的MCP服务器列表和详情接口,包含版本过滤功能
ai/​src/​main/​java/​com/​alibaba/​nacos/​ai/​form/​mcp/​admin/​McpForm.java 新增version和id字段支持多版本管理,移除旧的mcpName字段
ai/​src/​main/​java/​com/​alibaba/​nacos/​ai/​service/​McpServerOperationService.java 实现MCP服务器版本创建/更新/删除逻辑,集成索引服务提升查询效率
console-ui/​src/​pages/​AI/​NewMcpServer/​NewMcpServer.js 新增版本号输入和发布模式选择功能,支持多版本创建与发布

时序图

sequenceDiagram
    participant MC as McpRegistryController
    participant MS as McpServerOperationService
    participant MI as McpServerMemoryIndex
    participant CD as ConfigDetailService
    MC->>MS: listMcpServers()
    MS->>MI: searchMcpServerByName()
    MI-->>MS: 返回索引数据
    MS->>CD: 查询配置详情
    CD-->>MS: 配置内容
    MS-->>MC: 返回服务器列表

sequenceDiagram
    participant MD as McpDetail
    participant MS as McpServerOperationService
    MD->>MS: getMcpServerDetail()
    MS->>MI: 获取索引信息
    MI-->>MS: 返回服务器元数据
    MS->>CD: 查询版本配置
    CD-->>MS: 返回版本详情
    MS-->>MD: 返回完整服务器信息
Loading

💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @Lingma-Agent 分析这个方法的性能瓶颈并提供优化建议。

  • @Lingma-Agent 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @Lingma-Agent 请总结上述讨论并提出解决方案。

  • @Lingma-Agent 请根据讨论内容生成优化代码。

@KomachiSion KomachiSion merged commit 65e182c into alibaba:v3.0-develop May 16, 2025
3 checks passed
Copy link

@lingma-agents lingma-agents bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔍 代码评审报告

🎯 评审意见概览

严重度 数量 说明
🔴 Blocker 4 阻断性问题,需立即修复。例如:系统崩溃、关键功能不可用或严重安全漏洞。
🟠 Critical 3 严重问题,高优先级修复。例如:核心功能异常或性能瓶颈影响用户体验。
🟡 Major 15 主要问题,建议修复。例如:非核心功能缺陷或代码维护性较差。
🟢 Minor 8 次要问题,酌情优化。例如:代码格式不规范或注释缺失。

总计: 30 个问题

⚠️ **需要立即关注的阻断性问题**

ai/src/main/java/com/alibaba/nacos/ai/form/mcp/admin/McpForm.java

ai/src/main/java/com/alibaba/nacos/ai/utils/McpRequestUtil.java

api/src/main/java/com/alibaba/nacos/api/ai/model/mcp/McpServerBasicInfo.java

console-ui/src/pages/AI/McpDetail/McpDetail.js


📋 评审意见详情

💡 单文件建议

以下是文件级别的代码建议,聚焦于代码的可读性、可维护性和潜在问题。
☕ ai/src/main/java/com/alibaba/nacos/ai/controller/McpRegistryController.java (2 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/form/mcp/admin/McpForm.java (1 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/index/McpServerMemoryIndex.java (3 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/service/McpEndpointOperationService.java (1 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/model/mcp/McpServerIndexData.java (1 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/service/McpServerOperationService.java (3 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/service/McpToolOperationService.java (1 💬)
☕ ai/src/main/java/com/alibaba/nacos/ai/utils/McpRequestUtil.java (1 💬)
☕ api/src/main/java/com/alibaba/nacos/api/ai/constant/AiConstants.java (1 💬)
☕ api/src/main/java/com/alibaba/nacos/api/ai/model/mcp/McpServerBasicInfo.java (1 💬)
☕ api/src/main/java/com/alibaba/nacos/api/ai/model/mcp/registry/McpRegistryServer.java (1 💬)
☕ api/src/main/java/com/alibaba/nacos/api/ai/model/mcp/registry/Remote.java (1 💬)
📜 console-ui/src/components/NameSpaceList/NameSpaceList.js (1 💬)
☕ api/src/main/java/com/alibaba/nacos/api/ai/model/mcp/registry/Repository.java (1 💬)
☕ api/src/main/java/com/alibaba/nacos/api/ai/model/mcp/McpServerVersionInfo.java (1 💬)
📜 console-ui/src/locales/zh-CN.js (1 💬)
📜 console-ui/src/pages/AI/McpDetail/CreateTools/index.js (3 💬)
📜 console-ui/src/pages/AI/McpDetail/McpDetail.js (1 💬)
📜 console-ui/src/pages/AI/McpManagement/McpManagement.js (2 💬)
📜 console-ui/src/pages/AI/NewMcpServer/NewMcpServer.js (3 💬)

🚀 跨文件建议

以下是对代码架构和设计的综合分析,聚焦于跨文件交互、系统一致性和潜在优化空间。
🔍 1. 接口参数不一致导致客户端适配困难

MCP管理接口和注册接口使用不同的分页参数(pageNo/pageSize vs offset/limit),且版本参数传递方式不一致(McpForm的version字段与McpDetailForm的versionDetail嵌套结构)。这种参数设计差异会导致客户端需要处理两种不同的API规范,增加维护成本。

📌 关键代码:

pageForm.getPageNo(), pageForm.getPageSize()))
offset / limit, limit)

⚠️ 潜在风险: 客户端需要维护两种分页逻辑,版本参数传递不一致可能导致调用错误或数据不一致

🔍 2. 未验证的版本参数引发安全漏洞

McpRegistryController的getServer接口未对版本参数进行有效性验证,允许客户端任意指定版本获取服务详情。若存在未发布的版本,可能泄露未公开的配置信息。

📌 关键代码:

McpServerDetailInfo mcpServerDetail = mcpServerOperationService.getMcpServerDetail(Strings.EMPTY, id, getServerForm.getVersion());

⚠️ 潜在风险: 未授权访问未发布版本的敏感配置数据,导致信息泄露

🔍 3. ID与名称双重标识体系存在数据不一致风险

McpForm同时维护id和mcpName字段,但McpServerBasicInfo使用id作为主键而保留name字段。这种双重标识体系可能导致数据不一致,特别是在名称变更时无法通过ID定位资源。

📌 关键代码:

private String id; private String mcpName;
private String id; private String name;

⚠️ 潜在风险: 数据操作时可能出现ID与名称的关联错误,导致资源定位失败或数据污染

🔍 4. 内存索引未实现集群一致性

McpServerMemoryIndex作为单例内存缓存,未考虑分布式集群环境下的数据同步问题。当多个节点同时修改数据时,缓存数据可能不一致,导致查询结果错误。

📌 关键代码:

@Service public class McpServerMemoryIndex implements McpServerIndex {

⚠️ 潜在风险: 分布式环境下缓存数据不一致,查询结果不可靠

🔍 5. 版本控制逻辑存在设计缺陷

McpServerVersionInfo的versions字段与versionDetails字段命名冲突,且版本发布逻辑未限制只能发布最新版本。允许任意版本覆盖可能导致版本回滚风险。

📌 关键代码:

private List<ServerVersionDetail> versions;

⚠️ 潜在风险: 版本管理混乱,可能覆盖最新版本导致数据丢失

🔍 6. 跨服务数据模型不一致

McpServerBasicInfo保留version字段而改用versionDetail嵌套结构,但旧代码如McpController仍使用version字段,存在字段含义不一致问题。

📌 关键代码:

private ServerVersionDetail versionDetail;
mcpProxy.getMcpServer(mcpForm.getNamespaceId(), mcpForm.getMcpName(), mcpForm.getVersion());

⚠️ 潜在风险: 数据模型转换错误导致接口返回数据与客户端期望不匹配

🔍 7. 删除操作未实现原子性

McpServerOperationService的deleteMcpServer方法分多次删除不同版本的数据,但未使用事务机制。中途失败可能导致数据残留或不一致状态。

📌 关键代码:

for (String versionNeedDelete : versionsNeedDelete) {

⚠️ 潜在风险: 部分删除导致配置残留,产生脏数据影响系统稳定性

🔍 8. 跨层数据转换未做类型校验

McpRequestUtil的parseMcpServerBasicInfo等方法直接转换表单数据,未对JSON结构进行完整性校验。非法输入可能导致运行时异常或数据损坏。

📌 关键代码:

BeanUtils.copyProperties(serverSpecification, newSpecification);

⚠️ 潜在风险: 恶意构造的JSON数据可能破坏服务配置,导致系统异常

🔍 9. 版本控制缺少变更审计

版本发布和删除操作未记录变更日志,无法追溯版本变更的历史记录和责任人,不符合企业级系统审计要求。

⚠️ 潜在风险: 无法追踪关键配置变更,存在操作不可追溯的风险

🔍 10. 协议转换缺少兼容性设计

HTTP转MCP服务功能未与Higress组件实现解耦,硬编码依赖文档说明而非程序化验证,可能导致配置错误时无法及时发现。

📌 关键代码:

restToMcpNeedHigress: '存量http服务转化为MCP服务需要搭配higress使用,请参考文档'

⚠️ 潜在风险: 配置错误时系统无法主动校验,导致运行时协议转换失败


💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @Lingma-Agent 分析这个方法的性能瓶颈并提供优化建议。

  • @Lingma-Agent 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @Lingma-Agent 请总结上述讨论并提出解决方案。

  • @Lingma-Agent 请根据讨论内容生成优化代码。

throws NacosException {
int limit = listServerForm.getLimit();
int offset = listServerForm.getOffset();
Page<McpServerBasicInfo> servers = mcpServerOperationService.listMcpServer(listServerForm.getNamespaceId(), Strings.EMPTY, "blur", offset / limit, limit);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用硬编码字符串替代常量可能导致配置不一致

🟡 Major | 🧹 Code Smells

📋 问题详情

在listMcpServers方法中,参数search传入了硬编码字符串'blur',而Constants类中已定义MCP_LIST_SEARCH_ACCURATE和MCP_LIST_SEARCH_BLUR常量。直接使用字符串字面量违反了代码标准化原则,可能导致后续维护时出现配置不一致问题。

💡 解决方案

将硬编码字符串替换为Constants.MCP_LIST_SEARCH_BLUR常量

- "blur"
+ Constants.MCP_LIST_SEARCH_BLUR

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

* @author xinluo
*/
@NacosApi
@RestController
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API接口缺少权限验证注解

🟠 Critical | 🔓 Vulnerabilities

📋 问题详情

McpRegistryController类及其方法未添加@secured注解,可能导致未授权访问。根据项目安全规范,所有API接口必须包含必要的权限验证机制。

💡 解决方案

添加接口安全注解

+ @Secured(action = ActionTypes.READ, signType = SignType.AI, apiType = ApiType.ADMIN_API)

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

private String namespaceId;

private String version;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

参数验证逻辑缺失可能导致无效数据

🔴 Blocker | 🐞 Bugs

📋 问题详情

在validate方法中移除了对mcpName的验证,但该字段通过setId接收值。当客户端未传入id参数时,会导致后续服务端操作出现空指针或无效参数错误。需要恢复必要的参数验证逻辑。

💡 解决方案

补充参数有效性检查

+ if (StringUtils.isEmpty(id)) {
+     throw new NacosApiException(NacosException.INVALID_PARAM, ErrorCode.PARAMETER_MISSING, "Required parameter 'id' type String is not present");
+ }

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

id2InfoCache.put(versionInfo.getId(), data);
}
}
System.out.println("Init index " + JacksonUtils.toJson(id2InfoCache));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

使用System.out.println进行日志输出不符合规范

🟡 Major | 🧹 Code Smells

📋 问题详情

在initIndex和addIndex方法中使用System.out.println输出调试信息,这在生产环境会导致日志不可控。应替换为合适的日志框架(如log4j)实现标准化日志记录。

💡 解决方案

替换为log4j日志输出

- System.out.println(...)
+ logger.info("Init index: {}", JacksonUtils.toJson(id2InfoCache));

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

}).sorted(Comparator.comparing(McpServerIndexData::getId)).toList();

Page<McpServerIndexData> result = new Page<>();
int end = Math.min(limit, allServers.size());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

分页逻辑存在潜在越界风险

🟡 Major | 🐞 Bugs

📋 问题详情

searchMcpServerByName方法中分页计算存在错误:当offset+limit超过列表长度时,subList(offset, end)可能引发IndexOutOfBoundsException。当前end计算方式未考虑总长度,应修正为offset+limit

💡 解决方案

修正分页索引计算

- int end = Math.min(limit, allServers.size());
+ int end = Math.min(offset + limit, allServers.size());

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

Comment on lines +608 to +610
{!this.state.restToMcpSwitch && (
<FormItem label={locale.exportPath} required help={locale.exportPathDesc}>
<Input
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修复服务暴露路径显示条件错误

🟡 Major | 🧹 Code Smells

📋 问题详情

exportPath表单项的显示条件依赖restToMcpSwitch状态,当选择非stdio协议但未开启转换时,必要字段可能被隐藏导致表单验证失败

💡 解决方案

- {!this.state.restToMcpSwitch && (
+ {['mcp-sse', 'mcp-streamble'].includes(this.state.frontProtocol) && (

根据协议类型正确控制暴露路径显示条件


您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

Comment on lines +165 to +167
versionDetail: {
version: values?.version || '1.0.0',
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

修复版本号格式化问题

🟡 Major | 🧹 Code Smells

📋 问题详情

版本号字段将值包装在versionDetail对象中,但未进行空值处理可能导致JSON序列化错误

💡 解决方案

+ versionDetail: values?.version ? { version: values.version } : { version: '1.0.0' },

确保versionDetail对象始终正确构造


您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

Comment on lines +69 to +76
public void updateMcpServer(String namespaceId, String mcpName, boolean isPublish, McpServerBasicInfo serverSpecification,
McpToolSpecification toolSpecification, McpEndpointSpec endpointSpecification) throws NacosException {
clientHolder.getAiMaintainerService()
.updateMcpServer(mcpName, serverSpecification, toolSpecification, endpointSpecification);
}

@Override
public void deleteMcpServer(String namespaceId, String mcpName) throws NacosException {
public void deleteMcpServer(String namespaceId, String mcpName, String version) throws NacosException {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

更新MCP服务器时未传递新添加的isPublish参数

🟠 Critical | 🐞 Bugs

📋 问题详情

在McpRemoteHandler的updateMcpServer方法中,调用AiMaintainerService的updateMcpServer时未传递新增的isPublish参数。原接口需要该参数,可能导致功能缺失或逻辑错误。

💡 解决方案

需要将isPublish参数加入调用:

+ clientHolder.getAiMaintainerService().updateMcpServer(mcpName, isPublish, serverSpecification, toolSpecification, endpointSpecification);

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

Comment on lines +156 to +158
ServerVersionDetail versionDetail = new ServerVersionDetail();
versionDetail.setVersion(version);
serverSpec.setVersionDetail(versionDetail);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

版本信息封装不完整可能导致数据丢失

🟡 Major | 🧹 Code Smells

📋 问题详情

在createLocalMcpServer和createRemoteMcpServer方法中,将version设置到ServerVersionDetail对象后,未处理该对象的其他必要字段。需要确保ServerVersionDetail的其他字段(如描述、创建时间等)也被正确初始化,否则可能引发数据不完整问题。

💡 解决方案

建议补充必要字段的初始化:

+ versionDetail.setDescription("Initial version");
+ versionDetail.setCreateTime(System.currentTimeMillis());

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

public Result<String> deleteMcpServer(McpForm mcpForm) throws NacosException {
mcpForm.validate();
mcpProxy.deleteMcpServer(mcpForm.getNamespaceId(), mcpForm.getMcpName());
mcpProxy.deleteMcpServer(mcpForm.getNamespaceId(), mcpForm.getMcpName(), mcpForm.getVersion());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

删除MCP服务器时未验证版本参数有效性

🟡 Major | 📝 Reliability

📋 问题详情

在deleteMcpServer方法中,直接使用mcpForm.getVersion()参数,但未做空值或格式校验。若版本参数无效可能导致服务器删除操作失败或数据不一致。

💡 解决方案

建议添加参数校验:

+ if (StringUtils.isEmpty(mcpForm.getVersion())) {
+     throw new IllegalArgumentException("Version is required");
+ }

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

@KomachiSion KomachiSion linked an issue May 19, 2025 that may be closed by this pull request
KomachiSion added a commit that referenced this pull request May 21, 2025
* Feat support mcp registry api (#13376)

* Support tag fuzzy search  (#13387)

* support tag fuzzy search

* support tag fuzzy search

* Merge pull request #13391 from luoxiner/support-mcp-multi-version

Feat Support Mcp Registry

* Add copyright for mcp-adapter pom.

* Support version in ai maintainer sdk and fix some errors when build (#13401)

* add version for ai maintainer sdk and support display mcp server config

* fix pmd errors

* fix empty endpoint

* remote publish api

* fix tag fuzzy search sql unit test (#13402)

* Fix unit test.

---------

Co-authored-by: Xin Luo <65529035+luoxiner@users.noreply.github.com>
Co-authored-by: Sunrisea <49605583+Sunrisea@users.noreply.github.com>
Co-authored-by: luoxin.luo <luoxin.luo@alibaba-inc.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support mcp registry api in nacos mcp module

2 participants