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.
This commit is contained in:
@@ -2,7 +2,7 @@ import React, { useState } from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { X, Save, AlertCircle, ChevronDown, ChevronUp } from "lucide-react";
|
import { X, Save, AlertCircle, ChevronDown, ChevronUp } from "lucide-react";
|
||||||
import { McpServer, McpServerSpec } from "../../types";
|
import { McpServer, McpServerSpec } from "../../types";
|
||||||
import { mcpPresets } from "../../config/mcpPresets";
|
import { mcpPresets, getMcpPresetWithDescription } from "../../config/mcpPresets";
|
||||||
import { buttonStyles, inputStyles } from "../../lib/styles";
|
import { buttonStyles, inputStyles } from "../../lib/styles";
|
||||||
import McpWizardModal from "./McpWizardModal";
|
import McpWizardModal from "./McpWizardModal";
|
||||||
import {
|
import {
|
||||||
@@ -139,25 +139,27 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
|
|||||||
// 应用预设(写入表单但不落库)
|
// 应用预设(写入表单但不落库)
|
||||||
const applyPreset = (index: number) => {
|
const applyPreset = (index: number) => {
|
||||||
if (index < 0 || index >= mcpPresets.length) return;
|
if (index < 0 || index >= mcpPresets.length) return;
|
||||||
const p = mcpPresets[index];
|
const preset = mcpPresets[index];
|
||||||
const id = ensureUniqueId(p.id);
|
const presetWithDesc = getMcpPresetWithDescription(preset, t);
|
||||||
|
|
||||||
|
const id = ensureUniqueId(presetWithDesc.id);
|
||||||
setFormId(id);
|
setFormId(id);
|
||||||
setFormName(p.name || p.id);
|
setFormName(presetWithDesc.name || presetWithDesc.id);
|
||||||
setFormDescription(p.description || "");
|
setFormDescription(presetWithDesc.description || "");
|
||||||
setFormHomepage(p.homepage || "");
|
setFormHomepage(presetWithDesc.homepage || "");
|
||||||
setFormDocs(p.docs || "");
|
setFormDocs(presetWithDesc.docs || "");
|
||||||
setFormTags(p.tags?.join(", ") || "");
|
setFormTags(presetWithDesc.tags?.join(", ") || "");
|
||||||
|
|
||||||
// 根据格式转换配置
|
// 根据格式转换配置
|
||||||
if (useToml) {
|
if (useToml) {
|
||||||
const toml = mcpServerToToml(p.server);
|
const toml = mcpServerToToml(presetWithDesc.server);
|
||||||
setFormConfig(toml);
|
setFormConfig(toml);
|
||||||
{
|
{
|
||||||
const err = validateToml(toml);
|
const err = validateToml(toml);
|
||||||
setConfigError(formatTomlError(err));
|
setConfigError(formatTomlError(err));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const json = JSON.stringify(p.server, null, 2);
|
const json = JSON.stringify(presetWithDesc.server, null, 2);
|
||||||
setFormConfig(json);
|
setFormConfig(json);
|
||||||
setConfigError(validateJson(json));
|
setConfigError(validateJson(json));
|
||||||
}
|
}
|
||||||
@@ -464,21 +466,24 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
|
|||||||
>
|
>
|
||||||
{t("presetSelector.custom")}
|
{t("presetSelector.custom")}
|
||||||
</button>
|
</button>
|
||||||
{mcpPresets.map((p, idx) => (
|
{mcpPresets.map((preset, idx) => {
|
||||||
<button
|
const descriptionKey = `mcp.presets.${preset.id}.description`;
|
||||||
key={p.id}
|
return (
|
||||||
type="button"
|
<button
|
||||||
onClick={() => applyPreset(idx)}
|
key={preset.id}
|
||||||
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
|
type="button"
|
||||||
selectedPreset === idx
|
onClick={() => applyPreset(idx)}
|
||||||
? "bg-emerald-500 text-white dark:bg-emerald-600"
|
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
|
||||||
: "bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
|
selectedPreset === idx
|
||||||
}`}
|
? "bg-emerald-500 text-white dark:bg-emerald-600"
|
||||||
title={p.description}
|
: "bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||||
>
|
}`}
|
||||||
{p.id}
|
title={t(descriptionKey)}
|
||||||
</button>
|
>
|
||||||
))}
|
{preset.id}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
import { McpServer, McpServerSpec } from "../types";
|
import { McpServer, McpServerSpec } from "../types";
|
||||||
|
|
||||||
export type McpPreset = Omit<McpServer, "enabled">;
|
export type McpPreset = Omit<McpServer, "enabled" | "description">;
|
||||||
|
|
||||||
// 预设 MCP(逻辑简化版):
|
// 预设 MCP(逻辑简化版):
|
||||||
// - 仅包含最常用、可快速落地的 stdio 模式示例
|
// - 仅包含最常用、可快速落地的 stdio 模式示例
|
||||||
// - 不涉及分类/模板/测速等复杂逻辑,默认以 disabled 形式"回种"到 config.json
|
// - 不涉及分类/模板/测速等复杂逻辑,默认以 disabled 形式"回种"到 config.json
|
||||||
// - 用户可在 MCP 面板中一键启用/编辑
|
// - 用户可在 MCP 面板中一键启用/编辑
|
||||||
|
// - description 字段使用国际化 key,在使用时通过 t() 函数获取翻译
|
||||||
export const mcpPresets: McpPreset[] = [
|
export const mcpPresets: McpPreset[] = [
|
||||||
{
|
{
|
||||||
id: "fetch",
|
id: "fetch",
|
||||||
name: "mcp-server-fetch",
|
name: "mcp-server-fetch",
|
||||||
description:
|
|
||||||
"通用 HTTP 请求工具,支持 GET/POST 等 HTTP 方法,适合快速请求接口/抓取网页数据",
|
|
||||||
tags: ["stdio", "http", "web"],
|
tags: ["stdio", "http", "web"],
|
||||||
server: {
|
server: {
|
||||||
type: "stdio",
|
type: "stdio",
|
||||||
@@ -24,8 +23,6 @@ export const mcpPresets: McpPreset[] = [
|
|||||||
{
|
{
|
||||||
id: "time",
|
id: "time",
|
||||||
name: "@modelcontextprotocol/server-time",
|
name: "@modelcontextprotocol/server-time",
|
||||||
description:
|
|
||||||
"时间查询工具,提供当前时间、时区转换、日期计算等功能",
|
|
||||||
tags: ["stdio", "time", "utility"],
|
tags: ["stdio", "time", "utility"],
|
||||||
server: {
|
server: {
|
||||||
type: "stdio",
|
type: "stdio",
|
||||||
@@ -38,8 +35,6 @@ export const mcpPresets: McpPreset[] = [
|
|||||||
{
|
{
|
||||||
id: "memory",
|
id: "memory",
|
||||||
name: "@modelcontextprotocol/server-memory",
|
name: "@modelcontextprotocol/server-memory",
|
||||||
description:
|
|
||||||
"知识图谱记忆系统,支持存储实体、关系和观察,让 AI 记住对话中的重要信息",
|
|
||||||
tags: ["stdio", "memory", "graph"],
|
tags: ["stdio", "memory", "graph"],
|
||||||
server: {
|
server: {
|
||||||
type: "stdio",
|
type: "stdio",
|
||||||
@@ -52,7 +47,6 @@ export const mcpPresets: McpPreset[] = [
|
|||||||
{
|
{
|
||||||
id: "sequential-thinking",
|
id: "sequential-thinking",
|
||||||
name: "@modelcontextprotocol/server-sequential-thinking",
|
name: "@modelcontextprotocol/server-sequential-thinking",
|
||||||
description: "顺序思考工具,帮助 AI 将复杂问题分解为多个步骤,逐步深入思考",
|
|
||||||
tags: ["stdio", "thinking", "reasoning"],
|
tags: ["stdio", "thinking", "reasoning"],
|
||||||
server: {
|
server: {
|
||||||
type: "stdio",
|
type: "stdio",
|
||||||
@@ -65,8 +59,6 @@ export const mcpPresets: McpPreset[] = [
|
|||||||
{
|
{
|
||||||
id: "context7",
|
id: "context7",
|
||||||
name: "@upstash/context7-mcp",
|
name: "@upstash/context7-mcp",
|
||||||
description:
|
|
||||||
"Context7 文档搜索工具,提供最新的库文档和代码示例,配置 key 会有更高限额",
|
|
||||||
tags: ["stdio", "docs", "search"],
|
tags: ["stdio", "docs", "search"],
|
||||||
server: {
|
server: {
|
||||||
type: "stdio",
|
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;
|
export default mcpPresets;
|
||||||
|
|||||||
@@ -362,7 +362,27 @@
|
|||||||
"enabled": "Enabled",
|
"enabled": "Enabled",
|
||||||
"installed": "Installed",
|
"installed": "Installed",
|
||||||
"docs": "Docs",
|
"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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -362,7 +362,27 @@
|
|||||||
"enabled": "已启用",
|
"enabled": "已启用",
|
||||||
"installed": "已安装",
|
"installed": "已安装",
|
||||||
"docs": "文档",
|
"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 会有更高限额"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user