feat: 重构 MCP 配置管理,移除旧配置文件,更新为使用全局配置

This commit is contained in:
DrSmoothl
2026-03-30 23:32:13 +08:00
parent dc2bf02a42
commit abb1d071b1
10 changed files with 214 additions and 135 deletions

View File

@@ -1,6 +1,6 @@
from datetime import datetime
from pathlib import Path
from typing import Any, Callable, Mapping, Sequence, TypeVar
from typing import Any, Callable, Mapping, Sequence, TypeVar, cast
import asyncio
import copy
@@ -27,6 +27,7 @@ from .official_configs import (
LPMMKnowledgeConfig,
MaiSakaConfig,
MaimMessageConfig,
MCPConfig,
PluginRuntimeConfig,
MemoryConfig,
MessageReceiveConfig,
@@ -56,7 +57,7 @@ CONFIG_DIR: Path = PROJECT_ROOT / "config"
BOT_CONFIG_PATH: Path = (CONFIG_DIR / "bot_config.toml").resolve().absolute()
MODEL_CONFIG_PATH: Path = (CONFIG_DIR / "model_config.toml").resolve().absolute()
MMC_VERSION: str = "1.0.0"
CONFIG_VERSION: str = "8.1.11"
CONFIG_VERSION: str = "8.2.0"
MODEL_CONFIG_VERSION: str = "1.13.1"
logger = get_logger("config")
@@ -134,6 +135,9 @@ class Config(ConfigBase):
maisaka: MaiSakaConfig = Field(default_factory=MaiSakaConfig)
"""MaiSaka对话系统配置类"""
mcp: MCPConfig = Field(default_factory=MCPConfig)
"""MCP 配置类"""
plugin_runtime: PluginRuntimeConfig = Field(default_factory=PluginRuntimeConfig)
"""插件运行时配置类"""
@@ -332,7 +336,12 @@ class ConfigManager:
changed_scopes: 本次热重载命中的配置范围。
"""
result = callback(changed_scopes) if self._callback_accepts_scopes(callback) else callback()
if self._callback_accepts_scopes(callback):
callback_with_scopes = cast(Callable[[Sequence[str]], object], callback)
result = callback_with_scopes(changed_scopes)
else:
callback_without_scopes = cast(Callable[[], object], callback)
result = callback_without_scopes()
if asyncio.iscoroutine(result):
await result

View File

@@ -1,6 +1,7 @@
from .config_base import ConfigBase, Field
import re
from typing import Optional, Literal
from typing import Literal, Optional
from .config_base import ConfigBase, Field
"""
须知:
@@ -1493,15 +1494,6 @@ class MaiSakaConfig(ConfigBase):
)
"""启用知识库模块"""
enable_mcp: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "zap",
},
)
"""启用 MCP (Model Context Protocol) 支持"""
show_analyze_cognition_prompt: bool = Field(
default=False,
json_schema_extra={
@@ -1577,6 +1569,128 @@ class MaiSakaConfig(ConfigBase):
"""Maisaka终端图片预览的字符宽度"""
class MCPServerItemConfig(ConfigBase):
"""单个 MCP 服务器配置。"""
name: str = Field(
default="",
json_schema_extra={
"x-widget": "input",
"x-icon": "tag",
},
)
"""服务器名称,必须唯一"""
enabled: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "power",
},
)
"""是否启用当前 MCP 服务器"""
transport: Literal["stdio", "sse"] = Field(
default="stdio",
json_schema_extra={
"x-widget": "select",
"x-icon": "shuffle",
},
)
"""传输方式,可选 stdio 或 sse"""
command: str = Field(
default="",
json_schema_extra={
"x-widget": "input",
"x-icon": "terminal",
},
)
"""stdio 模式下启动服务器的命令"""
args: list[str] = Field(
default_factory=lambda: [],
json_schema_extra={
"x-widget": "custom",
"x-icon": "list",
},
)
"""stdio 模式下的命令参数列表"""
env: dict[str, str] = Field(
default_factory=lambda: {},
json_schema_extra={
"x-widget": "custom",
"x-icon": "variable",
},
)
"""stdio 模式下附加的环境变量"""
url: str = Field(
default="",
json_schema_extra={
"x-widget": "input",
"x-icon": "link",
},
)
"""sse 模式下的服务地址"""
headers: dict[str, str] = Field(
default_factory=lambda: {},
json_schema_extra={
"x-widget": "custom",
"x-icon": "file-json",
},
)
"""sse 模式下附加的请求头"""
def model_post_init(self, context: Optional[dict] = None) -> None:
"""验证 MCP 服务器配置。"""
if not self.name.strip():
raise ValueError("MCPServerItemConfig.name 不能为空")
if self.transport == "stdio" and not self.command.strip():
raise ValueError(f"MCP 服务器 {self.name} 使用 stdio 时必须填写 command")
if self.transport == "sse" and not self.url.strip():
raise ValueError(f"MCP 服务器 {self.name} 使用 sse 时必须填写 url")
return super().model_post_init(context)
class MCPConfig(ConfigBase):
"""MCP 总配置。"""
__ui_parent__ = "maisaka"
enable: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "zap",
},
)
"""是否启用 MCPModel Context Protocol"""
servers: list[MCPServerItemConfig] = Field(
default_factory=lambda: [],
json_schema_extra={
"x-widget": "custom",
"x-icon": "server",
},
)
"""_wrap_MCP 服务器配置列表"""
def model_post_init(self, context: Optional[dict] = None) -> None:
"""验证 MCP 总配置。"""
server_names = [server.name.strip() for server in self.servers if server.name.strip()]
if len(server_names) != len(set(server_names)):
raise ValueError("MCP 配置中的服务器名称不能重复")
return super().model_post_init(context)
class PluginRuntimeConfig(ConfigBase):
"""插件运行时配置类"""