Merge branch 'main' into v2

# Conflicts:
#	src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServerList.tsx
#	src/renderer/src/pages/settings/MCPSettings/McpProviderSettings.tsx
#	src/renderer/src/pages/settings/MCPSettings/McpServersList.tsx
#	src/renderer/src/pages/settings/MCPSettings/McpSettingsNavbar.tsx
#	src/renderer/src/pages/settings/MCPSettings/index.tsx
#	src/renderer/src/pages/settings/MCPSettings/providers/config.ts
This commit is contained in:
kangfenmao 2025-11-07 19:34:45 +08:00
commit 56df52d850
28 changed files with 758 additions and 253 deletions

View File

@ -11,6 +11,8 @@ The Test Plan is divided into the RC channel and the Beta channel, with the foll
Users can enable the "Test Plan" and select the version channel in the software's `Settings` > `About`. Please note that the versions in the "Test Plan" cannot guarantee data consistency, so be sure to back up your data before using them. Users can enable the "Test Plan" and select the version channel in the software's `Settings` > `About`. Please note that the versions in the "Test Plan" cannot guarantee data consistency, so be sure to back up your data before using them.
After enabling the RC channel or Beta channel, if a stable version is released, users will still be upgraded to the stable version.
Users are welcome to submit issues or provide feedback through other channels for any bugs encountered during testing. Your feedback is very important to us. Users are welcome to submit issues or provide feedback through other channels for any bugs encountered during testing. Your feedback is very important to us.
## Developer Guide ## Developer Guide

View File

@ -11,6 +11,8 @@
用户可以在软件的`设置`-`关于`中,开启“测试计划”并选择版本通道。请注意“测试计划”的版本无法保证数据的一致性,请使用前一定要备份数据。 用户可以在软件的`设置`-`关于`中,开启“测试计划”并选择版本通道。请注意“测试计划”的版本无法保证数据的一致性,请使用前一定要备份数据。
用户选择RC版通道或Beta版通道后若发布了正式版仍旧会升级到正式版。
用户在测试过程中发现的BUG欢迎提交issue或通过其他渠道反馈。用户的反馈对我们非常重要。 用户在测试过程中发现的BUG欢迎提交issue或通过其他渠道反馈。用户的反馈对我们非常重要。
## 开发者指南 ## 开发者指南

View File

@ -136,128 +136,59 @@ artifactBuildCompleted: scripts/artifact-build-completed.js
releaseInfo: releaseInfo:
releaseNotes: | releaseNotes: |
<!--LANG:en--> <!--LANG:en-->
What's New in v1.7.0-beta.3 What's New in v1.7.0-beta.4
Major Changes:
- UI Framework Upgrade: Improved performance and user experience with new design system
- App Menu i18n: Menu now supports multiple languages and syncs with app language settings
New Features: New Features:
- Enhanced Tool Permission System: Real-time tool approval interface with improved UX - AWS Bedrock API Key: Support Bedrock API key authentication with Extended Thinking (reasoning) capability
- Plugin Management System: Support for Claude Agent plugins (agents, commands, skills) - SophNet Provider: Added support for SophNet LLM provider
- Skill Tool: Add skill execution capabilities for agents - Auto Session Rename: Agent sessions automatically rename based on conversation topics
- Mobile App Data Restore: Support restoring data to mobile applications - TopP Parameter: Added TopP parameter support for more precise model control
- OpenMinerU Preprocessor: Knowledge base now supports open-source MinerU for document processing - Reasoning Effort Control: Quick access to reasoning effort settings in input bar
- HuggingFace Provider: Added HuggingFace as AI provider
- Claude Haiku 4.5: Support for the latest Claude Haiku 4.5 model
- Ling Series Models: Added support for Ling-1T and related models
- Intel OVMS Painting: New painting provider using Intel OpenVINO Model Server
- Automatic Update Checks: Implement periodic update checking with configurable intervals
- HuggingChat Mini App: New mini app for HuggingChat integration
Improvements: Improvements:
- Agent Creation: New agents are now automatically activated upon creation - Topics & Sessions: Enhanced UI with better styling and smoother interactions
- Lazy Loading: Optimize page load performance with route lazy loading - Quick Panel: Improved option visibility and control
- UI Enhancements: Improved agent item styling and layout consistency - Painting Models: Smarter model initialization with better defaults
- Navigation: Better navbar layout for fullscreen mode on macOS - System Shutdown: Better handling of shutdown events to prevent data loss
- Settings Tab: Enhanced context slider consistency - Smaller Package Size: Optimized build configuration for faster downloads
- Backup Manager: Unified footer layout for local and S3 backup managers
- Menu System: Enhanced application menu with improved help section
- Proxy Rules: Comprehensive proxy bypass rule matching
- German Language: Added German language support
- MCP Confirmation: Added confirmation modal when activating protocol-installed MCP servers
- Translation: Enhanced translation script with concurrency and validation
- Electron & Vite: Updated to Electron 38 and Vite 4.0.1
- QR Code Generation: Optimized performance for phone LAN export
- Enterprise Settings: Added enterprise section in About settings
- Assistant/Agent Popup: Enhanced UI for adding assistants and agents
Claude Code Tool Improvements:
- GlobTool: Now counts lines instead of files in output for better clarity
- ReadTool: Automatically removes system reminder tags from output
- TodoWriteTool: Improved rendering behavior
- Environment Variables: Updated model-related environment variable names
Bug Fixes: Bug Fixes:
- Fixed session model not being used when sending messages - Fixed Perplexity provider support and API host formatting
- Fixed tool approval UI and shared workspace plugin inconsistencies - Fixed CherryAI provider support and API host formatting
- Fixed API server readiness notification to renderer - Fixed i18n translations for painting image size options
- Fixed grouped items not respecting saved tag order - Fixed agent session message token usage tracking
- Fixed assistant/agent activation when creating new ones - Fixed prompt stream handling on completion or error
- Fixed Dashscope Anthropic API host and migrated old configs - Fixed message API initialization issues
- Fixed Qwen3 thinking mode control for Ollama
- Fixed disappeared MCP button
- Fixed create assistant causing blank screen
- Fixed up-down button visibility in some cases
- Fixed hooks preventing save on composing enter key
- Fixed Azure GPT-image-1 and OpenRouter Gemini-image
- Fixed Silicon reasoning issues
- Fixed topic branch incomplete copy with two-pass ID mapping
- Fixed deep research model search context restrictions
- Fixed model capability checking logic
- Fixed reranker API error response capture
- Fixed right-click paste file content into inputbar
- Fixed minimax-m2 support in aiCore
- Fixed Azure embedding issues
- Fixed agent edit modal loading race condition
- Fixed debounced save cancellation on file path update
<!--LANG:zh-CN--> <!--LANG:zh-CN-->
v1.7.0-beta.3 新特性 v1.7.0-beta.4 新特性
重大变更:
- UI 框架升级:采用新设计系统,提升性能和用户体验
- 应用菜单国际化:菜单支持多语言,并自动同步应用语言设置
新功能: 新功能:
- 增强工具权限系统:实时工具审批界面,改进用户体验 - AWS Bedrock API 密钥:支持 Bedrock API 密钥身份验证,并支持扩展思考(推理)能力
- 插件管理系统:支持 Claude Agent 插件agents、commands、skills - SophNet 提供商:添加 SophNet LLM 提供商支持
- 技能工具:为 Agent 添加技能执行能力 - 自动会话重命名Agent 会话根据对话主题自动重命名
- 移动应用数据恢复:支持将数据恢复到移动应用程序 - TopP 参数:添加 TopP 参数支持,更精确控制模型输出
- OpenMinerU 预处理器:知识库现支持使用开源 MinerU 处理文档
- HuggingFace 提供商:添加 HuggingFace 作为 AI 提供商
- Claude Haiku 4.5:支持最新的 Claude Haiku 4.5 模型
- Ling 系列模型:添加 Ling-1T 及相关模型支持
- Intel OVMS 绘图:使用 Intel OpenVINO 模型服务器的新绘图提供商
- 自动更新检查:实现可配置间隔的定期更新检查
- HuggingChat 小程序:新增 HuggingChat 集成小程序
改进: 改进:
- Agent 创建:新创建的 Agent 现在会自动激活 - 主题和会话:增强 UI改进样式和交互体验
- 懒加载:通过路由懒加载优化页面加载性能 - 快速面板:改进选项可见性和控制
- UI 增强:改进 Agent 项目样式和布局一致性 - 绘图模型:更智能的模型初始化和更好的默认值
- 导航:改进 macOS 全屏模式下的导航栏布局 - 系统关机:更好地处理关机事件,防止数据丢失
- 设置选项卡:增强上下文滑块一致性 - 更小的安装包:优化构建配置,下载更快
- 备份管理器:统一本地和 S3 备份管理器的页脚布局
- 菜单系统:增强应用菜单,改进帮助部分
- 代理规则:全面的代理绕过规则匹配
- 德语支持:添加德语语言支持
- MCP 确认:添加激活协议安装的 MCP 服务器时的确认模态框
- 翻译:增强翻译脚本的并发和验证功能
- Electron & Vite更新至 Electron 38 和 Vite 4.0.1
- 二维码生成:优化手机局域网导出性能
- 企业设置:在关于设置中添加企业部分
- 助手/Agent 弹窗:增强添加助手和 Agent 的界面
Claude Code 工具改进:
- GlobTool现在计算行数而不是文件数提供更清晰的输出
- ReadTool自动从输出中移除系统提醒标签
- TodoWriteTool改进渲染行为
- 环境变量:更新模型相关的环境变量名称
问题修复: 问题修复:
- 修复发送消息时未使用会话模型 - 修复 Perplexity 提供商支持和 API 主机格式化
- 修复工具审批 UI 和共享工作区插件不一致 - 修复 CherryAI 提供商支持和 API 主机格式化
- 修复 API 服务器就绪通知到渲染器 - 修复绘图图像大小选项的 i18n 翻译
- 修复分组项目不遵守已保存标签顺序 - 修复 Agent 会话消息的 token 使用量跟踪
- 修复创建新的助手/Agent 时的激活问题 - 修复完成或错误时的提示流处理
- 修复 Dashscope Anthropic API 主机并迁移旧配置 - 修复消息 API 初始化问题
- 修复 Ollama 的 Qwen3 思考模式控制
- 修复 MCP 按钮消失
- 修复创建助手导致空白屏幕
- 修复某些情况下上下按钮可见性
- 修复钩子在输入法输入时阻止保存
- 修复 Azure GPT-image-1 和 OpenRouter Gemini-image
- 修复 Silicon 推理问题
- 修复主题分支不完整复制,采用两阶段 ID 映射
- 修复深度研究模型搜索上下文限制
- 修复模型能力检查逻辑
- 修复 reranker API 错误响应捕获
- 修复右键粘贴文件内容到输入栏
- 修复 aiCore 中的 minimax-m2 支持
- 修复 Azure embedding 问题
- 修复 Agent 编辑模态框加载竞态条件
- 修复文件路径更新时防抖保存取消问题
<!--LANG:END--> <!--LANG:END-->

View File

