refactor(mcp): improve data structure with metadata/spec separation
- Separate MCP server metadata from connection spec for cleaner architecture - Add comprehensive server entry fields: name, description, tags, homepage, docs - Remove legacy format compatibility logic from extract_server_spec - Implement data validation and filtering in get_servers_snapshot_for - Add strict id consistency check in upsert_in_config_for - Enhance import logic with defensive programming for corrupted data - Simplify frontend by removing normalization logic (moved to backend) - Improve error messages with contextual information - Add comprehensive i18n support for new metadata fields
This commit is contained in:
@@ -55,9 +55,19 @@ export const translateMcpBackendError = (
|
||||
}
|
||||
if (
|
||||
msg.includes("MCP 服务器定义必须为 JSON 对象") ||
|
||||
msg.includes("MCP 服务器条目必须为 JSON 对象") ||
|
||||
msg.includes("MCP 服务器条目缺少 server 字段") ||
|
||||
msg.includes("MCP 服务器 server 字段必须为 JSON 对象") ||
|
||||
msg.includes("MCP 服务器连接定义必须为 JSON 对象") ||
|
||||
msg.includes("MCP 服务器 '" /* 不是对象 */) ||
|
||||
msg.includes("不是对象") ||
|
||||
msg.includes("服务器配置必须是对象")
|
||||
msg.includes("服务器配置必须是对象") ||
|
||||
msg.includes("MCP 服务器 name 必须为字符串") ||
|
||||
msg.includes("MCP 服务器 description 必须为字符串") ||
|
||||
msg.includes("MCP 服务器 homepage 必须为字符串") ||
|
||||
msg.includes("MCP 服务器 docs 必须为字符串") ||
|
||||
msg.includes("MCP 服务器 tags 必须为字符串数组") ||
|
||||
msg.includes("MCP 服务器 enabled 必须为布尔值")
|
||||
) {
|
||||
return t("mcp.error.jsonInvalid");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
||||
import { McpServer } from "../types";
|
||||
import { McpServerSpec } from "../types";
|
||||
|
||||
/**
|
||||
* 验证 TOML 格式并转换为 JSON 对象
|
||||
@@ -21,10 +21,10 @@ export const validateToml = (text: string): string => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 将 McpServer 对象转换为 TOML 字符串
|
||||
* 将 McpServerSpec 对象转换为 TOML 字符串
|
||||
* 使用 @iarna/toml 的 stringify,自动处理转义与嵌套表
|
||||
*/
|
||||
export const mcpServerToToml = (server: McpServer): string => {
|
||||
export const mcpServerToToml = (server: McpServerSpec): string => {
|
||||
const obj: any = {};
|
||||
if (server.type) obj.type = server.type;
|
||||
|
||||
@@ -49,7 +49,7 @@ export const mcpServerToToml = (server: McpServer): string => {
|
||||
};
|
||||
|
||||
/**
|
||||
* 将 TOML 文本转换为 McpServer 对象(单个服务器配置)
|
||||
* 将 TOML 文本转换为 McpServerSpec 对象(单个服务器配置)
|
||||
* 支持两种格式:
|
||||
* 1. 直接的服务器配置(type, command, args 等)
|
||||
* 2. [mcp.servers.<id>] 或 [mcp_servers.<id>] 格式(取第一个服务器)
|
||||
@@ -57,7 +57,7 @@ export const mcpServerToToml = (server: McpServer): string => {
|
||||
* @returns McpServer 对象
|
||||
* @throws 解析或转换失败时抛出错误
|
||||
*/
|
||||
export const tomlToMcpServer = (tomlText: string): McpServer => {
|
||||
export const tomlToMcpServer = (tomlText: string): McpServerSpec => {
|
||||
if (!tomlText.trim()) {
|
||||
throw new Error("TOML 内容不能为空");
|
||||
}
|
||||
@@ -104,7 +104,7 @@ export const tomlToMcpServer = (tomlText: string): McpServer => {
|
||||
/**
|
||||
* 规范化服务器配置对象为 McpServer 格式
|
||||
*/
|
||||
function normalizeServerConfig(config: any): McpServer {
|
||||
function normalizeServerConfig(config: any): McpServerSpec {
|
||||
if (!config || typeof config !== "object") {
|
||||
throw new Error("服务器配置必须是对象");
|
||||
}
|
||||
@@ -116,7 +116,7 @@ function normalizeServerConfig(config: any): McpServer {
|
||||
throw new Error("stdio 类型的 MCP 服务器必须包含 command 字段");
|
||||
}
|
||||
|
||||
const server: McpServer = {
|
||||
const server: McpServerSpec = {
|
||||
type: "stdio",
|
||||
command: config.command,
|
||||
};
|
||||
@@ -142,7 +142,7 @@ function normalizeServerConfig(config: any): McpServer {
|
||||
throw new Error("http 类型的 MCP 服务器必须包含 url 字段");
|
||||
}
|
||||
|
||||
const server: McpServer = {
|
||||
const server: McpServerSpec = {
|
||||
type: "http",
|
||||
url: config.url,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user