mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
fix: enable only synced ModelScope MCP servers (#9084)
* fix: enable only synced ModelScope MCP servers * fix: avoid mutating default MCP config
This commit is contained in:
@@ -1057,11 +1057,14 @@ class FunctionToolManager:
|
||||
"mcp_server_list",
|
||||
[],
|
||||
)
|
||||
local_mcp_config = self.load_mcp_config()
|
||||
local_mcp_config = copy.deepcopy(self.load_mcp_config())
|
||||
|
||||
synced_count = 0
|
||||
mcp_servers = local_mcp_config.setdefault("mcpServers", {})
|
||||
synced_servers: list[tuple[str, dict]] = []
|
||||
for server in mcp_server_list:
|
||||
server_name = server["name"]
|
||||
server_name = server.get("name")
|
||||
if not server_name:
|
||||
continue
|
||||
operational_urls = server.get("operational_urls", [])
|
||||
if not operational_urls:
|
||||
continue
|
||||
@@ -1070,28 +1073,28 @@ class FunctionToolManager:
|
||||
if not server_url:
|
||||
continue
|
||||
# 添加到配置中(同名会覆盖)
|
||||
local_mcp_config["mcpServers"][server_name] = {
|
||||
server_config = {
|
||||
"url": server_url,
|
||||
"transport": "sse",
|
||||
"active": True,
|
||||
"provider": "modelscope",
|
||||
}
|
||||
synced_count += 1
|
||||
mcp_servers[server_name] = server_config
|
||||
synced_servers.append((server_name, server_config))
|
||||
|
||||
if synced_count > 0:
|
||||
if synced_servers:
|
||||
self.save_mcp_config(local_mcp_config)
|
||||
tasks = []
|
||||
for server in mcp_server_list:
|
||||
name = server["name"]
|
||||
for name, config in synced_servers:
|
||||
tasks.append(
|
||||
self.enable_mcp_server(
|
||||
name=name,
|
||||
config=local_mcp_config["mcpServers"][name],
|
||||
config=config,
|
||||
),
|
||||
)
|
||||
await asyncio.gather(*tasks)
|
||||
logger.info(
|
||||
f"从 ModelScope 同步了 {synced_count} 个 MCP 服务器",
|
||||
f"从 ModelScope 同步了 {len(synced_servers)} 个 MCP 服务器",
|
||||
)
|
||||
else:
|
||||
logger.warning("没有找到可用的 ModelScope MCP 服务器")
|
||||
|
||||
@@ -3,6 +3,7 @@ import json
|
||||
import pytest
|
||||
|
||||
from astrbot.core import sp
|
||||
from astrbot.core.provider import func_tool_manager as ftm
|
||||
from astrbot.core.provider.func_tool_manager import FunctionToolManager
|
||||
from astrbot.core.tools.computer_tools.shell import ExecuteShellTool
|
||||
from astrbot.core.tools.message_tools import SendMessageToUserTool
|
||||
@@ -345,3 +346,80 @@ def test_firecrawl_tools_are_registered_as_builtin_tools():
|
||||
assert extract_tool.name == "firecrawl_extract_web_page"
|
||||
assert manager.is_builtin_tool("web_search_firecrawl") is True
|
||||
assert manager.is_builtin_tool("firecrawl_extract_web_page") is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_modelscope_sync_enables_only_synced_servers(monkeypatch):
|
||||
class FakeResponse:
|
||||
status = 200
|
||||
|
||||
async def __aenter__(self):
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
return False
|
||||
|
||||
async def json(self):
|
||||
return {
|
||||
"data": {
|
||||
"mcp_server_list": [
|
||||
{
|
||||
"name": "valid",
|
||||
"operational_urls": [{"url": "https://example.com/mcp"}],
|
||||
},
|
||||
{"name": "missing-url", "operational_urls": []},
|
||||
{"name": "empty-url", "operational_urls": [{}]},
|
||||
{"operational_urls": [{"url": "https://example.com/no-name"}]},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class FakeSession:
|
||||
async def __aenter__(self):
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc, tb):
|
||||
return False
|
||||
|
||||
def get(self, *_args, **_kwargs):
|
||||
return FakeResponse()
|
||||
|
||||
saved_configs = []
|
||||
enabled_servers = []
|
||||
default_config = {"mcpServers": {}}
|
||||
manager = FunctionToolManager()
|
||||
|
||||
async def fake_enable_mcp_server(name, config):
|
||||
enabled_servers.append((name, config))
|
||||
|
||||
monkeypatch.setattr(ftm.aiohttp, "ClientSession", lambda: FakeSession())
|
||||
monkeypatch.setattr(manager, "load_mcp_config", lambda: default_config)
|
||||
monkeypatch.setattr(manager, "save_mcp_config", saved_configs.append)
|
||||
monkeypatch.setattr(manager, "enable_mcp_server", fake_enable_mcp_server)
|
||||
|
||||
await manager.sync_modelscope_mcp_servers("token")
|
||||
|
||||
assert default_config == {"mcpServers": {}}
|
||||
assert saved_configs == [
|
||||
{
|
||||
"mcpServers": {
|
||||
"valid": {
|
||||
"url": "https://example.com/mcp",
|
||||
"transport": "sse",
|
||||
"active": True,
|
||||
"provider": "modelscope",
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
assert enabled_servers == [
|
||||
(
|
||||
"valid",
|
||||
{
|
||||
"url": "https://example.com/mcp",
|
||||
"transport": "sse",
|
||||
"active": True,
|
||||
"provider": "modelscope",
|
||||
},
|
||||
)
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user