@ -18,8 +18,10 @@ import { sortedObjectByKeys } from './sort'
// ========== SCRIPT CONFIGURATION AREA - MODIFY SETTINGS HERE ========== // ========== SCRIPT CONFIGURATION AREA - MODIFY SETTINGS HERE ==========
const SCRIPT_CONFIG = { const SCRIPT_CONFIG = {
// 🔧 Concurrency Control Configuration // 🔧 Concurrency Control Configuration
MAX_CONCURRENT_TRANSLATIONS: 5, // Max concurrent requests (Make sure the concurrency level does not exceed your provider's limits.) MAX_CONCURRENT_TRANSLATIONS: process.env.TRANSLATION_MAX_CONCURRENT_REQUESTS
TRANSLATION_DELAY_MS: 100, // Delay between requests to avoid rate limiting (Recommended: 100-500ms, Range: 0-5000ms) ? parseInt(process.env.TRANSLATION_MAX_CONCURRENT_REQUESTS)
: 5, // Max concurrent requests (Make sure the concurrency level does not exceed your provider's limits.)
TRANSLATION_DELAY_MS: process.env.TRANSLATION_DELAY_MS ? parseInt(process.env.TRANSLATION_DELAY_MS) : 500, // Delay between requests to avoid rate limiting (Recommended: 100-500ms, Range: 0-5000ms)
// 🔑 API Configuration // 🔑 API Configuration
API_KEY: process.env.TRANSLATION_API_KEY || '', // API key from environment variable API_KEY: process.env.TRANSLATION_API_KEY || '', // API key from environment variable

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -3801,6 +3801,7 @@
"description": "Do not enable MCP server functionality", "description": "Do not enable MCP server functionality",
"label": "Disable MCP Server" "label": "Disable MCP Server"
}, },
"discover": "Discover",
"duplicateName": "A server with this name already exists", "duplicateName": "A server with this name already exists",
"editJson": "Edit JSON", "editJson": "Edit JSON",
"editMcpJson": "Edit MCP Configuration", "editMcpJson": "Edit MCP Configuration",
@ -3811,6 +3812,10 @@
"32000": "MCP server failed to start, please check the parameters according to the tutorial", "32000": "MCP server failed to start, please check the parameters according to the tutorial",
"toolNotFound": "Tool {{name}} not found" "toolNotFound": "Tool {{name}} not found"
}, },
"fetch": {
"button": "Fetch Servers",
"success": "Successfully fetched MCP servers"
},
"findMore": "Find More MCP", "findMore": "Find More MCP",
"headers": "Headers", "headers": "Headers",
"headersTooltip": "Custom headers for HTTP requests", "headersTooltip": "Custom headers for HTTP requests",
@ -3826,6 +3831,7 @@
"logoUrl": "Logo URL", "logoUrl": "Logo URL",
"longRunning": "Long Running Mode", "longRunning": "Long Running Mode",
"longRunningTooltip": "When enabled, the server supports long-running tasks. When receiving progress notifications, the timeout will be reset and the maximum execution time will be extended to 10 minutes.", "longRunningTooltip": "When enabled, the server supports long-running tasks. When receiving progress notifications, the timeout will be reset and the maximum execution time will be extended to 10 minutes.",
"marketplaces": "Marketplaces",
"missingDependencies": "is Missing, please install it to continue.", "missingDependencies": "is Missing, please install it to continue.",
"more": { "more": {
"awesome": "Curated MCP Server List", "awesome": "Curated MCP Server List",
@ -3874,6 +3880,7 @@
"provider": "Provider", "provider": "Provider",
"providerPlaceholder": "Provider name", "providerPlaceholder": "Provider name",
"providerUrl": "Provider URL", "providerUrl": "Provider URL",
"providers": "Providers",
"registry": "Package Registry", "registry": "Package Registry",
"registryDefault": "Default", "registryDefault": "Default",
"registryTooltip": "Choose the registry for package installation to resolve network issues with the default registry.", "registryTooltip": "Choose the registry for package installation to resolve network issues with the default registry.",
@ -3896,6 +3903,7 @@
"searchNpx": "Search MCP", "searchNpx": "Search MCP",
"serverPlural": "servers", "serverPlural": "servers",
"serverSingular": "server", "serverSingular": "server",
"servers": "MCP Servers",
"sse": "Server-Sent Events (sse)", "sse": "Server-Sent Events (sse)",
"startError": "Start failed", "startError": "Start failed",
"stdio": "Standard Input/Output (stdio)", "stdio": "Standard Input/Output (stdio)",

View File

@ -3801,6 +3801,7 @@
"description": "不启用 MCP 服务功能", "description": "不启用 MCP 服务功能",
"label": "不使用 MCP 服务器" "label": "不使用 MCP 服务器"
}, },
"discover": "发现",
"duplicateName": "已存在同名服务器", "duplicateName": "已存在同名服务器",
"editJson": "编辑 JSON", "editJson": "编辑 JSON",
"editMcpJson": "编辑 MCP 配置", "editMcpJson": "编辑 MCP 配置",
@ -3811,6 +3812,10 @@
"32000": "MCP 服务器启动失败,请根据教程检查参数是否填写完整", "32000": "MCP 服务器启动失败,请根据教程检查参数是否填写完整",
"toolNotFound": "未找到工具 {{name}}" "toolNotFound": "未找到工具 {{name}}"
}, },
"fetch": {
"button": "获取服务器",
"success": "服务器获取成功"
},
"findMore": "更多 MCP", "findMore": "更多 MCP",
"headers": "请求头", "headers": "请求头",
"headersTooltip": "HTTP 请求的自定义请求头", "headersTooltip": "HTTP 请求的自定义请求头",
@ -3826,6 +3831,7 @@
"logoUrl": "标志网址", "logoUrl": "标志网址",
"longRunning": "长时间运行模式", "longRunning": "长时间运行模式",
"longRunningTooltip": "启用后服务器支持长时间任务接收到进度通知时会重置超时计时器并延长最大超时时间至10分钟", "longRunningTooltip": "启用后服务器支持长时间任务接收到进度通知时会重置超时计时器并延长最大超时时间至10分钟",
"marketplaces": "市场",
"missingDependencies": "缺失,请安装它以继续", "missingDependencies": "缺失,请安装它以继续",
"more": { "more": {
"awesome": "精选的 MCP 服务器列表", "awesome": "精选的 MCP 服务器列表",
@ -3874,6 +3880,7 @@
"provider": "提供者", "provider": "提供者",
"providerPlaceholder": "提供者名称", "providerPlaceholder": "提供者名称",
"providerUrl": "提供者网址", "providerUrl": "提供者网址",
"providers": "提供商",
"registry": "包管理源", "registry": "包管理源",
"registryDefault": "默认", "registryDefault": "默认",
"registryTooltip": "选择用于安装包的源,以解决默认源的网络问题", "registryTooltip": "选择用于安装包的源,以解决默认源的网络问题",
@ -3896,6 +3903,7 @@
"searchNpx": "搜索 MCP", "searchNpx": "搜索 MCP",
"serverPlural": "服务器", "serverPlural": "服务器",
"serverSingular": "服务器", "serverSingular": "服务器",
"servers": "MCP 服务器",
"sse": "服务器发送事件 (sse)", "sse": "服务器发送事件 (sse)",
"startError": "启动失败", "startError": "启动失败",
"stdio": "标准输入 / 输出 (stdio)", "stdio": "标准输入 / 输出 (stdio)",

View File

@ -3801,6 +3801,7 @@
"description": "不啟用 MCP 服務功能", "description": "不啟用 MCP 服務功能",
"label": "不使用 MCP 伺服器" "label": "不使用 MCP 伺服器"
}, },
"discover": "發現",
"duplicateName": "已存在相同名稱的伺服器", "duplicateName": "已存在相同名稱的伺服器",
"editJson": "編輯 JSON", "editJson": "編輯 JSON",
"editMcpJson": "編輯 MCP 配置", "editMcpJson": "編輯 MCP 配置",
@ -3811,6 +3812,10 @@
"32000": "MCP 伺服器啟動失敗,請根據教程檢查參數是否填寫完整", "32000": "MCP 伺服器啟動失敗,請根據教程檢查參數是否填寫完整",
"toolNotFound": "未找到工具 {{name}}" "toolNotFound": "未找到工具 {{name}}"
}, },
"fetch": {
"button": "獲取伺服器",
"success": "伺服器獲取成功"
},
"findMore": "更多 MCP", "findMore": "更多 MCP",
"headers": "請求標頭", "headers": "請求標頭",
"headersTooltip": "HTTP 請求的自定義標頭", "headersTooltip": "HTTP 請求的自定義標頭",
@ -3826,6 +3831,7 @@
"logoUrl": "標誌網址", "logoUrl": "標誌網址",
"longRunning": "長時間運行模式", "longRunning": "長時間運行模式",
"longRunningTooltip": "啟用後伺服器支援長時間任務接收到進度通知時會重置超時計時器並延長最大超時時間至10分鐘", "longRunningTooltip": "啟用後伺服器支援長時間任務接收到進度通知時會重置超時計時器並延長最大超時時間至10分鐘",
"marketplaces": "市場",
"missingDependencies": "缺失,請安裝它以繼續", "missingDependencies": "缺失,請安裝它以繼續",
"more": { "more": {
"awesome": "精選的 MCP 伺服器清單", "awesome": "精選的 MCP 伺服器清單",
@ -3874,6 +3880,7 @@
"provider": "提供者", "provider": "提供者",
"providerPlaceholder": "提供者名稱", "providerPlaceholder": "提供者名稱",
"providerUrl": "提供者網址", "providerUrl": "提供者網址",
"providers": "提供商",
"registry": "套件管理源", "registry": "套件管理源",
"registryDefault": "預設", "registryDefault": "預設",
"registryTooltip": "選擇用於安裝套件的源,以解決預設源的網路問題", "registryTooltip": "選擇用於安裝套件的源,以解決預設源的網路問題",
@ -3896,6 +3903,7 @@
"searchNpx": "搜索 MCP", "searchNpx": "搜索 MCP",
"serverPlural": "伺服器", "serverPlural": "伺服器",
"serverSingular": "伺服器", "serverSingular": "伺服器",
"servers": "MCP 伺服器",
"sse": "伺服器傳送事件 (sse)", "sse": "伺服器傳送事件 (sse)",
"startError": "啟動失敗", "startError": "啟動失敗",
"stdio": "標準輸入 / 輸出 (stdio)", "stdio": "標準輸入 / 輸出 (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "API-Server" "title": "API-Server"
}, },
"appMenu": {
"about": "Über",
"close": "Fenster schließen",
"copy": "Kopieren",
"cut": "Schneiden",
"delete": "Löschen",
"documentation": "Dokumentation",
"edit": "Bearbeiten",
"feedback": "Rückmeldung",
"file": "Datei",
"forceReload": "Neu laden erzwingen",
"front": "Alle in den Vordergrund bringen",
"help": "Hilfe",
"hide": "Verstecken",
"hideOthers": "Andere ausblenden",
"minimize": "Minimieren",
"paste": "Einfügen",
"quit": "Aufhören",
"redo": "Wiederholen",
"releases": "Veröffentlichungen",
"reload": "Neu laden",
"resetZoom": "Tatsächliche Größe",
"selectAll": "Alle auswählen",
"services": "Dienstleistungen",
"toggleDevTools": "Entwicklertools ein-/ausblenden",
"toggleFullscreen": "Vollbild umschalten",
"undo": "Rückgängig machen",
"unhide": "Alle anzeigen",
"view": "Ansicht",
"website": "Website",
"window": "Fenster",
"zoom": "Zoom",
"zoomIn": "Heranzoomen",
"zoomOut": "Herauszoomen"
},
"assistants": { "assistants": {
"abbr": "Assistent", "abbr": "Assistent",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "MCP-Service-Funktion nicht aktivieren", "description": "MCP-Service-Funktion nicht aktivieren",
"label": "MCP-Server nicht verwenden" "label": "MCP-Server nicht verwenden"
}, },
"discover": "Entdecken",
"duplicateName": "Server mit gleichem Namen existiert bereits", "duplicateName": "Server mit gleichem Namen existiert bereits",
"editJson": "JSON bearbeiten", "editJson": "JSON bearbeiten",
"editMcpJson": "MCP-Konfiguration bearbeiten", "editMcpJson": "MCP-Konfiguration bearbeiten",
@ -3776,6 +3812,10 @@
"32000": "MCP-Server starten fehlgeschlagen, bitte überprüfen Sie, ob alle Parameter vollständig ausgefüllt sind", "32000": "MCP-Server starten fehlgeschlagen, bitte überprüfen Sie, ob alle Parameter vollständig ausgefüllt sind",
"toolNotFound": "Tool {{name}} nicht gefunden" "toolNotFound": "Tool {{name}} nicht gefunden"
}, },
"fetch": {
"button": "Server abrufen",
"success": "MCP-Server erfolgreich abgerufen"
},
"findMore": "Mehr MCP", "findMore": "Mehr MCP",
"headers": "Request-Header", "headers": "Request-Header",
"headersTooltip": "Benutzerdefinierte Request-Header für HTTP-Anfragen", "headersTooltip": "Benutzerdefinierte Request-Header für HTTP-Anfragen",
@ -3791,6 +3831,7 @@
"logoUrl": "Logo-URL", "logoUrl": "Logo-URL",
"longRunning": "Lang laufender Modus", "longRunning": "Lang laufender Modus",
"longRunningTooltip": "Nach Aktivierung unterstützt der Server lange Aufgaben. Wenn ein Fortschrittsbenachrichtigung empfangen wird, wird der Timeout-Timer zurückgesetzt und die maximale Timeout-Zeit auf 10 Minuten verlängert", "longRunningTooltip": "Nach Aktivierung unterstützt der Server lange Aufgaben. Wenn ein Fortschrittsbenachrichtigung empfangen wird, wird der Timeout-Timer zurückgesetzt und die maximale Timeout-Zeit auf 10 Minuten verlängert",
"marketplaces": "Marktplätze",
"missingDependencies": "Abhängigkeiten fehlen, bitte installieren Sie sie, um fortzufahren", "missingDependencies": "Abhängigkeiten fehlen, bitte installieren Sie sie, um fortzufahren",
"more": { "more": {
"awesome": "Kuratierte MCP-Serverliste", "awesome": "Kuratierte MCP-Serverliste",
@ -3839,6 +3880,7 @@
"provider": "Anbieter", "provider": "Anbieter",
"providerPlaceholder": "Anbietername", "providerPlaceholder": "Anbietername",
"providerUrl": "Anbieter-Website", "providerUrl": "Anbieter-Website",
"providers": "Anbieter",
"registry": "Paketverwaltungsquelle", "registry": "Paketverwaltungsquelle",
"registryDefault": "Standard", "registryDefault": "Standard",
"registryTooltip": "Quelle für Paketinstallation auswählen um Netzwerkprobleme der Standardquelle zu lösen", "registryTooltip": "Quelle für Paketinstallation auswählen um Netzwerkprobleme der Standardquelle zu lösen",
@ -3861,6 +3903,7 @@
"searchNpx": "MCP durchsuchen", "searchNpx": "MCP durchsuchen",
"serverPlural": "Server", "serverPlural": "Server",
"serverSingular": "Server", "serverSingular": "Server",
"servers": "MCP-Server",
"sse": "Server-Sende-Ereignisse (sse)", "sse": "Server-Sende-Ereignisse (sse)",
"startError": "Start fehlgeschlagen", "startError": "Start fehlgeschlagen",
"stdio": "Standard-Eingabe / -Ausgabe (stdio)", "stdio": "Standard-Eingabe / -Ausgabe (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "Διακομιστής API" "title": "Διακομιστής API"
}, },
"appMenu": {
"about": "Σχετικά",
"close": "Κλείσιμο Παραθύρου",
"copy": "Αντιγραφή",
"cut": "Κόψε",
"delete": "Διαγραφή",
"documentation": "Τεκμηρίωση",
"edit": "Επεξεργασία",
"feedback": "Σχόλια",
"file": "Αρχείο",
"forceReload": "Εξαναγκασμένη επαναφόρτωση",
"front": "Μεταφορά Όλων Μπροστά",
"help": "Βοήθεια",
"hide": "Κρύψε",
"hideOthers": "Απόκρυψη Άλλων",
"minimize": "Ελαχιστοποίηση",
"paste": "Επικόλληση",
"quit": "Παραιτήσου",
"redo": "Ξανακάνε",
"releases": "Κυκλοφορίες",
"reload": "Επαναφόρτωση",
"resetZoom": "Πραγματικό Μέγεθος",
"selectAll": "Επιλογή Όλων",
"services": "Υπηρεσίες",
"toggleDevTools": "Εναλλαγή Εργαλείων Προγραμματιστή",
"toggleFullscreen": "Εναλλαγή πλήρους οθόνης",
"undo": "Αναίρεση",
"unhide": "Εμφάνιση Όλων",
"view": "Προβολή",
"website": "Ιστοσελίδα",
"window": "Παράθυρο",
"zoom": "Ζουμ",
"zoomIn": "Μεγέθυνση",
"zoomOut": "Σμίκρυνση"
},
"assistants": { "assistants": {
"abbr": "Βοηθός", "abbr": "Βοηθός",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "Να μην ενεργοποιείται η λειτουργία υπηρεσίας MCP", "description": "Να μην ενεργοποιείται η λειτουργία υπηρεσίας MCP",
"label": "Να μην χρησιμοποιείται διακομιστής MCP" "label": "Να μην χρησιμοποιείται διακομιστής MCP"
}, },
"discover": "Ανακαλύψτε",
"duplicateName": "Υπάρχει ήδη ένας διακομιστής με αυτό το όνομα", "duplicateName": "Υπάρχει ήδη ένας διακομιστής με αυτό το όνομα",
"editJson": "Επεξεργασία JSON", "editJson": "Επεξεργασία JSON",
"editMcpJson": "Επεξεργασία ρύθμισης MCP", "editMcpJson": "Επεξεργασία ρύθμισης MCP",
@ -3776,6 +3812,10 @@
"32000": "Η εκκίνηση του MCP απέτυχε. Παρακαλώ ελέγξτε αν όλες οι παράμετροι έχουν συμπληρωθεί σύμφωνα με τον οδηγό.", "32000": "Η εκκίνηση του MCP απέτυχε. Παρακαλώ ελέγξτε αν όλες οι παράμετροι έχουν συμπληρωθεί σύμφωνα με τον οδηγό.",
"toolNotFound": "Δεν βρέθηκε το εργαλείο {{name}}" "toolNotFound": "Δεν βρέθηκε το εργαλείο {{name}}"
}, },
"fetch": {
"button": "Λήψη Διακομιστών",
"success": "Επιτυχής ανάκτηση διακομιστών MCP"
},
"findMore": "Περισσότεροι διακομιστές MCP", "findMore": "Περισσότεροι διακομιστές MCP",
"headers": "Κεφαλίδες", "headers": "Κεφαλίδες",
"headersTooltip": "Προσαρμοσμένες κεφαλίδες HTTP αιτήσεων", "headersTooltip": "Προσαρμοσμένες κεφαλίδες HTTP αιτήσεων",
@ -3791,6 +3831,7 @@
"logoUrl": "URL Λογότυπου", "logoUrl": "URL Λογότυπου",
"longRunning": "Μακροχρόνια λειτουργία", "longRunning": "Μακροχρόνια λειτουργία",
"longRunningTooltip": "Όταν ενεργοποιηθεί, ο διακομιστής υποστηρίζει μακροχρόνιες εργασίες, επαναφέρει το χρονικό όριο μετά από λήψη ειδοποίησης προόδου και επεκτείνει το μέγιστο χρονικό όριο σε 10 λεπτά.", "longRunningTooltip": "Όταν ενεργοποιηθεί, ο διακομιστής υποστηρίζει μακροχρόνιες εργασίες, επαναφέρει το χρονικό όριο μετά από λήψη ειδοποίησης προόδου και επεκτείνει το μέγιστο χρονικό όριο σε 10 λεπτά.",
"marketplaces": "Αγορές",
"missingDependencies": "Λείπει, παρακαλώ εγκαταστήστε το για να συνεχίσετε", "missingDependencies": "Λείπει, παρακαλώ εγκαταστήστε το για να συνεχίσετε",
"more": { "more": {
"awesome": "Επιλεγμένος κατάλογος διακομιστών MCP", "awesome": "Επιλεγμένος κατάλογος διακομιστών MCP",
@ -3839,6 +3880,7 @@
"provider": "Πάροχος", "provider": "Πάροχος",
"providerPlaceholder": "Όνομα παρόχου", "providerPlaceholder": "Όνομα παρόχου",
"providerUrl": "URL Παρόχου", "providerUrl": "URL Παρόχου",
"providers": "Πάροχοι",
"registry": "Πηγή Διαχείρισης πακέτων", "registry": "Πηγή Διαχείρισης πακέτων",
"registryDefault": "Προεπιλεγμένη", "registryDefault": "Προεπιλεγμένη",
"registryTooltip": "Επιλέξτε την πηγή για την εγκατάσταση πακέτων, για να αντιμετωπιστούν προβλήματα δικτύου από την προεπιλεγμένη πηγή.", "registryTooltip": "Επιλέξτε την πηγή για την εγκατάσταση πακέτων, για να αντιμετωπιστούν προβλήματα δικτύου από την προεπιλεγμένη πηγή.",
@ -3861,6 +3903,7 @@
"searchNpx": "Αναζήτηση MCP", "searchNpx": "Αναζήτηση MCP",
"serverPlural": "Διακομιστές", "serverPlural": "Διακομιστές",
"serverSingular": "Διακομιστής", "serverSingular": "Διακομιστής",
"servers": "Διακομιστές MCP",
"sse": "Συμβάντα Αποστολής από τον Διακομιστή (sse)", "sse": "Συμβάντα Αποστολής από τον Διακομιστή (sse)",
"startError": "Εκκίνηση Απέτυχε", "startError": "Εκκίνηση Απέτυχε",
"stdio": "Πρότυπη Είσοδος/Έξοδος (stdio)", "stdio": "Πρότυπη Είσοδος/Έξοδος (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "Servidor API" "title": "Servidor API"
}, },
"appMenu": {
"about": "Acerca de",
"close": "Cerrar ventana",
"copy": "Copiar",
"cut": "Cortar",
"delete": "Eliminar",
"documentation": "Documentación",
"edit": "Editar",
"feedback": "Retroalimentación",
"file": "Archivo",
"forceReload": "Forzar recarga",
"front": "Traer todo al frente",
"help": "Ayuda",
"hide": "Ocultar",
"hideOthers": "Ocultar Otros",
"minimize": "Minimizar",
"paste": "Pegar",
"quit": "Abandonar",
"redo": "Rehacer",
"releases": "Lanzamientos",
"reload": "Recargar",
"resetZoom": "Tamaño Real",
"selectAll": "Seleccionar todo",
"services": "Servicios",
"toggleDevTools": "Alternar herramientas de desarrollo",
"toggleFullscreen": "Activar pantalla completa",
"undo": "Deshacer",
"unhide": "Mostrar todo",
"view": "Vista",
"website": "Sitio web",
"window": "Ventana",
"zoom": "Zoom",
"zoomIn": "Acercar",
"zoomOut": "Alejar"
},
"assistants": { "assistants": {
"abbr": "Asistente", "abbr": "Asistente",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "No habilitar funciones del servicio MCP", "description": "No habilitar funciones del servicio MCP",
"label": "No utilizar servidor MCP" "label": "No utilizar servidor MCP"
}, },
"discover": "Descubrir",
"duplicateName": "Ya existe un servidor con el mismo nombre", "duplicateName": "Ya existe un servidor con el mismo nombre",
"editJson": "Editar JSON", "editJson": "Editar JSON",
"editMcpJson": "Editar configuración MCP", "editMcpJson": "Editar configuración MCP",
@ -3776,6 +3812,10 @@
"32000": "El servidor MCP no se pudo iniciar, verifique si los parámetros están completos según la guía", "32000": "El servidor MCP no se pudo iniciar, verifique si los parámetros están completos según la guía",
"toolNotFound": "Herramienta no encontrada {{name}}" "toolNotFound": "Herramienta no encontrada {{name}}"
}, },
"fetch": {
"button": "Obtener Servidores",
"success": "Servidores MCP obtenidos con éxito"
},
"findMore": "Más servidores MCP", "findMore": "Más servidores MCP",
"headers": "Encabezados", "headers": "Encabezados",
"headersTooltip": "Encabezados personalizados para solicitudes HTTP", "headersTooltip": "Encabezados personalizados para solicitudes HTTP",
@ -3791,6 +3831,7 @@
"logoUrl": "URL del logotipo", "logoUrl": "URL del logotipo",
"longRunning": "Modo de ejecución prolongada", "longRunning": "Modo de ejecución prolongada",
"longRunningTooltip": "Una vez habilitado, el servidor admite tareas de larga duración, reinicia el temporizador de tiempo de espera al recibir notificaciones de progreso y amplía el tiempo máximo de espera hasta 10 minutos.", "longRunningTooltip": "Una vez habilitado, el servidor admite tareas de larga duración, reinicia el temporizador de tiempo de espera al recibir notificaciones de progreso y amplía el tiempo máximo de espera hasta 10 minutos.",
"marketplaces": "Mercados",
"missingDependencies": "Faltan, instalelas para continuar", "missingDependencies": "Faltan, instalelas para continuar",
"more": { "more": {
"awesome": "Lista seleccionada de servidores MCP", "awesome": "Lista seleccionada de servidores MCP",
@ -3839,6 +3880,7 @@
"provider": "Proveedor", "provider": "Proveedor",
"providerPlaceholder": "Nombre del proveedor", "providerPlaceholder": "Nombre del proveedor",
"providerUrl": "URL del proveedor", "providerUrl": "URL del proveedor",
"providers": "Proveedores",
"registry": "Repositorio de paquetes", "registry": "Repositorio de paquetes",
"registryDefault": "Predeterminado", "registryDefault": "Predeterminado",
"registryTooltip": "Seleccione un repositorio para instalar paquetes, útil para resolver problemas de red con el repositorio predeterminado.", "registryTooltip": "Seleccione un repositorio para instalar paquetes, útil para resolver problemas de red con el repositorio predeterminado.",
@ -3861,6 +3903,7 @@
"searchNpx": "Buscar MCP", "searchNpx": "Buscar MCP",
"serverPlural": "Servidores", "serverPlural": "Servidores",
"serverSingular": "Servidor", "serverSingular": "Servidor",
"servers": "Servidores MCP",
"sse": "Eventos enviados por el servidor (sse)", "sse": "Eventos enviados por el servidor (sse)",
"startError": "Inicio fallido", "startError": "Inicio fallido",
"stdio": "Entrada/Salida estándar (stdio)", "stdio": "Entrada/Salida estándar (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "Serveur API" "title": "Serveur API"
}, },
"appMenu": {
"about": "À propos",
"close": "Fermer la fenêtre",
"copy": "Copier",
"cut": "Couper",
"delete": "Supprimer",
"documentation": "Documentation",
"edit": "Modifier",
"feedback": "Retour d'information",
"file": "Fichier",
"forceReload": "Rechargement forcé",
"front": "Tout ramener au premier plan",
"help": "Aide",
"hide": "Cacher",
"hideOthers": "Masquer les autres",
"minimize": "Minimiser",
"paste": "Coller",
"quit": "Quitter",
"redo": "Refaire",
"releases": "Sorties",
"reload": "Recharger",
"resetZoom": "Taille réelle",
"selectAll": "Tout sélectionner",
"services": "Services",
"toggleDevTools": "Basculer les outils de développement",
"toggleFullscreen": "Basculer en plein écran",
"undo": "Annuler",
"unhide": "Tout afficher",
"view": "Vue",
"website": "Site web",
"window": "Fenêtre",
"zoom": "Zoom",
"zoomIn": "Zoom Avant",
"zoomOut": "Dézoomer"
},
"assistants": { "assistants": {
"abbr": "Aide", "abbr": "Aide",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "Désactiver les fonctionnalités du service MCP", "description": "Désactiver les fonctionnalités du service MCP",
"label": "Ne pas utiliser le serveur MCP" "label": "Ne pas utiliser le serveur MCP"
}, },
"discover": "Découvrir",
"duplicateName": "Un serveur portant le même nom existe déjà", "duplicateName": "Un serveur portant le même nom existe déjà",
"editJson": "Modifier le JSON", "editJson": "Modifier le JSON",
"editMcpJson": "Редактировать конфигурацию MCP", "editMcpJson": "Редактировать конфигурацию MCP",
@ -3776,6 +3812,10 @@
"32000": "Échec du démarrage du serveur MCP, veuillez vérifier si tous les paramètres sont correctement remplis conformément au tutoriel", "32000": "Échec du démarrage du serveur MCP, veuillez vérifier si tous les paramètres sont correctement remplis conformément au tutoriel",
"toolNotFound": "Outil non trouvé {{name}}" "toolNotFound": "Outil non trouvé {{name}}"
}, },
"fetch": {
"button": "Récupérer les serveurs",
"success": "Serveurs MCP récupérés avec succès"
},
"findMore": "Plus de serveurs MCP", "findMore": "Plus de serveurs MCP",
"headers": "Заголовки запроса", "headers": "Заголовки запроса",
"headersTooltip": "Пользовательские заголовки HTTP-запроса", "headersTooltip": "Пользовательские заголовки HTTP-запроса",
@ -3791,6 +3831,7 @@
"logoUrl": "Адрес логотипа", "logoUrl": "Адрес логотипа",
"longRunning": "Mode d'exécution prolongée", "longRunning": "Mode d'exécution prolongée",
"longRunningTooltip": "Une fois activé, le serveur prend en charge les tâches de longue durée, réinitialise le minuteur de temporisation à la réception des notifications de progression, et prolonge le délai d'expiration maximal à 10 minutes.", "longRunningTooltip": "Une fois activé, le serveur prend en charge les tâches de longue durée, réinitialise le minuteur de temporisation à la réception des notifications de progression, et prolonge le délai d'expiration maximal à 10 minutes.",
"marketplaces": "Places de marché",
"missingDependencies": "Manquantes, veuillez les installer pour continuer", "missingDependencies": "Manquantes, veuillez les installer pour continuer",
"more": { "more": {
"awesome": "Liste sélectionnée de serveurs MCP", "awesome": "Liste sélectionnée de serveurs MCP",
@ -3839,6 +3880,7 @@
"provider": "Поставщик", "provider": "Поставщик",
"providerPlaceholder": "Название поставщика", "providerPlaceholder": "Название поставщика",
"providerUrl": "Адрес поставщика", "providerUrl": "Адрес поставщика",
"providers": "Fournisseurs",
"registry": "Источник управления пакетами", "registry": "Источник управления пакетами",
"registryDefault": "По умолчанию", "registryDefault": "По умолчанию",
"registryTooltip": "Выберите источник для установки пакетов, чтобы решить проблемы с сетью по умолчанию.", "registryTooltip": "Выберите источник для установки пакетов, чтобы решить проблемы с сетью по умолчанию.",
@ -3861,6 +3903,7 @@
"searchNpx": "Поиск MCP", "searchNpx": "Поиск MCP",
"serverPlural": "Serveurs", "serverPlural": "Serveurs",
"serverSingular": "Serveur", "serverSingular": "Serveur",
"servers": "Serveurs MCP",
"sse": "Серверные отправляемые события (sse)", "sse": "Серверные отправляемые события (sse)",
"startError": "Ошибка запуска", "startError": "Ошибка запуска",
"stdio": "Стандартный ввод/вывод (stdio)", "stdio": "Стандартный ввод/вывод (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "API サーバー" "title": "API サーバー"
}, },
"appMenu": {
"about": "について",
"close": "ウィンドウを閉じる",
"copy": "コピー",
"cut": "切る",
"delete": "削除",
"documentation": "ドキュメント",
"edit": "編集",
"feedback": "フィードバック",
"file": "ファイル",
"forceReload": "強制再読み込み",
"front": "すべてを前面に移動",
"help": "助け",
"hide": "隠す",
"hideOthers": "他を隠す",
"minimize": "最小化",
"paste": "ペースト",
"quit": "やめる",
"redo": "やり直し",
"releases": "リリース",
"reload": "リロード",
"resetZoom": "実寸",
"selectAll": "すべて選択",
"services": "サービス",
"toggleDevTools": "開発者ツールを切り替え",
"toggleFullscreen": "全画面表示を切り替え",
"undo": "元に戻す",
"unhide": "すべて表示",
"view": "表示",
"website": "ウェブサイト",
"window": "窓",
"zoom": "ズーム",
"zoomIn": "ズームイン",
"zoomOut": "ズームアウト"
},
"assistants": { "assistants": {
"abbr": "アシスタント", "abbr": "アシスタント",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "MCP機能を有効にしない", "description": "MCP機能を有効にしない",
"label": "MCPサーバーを無効にする" "label": "MCPサーバーを無効にする"
}, },
"discover": "発見",
"duplicateName": "同じ名前のサーバーが既に存在します", "duplicateName": "同じ名前のサーバーが既に存在します",
"editJson": "JSONを編集", "editJson": "JSONを編集",
"editMcpJson": "MCP 設定を編集", "editMcpJson": "MCP 設定を編集",
@ -3776,6 +3812,10 @@
"32000": "MCP サーバーが起動しませんでした。パラメーターを確認してください", "32000": "MCP サーバーが起動しませんでした。パラメーターを確認してください",
"toolNotFound": "ツール {{name}} が見つかりません" "toolNotFound": "ツール {{name}} が見つかりません"
}, },
"fetch": {
"button": "サーバーを取得",
"success": "MCPサーバーの取得に成功しました"
},
"findMore": "MCP を見つける", "findMore": "MCP を見つける",
"headers": "ヘッダー", "headers": "ヘッダー",
"headersTooltip": "HTTP リクエストのカスタムヘッダー", "headersTooltip": "HTTP リクエストのカスタムヘッダー",
@ -3791,6 +3831,7 @@
"logoUrl": "ロゴURL", "logoUrl": "ロゴURL",
"longRunning": "長時間運行モード", "longRunning": "長時間運行モード",
"longRunningTooltip": "このオプションを有効にすると、サーバーは長時間のタスクをサポートします。進行状況通知を受信すると、タイムアウトがリセットされ、最大実行時間が10分に延長されます。", "longRunningTooltip": "このオプションを有効にすると、サーバーは長時間のタスクをサポートします。進行状況通知を受信すると、タイムアウトがリセットされ、最大実行時間が10分に延長されます。",
"marketplaces": "マーケットプレイス",
"missingDependencies": "が不足しています。続行するにはインストールしてください。", "missingDependencies": "が不足しています。続行するにはインストールしてください。",
"more": { "more": {
"awesome": "厳選された MCP サーバーリスト", "awesome": "厳選された MCP サーバーリスト",
@ -3839,6 +3880,7 @@
"provider": "プロバイダー", "provider": "プロバイダー",
"providerPlaceholder": "プロバイダー名", "providerPlaceholder": "プロバイダー名",
"providerUrl": "プロバイダーURL", "providerUrl": "プロバイダーURL",
"providers": "プロバイダー",
"registry": "パッケージ管理レジストリ", "registry": "パッケージ管理レジストリ",
"registryDefault": "デフォルト", "registryDefault": "デフォルト",
"registryTooltip": "デフォルトのレジストリでネットワークの問題が発生した場合、パッケージインストールに使用するレジストリを選択してください。", "registryTooltip": "デフォルトのレジストリでネットワークの問題が発生した場合、パッケージインストールに使用するレジストリを選択してください。",
@ -3861,6 +3903,7 @@
"searchNpx": "MCP を検索", "searchNpx": "MCP を検索",
"serverPlural": "サーバー", "serverPlural": "サーバー",
"serverSingular": "サーバー", "serverSingular": "サーバー",
"servers": "MCPサーバー",
"sse": "サーバー送信イベント (sse)", "sse": "サーバー送信イベント (sse)",
"startError": "起動に失敗しました", "startError": "起動に失敗しました",
"stdio": "標準入力/出力 (stdio)", "stdio": "標準入力/出力 (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "Servidor API" "title": "Servidor API"
}, },
"appMenu": {
"about": "Sobre",
"close": "Fechar Janela",
"copy": "Copiar",
"cut": "Corte",
"delete": "Excluir",
"documentation": "Documentação",
"edit": "Editar",
"feedback": "Feedback",
"file": "Arquivo",
"forceReload": "Forçar Recarregamento",
"front": "Trazer Tudo para a Frente",
"help": "Ajuda",
"hide": "Esconder",
"hideOthers": "Ocultar Outros",
"minimize": "Minimizar",
"paste": "Colar",
"quit": "Sair",
"redo": "Refazer",
"releases": "Lançamentos",
"reload": "Recarregar",
"resetZoom": "Tamanho Real",
"selectAll": "Selecionar Todos",
"services": "Serviços",
"toggleDevTools": "Alternar Ferramentas de Desenvolvedor",
"toggleFullscreen": "Alternar Tela Cheia",
"undo": "Desfazer",
"unhide": "Mostrar Todos",
"view": "Visualizar",
"website": "Site",
"window": "Janela",
"zoom": "Zoom",
"zoomIn": "Ampliar",
"zoomOut": "Reduzir Zoom"
},
"assistants": { "assistants": {
"abbr": "Assistente", "abbr": "Assistente",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "Não ativar a funcionalidade do serviço MCP", "description": "Não ativar a funcionalidade do serviço MCP",
"label": "Não usar servidor MCP" "label": "Não usar servidor MCP"
}, },
"discover": "Descobrir",
"duplicateName": "Já existe um servidor com o mesmo nome", "duplicateName": "Já existe um servidor com o mesmo nome",
"editJson": "Editar JSON", "editJson": "Editar JSON",
"editMcpJson": "Editar Configuração MCP", "editMcpJson": "Editar Configuração MCP",
@ -3776,6 +3812,10 @@
"32000": "Falha ao iniciar o servidor MCP, verifique se todos os parâmetros foram preenchidos corretamente conforme o tutorial", "32000": "Falha ao iniciar o servidor MCP, verifique se todos os parâmetros foram preenchidos corretamente conforme o tutorial",
"toolNotFound": "Ferramenta não encontrada {{name}}" "toolNotFound": "Ferramenta não encontrada {{name}}"
}, },
"fetch": {
"button": "Buscar Servidores",
"success": "Servidores MCP obtidos com sucesso"
},
"findMore": "Mais servidores MCP", "findMore": "Mais servidores MCP",
"headers": "Cabeçalhos da Requisição", "headers": "Cabeçalhos da Requisição",
"headersTooltip": "Cabeçalhos HTTP personalizados para as requisições", "headersTooltip": "Cabeçalhos HTTP personalizados para as requisições",
@ -3791,6 +3831,7 @@
"logoUrl": "URL do Logotipo", "logoUrl": "URL do Logotipo",
"longRunning": "Modo de execução prolongada", "longRunning": "Modo de execução prolongada",
"longRunningTooltip": "Quando ativado, o servidor suporta tarefas de longa duração, redefinindo o temporizador de tempo limite ao receber notificações de progresso e estendendo o tempo máximo de tempo limite para 10 minutos.", "longRunningTooltip": "Quando ativado, o servidor suporta tarefas de longa duração, redefinindo o temporizador de tempo limite ao receber notificações de progresso e estendendo o tempo máximo de tempo limite para 10 minutos.",
"marketplaces": "Mercados",
"missingDependencies": "Ausente, instale para continuar", "missingDependencies": "Ausente, instale para continuar",
"more": { "more": {
"awesome": "Lista selecionada de servidores MCP", "awesome": "Lista selecionada de servidores MCP",
@ -3839,6 +3880,7 @@
"provider": "Fornecedor", "provider": "Fornecedor",
"providerPlaceholder": "Nome do Fornecedor", "providerPlaceholder": "Nome do Fornecedor",
"providerUrl": "URL do Fornecedor", "providerUrl": "URL do Fornecedor",
"providers": "Fornecedores",
"registry": "Fonte de Gerenciamento de Pacotes", "registry": "Fonte de Gerenciamento de Pacotes",
"registryDefault": "Padrão", "registryDefault": "Padrão",
"registryTooltip": "Selecione uma fonte alternativa para instalar pacotes, caso tenha problemas de rede com a fonte padrão.", "registryTooltip": "Selecione uma fonte alternativa para instalar pacotes, caso tenha problemas de rede com a fonte padrão.",
@ -3861,6 +3903,7 @@
"searchNpx": "Buscar MCP", "searchNpx": "Buscar MCP",
"serverPlural": "Servidores", "serverPlural": "Servidores",
"serverSingular": "Servidor", "serverSingular": "Servidor",
"servers": "Servidores MCP",
"sse": "Eventos do Servidor (sse)", "sse": "Eventos do Servidor (sse)",
"startError": "Falha ao Iniciar", "startError": "Falha ao Iniciar",
"stdio": "Entrada/Saída Padrão (stdio)", "stdio": "Entrada/Saída Padrão (stdio)",

View File

@ -339,6 +339,41 @@
}, },
"title": "API Сервер" "title": "API Сервер"
}, },
"appMenu": {
"about": "О",
"close": "Закрыть окно",
"copy": "Копировать",
"cut": "Резать",
"delete": "Удалить",
"documentation": "Документация",
"edit": "Редактировать",
"feedback": "Обратная связь",
"file": "Файл",
"forceReload": "Принудительная перезагрузка",
"front": "Показать все поверх других",
"help": "Помощь",
"hide": "Скрыть",
"hideOthers": "Скрыть остальные",
"minimize": "Минимизировать",
"paste": "Вставить",
"quit": "Выйти",
"redo": "Переделать",
"releases": "Релизы",
"reload": "Перезагрузка",
"resetZoom": "Настоящий размер",
"selectAll": "Выбрать все",
"services": "Услуги",
"toggleDevTools": "Переключить инструменты разработчика",
"toggleFullscreen": "Переключить полноэкранный режим",
"undo": "Отменить",
"unhide": "Показать все",
"view": "Вид",
"website": "Веб-сайт",
"window": "Окно",
"zoom": "Zoom",
"zoomIn": "Увеличить",
"zoomOut": "Отдалить"
},
"assistants": { "assistants": {
"abbr": "Ассистент", "abbr": "Ассистент",
"clear": { "clear": {
@ -3766,6 +3801,7 @@
"description": "Не включать функциональность сервера MCP", "description": "Не включать функциональность сервера MCP",
"label": "Отключить сервер MCP" "label": "Отключить сервер MCP"
}, },
"discover": "Откройте",
"duplicateName": "Сервер с таким именем уже существует", "duplicateName": "Сервер с таким именем уже существует",
"editJson": "Редактировать JSON", "editJson": "Редактировать JSON",
"editMcpJson": "Редактировать MCP", "editMcpJson": "Редактировать MCP",
@ -3776,6 +3812,10 @@
"32000": "MCP сервер не запущен, пожалуйста, проверьте параметры", "32000": "MCP сервер не запущен, пожалуйста, проверьте параметры",
"toolNotFound": "Инструмент {{name}} не найден" "toolNotFound": "Инструмент {{name}} не найден"
}, },
"fetch": {
"button": "Получить серверы",
"success": "Успешно получены MCP-серверы"
},
"findMore": "Найти больше MCP", "findMore": "Найти больше MCP",
"headers": "Заголовки", "headers": "Заголовки",
"headersTooltip": "Пользовательские заголовки для HTTP-запросов", "headersTooltip": "Пользовательские заголовки для HTTP-запросов",
@ -3791,6 +3831,7 @@
"logoUrl": "URL логотипа", "logoUrl": "URL логотипа",
"longRunning": "Длительный режим работы", "longRunning": "Длительный режим работы",
"longRunningTooltip": "Включив эту опцию, сервер будет поддерживать длительные задачи. При получении уведомлений о ходе выполнения будет сброшен тайм-аут и максимальное время выполнения будет увеличено до 10 минут.", "longRunningTooltip": "Включив эту опцию, сервер будет поддерживать длительные задачи. При получении уведомлений о ходе выполнения будет сброшен тайм-аут и максимальное время выполнения будет увеличено до 10 минут.",
"marketplaces": "Торговые площадки",
"missingDependencies": "отсутствует, пожалуйста, установите для продолжения.", "missingDependencies": "отсутствует, пожалуйста, установите для продолжения.",
"more": { "more": {
"awesome": "Кураторский список серверов MCP", "awesome": "Кураторский список серверов MCP",
@ -3839,6 +3880,7 @@
"provider": "Провайдер", "provider": "Провайдер",
"providerPlaceholder": "Имя провайдера", "providerPlaceholder": "Имя провайдера",
"providerUrl": "URL провайдера", "providerUrl": "URL провайдера",
"providers": "Поставщики",
"registry": "Реестр пакетов", "registry": "Реестр пакетов",
"registryDefault": "По умолчанию", "registryDefault": "По умолчанию",
"registryTooltip": "Выберите реестр для установки пакетов, если возникают проблемы с сетью при использовании реестра по умолчанию.", "registryTooltip": "Выберите реестр для установки пакетов, если возникают проблемы с сетью при использовании реестра по умолчанию.",
@ -3861,6 +3903,7 @@
"searchNpx": "Найти MCP", "searchNpx": "Найти MCP",
"serverPlural": "серверы", "serverPlural": "серверы",
"serverSingular": "сервер", "serverSingular": "сервер",
"servers": "Серверы MCP",
"sse": "События, отправляемые сервером (sse)", "sse": "События, отправляемые сервером (sse)",
"startError": "Запуск не удалось", "startError": "Запуск не удалось",
"stdio": "Стандартный ввод/вывод (stdio)", "stdio": "Стандартный ввод/вывод (stdio)",

View File

@ -1,9 +1,8 @@
import { CheckOutlined, PlusOutlined } from '@ant-design/icons' import { CheckOutlined, PlusOutlined } from '@ant-design/icons'
import { Button } from '@cherrystudio/ui'
import { useMCPServers } from '@renderer/hooks/useMCPServers' import { useMCPServers } from '@renderer/hooks/useMCPServers'
import { getBuiltInMcpServerDescriptionLabel, getMcpTypeLabel } from '@renderer/i18n/label' import { getBuiltInMcpServerDescriptionLabel, getMcpTypeLabel } from '@renderer/i18n/label'
import { builtinMCPServers } from '@renderer/store/mcp' import { builtinMCPServers } from '@renderer/store/mcp'
import { Popover, Tag } from 'antd' import { Button, Popover, Tag } from 'antd'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
@ -16,7 +15,7 @@ const BuiltinMCPServerList: FC = () => {
return ( return (
<> <>
<SettingTitle style={{ marginBottom: 10 }}>{t('settings.mcp.builtinServers')}</SettingTitle> <SettingTitle style={{ gap: 3, marginBottom: 10 }}>{t('settings.mcp.builtinServers')}</SettingTitle>
<ServersGrid> <ServersGrid>
{builtinMCPServers.map((server) => { {builtinMCPServers.map((server) => {
const isInstalled = mcpServers.some((existingServer) => existingServer.name === server.name) const isInstalled = mcpServers.some((existingServer) => existingServer.name === server.name)
@ -29,8 +28,9 @@ const BuiltinMCPServerList: FC = () => {
</ServerName> </ServerName>
<StatusIndicator> <StatusIndicator>
<Button <Button
variant="ghost" type="text"
size="icon-sm" icon={isInstalled ? <CheckOutlined style={{ color: 'var(--color-primary)' }} /> : <PlusOutlined />}
size="small"
onClick={() => { onClick={() => {
if (isInstalled) { if (isInstalled) {
return return
@ -39,9 +39,8 @@ const BuiltinMCPServerList: FC = () => {
addMCPServer(server) addMCPServer(server)
window.toast.success(t('settings.mcp.addSuccess')) window.toast.success(t('settings.mcp.addSuccess'))
}} }}
disabled={isInstalled}> disabled={isInstalled}
{isInstalled ? <CheckOutlined style={{ color: 'var(--color-primary)' }} /> : <PlusOutlined />} />
</Button>
</StatusIndicator> </StatusIndicator>
</ServerHeader> </ServerHeader>
<Popover <Popover

View File

@ -34,7 +34,7 @@ const mcpMarkets = [
{ {
name: 'smithery.ai', name: 'smithery.ai',
url: 'https://smithery.ai/', url: 'https://smithery.ai/',
logo: 'https://smithery.ai/logo.svg', logo: 'https://smithery.ai/icon.svg',
descriptionKey: 'settings.mcp.more.smithery' descriptionKey: 'settings.mcp.more.smithery'
}, },
{ {

View File

@ -1,16 +1,21 @@
import { Button, Flex, RowFlex } from '@cherrystudio/ui' import { loggerService } from '@logger'
import CollapsibleSearchBar from '@renderer/components/CollapsibleSearchBar'
import Scrollbar from '@renderer/components/Scrollbar'
import db from '@renderer/databases'
import { useMCPServers } from '@renderer/hooks/useMCPServers' import { useMCPServers } from '@renderer/hooks/useMCPServers'
import type { MCPServer } from '@renderer/types' import type { MCPServer } from '@renderer/types'
import { Divider, Input, Space } from 'antd' import { Button, Divider, Flex, Input, Space } from 'antd'
import Link from 'antd/es/typography/Link' import Link from 'antd/es/typography/Link'
import { SquareArrowOutUpRight } from 'lucide-react' import { Check, Plus, SquareArrowOutUpRight } from 'lucide-react'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
import { SettingHelpLink, SettingHelpTextRow, SettingSubtitle } from '..' import { SettingHelpLink, SettingHelpTextRow, SettingSubtitle } from '..'
import type { ProviderConfig } from './providers/config' import type { ProviderConfig } from './providers/config'
const logger = loggerService.withContext('McpProviderSettings')
interface Props { interface Props {
provider: ProviderConfig provider: ProviderConfig
existingServers: MCPServer[] existingServers: MCPServer[]
@ -21,15 +26,65 @@ const McpProviderSettings: React.FC<Props> = ({ provider, existingServers }) =>
const [isFetching, setIsFetching] = useState(false) const [isFetching, setIsFetching] = useState(false)
const [token, setToken] = useState<string>('') const [token, setToken] = useState<string>('')
const [availableServers, setAvailableServers] = useState<MCPServer[]>([]) const [availableServers, setAvailableServers] = useState<MCPServer[]>([])
const [searchText, setSearchText] = useState('')
const { t } = useTranslation() const { t } = useTranslation()
useEffect(() => { useEffect(() => {
const savedToken = provider.getToken() setToken(provider.getToken() || '')
if (savedToken) {
setToken(savedToken)
}
}, [provider]) }, [provider])
// Load available servers from database when provider changes
useEffect(() => {
const loadServersFromDb = async () => {
try {
const dbKey = `mcp:provider:${provider.key}:servers`
const setting = await db.settings.get(dbKey)
const savedServers = setting?.value || []
setAvailableServers(savedServers)
} catch (error) {
logger.error('Failed to load servers from database', error as Error)
setAvailableServers([])
}
}
loadServersFromDb()
}, [provider.key])
// Sort servers: servers with logo first, then by name
const sortedServers = useMemo(() => {
return [...availableServers].sort((a, b) => {
// Servers with logo come first
if (a.logoUrl && !b.logoUrl) return -1
if (!a.logoUrl && b.logoUrl) return 1
// If both have or both don't have logo, sort by name
return a.name.localeCompare(b.name)
})
}, [availableServers])
// Filter servers based on search text
const filteredServers = useMemo(() => {
if (!searchText.trim()) {
return sortedServers
}
const lowerSearchText = searchText.toLowerCase()
return sortedServers.filter(
(server) =>
server.name.toLowerCase().includes(lowerSearchText) ||
server.description?.toLowerCase().includes(lowerSearchText)
)
}, [sortedServers, searchText])
const handleTokenChange = useCallback(
(value: string) => {
setToken(value)
// Auto-save token when user types
if (value.trim()) {
provider.saveToken(value)
}
},
[provider]
)
const handleFetch = useCallback(async () => { const handleFetch = useCallback(async () => {
if (!token.trim()) { if (!token.trim()) {
window.toast.error(t('settings.mcp.sync.tokenRequired', 'API Token is required')) window.toast.error(t('settings.mcp.sync.tokenRequired', 'API Token is required'))
@ -43,12 +98,19 @@ const McpProviderSettings: React.FC<Props> = ({ provider, existingServers }) =>
const result = await provider.syncServers(token, existingServers) const result = await provider.syncServers(token, existingServers)
if (result.success) { if (result.success) {
setAvailableServers(result.addedServers || []) const servers = result.allServers || []
setAvailableServers(servers)
// Save to database
const dbKey = `mcp:provider:${provider.key}:servers`
await db.settings.put({ id: dbKey, value: servers })
window.toast.success(t('settings.mcp.fetch.success', 'Successfully fetched MCP servers')) window.toast.success(t('settings.mcp.fetch.success', 'Successfully fetched MCP servers'))
} else { } else {
window.toast.error(result.message) window.toast.error(result.message)
} }
} catch (error: any) { } catch (error: any) {
logger.error('Failed to fetch MCP servers', error)
window.toast.error(`${t('settings.mcp.sync.error')}: ${error.message}`) window.toast.error(`${t('settings.mcp.sync.error')}: ${error.message}`)
} finally { } finally {
setIsFetching(false) setIsFetching(false)
@ -60,17 +122,17 @@ const McpProviderSettings: React.FC<Props> = ({ provider, existingServers }) =>
return ( return (
<DetailContainer> <DetailContainer>
<ProviderHeader> <ProviderHeader>
<Flex className="items-center gap-2"> <Flex className="items-center">
<ProviderName>{provider.name}</ProviderName> <ProviderName>{provider.name}</ProviderName>
{provider.discoverUrl && ( {provider.discoverUrl && (
<Link target="_blank" href={provider.discoverUrl} style={{ display: 'flex' }}> <Link target="_blank" href={provider.discoverUrl} style={{ display: 'flex' }}>
<Button variant="ghost" size="sm"> <Button type="text" size="small">
<SquareArrowOutUpRight size={14} /> <SquareArrowOutUpRight size={14} />
</Button> </Button>
</Link> </Link>
)} )}
</Flex> </Flex>
<Button variant="default" onClick={handleFetch} disabled={isFetching || isFetchDisabled}> <Button type="primary" onClick={handleFetch} disabled={isFetching || isFetchDisabled}>
{t('settings.mcp.fetch.button', 'Fetch Servers')} {t('settings.mcp.fetch.button', 'Fetch Servers')}
</Button> </Button>
</ProviderHeader> </ProviderHeader>
@ -80,47 +142,62 @@ const McpProviderSettings: React.FC<Props> = ({ provider, existingServers }) =>
<Input.Password <Input.Password
value={token} value={token}
placeholder={t('settings.mcp.sync.tokenPlaceholder', 'Enter API token here')} placeholder={t('settings.mcp.sync.tokenPlaceholder', 'Enter API token here')}
onChange={(e) => setToken(e.target.value)} onChange={(e) => handleTokenChange(e.target.value)}
spellCheck={false} spellCheck={false}
/> />
</Space.Compact> </Space.Compact>
<SettingHelpTextRow> <SettingHelpTextRow>
<RowFlex> <Flex dir="row">
{provider.apiKeyUrl && ( {provider.apiKeyUrl && (
<SettingHelpLink target="_blank" href={provider.apiKeyUrl}> <SettingHelpLink target="_blank" href={provider.apiKeyUrl}>
{t('settings.provider.get_api_key')} {t('settings.provider.get_api_key')}
</SettingHelpLink> </SettingHelpLink>
)} )}
</RowFlex> </Flex>
</SettingHelpTextRow> </SettingHelpTextRow>
{availableServers.length > 0 && ( {sortedServers.length > 0 && (
<> <>
<SettingSubtitle style={{ marginTop: 20 }}> <Flex justify="space-between" align="center" style={{ marginTop: 20 }}>
{t('settings.mcp.available.servers', 'Available MCP Servers')} <SettingSubtitle style={{ margin: 0 }}>
</SettingSubtitle> {t('settings.mcp.servers', 'Available MCP Servers')}
</SettingSubtitle>
<CollapsibleSearchBar
onSearch={setSearchText}
placeholder={t('settings.mcp.search.placeholder', 'Search servers...')}
tooltip={t('settings.mcp.search.tooltip', 'Search servers')}
maxWidth={200}
style={{ borderRadius: 20 }}
/>
</Flex>
<ServerList> <ServerList>
{availableServers.map((server) => ( {filteredServers.map((server) => (
<ServerItem key={server.id}> <ServerItem key={server.id}>
<ServerInfo> <div className="flex flex-1 flex-row items-center gap-3">
<ServerName>{server.name}</ServerName> {server.logoUrl && (
<ServerDescription>{server.description}</ServerDescription> <div className="flex h-8 w-8 flex-shrink-0 items-center justify-center overflow-hidden rounded-md bg-gray-100 dark:bg-gray-800">
</ServerInfo> <img src={server.logoUrl} alt={server.name} className="h-full w-full object-cover" />
</div>
)}
<div className="flex min-w-0 flex-1 flex-col">
<ServerName>{server.name}</ServerName>
<ServerDescription>{server.description}</ServerDescription>
</div>
</div>
{(() => { {(() => {
const isAlreadyAdded = existingServers.some((existing) => existing.id === server.id) const isAlreadyAdded = existingServers.some((existing) => existing.id === server.id)
return ( return (
<Button <Button
variant={isAlreadyAdded ? 'outline' : 'default'}
size="sm"
disabled={isAlreadyAdded} disabled={isAlreadyAdded}
style={{ marginLeft: 10 }}
onClick={() => { onClick={() => {
if (!isAlreadyAdded) { if (!isAlreadyAdded) {
addMCPServer(server) addMCPServer(server)
window.toast.success(t('settings.mcp.server.added', 'MCP server added')) window.toast.success(t('settings.mcp.addSuccess'))
} }
}}> }}
{isAlreadyAdded ? t('settings.mcp.server.added', 'Added') : t('settings.mcp.add.server', 'Add')} icon={isAlreadyAdded ? <Check size={14} /> : <Plus size={14} />}
</Button> />
) )
})()} })()}
</ServerItem> </ServerItem>
@ -132,10 +209,11 @@ const McpProviderSettings: React.FC<Props> = ({ provider, existingServers }) =>
) )
} }
const DetailContainer = styled.div` const DetailContainer = styled(Scrollbar)`
padding: 20px; padding: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: calc(100vh - var(--navbar-height));
` `
const ProviderHeader = styled.div` const ProviderHeader = styled.div`
@ -165,12 +243,9 @@ const ServerItem = styled.div`
border: 1px solid var(--color-border); border: 1px solid var(--color-border);
border-radius: 8px; border-radius: 8px;
background-color: var(--color-background); background-color: var(--color-background);
` &:hover {
border-color: var(--color-primary);
const ServerInfo = styled.div` }
display: flex;
flex-direction: column;
flex: 1;
` `
const ServerName = styled.div` const ServerName = styled.div`

View File

@ -1,16 +1,15 @@
import { Sortable, useDndReorder } from '@cherrystudio/ui' import { Sortable, useDndReorder } from '@cherrystudio/ui'
import { Button } from '@cherrystudio/ui'
import { loggerService } from '@logger' import { loggerService } from '@logger'
import { nanoid } from '@reduxjs/toolkit' import { nanoid } from '@reduxjs/toolkit'
import CollapsibleSearchBar from '@renderer/components/CollapsibleSearchBar' import CollapsibleSearchBar from '@renderer/components/CollapsibleSearchBar'
import { EditIcon, RefreshIcon } from '@renderer/components/Icons' import { EditIcon } from '@renderer/components/Icons'
import Scrollbar from '@renderer/components/Scrollbar' import Scrollbar from '@renderer/components/Scrollbar'
import { useMCPServers } from '@renderer/hooks/useMCPServers' import { useMCPServers } from '@renderer/hooks/useMCPServers'
import { useMCPServerTrust } from '@renderer/hooks/useMCPServerTrust' import { useMCPServerTrust } from '@renderer/hooks/useMCPServerTrust'
import type { MCPServer } from '@renderer/types' import type { MCPServer } from '@renderer/types'
import { formatMcpError } from '@renderer/utils/error' import { formatMcpError } from '@renderer/utils/error'
import { matchKeywordsInString } from '@renderer/utils/match' import { matchKeywordsInString } from '@renderer/utils/match'
import { Dropdown, Empty } from 'antd' import { Button, Dropdown, Empty } from 'antd'
import { Plus } from 'lucide-react' import { Plus } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'
import { startTransition, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { startTransition, useCallback, useEffect, useMemo, useRef, useState } from 'react'
@ -20,12 +19,9 @@ import styled from 'styled-components'
import { SettingTitle } from '..' import { SettingTitle } from '..'
import AddMcpServerModal from './AddMcpServerModal' import AddMcpServerModal from './AddMcpServerModal'
import BuiltinMCPServerList from './BuiltinMCPServerList'
import EditMcpJsonPopup from './EditMcpJsonPopup' import EditMcpJsonPopup from './EditMcpJsonPopup'
import InstallNpxUv from './InstallNpxUv' import InstallNpxUv from './InstallNpxUv'
import McpMarketList from './McpMarketList'
import McpServerCard from './McpServerCard' import McpServerCard from './McpServerCard'
import SyncServersPopup from './SyncServersPopup'
const logger = loggerService.withContext('McpServersList') const logger = loggerService.withContext('McpServersList')
@ -144,10 +140,6 @@ const McpServersList: FC = () => {
[t] [t]
) )
const onSyncServers = useCallback(() => {
SyncServersPopup.show(mcpServers)
}, [mcpServers])
const handleAddServerSuccess = useCallback( const handleAddServerSuccess = useCallback(
async (server: MCPServer) => { async (server: MCPServer) => {
addMCPServer(server) addMCPServer(server)
@ -239,24 +231,14 @@ const McpServersList: FC = () => {
</SettingTitle> </SettingTitle>
<ButtonGroup> <ButtonGroup>
<InstallNpxUv mini /> <InstallNpxUv mini />
<Button variant="default" className="rounded-full" onClick={() => EditMcpJsonPopup.show()}> <Button icon={<EditIcon size={14} />} type="default" shape="round" onClick={() => EditMcpJsonPopup.show()}>
<EditIcon size={14} />
{t('common.edit')} {t('common.edit')}
</Button> </Button>
<Dropdown <Dropdown menu={{ items: menuItems }} trigger={['click']} placement="bottomRight">
menu={{ <Button icon={<Plus size={16} />} type="default" shape="round">
items: menuItems
}}
trigger={['click']}>
<Button variant="default" className="rounded-full">
<Plus size={16} />
{t('common.add')} {t('common.add')}
</Button> </Button>
</Dropdown> </Dropdown>
<Button variant="default" onClick={onSyncServers} className="rounded-full">
<RefreshIcon size={14} />
{t('settings.mcp.sync.button')}
</Button>
</ButtonGroup> </ButtonGroup>
</ListHeader> </ListHeader>
<Sortable <Sortable
@ -291,9 +273,6 @@ const McpServersList: FC = () => {
/> />
)} )}
<McpMarketList />
<BuiltinMCPServerList />
<AddMcpServerModal <AddMcpServerModal
visible={isAddModalVisible} visible={isAddModalVisible}
onClose={() => setIsAddModalVisible(false)} onClose={() => setIsAddModalVisible(false)}

View File

@ -1,31 +0,0 @@
import { RowFlex } from '@cherrystudio/ui'
import { Button } from '@cherrystudio/ui'
import { NavbarRight } from '@renderer/components/app/Navbar'
import { isLinux, isWin } from '@renderer/config/constant'
import { useFullscreen } from '@renderer/hooks/useFullscreen'
import { Search } from 'lucide-react'
import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
import InstallNpxUv from './InstallNpxUv'
export const McpSettingsNavbar = () => {
const { t } = useTranslation()
const navigate = useNavigate()
return (
<NavbarRight style={{ paddingRight: useFullscreen() ? '12px' : isWin ? 150 : isLinux ? 120 : 12 }}>
<RowFlex className="items-center gap-[5px]">
<Button
size="sm"
variant="ghost"
onClick={() => navigate('/settings/mcp/npx-search')}
className="nodrag h-7 rounded-[20px] text-[13px]">
<Search size={14} />
{t('settings.mcp.searchNpx')}
</Button>
<InstallNpxUv mini />
</RowFlex>
</NavbarRight>
)
}

View File

@ -1,13 +1,16 @@
import { ArrowLeftOutlined } from '@ant-design/icons' import { ArrowLeftOutlined } from '@ant-design/icons'
import { Button, DividerWithText, ListItem } from '@cherrystudio/ui'
import { RowFlex, Scrollbar } from '@cherrystudio/ui'
import Ai302ProviderLogo from '@renderer/assets/images/providers/302ai.webp' import Ai302ProviderLogo from '@renderer/assets/images/providers/302ai.webp'
import BailianProviderLogo from '@renderer/assets/images/providers/bailian.png' import BailianProviderLogo from '@renderer/assets/images/providers/bailian.png'
import LanyunProviderLogo from '@renderer/assets/images/providers/lanyun.png' import LanyunProviderLogo from '@renderer/assets/images/providers/lanyun.png'
import MCPRouterProviderLogo from '@renderer/assets/images/providers/mcprouter.webp'
import ModelScopeProviderLogo from '@renderer/assets/images/providers/modelscope.png' import ModelScopeProviderLogo from '@renderer/assets/images/providers/modelscope.png'
import TokenFluxProviderLogo from '@renderer/assets/images/providers/tokenflux.png' import TokenFluxProviderLogo from '@renderer/assets/images/providers/tokenflux.png'
import DividerWithText from '@renderer/components/DividerWithText'
import ListItem from '@renderer/components/ListItem'
import Scrollbar from '@renderer/components/Scrollbar'
import { useTheme } from '@renderer/context/ThemeProvider' import { useTheme } from '@renderer/context/ThemeProvider'
import { useMCPServers } from '@renderer/hooks/useMCPServers' import { useMCPServers } from '@renderer/hooks/useMCPServers'
import { Button, Flex } from 'antd'
import { FolderCog, Package, ShoppingBag } from 'lucide-react' import { FolderCog, Package, ShoppingBag } from 'lucide-react'
import type { FC } from 'react' import type { FC } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
@ -70,37 +73,37 @@ const MCPSettings: FC = () => {
tokenflux: <ProviderIcon src={TokenFluxProviderLogo} alt="TokenFlux" />, tokenflux: <ProviderIcon src={TokenFluxProviderLogo} alt="TokenFlux" />,
lanyun: <ProviderIcon src={LanyunProviderLogo} alt="Lanyun" />, lanyun: <ProviderIcon src={LanyunProviderLogo} alt="Lanyun" />,
'302ai': <ProviderIcon src={Ai302ProviderLogo} alt="302AI" />, '302ai': <ProviderIcon src={Ai302ProviderLogo} alt="302AI" />,
bailian: <ProviderIcon src={BailianProviderLogo} alt="Bailian" /> bailian: <ProviderIcon src={BailianProviderLogo} alt="Bailian" />,
mcprouter: <ProviderIcon src={MCPRouterProviderLogo} alt="MCPRouter" />
} }
return ( return (
<Container> <Container>
<MainContainer> <MainContainer>
<MenuList> <MenuList>
<DividerWithText text={t('settings.mcp.management', 'Management')} style={{ margin: '8px 0' }} />
<ListItem <ListItem
title={t('settings.mcp.servers', 'MCP Servers')} title={t('settings.mcp.servers', 'MCP Servers')}
active={activeView === 'servers'} active={activeView === 'servers'}
onClick={() => navigate('/settings/mcp/servers')} onClick={() => navigate('/settings/mcp/servers')}
icon={<FolderCog size={16} />} icon={<FolderCog size={18} />}
titleStyle={{ fontWeight: 500 }} titleStyle={{ fontWeight: 500 }}
/> />
<DividerWithText text={t('settings.mcp.discover', 'Discover')} style={{ margin: '16px 0 8px 0' }} /> <DividerWithText text={t('settings.mcp.discover', 'Discover')} style={{ margin: '10px 0 8px 0' }} />
<ListItem <ListItem
title={t('settings.mcp.builtinServers', 'Built-in Servers')} title={t('settings.mcp.builtinServers', 'Built-in Servers')}
active={activeView === 'builtin'} active={activeView === 'builtin'}
onClick={() => navigate('/settings/mcp/builtin')} onClick={() => navigate('/settings/mcp/builtin')}
icon={<Package size={16} />} icon={<Package size={18} />}
titleStyle={{ fontWeight: 500 }} titleStyle={{ fontWeight: 500 }}
/> />
<ListItem <ListItem
title={t('settings.mcp.marketplaces', 'Marketplaces')} title={t('settings.mcp.marketplaces', 'Marketplaces')}
active={activeView === 'marketplaces'} active={activeView === 'marketplaces'}
onClick={() => navigate('/settings/mcp/marketplaces')} onClick={() => navigate('/settings/mcp/marketplaces')}
icon={<ShoppingBag size={16} />} icon={<ShoppingBag size={18} />}
titleStyle={{ fontWeight: 500 }} titleStyle={{ fontWeight: 500 }}
/> />
<DividerWithText text={t('settings.mcp.providers', 'Providers')} style={{ margin: '16px 0 8px 0' }} /> <DividerWithText text={t('settings.mcp.providers', 'Providers')} style={{ margin: '10px 0 8px 0' }} />
{providers.map((provider) => ( {providers.map((provider) => (
<ListItem <ListItem
key={provider.key} key={provider.key}
@ -116,7 +119,7 @@ const MCPSettings: FC = () => {
{!isHomePage() && ( {!isHomePage() && (
<BackButtonContainer> <BackButtonContainer>
<Link to="/settings/mcp/servers"> <Link to="/settings/mcp/servers">
<Button variant="default" className="rounded-full" size="icon"> <Button type="default" shape="circle" size="small">
<ArrowLeftOutlined /> <ArrowLeftOutlined />
</Button> </Button>
</Link> </Link>
@ -172,7 +175,7 @@ const MCPSettings: FC = () => {
) )
} }
const Container = styled(RowFlex)` const Container = styled(Flex)`
flex: 1; flex: 1;
` `
@ -196,7 +199,7 @@ const MenuList = styled(Scrollbar)`
height: calc(100vh - var(--navbar-height)); height: calc(100vh - var(--navbar-height));
` `
const RightContainer = styled(Scrollbar)` const RightContainer = styled.div`
flex: 1; flex: 1;
position: relative; position: relative;
` `

View File

@ -30,6 +30,7 @@ interface Ai302SyncResult {
message: string message: string
addedServers: MCPServer[] addedServers: MCPServer[]
updatedServers: MCPServer[] updatedServers: MCPServer[]
allServers: MCPServer[]
errorDetails?: string errorDetails?: string
} }
@ -53,7 +54,8 @@ export const syncAi302Servers = async (token: string, existingServers: MCPServer
success: false, success: false,
message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'), message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
@ -64,6 +66,7 @@ export const syncAi302Servers = async (token: string, existingServers: MCPServer
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}` errorDetails: `Status: ${response.status}`
} }
} }
@ -78,13 +81,15 @@ export const syncAi302Servers = async (token: string, existingServers: MCPServer
success: true, success: true,
message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'), message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
// Transform 302ai servers to MCP servers format // Transform 302ai servers to MCP servers format
const addedServers: MCPServer[] = [] const addedServers: MCPServer[] = []
const updatedServers: MCPServer[] = [] const updatedServers: MCPServer[] = []
const allServers: MCPServer[] = []
for (const server of servers) { for (const server of servers) {
try { try {
@ -121,7 +126,8 @@ export const syncAi302Servers = async (token: string, existingServers: MCPServer
success: true, success: true,
message: t('settings.mcp.sync.success', { count: totalServers }), message: t('settings.mcp.sync.success', { count: totalServers }),
addedServers, addedServers,
updatedServers updatedServers,
allServers
} }
} catch (error) { } catch (error) {
logger.error('302ai sync error:', error as Error) logger.error('302ai sync error:', error as Error)
@ -130,6 +136,7 @@ export const syncAi302Servers = async (token: string, existingServers: MCPServer
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: String(error) errorDetails: String(error)
} }
} }

View File

@ -55,6 +55,7 @@ export interface BailianSyncResult {
message: string message: string
addedServers: MCPServer[] addedServers: MCPServer[]
updatedServers: MCPServer[] updatedServers: MCPServer[]
allServers: MCPServer[]
errorDetails?: string errorDetails?: string
} }
@ -117,6 +118,7 @@ export const syncBailianServers = async (token: string, existingServers: MCPServ
const addedServers: MCPServer[] = [] const addedServers: MCPServer[] = []
const updatedServers: MCPServer[] = [] const updatedServers: MCPServer[] = []
const allServers: MCPServer[] = []
for (const server of servers) { for (const server of servers) {
try { try {
@ -151,6 +153,7 @@ export const syncBailianServers = async (token: string, existingServers: MCPServ
} else { } else {
addedServers.push(mcpServer) addedServers.push(mcpServer)
} }
allServers.push(mcpServer)
} catch (err) { } catch (err) {
logger.error(`Error processing Bailian server ${server.id}:`, err as Error) logger.error(`Error processing Bailian server ${server.id}:`, err as Error)
} }
@ -162,7 +165,8 @@ export const syncBailianServers = async (token: string, existingServers: MCPServ
success: true, success: true,
message: t('settings.mcp.sync.success', { count: totalServers }), message: t('settings.mcp.sync.success', { count: totalServers }),
addedServers, addedServers,
updatedServers updatedServers,
allServers
} }
} catch (error) { } catch (error) {
let message = '' let message = ''
@ -176,7 +180,8 @@ export const syncBailianServers = async (token: string, existingServers: MCPServ
success: false, success: false,
message, message,
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
@ -189,6 +194,7 @@ export const syncBailianServers = async (token: string, existingServers: MCPServ
message, message,
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails errorDetails
} }
} }
@ -202,6 +208,7 @@ export const syncBailianServers = async (token: string, existingServers: MCPServ
message, message,
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails errorDetails
} }
} }

View File

@ -1,8 +1,10 @@
import { getProviderLabel } from '@renderer/i18n/label'
import type { MCPServer } from '@renderer/types' import type { MCPServer } from '@renderer/types'
import { getAI302Token, saveAI302Token, syncAi302Servers } from './302ai' import { getAI302Token, saveAI302Token, syncAi302Servers } from './302ai'
import { getBailianToken, saveBailianToken, syncBailianServers } from './bailian' import { getBailianToken, saveBailianToken, syncBailianServers } from './bailian'
import { getTokenLanYunToken, LANYUN_KEY_HOST, saveTokenLanYunToken, syncTokenLanYunServers } from './lanyun' import { getTokenLanYunToken, LANYUN_KEY_HOST, saveTokenLanYunToken, syncTokenLanYunServers } from './lanyun'
import { getMCPRouterToken, saveMCPRouterToken, syncMCPRouterServers } from './mcprouter'
import { getModelScopeToken, MODELSCOPE_HOST, saveModelScopeToken, syncModelScopeServers } from './modelscope' import { getModelScopeToken, MODELSCOPE_HOST, saveModelScopeToken, syncModelScopeServers } from './modelscope'
import { getTokenFluxToken, saveTokenFluxToken, syncTokenFluxServers, TOKENFLUX_HOST } from './tokenflux' import { getTokenFluxToken, saveTokenFluxToken, syncTokenFluxServers, TOKENFLUX_HOST } from './tokenflux'
@ -19,6 +21,17 @@ export interface ProviderConfig {
} }
export const providers: ProviderConfig[] = [ export const providers: ProviderConfig[] = [
{
key: 'bailian',
name: getProviderLabel('dashscope'),
description: '百炼平台服务',
discoverUrl: `https://bailian.console.aliyun.com/?tab=mcp#/mcp-market`,
apiKeyUrl: `https://bailian.console.aliyun.com/?tab=app#/api-key`,
tokenFieldName: 'bailianToken',
getToken: getBailianToken,
saveToken: saveBailianToken,
syncServers: syncBailianServers
},
{ {
key: 'modelscope', key: 'modelscope',
name: 'ModelScope', name: 'ModelScope',
@ -43,7 +56,7 @@ export const providers: ProviderConfig[] = [
}, },
{ {
key: 'lanyun', key: 'lanyun',
name: '蓝耘科技', name: getProviderLabel('lanyun'),
description: '蓝耘科技云平台 MCP 服务', description: '蓝耘科技云平台 MCP 服务',
discoverUrl: 'https://mcp.lanyun.net', discoverUrl: 'https://mcp.lanyun.net',
apiKeyUrl: LANYUN_KEY_HOST, apiKeyUrl: LANYUN_KEY_HOST,
@ -64,14 +77,14 @@ export const providers: ProviderConfig[] = [
syncServers: syncAi302Servers syncServers: syncAi302Servers
}, },
{ {
key: 'bailian', key: 'mcprouter',
name: '阿里云百炼', name: 'MCP Router',
description: '百炼平台服务', description: 'MCP Router 平台 MCP 服务',
discoverUrl: `https://bailian.console.aliyun.com/?tab=mcp#/mcp-market`, discoverUrl: 'https://mcprouter.co',
apiKeyUrl: `https://bailian.console.aliyun.com/?tab=app#/api-key`, apiKeyUrl: 'https://mcprouter.co/settings/keys',
tokenFieldName: 'bailianToken', tokenFieldName: 'mcprouterToken',
getToken: getBailianToken, getToken: getMCPRouterToken,
saveToken: saveBailianToken, saveToken: saveMCPRouterToken,
syncServers: syncBailianServers syncServers: syncMCPRouterServers
} }
] ]

View File

@ -56,6 +56,7 @@ interface TokenLanYunSyncResult {
message: string message: string
addedServers: MCPServer[] addedServers: MCPServer[]
updatedServers: MCPServer[] updatedServers: MCPServer[]
allServers: MCPServer[]
errorDetails?: string errorDetails?: string
} }
@ -82,7 +83,8 @@ export const syncTokenLanYunServers = async (
success: false, success: false,
message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'), message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
@ -93,6 +95,7 @@ export const syncTokenLanYunServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}` errorDetails: `Status: ${response.status}`
} }
} }
@ -105,6 +108,7 @@ export const syncTokenLanYunServers = async (
message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'), message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}` errorDetails: `Status: ${response.status}`
} }
} }
@ -114,6 +118,7 @@ export const syncTokenLanYunServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}` errorDetails: `Status: ${response.status}`
} }
} }
@ -125,14 +130,17 @@ export const syncTokenLanYunServers = async (
success: true, success: true,
message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'), message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
// Transform Token servers to MCP servers format // Transform Token servers to MCP servers format
const addedServers: MCPServer[] = [] const addedServers: MCPServer[] = []
const updatedServers: MCPServer[] = [] const updatedServers: MCPServer[] = []
const allServers: MCPServer[] = []
logger.debug('TokenLanYun servers:', servers) logger.debug('TokenLanYun servers:', servers)
for (const server of servers) { for (const server of servers) {
try { try {
if (!server.operationalUrls?.[0]?.url) continue if (!server.operationalUrls?.[0]?.url) continue
@ -164,6 +172,7 @@ export const syncTokenLanYunServers = async (
// Add new server // Add new server
addedServers.push(mcpServer) addedServers.push(mcpServer)
} }
allServers.push(mcpServer)
} catch (err) { } catch (err) {
logger.error('Error processing LanYun server:', err as Error) logger.error('Error processing LanYun server:', err as Error)
} }
@ -174,7 +183,8 @@ export const syncTokenLanYunServers = async (
success: true, success: true,
message: t('settings.mcp.sync.success', { count: totalServers }), message: t('settings.mcp.sync.success', { count: totalServers }),
addedServers, addedServers,
updatedServers updatedServers,
allServers
} }
} catch (error) { } catch (error) {
logger.error('TokenLanyun sync error:', error as Error) logger.error('TokenLanyun sync error:', error as Error)
@ -183,6 +193,7 @@ export const syncTokenLanYunServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: String(error) errorDetails: String(error)
} }
} }

View File

@ -0,0 +1,164 @@
import { loggerService } from '@logger'
import { nanoid } from '@reduxjs/toolkit'
import type { MCPServer } from '@renderer/types'
import i18next from 'i18next'
const logger = loggerService.withContext('MCPRouterSyncUtils')
// Token storage constants and utilities
const TOKEN_STORAGE_KEY = 'mcprouter_token'
export const MCPROUTER_HOST = 'https://mcprouter.co'
export const saveMCPRouterToken = (token: string): void => {
localStorage.setItem(TOKEN_STORAGE_KEY, token)
}
export const getMCPRouterToken = (): string | null => {
return localStorage.getItem(TOKEN_STORAGE_KEY)
}
export const clearMCPRouterToken = (): void => {
localStorage.removeItem(TOKEN_STORAGE_KEY)
}
export const hasMCPRouterToken = (): boolean => {
return !!getMCPRouterToken()
}
interface MCPRouterServer {
created_at: string
updated_at: string
name: string
author_name?: string
title?: string
description?: string
content?: string
server_key: string
config_name: string
server_url: string
}
interface MCPRouterSyncResult {
success: boolean
message: string
addedServers: MCPServer[]
updatedServers: MCPServer[]
allServers: MCPServer[]
errorDetails?: string
}
// Function to fetch and process MCPRouter servers
export const syncMCPRouterServers = async (
token: string,
existingServers: MCPServer[]
): Promise<MCPRouterSyncResult> => {
const t = i18next.t
try {
const response = await fetch('https://api.mcprouter.to/v1/list-servers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
'HTTP-Referer': 'https://cherry-ai.com',
'X-Title': 'Cherry Studio'
},
body: JSON.stringify({})
})
// Handle authentication errors
if (response.status === 401 || response.status === 403) {
clearMCPRouterToken()
return {
success: false,
message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'),
addedServers: [],
updatedServers: [],
allServers: []
}
}
// Handle server errors
if (response.status === 500 || !response.ok) {
return {
success: false,
message: t('settings.mcp.sync.error'),
addedServers: [],
updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}`
}
}
// Process successful response
const data = await response.json()
const servers: MCPRouterServer[] = data.data?.servers || []
if (servers.length === 0) {
return {
success: true,
message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'),
addedServers: [],
updatedServers: [],
allServers: []
}
}
// Transform MCPRouter servers to MCP servers format
const addedServers: MCPServer[] = []
const updatedServers: MCPServer[] = []
const allServers: MCPServer[] = []
for (const server of servers) {
try {
// Check if server already exists using server_key
const existingServer = existingServers.find((s) => s.id === `@mcprouter/${server.server_key}`)
const mcpServer: MCPServer = {
id: `@mcprouter/${server.server_key}`,
name: server.title || server.name || `MCPRouter Server ${nanoid()}`,
description: server.description || '',
type: 'streamableHttp',
baseUrl: server.server_url,
isActive: true,
provider: 'MCPRouter',
providerUrl: `https://mcprouter.co/${server.server_key}`,
logoUrl: '',
tags: [],
headers: {
Authorization: `Bearer ${token}`
}
}
if (existingServer) {
// Update existing server with corrected URL and latest info
updatedServers.push(mcpServer)
} else {
// Add new server
addedServers.push(mcpServer)
}
allServers.push(mcpServer)
} catch (err) {
logger.error('Error processing MCPRouter server:', err as Error)
}
}
const totalServers = addedServers.length + updatedServers.length
return {
success: true,
message: t('settings.mcp.sync.success', { count: totalServers }),
addedServers,
updatedServers,
allServers
}
} catch (error) {
logger.error('MCPRouter sync error:', error as Error)
return {
success: false,
message: t('settings.mcp.sync.error'),
addedServers: [],
updatedServers: [],
allServers: [],
errorDetails: String(error)
}
}
}

View File

@ -40,6 +40,7 @@ interface ModelScopeSyncResult {
message: string message: string
addedServers: MCPServer[] addedServers: MCPServer[]
updatedServers: MCPServer[] updatedServers: MCPServer[]
allServers: MCPServer[]
errorDetails?: string errorDetails?: string
} }
@ -66,7 +67,8 @@ export const syncModelScopeServers = async (
success: false, success: false,
message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'), message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
@ -77,6 +79,7 @@ export const syncModelScopeServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}` errorDetails: `Status: ${response.status}`
} }
} }
@ -90,14 +93,16 @@ export const syncModelScopeServers = async (
success: true, success: true,
message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'), message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
// Transform ModelScope servers to MCP servers format // Transform ModelScope servers to MCP servers format
const addedServers: MCPServer[] = [] const addedServers: MCPServer[] = []
const updatedServers: MCPServer[] = [] const updatedServers: MCPServer[] = []
const allServers: MCPServer[] = []
logger.debug('ModelScope servers:', servers)
for (const server of servers) { for (const server of servers) {
try { try {
if (!server.operational_urls?.[0]?.url) continue if (!server.operational_urls?.[0]?.url) continue
@ -128,6 +133,7 @@ export const syncModelScopeServers = async (
// Add new server // Add new server
addedServers.push(mcpServer) addedServers.push(mcpServer)
} }
allServers.push(mcpServer)
} catch (err) { } catch (err) {
logger.error('Error processing ModelScope server:', err as Error) logger.error('Error processing ModelScope server:', err as Error)
} }
@ -138,7 +144,8 @@ export const syncModelScopeServers = async (
success: true, success: true,
message: t('settings.mcp.sync.success', { count: totalServers }), message: t('settings.mcp.sync.success', { count: totalServers }),
addedServers, addedServers,
updatedServers updatedServers,
allServers
} }
} catch (error) { } catch (error) {
logger.error('ModelScope sync error:', error as Error) logger.error('ModelScope sync error:', error as Error)
@ -147,6 +154,7 @@ export const syncModelScopeServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: String(error) errorDetails: String(error)
} }
} }

View File

@ -46,6 +46,7 @@ interface TokenFluxSyncResult {
message: string message: string
addedServers: MCPServer[] addedServers: MCPServer[]
updatedServers: MCPServer[] updatedServers: MCPServer[]
allServers: MCPServer[]
errorDetails?: string errorDetails?: string
} }
@ -72,7 +73,8 @@ export const syncTokenFluxServers = async (
success: false, success: false,
message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'), message: t('settings.mcp.sync.unauthorized', 'Sync Unauthorized'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
@ -83,6 +85,7 @@ export const syncTokenFluxServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: `Status: ${response.status}` errorDetails: `Status: ${response.status}`
} }
} }
@ -96,14 +99,16 @@ export const syncTokenFluxServers = async (
success: true, success: true,
message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'), message: t('settings.mcp.sync.noServersAvailable', 'No MCP servers available'),
addedServers: [], addedServers: [],
updatedServers: [] updatedServers: [],
allServers: []
} }
} }
// Transform TokenFlux servers to MCP servers format // Transform TokenFlux servers to MCP servers format
const addedServers: MCPServer[] = [] const addedServers: MCPServer[] = []
const updatedServers: MCPServer[] = [] const updatedServers: MCPServer[] = []
const allServers: MCPServer[] = []
logger.debug('TokenFlux servers:', servers)
for (const server of servers) { for (const server of servers) {
try { try {
// Check if server already exists // Check if server already exists
@ -138,6 +143,7 @@ export const syncTokenFluxServers = async (
// Add new server // Add new server
addedServers.push(mcpServer) addedServers.push(mcpServer)
} }
allServers.push(mcpServer)
} catch (err) { } catch (err) {
logger.error('Error processing TokenFlux server:', err as Error) logger.error('Error processing TokenFlux server:', err as Error)
} }
@ -148,7 +154,8 @@ export const syncTokenFluxServers = async (
success: true, success: true,
message: t('settings.mcp.sync.success', { count: totalServers }), message: t('settings.mcp.sync.success', { count: totalServers }),
addedServers, addedServers,
updatedServers updatedServers,
allServers
} }
} catch (error) { } catch (error) {
logger.error('TokenFlux sync error:', error as Error) logger.error('TokenFlux sync error:', error as Error)
@ -157,6 +164,7 @@ export const syncTokenFluxServers = async (
message: t('settings.mcp.sync.error'), message: t('settings.mcp.sync.error'),
addedServers: [], addedServers: [],
updatedServers: [], updatedServers: [],
allServers: [],
errorDetails: String(error) errorDetails: String(error)
} }
} }