Conversation
Walkthrough此次 PR 对 MCP 服务器管理功能进行了全面改进。新增和更新了测试用例、前端组件、后端服务及相关接口,实现了对 MCP 服务器的获取、启动、停止以及工具注册和配置的管理。同时,引入了新的 MCP 配置命令、界面组件和样式,并对常量和本地化条目做了统一更新,改进了内建服务器的初始化流程以及偏好配置的获取逻辑,从而增强 MCP 服务器与工具的整体管理能力。 Changes
Sequence Diagram(s)sequenceDiagram
participant User as 用户
participant ChatView as AIChatView
participant CommandSvc as CommandService
participant mcpProxy as MCPServerProxyService
User->>ChatView: 点击 MCP 配置或工具按钮
ChatView->>CommandSvc: 调用 handleShowMCPConfig / handleShowMCPTools
CommandSvc-->>ChatView: 执行命令返回结果
Note over ChatView: 更新 mcpToolsCount 与 mcpServersCount
%% 监听服务器状态变更流程
mcpProxy->>ChatView: 触发 onChangeMCPServers 事件
ChatView->>ChatView: useEventEffect 更新状态
sequenceDiagram
participant User as 用户
participant Registry as CommandRegistry
participant MCPCommand as MCPConfigCommandContribution
participant Editor as WorkbenchEditorService
User->>Registry: 触发 OPEN_MCP_CONFIG_COMMAND
Registry->>MCPCommand: 执行注册回调
MCPCommand->>Editor: 通过 URI 打开 MCP 配置组件
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 ESLint
yarn install v1.22.22 ✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (17)
packages/ai-native/__test__/node/mcp-server.test.ts (1)
6-6: 类重命名实现完整,建议补充错误处理测试用例!将
MCPServerImpl重命名为StdioMCPServerImpl更好地反映了该实现是基于标准输入输出的特性。重命名的修改很完整,但建议:
- 添加服务器启动失败的测试场景
- 添加标准输入输出流异常的测试场景
- 添加进程意外终止的测试场景
Also applies to: 11-12, 27-27
packages/ai-native/src/browser/index.ts (1)
58-59: 模块依赖组织建议新增的 MCP 配置相关组件集成正确。建议:
- 将 MCP 相关的导入语句分组放置,提高代码可读性
- 考虑在 providers 数组中为 MCP 相关的提供者添加注释分组,类似已有的 "MCP Server Contributions" 分组
建议按如下方式组织导入语句:
import { LanguageParserService } from './languages/service'; +// MCP Config Contributions import { MCPConfigCommandContribution } from './mcp/config/mcp-config.commands'; import { MCPConfigContribution } from './mcp/config/mcp-config.contribution'; +// MCP Server Components import { MCPServerProxyService } from './mcp/mcp-server-proxy.service';Also applies to: 96-97
packages/ai-native/src/browser/mcp/config/mcp-config.commands.ts (1)
8-11: 建议添加命令描述!命令定义应该包含描述字段,以便在命令面板中提供更多上下文信息:
export const OPEN_MCP_CONFIG_COMMAND = { id: 'opensumi-mcp.openConfig', label: 'Open MCP Configuration', + description: '打开 MCP 服务器配置界面', };packages/ai-native/src/browser/mcp/config/mcp-config.contribution.ts (2)
19-19: 为导出的类型添加文档注释建议为
IMCPConfigResource类型添加 JSDoc 文档注释,说明其用途和configType字段的含义。+/** + * MCP 配置资源的接口定义 + * @property configType - MCP 配置的类型标识 + */ export type IMCPConfigResource = IResource<{ configType: string }>;
48-64: 增强资源提供者的错误处理建议在
provideResource方法中添加错误处理,以便在 URI 解析失败时提供更好的错误信息。registerResource(service: ResourceService) { service.registerResourceProvider({ scheme: MCP_CONFIG_COMPONENTS_SCHEME_ID, provideResource: async (uri: URI): Promise<IMCPConfigResource> => { + try { const { configType } = uri.getParsedQuery(); + if (!configType) { + throw new Error('配置类型未指定'); + } return { uri, name: 'MCP Configuration', icon: 'settings', metadata: { configType, }, }; + } catch (error) { + throw new Error(`无法解析 MCP 配置资源: ${error.message}`); + } }, }); }packages/ai-native/src/browser/mcp/config/components/mcp-config.view.tsx (2)
25-27: 添加加载状态处理建议添加加载状态管理,以提供更好的用户体验。
+const [isLoading, setIsLoading] = React.useState(false); const [servers, setServers] = React.useState<MCPServer[]>([]); const [formVisible, setFormVisible] = React.useState(false); const [editingServer, setEditingServer] = React.useState<MCPServerFormData | undefined>();
134-214: 拆分大型组件建议将服务器列表和表单部分拆分为独立的组件,以提高代码的可维护性。
建议将服务器列表项抽取为独立组件:
interface ServerItemProps { server: MCPServer; onEdit: (server: MCPServer) => void; onControl: (serverName: string, start: boolean) => void; onDelete: (serverName: string) => void; } const ServerItem: React.FC<ServerItemProps> = ({ server, onEdit, onControl, onDelete }) => { // ... 服务器项的渲染逻辑 ... };packages/ai-native/src/browser/mcp/mcp-server.feature.registry.ts (1)
53-77: 增强错误处理和类型安全建议改进
callMCPTool方法的错误处理和类型安全性。async callMCPTool( name: string, - args: any, + args: Record<string, unknown>, ): Promise<{ content: { type: string; text: string }[]; isError?: boolean; }> { try { const tool = this.tools.find((tool) => tool.name === name); if (!tool) { - throw new Error(`MCP tool ${name} not found`); + throw new Error(`未找到 MCP 工具: ${name}`); } // 统一校验并转换 const toolCallId = args.toolCallId; args = tool.inputSchema.parse(args); return await tool.handler({ ...args, toolCallId }, this.logger); } catch (error) { - // eslint-disable-next-line no-console - console.error('callMCPTool error:', error); + this.logger.appendLine(`工具调用失败: ${error.message}`); return { - content: [{ type: 'text', text: `The tool ${name} failed to execute. Error: ${error}` }], + content: [{ type: 'text', text: `工具 ${name} 执行失败: ${error.message}` }], isError: true, }; } }packages/ai-native/src/node/mcp-server.ts (1)
9-12: 类命名与公开属性实现细节。
新类StdioMCPServerImpl实现了IMCPServer,并公开了command与可选args;从设计上看,这些字段需在运行时灵活变更,设置为public可以接受。但需确认在其他地方如构造器或update方法中,不会意外地将这些字段修改为无效值,建议在需要确保字段有效性时增加相应类型或校验逻辑。packages/ai-native/src/browser/mcp/config/components/mcp-server-form.tsx (2)
28-29: 保留的 TODO 属性需确认后续规划。
在表单数据中硬编码了type: 'stdio',且标注了// TODO: 支持 SSE。需要确保在后续修正或实现此功能时不会遗留无效字段。
61-80:handleSubmit处理参数与环境变量的解析非常直接,但应添加容错。
目前假设argsText以空格分隔,envText以换行分隔且每行通过'='分割键值。若用户输入不符合规范,可能导致解析异常或丢失。建议在解析前,对每行做更多校验或提供错误提示。packages/ai-native/src/node/mcp-server-manager-impl.ts (2)
18-20: 公开getServers接口便于外部统一管理 Server 集合。
新增方法使外部可便利获取服务器映射对象,能在调试或扩展时提高可见性。后续使用场景较多时,也可考虑返回快照或只读结构以避免集合被意外篡改。
145-151: 新增enabled参数控制内置服务器启动逻辑。
如果将来可能需要在运行中开启/禁用内置服务器,可考虑在此方法中根据实时条件决定是否停止/重启,以保持管理接口一致性。packages/ai-native/src/browser/chat/chat.view.tsx (2)
670-681: 建议添加错误处理逻辑当前的异步调用缺少错误处理机制。建议添加 try-catch 块来处理潜在的错误。
useEventEffect( mcpServerProxyService.onChangeMCPServers, () => { - mcpServerProxyService.getAllMCPTools().then((tools) => { - setMcpToolsCount(tools.length); - }); - mcpServerProxyService.$getServers().then((servers) => { - setMcpServersCount(servers.length); - }); + Promise.all([ + mcpServerProxyService.getAllMCPTools().catch(error => { + console.error('获取 MCP 工具失败:', error); + return []; + }), + mcpServerProxyService.$getServers().catch(error => { + console.error('获取 MCP 服务器失败:', error); + return []; + }) + ]).then(([tools, servers]) => { + setMcpToolsCount(tools.length); + setMcpServersCount(servers.length); + }); }, [mcpServerProxyService], );
735-746: 建议添加加载状态指示当点击显示 MCP 工具或配置时,建议添加加载状态指示器来提升用户体验。
<div className={styles.header_operate_right}> {aiNativeConfigService.capabilities.supportsMCP && ( <> + {isLoading && <LoadingSpinner className={styles.loading} />} <div className={styles.tag} onClick={handleShowMCPConfig}> {`MCP Servers: ${mcpServersCount}`} </div> <div className={styles.tag} onClick={handleShowMCPTools}> {`MCP Tools: ${mcpToolsCount}`} </div> </> )} </div>packages/ai-native/src/common/index.ts (2)
34-35: 建议完善常量注释虽然已添加中文注释,但建议补充更详细的说明,包括使用场景和注意事项。
- // 内置 MCP 服务器名称 + /** + * 内置 MCP 服务器名称 + * 用于标识和管理 OpenSumi 内置的 MCP 服务器 + * 该常量在服务器注册、状态管理等场景中使用 + */
129-135: 接口设计清晰,但建议添加方法文档新增的服务器管理方法设计合理,建议为每个方法添加 JSDoc 文档说明其用途、参数和返回值。
+ /** + * 初始化内置 MCP 服务器 + * @param enabled - 是否启用服务器 + */ initBuiltinMCPServer(enabled: boolean): void; + /** + * 获取所有 MCP 服务器的状态信息 + * @returns 包含服务器名称和运行状态的数组 + */ getServers(): Promise<Array<{ name: string; isStarted: boolean }>>;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
packages/ai-native/__test__/common/mcp-server-manager.test.ts(1 hunks)packages/ai-native/__test__/node/mcp-server.test.ts(2 hunks)packages/ai-native/src/browser/ai-core.contribution.ts(2 hunks)packages/ai-native/src/browser/chat/chat.view.tsx(7 hunks)packages/ai-native/src/browser/index.ts(2 hunks)packages/ai-native/src/browser/mcp/config/components/mcp-config.module.less(1 hunks)packages/ai-native/src/browser/mcp/config/components/mcp-config.view.tsx(1 hunks)packages/ai-native/src/browser/mcp/config/components/mcp-server-form.module.less(1 hunks)packages/ai-native/src/browser/mcp/config/components/mcp-server-form.tsx(1 hunks)packages/ai-native/src/browser/mcp/config/mcp-config.commands.ts(1 hunks)packages/ai-native/src/browser/mcp/config/mcp-config.contribution.ts(1 hunks)packages/ai-native/src/browser/mcp/mcp-server-proxy.service.ts(3 hunks)packages/ai-native/src/browser/mcp/mcp-server.feature.registry.ts(3 hunks)packages/ai-native/src/browser/preferences/schema.ts(1 hunks)packages/ai-native/src/common/index.ts(2 hunks)packages/ai-native/src/common/mcp-server-manager.ts(3 hunks)packages/ai-native/src/common/tool-invocation-registry.ts(2 hunks)packages/ai-native/src/common/types.ts(1 hunks)packages/ai-native/src/common/utils.ts(2 hunks)packages/ai-native/src/node/mcp-server-manager-impl.ts(5 hunks)packages/ai-native/src/node/mcp-server.ts(2 hunks)packages/ai-native/src/node/mcp/sumi-mcp-server.ts(4 hunks)packages/i18n/src/common/en-US.lang.ts(1 hunks)packages/i18n/src/common/zh-CN.lang.ts(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- packages/ai-native/src/browser/mcp/config/components/mcp-server-form.module.less
- packages/ai-native/src/browser/mcp/config/components/mcp-config.module.less
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build (ubuntu-latest, 20.x)
- GitHub Check: build-windows
🔇 Additional comments (26)
packages/ai-native/__test__/common/mcp-server-manager.test.ts (1)
34-34: 新增的 getServers 方法实现正确!新增的 mock 方法与现有的测试模式保持一致,有助于完善 MCP 服务器管理功能的测试覆盖率。
packages/ai-native/src/common/utils.ts (1)
3-3: 优化:使用常量替代硬编码值!将内置 MCP 服务器名称改为使用
BUILTIN_MCP_SERVER_NAME常量是一个很好的改进,这样可以:
- 提高代码的可维护性
- 确保服务器名称在整个代码库中保持一致
- 减少因硬编码值导致的潜在错误
Also applies to: 54-54
packages/i18n/src/common/en-US.lang.ts (1)
1572-1574: 代码变更看起来不错!本地化条目添加合理,遵循了现有的命名约定和组织结构。这些条目为 MCP 服务器连接类型提供了清晰的描述。
packages/i18n/src/common/zh-CN.lang.ts (1)
1335-1338: 新增的本地化条目清晰且符合规范!新增的 MCP 服务器连接类型相关的本地化条目描述准确,翻译风格统一。
packages/ai-native/src/browser/preferences/schema.ts (1)
111-132: MCP 服务器配置模式的扩展设计合理!新增的配置项完善了 MCP 服务器的配置能力:
- 新增
type字段用于配置连接类型- 新增
enabled字段用于控制服务器启用状态- 为
args字段设置了合理的默认值packages/ai-native/src/browser/ai-core.contribution.ts (1)
331-348: MCP 服务器初始化逻辑优化合理!改进后的初始化流程更加清晰和可控:
- 分离内置服务器和外部服务器的初始化逻辑
- 根据配置控制内置服务器的启用状态
- 避免重复初始化内置服务器
packages/ai-native/src/common/mcp-server-manager.ts (2)
3-11: MCP 服务器接口设计规范且完整!新增的
IMCPServer接口定义了服务器的核心操作:
- 状态查询和控制
- 工具调用和获取
- 配置更新
- 生命周期管理
24-24: MCP 服务器管理接口扩展合理!接口扩展增强了服务器管理能力:
initBuiltinServer支持控制服务器启用状态getServers提供对所有服务器实例的访问MCPServerDescription新增enabled配置项Also applies to: 32-32, 60-64
packages/ai-native/src/common/types.ts (1)
35-40: 代码变更符合预期!新增的服务器管理方法定义清晰,返回类型和参数类型设计合理,注释说明完整。这些接口很好地支持了 MCP 服务器的管理功能。
packages/ai-native/src/common/tool-invocation-registry.ts (1)
75-75: 方法重命名提高了代码可读性!将
unregisterAllTools重命名为unregisterProviderTools更准确地反映了该方法的实际功能 - 注销特定提供者的工具。Also applies to: 86-94
packages/ai-native/src/browser/mcp/mcp-server-proxy.service.ts (1)
7-7: 常量引用改进了代码维护性!使用
BUILTIN_MCP_SERVER_NAME常量替换硬编码的字符串值,提高了代码的可维护性。Also applies to: 38-38
packages/ai-native/src/browser/mcp/config/mcp-config.commands.ts (1)
13-29: 命令实现遵循最佳实践!
- 使用了依赖注入获取编辑器服务
- 正确配置了编辑器选项(禁用预览,启用焦点)
- 实现遵循了 OpenSumi 的命令贡献模式
packages/ai-native/src/node/mcp-server.ts (2)
7-7: 导入接口无异常,符合依赖需求。
该行仅引入IMCPServer接口,与后续实现相匹配,目前无明显问题。
111-121: 异步停止逻辑需考虑潜在异常处理后的状态一致性。
stop方法通过异步关闭连接并使用 try/catch 捕获异常,但无论close是否成功,最后仍标记this.started = false。如果关闭失败,服务器可能处于未知状态,可能需要额外逻辑(例如重试或重新抛出异常)以避免客户端重复调用或执行后续操作。packages/ai-native/src/browser/mcp/config/components/mcp-server-form.tsx (3)
8-13: 表单数据类型设计无明显问题。
MCPServerFormData封装了与 MCP Server 配置相关的必需字段,符合常见表单设计,可保持扩展性。
42-59: 自动同步初始数据与表单状态的逻辑。
useEffect用于当initialData变化时重置表单状态,这种场景常见且易用。但若要重设某些字段为默认值,需确保与已有数据合并的逻辑正确,不会意外覆盖。
82-145: 表单布局与操作逻辑直观清晰,基础可用。
整体结构清晰,使用Modal+ 表单控件组合使功能易于扩展。建议后续配合视觉与交互需求完善表单校验与用户反馈,以提升易用性。packages/ai-native/src/node/mcp-server-manager-impl.ts (7)
5-5: 引入IMCPServer后与后续实现保持一致。
此改动有助于在 Manager 中直接取用通用接口,与具体实现解耦。无明显问题。
9-9: 新导入StdioMCPServerImpl。
替换旧的MCPServerImpl有助于统一 Server 的实现方式,注意确保相关依赖与测试用例均已更新。
31-34: 抽取unregisterServerTools方法减少重复逻辑。
清晰的私有方法让代码更易维护;注意确保对所有可能的工具注销场景均能正确处理。
41-44: 停止服务器并注销工具的顺序正确性。
先await server.stop()再取消工具注册逻辑,确保不会在停止前就移除工具。流程清晰,无明显问题。
70-70: 在startServer后立刻注册工具强化一致性。
此处await this.registerTools(serverName);保证服务器启动成功后再注册,逻辑正确;需确认若启动过程中出错时,是否需要回滚或额外处理。
136-136: 实例化StdioMCPServerImpl替换旧实现,保持接口一致。
符合 Server 统一管理要求,无明显问题。但建议在外部检查命令与运行环境的可行性,以防启动失败。
157-160: 在循环中跳过未启用的服务器。
条件判断清晰,逻辑简单易懂。若部分服务器日后需在特定场景临时启动,需确保此处能灵活扩展。packages/ai-native/src/browser/chat/chat.view.tsx (1)
6-6: 代码结构清晰,状态管理合理!新增的 MCP 相关导入和状态变量设计合理,能够有效跟踪 MCP 工具和服务器的数量。
Also applies to: 56-56, 87-87, 117-118
packages/ai-native/src/node/mcp/sumi-mcp-server.ts (1)
196-207: 良好的初始状态设置
BuiltinMCPServer类的初始状态设置和命名常量使用恰当。
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v3.8 #4387 +/- ##
==========================================
- Coverage 53.49% 53.45% -0.04%
==========================================
Files 1656 1657 +1
Lines 102032 102094 +62
Branches 22071 22083 +12
==========================================
- Hits 54578 54572 -6
- Misses 39486 39542 +56
- Partials 7968 7980 +12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Types
支持 MCP Server 的管理,包括可视化的界面,Server 的启用 / 禁用
Background or solution
Changelog
Summary by CodeRabbit
新功能
界面更新
本地化