Merge pull request #1245 from AstrBotDevs/perf-mcpserver

perf: 适配 MCP 配置文件带 mcpServers 的情况(Cursor)
This commit is contained in:
Soulter
2025-04-12 23:06:39 +08:00
committed by GitHub
3 changed files with 33 additions and 3 deletions

View File

@@ -95,7 +95,10 @@ class MCPClient:
mcp_server_config (dict): Configuration for the MCP server. See https://modelcontextprotocol.io/quickstart/server mcp_server_config (dict): Configuration for the MCP server. See https://modelcontextprotocol.io/quickstart/server
""" """
cfg = mcp_server_config.copy() cfg = mcp_server_config.copy()
cfg.pop("active", None) if "mcpServers" in cfg and len(cfg["mcpServers"]) > 0:
key_0 = list(cfg["mcpServers"].keys())[0]
cfg = cfg["mcpServers"][key_0]
cfg.pop("active", None) # Remove active flag from config
server_params = mcp.StdioServerParameters( server_params = mcp.StdioServerParameters(
**cfg, **cfg,
) )
@@ -260,6 +263,11 @@ class FuncCall:
if data["name"] in self.mcp_client_event: if data["name"] in self.mcp_client_event:
self.mcp_client_event[data["name"]].set() self.mcp_client_event[data["name"]].set()
self.mcp_client_event.pop(data["name"], None) self.mcp_client_event.pop(data["name"], None)
self.func_list = [
f
for f in self.func_list
if not (f.origin == "mcp" and f.mcp_server_name == data["name"])
]
else: else:
for name in self.mcp_client_dict.keys(): for name in self.mcp_client_dict.keys():
# await self._terminate_mcp_client(name) # await self._terminate_mcp_client(name)
@@ -267,6 +275,11 @@ class FuncCall:
if name in self.mcp_client_event: if name in self.mcp_client_event:
self.mcp_client_event[name].set() self.mcp_client_event[name].set()
self.mcp_client_event.pop(name, None) self.mcp_client_event.pop(name, None)
self.func_list = [
f
for f in self.func_list
if f.origin != "mcp"
]
async def _init_mcp_client_task_wrapper( async def _init_mcp_client_task_wrapper(
self, name: str, cfg: dict, event: asyncio.Event self, name: str, cfg: dict, event: asyncio.Event

View File

@@ -106,7 +106,11 @@ class ToolsRoute(Route):
# 复制所有配置字段 # 复制所有配置字段
for key, value in server_data.items(): for key, value in server_data.items():
if key not in ["name", "active", "tools"]: # 排除特殊字段 if key not in ["name", "active", "tools"]: # 排除特殊字段
server_config[key] = value if key == "mcpServers":
key_0 = list(server_data["mcpServers"].keys())[0] # 不考虑为空的情况
server_config = server_data["mcpServers"][key_0]
else:
server_config[key] = value
has_valid_config = True has_valid_config = True
if not has_valid_config: if not has_valid_config:
@@ -163,7 +167,11 @@ class ToolsRoute(Route):
# 复制所有配置字段 # 复制所有配置字段
for key, value in server_data.items(): for key, value in server_data.items():
if key not in ["name", "active", "tools"]: # 排除特殊字段 if key not in ["name", "active", "tools"]: # 排除特殊字段
server_config[key] = value if key == "mcpServers":
key_0 = list(server_data["mcpServers"].keys())[0] # 不考虑为空的情况
server_config = server_data["mcpServers"][key_0]
else:
server_config[key] = value
only_update_active = False only_update_active = False
# 如果只更新活动状态,保留原始配置 # 如果只更新活动状态,保留原始配置

View File

@@ -32,6 +32,7 @@
<v-card-title class="d-flex align-center py-3 px-4"> <v-card-title class="d-flex align-center py-3 px-4">
<v-icon color="primary" class="me-2">mdi-server</v-icon> <v-icon color="primary" class="me-2">mdi-server</v-icon>
<span class="text-h6">MCP 服务器</span> <span class="text-h6">MCP 服务器</span>
<v-progress-circular indeterminate color="primary" size="24" style="margin-left: 16px;" v-show="loading"></v-progress-circular>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn color="primary" prepend-icon="mdi-plus" variant="tonal" @click="showMcpServerDialog = true"> <v-btn color="primary" prepend-icon="mdi-plus" variant="tonal" @click="showMcpServerDialog = true">
新增服务器 新增服务器
@@ -404,6 +405,11 @@ export default {
mounted() { mounted() {
this.getServers(); this.getServers();
this.getTools(); this.getTools();
setInterval(() => {
this.getServers();
this.getTools();
}, 5000); // 每 5 秒刷新一次服务器列表
}, },
methods: { methods: {
@@ -420,12 +426,15 @@ export default {
}, },
getServers() { getServers() {
this.loading = true
axios.get('/api/tools/mcp/servers') axios.get('/api/tools/mcp/servers')
.then(response => { .then(response => {
this.mcpServers = response.data.data || []; this.mcpServers = response.data.data || [];
this.loading = false
}) })
.catch(error => { .catch(error => {
this.showError("获取 MCP 服务器列表失败: " + error.message); this.showError("获取 MCP 服务器列表失败: " + error.message);
this.loading = false
}); });
}, },