From 2ec0a10a2c3e6b86683272c6f680945caeee9d8e Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 12 Oct 2025 16:34:32 +0800 Subject: [PATCH] feat(i18n): complete internationalization for MCP preset descriptions - Add i18n keys for all 5 MCP preset descriptions (fetch, time, memory, sequential-thinking, context7) - Refactor mcpPresets.ts to use i18n keys instead of hardcoded Chinese descriptions - Add getMcpPresetWithDescription() helper function for dynamic translation - Update McpFormModal to use translated descriptions when applying presets - Fix inconsistent key naming: sequentialThinking -> sequential-thinking This ensures MCP preset descriptions automatically switch language based on user's locale setting. --- src/components/mcp/McpFormModal.tsx | 55 ++++++++++++++++------------- src/config/mcpPresets.ts | 24 +++++++------ src/i18n/locales/en.json | 22 +++++++++++- src/i18n/locales/zh.json | 22 +++++++++++- 4 files changed, 86 insertions(+), 37 deletions(-) diff --git a/src/components/mcp/McpFormModal.tsx b/src/components/mcp/McpFormModal.tsx index e609744..18ffa91 100644 --- a/src/components/mcp/McpFormModal.tsx +++ b/src/components/mcp/McpFormModal.tsx @@ -2,7 +2,7 @@ import React, { useState } from "react"; import { useTranslation } from "react-i18next"; import { X, Save, AlertCircle, ChevronDown, ChevronUp } from "lucide-react"; import { McpServer, McpServerSpec } from "../../types"; -import { mcpPresets } from "../../config/mcpPresets"; +import { mcpPresets, getMcpPresetWithDescription } from "../../config/mcpPresets"; import { buttonStyles, inputStyles } from "../../lib/styles"; import McpWizardModal from "./McpWizardModal"; import { @@ -139,25 +139,27 @@ const McpFormModal: React.FC = ({ // 应用预设(写入表单但不落库) const applyPreset = (index: number) => { if (index < 0 || index >= mcpPresets.length) return; - const p = mcpPresets[index]; - const id = ensureUniqueId(p.id); + const preset = mcpPresets[index]; + const presetWithDesc = getMcpPresetWithDescription(preset, t); + + const id = ensureUniqueId(presetWithDesc.id); setFormId(id); - setFormName(p.name || p.id); - setFormDescription(p.description || ""); - setFormHomepage(p.homepage || ""); - setFormDocs(p.docs || ""); - setFormTags(p.tags?.join(", ") || ""); + setFormName(presetWithDesc.name || presetWithDesc.id); + setFormDescription(presetWithDesc.description || ""); + setFormHomepage(presetWithDesc.homepage || ""); + setFormDocs(presetWithDesc.docs || ""); + setFormTags(presetWithDesc.tags?.join(", ") || ""); // 根据格式转换配置 if (useToml) { - const toml = mcpServerToToml(p.server); + const toml = mcpServerToToml(presetWithDesc.server); setFormConfig(toml); { const err = validateToml(toml); setConfigError(formatTomlError(err)); } } else { - const json = JSON.stringify(p.server, null, 2); + const json = JSON.stringify(presetWithDesc.server, null, 2); setFormConfig(json); setConfigError(validateJson(json)); } @@ -464,21 +466,24 @@ const McpFormModal: React.FC = ({ > {t("presetSelector.custom")} - {mcpPresets.map((p, idx) => ( - - ))} + {mcpPresets.map((preset, idx) => { + const descriptionKey = `mcp.presets.${preset.id}.description`; + return ( + + ); + })} )} diff --git a/src/config/mcpPresets.ts b/src/config/mcpPresets.ts index 070b0d5..e52efdc 100644 --- a/src/config/mcpPresets.ts +++ b/src/config/mcpPresets.ts @@ -1,17 +1,16 @@ import { McpServer, McpServerSpec } from "../types"; -export type McpPreset = Omit; +export type McpPreset = Omit; // 预设 MCP(逻辑简化版): // - 仅包含最常用、可快速落地的 stdio 模式示例 // - 不涉及分类/模板/测速等复杂逻辑,默认以 disabled 形式"回种"到 config.json // - 用户可在 MCP 面板中一键启用/编辑 +// - description 字段使用国际化 key,在使用时通过 t() 函数获取翻译 export const mcpPresets: McpPreset[] = [ { id: "fetch", name: "mcp-server-fetch", - description: - "通用 HTTP 请求工具,支持 GET/POST 等 HTTP 方法,适合快速请求接口/抓取网页数据", tags: ["stdio", "http", "web"], server: { type: "stdio", @@ -24,8 +23,6 @@ export const mcpPresets: McpPreset[] = [ { id: "time", name: "@modelcontextprotocol/server-time", - description: - "时间查询工具,提供当前时间、时区转换、日期计算等功能", tags: ["stdio", "time", "utility"], server: { type: "stdio", @@ -38,8 +35,6 @@ export const mcpPresets: McpPreset[] = [ { id: "memory", name: "@modelcontextprotocol/server-memory", - description: - "知识图谱记忆系统,支持存储实体、关系和观察,让 AI 记住对话中的重要信息", tags: ["stdio", "memory", "graph"], server: { type: "stdio", @@ -52,7 +47,6 @@ export const mcpPresets: McpPreset[] = [ { id: "sequential-thinking", name: "@modelcontextprotocol/server-sequential-thinking", - description: "顺序思考工具,帮助 AI 将复杂问题分解为多个步骤,逐步深入思考", tags: ["stdio", "thinking", "reasoning"], server: { type: "stdio", @@ -65,8 +59,6 @@ export const mcpPresets: McpPreset[] = [ { id: "context7", name: "@upstash/context7-mcp", - description: - "Context7 文档搜索工具,提供最新的库文档和代码示例,配置 key 会有更高限额", tags: ["stdio", "docs", "search"], server: { type: "stdio", @@ -78,4 +70,16 @@ export const mcpPresets: McpPreset[] = [ }, ]; +// 获取带国际化描述的预设 +export const getMcpPresetWithDescription = ( + preset: McpPreset, + t: (key: string) => string, +): McpServer => { + const descriptionKey = `mcp.presets.${preset.id}.description`; + return { + ...preset, + description: t(descriptionKey), + } as McpServer; +}; + export default mcpPresets; diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 7dcecd3..d6cbecb 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -362,7 +362,27 @@ "enabled": "Enabled", "installed": "Installed", "docs": "Docs", - "requiresEnv": "Requires env" + "requiresEnv": "Requires env", + "fetch": { + "name": "mcp-server-fetch", + "description": "Universal HTTP request tool, supports GET/POST and other HTTP methods, suitable for quick API requests and web data scraping" + }, + "time": { + "name": "@modelcontextprotocol/server-time", + "description": "Time query tool providing current time, timezone conversion, and date calculation features" + }, + "memory": { + "name": "@modelcontextprotocol/server-memory", + "description": "Knowledge graph memory system supporting entities, relations, and observations to help AI remember important information from conversations" + }, + "sequential-thinking": { + "name": "@modelcontextprotocol/server-sequential-thinking", + "description": "Sequential thinking tool helping AI break down complex problems into multiple steps for deeper thinking" + }, + "context7": { + "name": "@upstash/context7-mcp", + "description": "Context7 documentation search tool providing latest library docs and code examples, with higher limits when configured with a key" + } } } } diff --git a/src/i18n/locales/zh.json b/src/i18n/locales/zh.json index b4a32cb..d04ec1e 100644 --- a/src/i18n/locales/zh.json +++ b/src/i18n/locales/zh.json @@ -362,7 +362,27 @@ "enabled": "已启用", "installed": "已安装", "docs": "文档", - "requiresEnv": "需要环境变量" + "requiresEnv": "需要环境变量", + "fetch": { + "name": "mcp-server-fetch", + "description": "通用 HTTP 请求工具,支持 GET/POST 等 HTTP 方法,适合快速请求接口/抓取网页数据" + }, + "time": { + "name": "@modelcontextprotocol/server-time", + "description": "时间查询工具,提供当前时间、时区转换、日期计算等功能" + }, + "memory": { + "name": "@modelcontextprotocol/server-memory", + "description": "知识图谱记忆系统,支持存储实体、关系和观察,让 AI 记住对话中的重要信息" + }, + "sequentialThinking": { + "name": "@modelcontextprotocol/server-sequential-thinking", + "description": "顺序思考工具,帮助 AI 将复杂问题分解为多个步骤,逐步深入思考" + }, + "context7": { + "name": "@upstash/context7-mcp", + "description": "Context7 文档搜索工具,提供最新的库文档和代码示例,配置 key 会有更高限额" + } } } }