diff --git a/scripts/auto-translate-i18n.ts b/scripts/auto-translate-i18n.ts index 71650f6618..7a1bea6f35 100644 --- a/scripts/auto-translate-i18n.ts +++ b/scripts/auto-translate-i18n.ts @@ -18,8 +18,10 @@ import { sortedObjectByKeys } from './sort' // ========== SCRIPT CONFIGURATION AREA - MODIFY SETTINGS HERE ========== const SCRIPT_CONFIG = { // 🔧 Concurrency Control Configuration - MAX_CONCURRENT_TRANSLATIONS: 5, // Max concurrent requests (Make sure the concurrency level does not exceed your provider's limits.) - TRANSLATION_DELAY_MS: 100, // Delay between requests to avoid rate limiting (Recommended: 100-500ms, Range: 0-5000ms) + MAX_CONCURRENT_TRANSLATIONS: process.env.TRANSLATION_MAX_CONCURRENT_REQUESTS + ? 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_KEY: process.env.TRANSLATION_API_KEY || '', // API key from environment variable diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index e851242559..fbffb92777 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -3801,6 +3801,7 @@ "description": "Do not enable MCP server functionality", "label": "Disable MCP Server" }, + "discover": "Discover", "duplicateName": "A server with this name already exists", "editJson": "Edit JSON", "editMcpJson": "Edit MCP Configuration", @@ -3811,6 +3812,10 @@ "32000": "MCP server failed to start, please check the parameters according to the tutorial", "toolNotFound": "Tool {{name}} not found" }, + "fetch": { + "button": "Fetch Servers", + "success": "Successfully fetched MCP servers" + }, "findMore": "Find More MCP", "headers": "Headers", "headersTooltip": "Custom headers for HTTP requests", @@ -3826,6 +3831,7 @@ "logoUrl": "Logo URL", "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.", + "marketplaces": "Marketplaces", "missingDependencies": "is Missing, please install it to continue.", "more": { "awesome": "Curated MCP Server List", @@ -3874,6 +3880,7 @@ "provider": "Provider", "providerPlaceholder": "Provider name", "providerUrl": "Provider URL", + "providers": "Providers", "registry": "Package Registry", "registryDefault": "Default", "registryTooltip": "Choose the registry for package installation to resolve network issues with the default registry.", @@ -3896,6 +3903,7 @@ "searchNpx": "Search MCP", "serverPlural": "servers", "serverSingular": "server", + "servers": "MCP Servers", "sse": "Server-Sent Events (sse)", "startError": "Start failed", "stdio": "Standard Input/Output (stdio)", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 4a42f6c92a..26fb5dbe75 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -3801,6 +3801,7 @@ "description": "不启用 MCP 服务功能", "label": "不使用 MCP 服务器" }, + "discover": "发现", "duplicateName": "已存在同名服务器", "editJson": "编辑 JSON", "editMcpJson": "编辑 MCP 配置", @@ -3811,6 +3812,10 @@ "32000": "MCP 服务器启动失败,请根据教程检查参数是否填写完整", "toolNotFound": "未找到工具 {{name}}" }, + "fetch": { + "button": "获取服务器", + "success": "服务器获取成功" + }, "findMore": "更多 MCP", "headers": "请求头", "headersTooltip": "HTTP 请求的自定义请求头", @@ -3826,6 +3831,7 @@ "logoUrl": "标志网址", "longRunning": "长时间运行模式", "longRunningTooltip": "启用后,服务器支持长时间任务,接收到进度通知时会重置超时计时器,并延长最大超时时间至10分钟", + "marketplaces": "市场", "missingDependencies": "缺失,请安装它以继续", "more": { "awesome": "精选的 MCP 服务器列表", @@ -3874,6 +3880,7 @@ "provider": "提供者", "providerPlaceholder": "提供者名称", "providerUrl": "提供者网址", + "providers": "提供商", "registry": "包管理源", "registryDefault": "默认", "registryTooltip": "选择用于安装包的源,以解决默认源的网络问题", @@ -3896,6 +3903,7 @@ "searchNpx": "搜索 MCP", "serverPlural": "服务器", "serverSingular": "服务器", + "servers": "MCP 服务器", "sse": "服务器发送事件 (sse)", "startError": "启动失败", "stdio": "标准输入 / 输出 (stdio)", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index c65815ad5b..8b16b3e94e 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -3801,6 +3801,7 @@ "description": "不啟用 MCP 服務功能", "label": "不使用 MCP 伺服器" }, + "discover": "發現", "duplicateName": "已存在相同名稱的伺服器", "editJson": "編輯 JSON", "editMcpJson": "編輯 MCP 配置", @@ -3811,6 +3812,10 @@ "32000": "MCP 伺服器啟動失敗,請根據教程檢查參數是否填寫完整", "toolNotFound": "未找到工具 {{name}}" }, + "fetch": { + "button": "獲取伺服器", + "success": "伺服器獲取成功" + }, "findMore": "更多 MCP", "headers": "請求標頭", "headersTooltip": "HTTP 請求的自定義標頭", @@ -3826,6 +3831,7 @@ "logoUrl": "標誌網址", "longRunning": "長時間運行模式", "longRunningTooltip": "啟用後,伺服器支援長時間任務,接收到進度通知時會重置超時計時器,並延長最大超時時間至10分鐘", + "marketplaces": "市場", "missingDependencies": "缺失,請安裝它以繼續", "more": { "awesome": "精選的 MCP 伺服器清單", @@ -3874,6 +3880,7 @@ "provider": "提供者", "providerPlaceholder": "提供者名稱", "providerUrl": "提供者網址", + "providers": "提供商", "registry": "套件管理源", "registryDefault": "預設", "registryTooltip": "選擇用於安裝套件的源,以解決預設源的網路問題", @@ -3896,6 +3903,7 @@ "searchNpx": "搜索 MCP", "serverPlural": "伺服器", "serverSingular": "伺服器", + "servers": "MCP 伺服器", "sse": "伺服器傳送事件 (sse)", "startError": "啟動失敗", "stdio": "標準輸入 / 輸出 (stdio)", diff --git a/src/renderer/src/i18n/translate/de-de.json b/src/renderer/src/i18n/translate/de-de.json index 359acf8c33..d94e74422b 100644 --- a/src/renderer/src/i18n/translate/de-de.json +++ b/src/renderer/src/i18n/translate/de-de.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "Assistent", "clear": { @@ -3766,6 +3801,7 @@ "description": "MCP-Service-Funktion nicht aktivieren", "label": "MCP-Server nicht verwenden" }, + "discover": "Entdecken", "duplicateName": "Server mit gleichem Namen existiert bereits", "editJson": "JSON 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", "toolNotFound": "Tool {{name}} nicht gefunden" }, + "fetch": { + "button": "Server abrufen", + "success": "MCP-Server erfolgreich abgerufen" + }, "findMore": "Mehr MCP", "headers": "Request-Header", "headersTooltip": "Benutzerdefinierte Request-Header für HTTP-Anfragen", @@ -3791,6 +3831,7 @@ "logoUrl": "Logo-URL", "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", + "marketplaces": "Marktplätze", "missingDependencies": "Abhängigkeiten fehlen, bitte installieren Sie sie, um fortzufahren", "more": { "awesome": "Kuratierte MCP-Serverliste", @@ -3839,6 +3880,7 @@ "provider": "Anbieter", "providerPlaceholder": "Anbietername", "providerUrl": "Anbieter-Website", + "providers": "Anbieter", "registry": "Paketverwaltungsquelle", "registryDefault": "Standard", "registryTooltip": "Quelle für Paketinstallation auswählen um Netzwerkprobleme der Standardquelle zu lösen", @@ -3861,6 +3903,7 @@ "searchNpx": "MCP durchsuchen", "serverPlural": "Server", "serverSingular": "Server", + "servers": "MCP-Server", "sse": "Server-Sende-Ereignisse (sse)", "startError": "Start fehlgeschlagen", "stdio": "Standard-Eingabe / -Ausgabe (stdio)", diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index 4b9ed72159..069cd8da8b 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "Βοηθός", "clear": { @@ -3766,6 +3801,7 @@ "description": "Να μην ενεργοποιείται η λειτουργία υπηρεσίας MCP", "label": "Να μην χρησιμοποιείται διακομιστής MCP" }, + "discover": "Ανακαλύψτε", "duplicateName": "Υπάρχει ήδη ένας διακομιστής με αυτό το όνομα", "editJson": "Επεξεργασία JSON", "editMcpJson": "Επεξεργασία ρύθμισης MCP", @@ -3776,6 +3812,10 @@ "32000": "Η εκκίνηση του MCP απέτυχε. Παρακαλώ ελέγξτε αν όλες οι παράμετροι έχουν συμπληρωθεί σύμφωνα με τον οδηγό.", "toolNotFound": "Δεν βρέθηκε το εργαλείο {{name}}" }, + "fetch": { + "button": "Λήψη Διακομιστών", + "success": "Επιτυχής ανάκτηση διακομιστών MCP" + }, "findMore": "Περισσότεροι διακομιστές MCP", "headers": "Κεφαλίδες", "headersTooltip": "Προσαρμοσμένες κεφαλίδες HTTP αιτήσεων", @@ -3791,6 +3831,7 @@ "logoUrl": "URL Λογότυπου", "longRunning": "Μακροχρόνια λειτουργία", "longRunningTooltip": "Όταν ενεργοποιηθεί, ο διακομιστής υποστηρίζει μακροχρόνιες εργασίες, επαναφέρει το χρονικό όριο μετά από λήψη ειδοποίησης προόδου και επεκτείνει το μέγιστο χρονικό όριο σε 10 λεπτά.", + "marketplaces": "Αγορές", "missingDependencies": "Λείπει, παρακαλώ εγκαταστήστε το για να συνεχίσετε", "more": { "awesome": "Επιλεγμένος κατάλογος διακομιστών MCP", @@ -3839,6 +3880,7 @@ "provider": "Πάροχος", "providerPlaceholder": "Όνομα παρόχου", "providerUrl": "URL Παρόχου", + "providers": "Πάροχοι", "registry": "Πηγή Διαχείρισης πακέτων", "registryDefault": "Προεπιλεγμένη", "registryTooltip": "Επιλέξτε την πηγή για την εγκατάσταση πακέτων, για να αντιμετωπιστούν προβλήματα δικτύου από την προεπιλεγμένη πηγή.", @@ -3861,6 +3903,7 @@ "searchNpx": "Αναζήτηση MCP", "serverPlural": "Διακομιστές", "serverSingular": "Διακομιστής", + "servers": "Διακομιστές MCP", "sse": "Συμβάντα Αποστολής από τον Διακομιστή (sse)", "startError": "Εκκίνηση Απέτυχε", "stdio": "Πρότυπη Είσοδος/Έξοδος (stdio)", diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index cf1b029db3..f3c7342b21 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "Asistente", "clear": { @@ -3766,6 +3801,7 @@ "description": "No habilitar funciones del servicio MCP", "label": "No utilizar servidor MCP" }, + "discover": "Descubrir", "duplicateName": "Ya existe un servidor con el mismo nombre", "editJson": "Editar JSON", "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", "toolNotFound": "Herramienta no encontrada {{name}}" }, + "fetch": { + "button": "Obtener Servidores", + "success": "Servidores MCP obtenidos con éxito" + }, "findMore": "Más servidores MCP", "headers": "Encabezados", "headersTooltip": "Encabezados personalizados para solicitudes HTTP", @@ -3791,6 +3831,7 @@ "logoUrl": "URL del logotipo", "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.", + "marketplaces": "Mercados", "missingDependencies": "Faltan, instalelas para continuar", "more": { "awesome": "Lista seleccionada de servidores MCP", @@ -3839,6 +3880,7 @@ "provider": "Proveedor", "providerPlaceholder": "Nombre del proveedor", "providerUrl": "URL del proveedor", + "providers": "Proveedores", "registry": "Repositorio de paquetes", "registryDefault": "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", "serverPlural": "Servidores", "serverSingular": "Servidor", + "servers": "Servidores MCP", "sse": "Eventos enviados por el servidor (sse)", "startError": "Inicio fallido", "stdio": "Entrada/Salida estándar (stdio)", diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index c1c699afaf..79dd7c4141 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "Aide", "clear": { @@ -3766,6 +3801,7 @@ "description": "Désactiver les fonctionnalités du service MCP", "label": "Ne pas utiliser le serveur MCP" }, + "discover": "Découvrir", "duplicateName": "Un serveur portant le même nom existe déjà", "editJson": "Modifier le JSON", "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", "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", "headers": "Заголовки запроса", "headersTooltip": "Пользовательские заголовки HTTP-запроса", @@ -3791,6 +3831,7 @@ "logoUrl": "Адрес логотипа", "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.", + "marketplaces": "Places de marché", "missingDependencies": "Manquantes, veuillez les installer pour continuer", "more": { "awesome": "Liste sélectionnée de serveurs MCP", @@ -3839,6 +3880,7 @@ "provider": "Поставщик", "providerPlaceholder": "Название поставщика", "providerUrl": "Адрес поставщика", + "providers": "Fournisseurs", "registry": "Источник управления пакетами", "registryDefault": "По умолчанию", "registryTooltip": "Выберите источник для установки пакетов, чтобы решить проблемы с сетью по умолчанию.", @@ -3861,6 +3903,7 @@ "searchNpx": "Поиск MCP", "serverPlural": "Serveurs", "serverSingular": "Serveur", + "servers": "Serveurs MCP", "sse": "Серверные отправляемые события (sse)", "startError": "Ошибка запуска", "stdio": "Стандартный ввод/вывод (stdio)", diff --git a/src/renderer/src/i18n/translate/ja-jp.json b/src/renderer/src/i18n/translate/ja-jp.json index 95b5a7e694..9655d8fb7b 100644 --- a/src/renderer/src/i18n/translate/ja-jp.json +++ b/src/renderer/src/i18n/translate/ja-jp.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "アシスタント", "clear": { @@ -3766,6 +3801,7 @@ "description": "MCP機能を有効にしない", "label": "MCPサーバーを無効にする" }, + "discover": "発見", "duplicateName": "同じ名前のサーバーが既に存在します", "editJson": "JSONを編集", "editMcpJson": "MCP 設定を編集", @@ -3776,6 +3812,10 @@ "32000": "MCP サーバーが起動しませんでした。パラメーターを確認してください", "toolNotFound": "ツール {{name}} が見つかりません" }, + "fetch": { + "button": "サーバーを取得", + "success": "MCPサーバーの取得に成功しました" + }, "findMore": "MCP を見つける", "headers": "ヘッダー", "headersTooltip": "HTTP リクエストのカスタムヘッダー", @@ -3791,6 +3831,7 @@ "logoUrl": "ロゴURL", "longRunning": "長時間運行モード", "longRunningTooltip": "このオプションを有効にすると、サーバーは長時間のタスクをサポートします。進行状況通知を受信すると、タイムアウトがリセットされ、最大実行時間が10分に延長されます。", + "marketplaces": "マーケットプレイス", "missingDependencies": "が不足しています。続行するにはインストールしてください。", "more": { "awesome": "厳選された MCP サーバーリスト", @@ -3839,6 +3880,7 @@ "provider": "プロバイダー", "providerPlaceholder": "プロバイダー名", "providerUrl": "プロバイダーURL", + "providers": "プロバイダー", "registry": "パッケージ管理レジストリ", "registryDefault": "デフォルト", "registryTooltip": "デフォルトのレジストリでネットワークの問題が発生した場合、パッケージインストールに使用するレジストリを選択してください。", @@ -3861,6 +3903,7 @@ "searchNpx": "MCP を検索", "serverPlural": "サーバー", "serverSingular": "サーバー", + "servers": "MCPサーバー", "sse": "サーバー送信イベント (sse)", "startError": "起動に失敗しました", "stdio": "標準入力/出力 (stdio)", diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index 7ad1184b15..4be4a3dd97 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "Assistente", "clear": { @@ -3766,6 +3801,7 @@ "description": "Não ativar a funcionalidade do serviço MCP", "label": "Não usar servidor MCP" }, + "discover": "Descobrir", "duplicateName": "Já existe um servidor com o mesmo nome", "editJson": "Editar JSON", "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", "toolNotFound": "Ferramenta não encontrada {{name}}" }, + "fetch": { + "button": "Buscar Servidores", + "success": "Servidores MCP obtidos com sucesso" + }, "findMore": "Mais servidores MCP", "headers": "Cabeçalhos da Requisição", "headersTooltip": "Cabeçalhos HTTP personalizados para as requisições", @@ -3791,6 +3831,7 @@ "logoUrl": "URL do Logotipo", "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.", + "marketplaces": "Mercados", "missingDependencies": "Ausente, instale para continuar", "more": { "awesome": "Lista selecionada de servidores MCP", @@ -3839,6 +3880,7 @@ "provider": "Fornecedor", "providerPlaceholder": "Nome do Fornecedor", "providerUrl": "URL do Fornecedor", + "providers": "Fornecedores", "registry": "Fonte de Gerenciamento de Pacotes", "registryDefault": "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", "serverPlural": "Servidores", "serverSingular": "Servidor", + "servers": "Servidores MCP", "sse": "Eventos do Servidor (sse)", "startError": "Falha ao Iniciar", "stdio": "Entrada/Saída Padrão (stdio)", diff --git a/src/renderer/src/i18n/translate/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json index ecdc0ecef0..241fde8fd3 100644 --- a/src/renderer/src/i18n/translate/ru-ru.json +++ b/src/renderer/src/i18n/translate/ru-ru.json @@ -339,6 +339,41 @@ }, "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": { "abbr": "Ассистент", "clear": { @@ -3766,6 +3801,7 @@ "description": "Не включать функциональность сервера MCP", "label": "Отключить сервер MCP" }, + "discover": "Откройте", "duplicateName": "Сервер с таким именем уже существует", "editJson": "Редактировать JSON", "editMcpJson": "Редактировать MCP", @@ -3776,6 +3812,10 @@ "32000": "MCP сервер не запущен, пожалуйста, проверьте параметры", "toolNotFound": "Инструмент {{name}} не найден" }, + "fetch": { + "button": "Получить серверы", + "success": "Успешно получены MCP-серверы" + }, "findMore": "Найти больше MCP", "headers": "Заголовки", "headersTooltip": "Пользовательские заголовки для HTTP-запросов", @@ -3791,6 +3831,7 @@ "logoUrl": "URL логотипа", "longRunning": "Длительный режим работы", "longRunningTooltip": "Включив эту опцию, сервер будет поддерживать длительные задачи. При получении уведомлений о ходе выполнения будет сброшен тайм-аут и максимальное время выполнения будет увеличено до 10 минут.", + "marketplaces": "Торговые площадки", "missingDependencies": "отсутствует, пожалуйста, установите для продолжения.", "more": { "awesome": "Кураторский список серверов MCP", @@ -3839,6 +3880,7 @@ "provider": "Провайдер", "providerPlaceholder": "Имя провайдера", "providerUrl": "URL провайдера", + "providers": "Поставщики", "registry": "Реестр пакетов", "registryDefault": "По умолчанию", "registryTooltip": "Выберите реестр для установки пакетов, если возникают проблемы с сетью при использовании реестра по умолчанию.", @@ -3861,6 +3903,7 @@ "searchNpx": "Найти MCP", "serverPlural": "серверы", "serverSingular": "сервер", + "servers": "Серверы MCP", "sse": "События, отправляемые сервером (sse)", "startError": "Запуск не удалось", "stdio": "Стандартный ввод/вывод (stdio)", diff --git a/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServerList.tsx b/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServerList.tsx index 617688fb22..6ee9f3efca 100644 --- a/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServerList.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/BuiltinMCPServerList.tsx @@ -15,7 +15,7 @@ const BuiltinMCPServerList: FC = () => { return ( <> - {t('settings.mcp.builtinServers')} + {t('settings.mcp.builtinServers')} {builtinMCPServers.map((server) => { const isInstalled = mcpServers.some((existingServer) => existingServer.name === server.name) diff --git a/src/renderer/src/pages/settings/MCPSettings/McpMarketList.tsx b/src/renderer/src/pages/settings/MCPSettings/McpMarketList.tsx index 274fa93686..9255a82697 100644 --- a/src/renderer/src/pages/settings/MCPSettings/McpMarketList.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/McpMarketList.tsx @@ -34,7 +34,7 @@ const mcpMarkets = [ { name: 'smithery.ai', url: 'https://smithery.ai/', - logo: 'https://smithery.ai/logo.svg', + logo: 'https://smithery.ai/icon.svg', descriptionKey: 'settings.mcp.more.smithery' }, { @@ -74,7 +74,7 @@ const McpMarketList: FC = () => { return ( <> - {t('settings.mcp.findMore')} + {t('settings.mcp.findMore')} {mcpMarkets.map((resource) => ( window.open(resource.url, '_blank', 'noopener,noreferrer')}> diff --git a/src/renderer/src/pages/settings/MCPSettings/McpProviderSettings.tsx b/src/renderer/src/pages/settings/MCPSettings/McpProviderSettings.tsx new file mode 100644 index 0000000000..d97fc86fea --- /dev/null +++ b/src/renderer/src/pages/settings/MCPSettings/McpProviderSettings.tsx @@ -0,0 +1,260 @@ +import { loggerService } from '@logger' +import CollapsibleSearchBar from '@renderer/components/CollapsibleSearchBar' +import db from '@renderer/databases' +import { useMCPServers } from '@renderer/hooks/useMCPServers' +import type { MCPServer } from '@renderer/types' +import { Button, Divider, Flex, Input, Space } from 'antd' +import Link from 'antd/es/typography/Link' +import { Check, Plus, SquareArrowOutUpRight } from 'lucide-react' +import { useCallback, useEffect, useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import styled from 'styled-components' + +import { SettingHelpLink, SettingHelpTextRow, SettingSubtitle } from '..' +import type { ProviderConfig } from './providers/config' + +const logger = loggerService.withContext('McpProviderSettings') + +interface Props { + provider: ProviderConfig + existingServers: MCPServer[] +} + +const McpProviderSettings: React.FC = ({ provider, existingServers }) => { + const { addMCPServer } = useMCPServers() + const [isFetching, setIsFetching] = useState(false) + const [token, setToken] = useState('') + const [availableServers, setAvailableServers] = useState([]) + const [searchText, setSearchText] = useState('') + const { t } = useTranslation() + + useEffect(() => { + setToken(provider.getToken() || '') + }, [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 () => { + if (!token.trim()) { + window.toast.error(t('settings.mcp.sync.tokenRequired', 'API Token is required')) + return + } + + setIsFetching(true) + + try { + provider.saveToken(token) + const result = await provider.syncServers(token, existingServers) + + if (result.success) { + const servers = result.addedServers || [] + 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')) + } else { + window.toast.error(result.message) + } + } catch (error: any) { + logger.error('Failed to fetch MCP servers', error) + window.toast.error(`${t('settings.mcp.sync.error')}: ${error.message}`) + } finally { + setIsFetching(false) + } + }, [existingServers, provider, t, token]) + + const isFetchDisabled = !token + + return ( + + + + {provider.name} + {provider.discoverUrl && ( + + + + + + )} + + + {t('settings.mcp.fetch.button', 'Fetch Servers')} + + + + {t('settings.provider.api_key.label')} + + handleTokenChange(e.target.value)} + spellCheck={false} + /> + + + + {provider.apiKeyUrl && ( + + {t('settings.provider.get_api_key')} + + )} + + + + {sortedServers.length > 0 && ( + <> + + + {t('settings.mcp.servers', 'Available MCP Servers')} + + + + + {filteredServers.map((server) => ( + + + {server.logoUrl && ( + + + + )} + + {server.name} + {server.description} + + + {(() => { + const isAlreadyAdded = existingServers.some((existing) => existing.id === server.id) + return ( + { + if (!isAlreadyAdded) { + addMCPServer(server) + window.toast.success(t('settings.mcp.addSuccess')) + } + }} + icon={isAlreadyAdded ? : } + /> + ) + })()} + + ))} + + > + )} + + ) +} + +const DetailContainer = styled.div` + padding: 20px; + display: flex; + flex-direction: column; +` + +const ProviderHeader = styled.div` + display: flex; + align-items: center; + justify-content: space-between; +` + +const ProviderName = styled.span` + font-size: 14px; + font-weight: 500; + margin-right: -2px; +` + +const ServerList = styled.div` + display: flex; + flex-direction: column; + gap: 12px; + margin-top: 8px; +` + +const ServerItem = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 16px; + border: 1px solid var(--color-border); + border-radius: 8px; + background-color: var(--color-background); + &:hover { + border-color: var(--color-primary); + } +` + +const ServerName = styled.div` + font-weight: 500; + font-size: 14px; + margin-bottom: 4px; +` + +const ServerDescription = styled.div` + color: var(--color-text-secondary); + font-size: 12px; +` + +export default McpProviderSettings diff --git a/src/renderer/src/pages/settings/MCPSettings/McpServersList.tsx b/src/renderer/src/pages/settings/MCPSettings/McpServersList.tsx index f7d30d1cf5..d429b228ac 100644 --- a/src/renderer/src/pages/settings/MCPSettings/McpServersList.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/McpServersList.tsx @@ -2,7 +2,7 @@ import { loggerService } from '@logger' import { nanoid } from '@reduxjs/toolkit' import CollapsibleSearchBar from '@renderer/components/CollapsibleSearchBar' import { Sortable, useDndReorder } from '@renderer/components/dnd' -import { EditIcon, RefreshIcon } from '@renderer/components/Icons' +import { EditIcon } from '@renderer/components/Icons' import Scrollbar from '@renderer/components/Scrollbar' import { useMCPServers } from '@renderer/hooks/useMCPServers' import { useMCPServerTrust } from '@renderer/hooks/useMCPServerTrust' @@ -19,12 +19,9 @@ import styled from 'styled-components' import { SettingTitle } from '..' import AddMcpServerModal from './AddMcpServerModal' -import BuiltinMCPServerList from './BuiltinMCPServerList' import EditMcpJsonPopup from './EditMcpJsonPopup' import InstallNpxUv from './InstallNpxUv' -import McpMarketList from './McpMarketList' import McpServerCard from './McpServerCard' -import SyncServersPopup from './SyncServersPopup' const logger = loggerService.withContext('McpServersList') @@ -143,10 +140,6 @@ const McpServersList: FC = () => { [t] ) - const onSyncServers = useCallback(() => { - SyncServersPopup.show(mcpServers) - }, [mcpServers]) - const handleAddServerSuccess = useCallback( async (server: MCPServer) => { addMCPServer(server) @@ -241,18 +234,11 @@ const McpServersList: FC = () => { } type="default" shape="round" onClick={() => EditMcpJsonPopup.show()}> {t('common.edit')} - + } type="default" shape="round"> {t('common.add')} - } type="default" onClick={onSyncServers} shape="round"> - {t('settings.mcp.sync.button')} - { /> )} - - - setIsAddModalVisible(false)} diff --git a/src/renderer/src/pages/settings/MCPSettings/McpSettingsNavbar.tsx b/src/renderer/src/pages/settings/MCPSettings/McpSettingsNavbar.tsx deleted file mode 100644 index 465c6b3f65..0000000000 --- a/src/renderer/src/pages/settings/MCPSettings/McpSettingsNavbar.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { NavbarRight } from '@renderer/components/app/Navbar' -import { HStack } from '@renderer/components/Layout' -import { isLinux, isWin } from '@renderer/config/constant' -import { useFullscreen } from '@renderer/hooks/useFullscreen' -import { Button } from 'antd' -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 ( - - - navigate('/settings/mcp/npx-search')} - icon={} - className="nodrag" - style={{ fontSize: 13, height: 28, borderRadius: 20 }}> - {t('settings.mcp.searchNpx')} - - - - - ) -} diff --git a/src/renderer/src/pages/settings/MCPSettings/index.tsx b/src/renderer/src/pages/settings/MCPSettings/index.tsx index 9fe0a1cc62..6e4ac3d2af 100644 --- a/src/renderer/src/pages/settings/MCPSettings/index.tsx +++ b/src/renderer/src/pages/settings/MCPSettings/index.tsx @@ -1,39 +1,131 @@ import { ArrowLeftOutlined } from '@ant-design/icons' -import { ErrorBoundary } from '@renderer/components/ErrorBoundary' +import Ai302ProviderLogo from '@renderer/assets/images/providers/302ai.webp' +import BailianProviderLogo from '@renderer/assets/images/providers/bailian.png' +import LanyunProviderLogo from '@renderer/assets/images/providers/lanyun.png' +import ModelScopeProviderLogo from '@renderer/assets/images/providers/modelscope.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 { Button } from 'antd' +import { useMCPServers } from '@renderer/hooks/useMCPServers' +import { Button, Flex } from 'antd' +import { FolderCog, Package, ShoppingBag } from 'lucide-react' import type { FC } from 'react' -import { Route, Routes, useLocation } from 'react-router' +import { useTranslation } from 'react-i18next' +import { Navigate, Route, Routes, useLocation, useNavigate } from 'react-router' import { Link } from 'react-router-dom' import styled from 'styled-components' import { SettingContainer } from '..' +import BuiltinMCPServerList from './BuiltinMCPServerList' import InstallNpxUv from './InstallNpxUv' +import McpMarketList from './McpMarketList' +import ProviderDetail from './McpProviderSettings' import McpServersList from './McpServersList' import McpSettings from './McpSettings' import NpxSearch from './NpxSearch' +import { providers } from './providers/config' const MCPSettings: FC = () => { const { theme } = useTheme() - + const { t } = useTranslation() + const { mcpServers } = useMCPServers() + const navigate = useNavigate() const location = useLocation() - const pathname = location.pathname - const isHome = pathname === '/settings/mcp' + // 获取当前激活的页面 + const getActiveView = () => { + const path = location.pathname + + // 精确匹配路径 + if (path === '/settings/mcp/builtin') return 'builtin' + if (path === '/settings/mcp/marketplaces') return 'marketplaces' + + // 检查是否是服务商页面 - 精确匹配 + for (const provider of providers) { + if (path === `/settings/mcp/${provider.key}`) { + return provider.key + } + } + + // 其他所有情况(包括 servers、settings/:serverId、npx-search、mcp-install)都属于 servers + return 'servers' + } + + const activeView = getActiveView() + + // 判断是否为主页面(是否显示返回按钮) + const isHomePage = () => { + const path = location.pathname + // 主页面不显示返回按钮 + if (path === '/settings/mcp' || path === '/settings/mcp/servers') return true + if (path === '/settings/mcp/builtin' || path === '/settings/mcp/marketplaces') return true + + // 服务商页面也是主页面 + return providers.some((p) => path === `/settings/mcp/${p.key}`) + } + + // Provider icons map + const providerIcons: Record = { + modelscope: , + tokenflux: , + lanyun: , + '302ai': , + bailian: + } return ( - - {!isHome && ( - - - } shape="circle" /> - - - )} + - + + navigate('/settings/mcp/servers')} + icon={} + titleStyle={{ fontWeight: 500 }} + /> + + navigate('/settings/mcp/builtin')} + icon={} + titleStyle={{ fontWeight: 500 }} + /> + navigate('/settings/mcp/marketplaces')} + icon={} + titleStyle={{ fontWeight: 500 }} + /> + + {providers.map((provider) => ( + navigate(`/settings/mcp/${provider.key}`)} + icon={providerIcons[provider.key] || } + titleStyle={{ fontWeight: 500 }} + /> + ))} + + + {!isHomePage() && ( + + + + + + + + )} - } /> + } /> + } /> } /> { } /> + + + + } + /> + + + + } + /> + {providers.map((provider) => ( + } + /> + ))} - + - + ) } +const Container = styled(Flex)` + flex: 1; +` + +const MainContainer = styled.div` + display: flex; + flex: 1; + flex-direction: row; + width: 100%; + height: calc(100vh - var(--navbar-height) - 6px); + overflow: hidden; +` + +const MenuList = styled(Scrollbar)` + display: flex; + flex-direction: column; + gap: 5px; + width: var(--settings-width); + padding: 12px; + padding-bottom: 48px; + border-right: 0.5px solid var(--color-border); + height: calc(100vh - var(--navbar-height)); +` + +const RightContainer = styled(Scrollbar)` + flex: 1; + position: relative; +` + +const ProviderIcon = styled.img` + width: 24px; + height: 24px; + object-fit: cover; + border-radius: 50%; + background-color: var(--color-background-soft); +` + +const ContentWrapper = styled.div` + padding: 20px; + overflow-y: auto; + height: 100%; +` + const BackButtonContainer = styled.div` display: flex; align-items: center; @@ -70,10 +228,4 @@ const BackButtonContainer = styled.div` z-index: 1000; ` -const MainContainer = styled.div` - display: flex; - flex: 1; - width: 100%; -` - export default MCPSettings diff --git a/src/renderer/src/pages/settings/MCPSettings/providers/config.ts b/src/renderer/src/pages/settings/MCPSettings/providers/config.ts new file mode 100644 index 0000000000..efe46be5fb --- /dev/null +++ b/src/renderer/src/pages/settings/MCPSettings/providers/config.ts @@ -0,0 +1,77 @@ +import type { MCPServer } from '@renderer/types' + +import { getAI302Token, saveAI302Token, syncAi302Servers } from './302ai' +import { getBailianToken, saveBailianToken, syncBailianServers } from './bailian' +import { getTokenLanYunToken, LANYUN_KEY_HOST, saveTokenLanYunToken, syncTokenLanYunServers } from './lanyun' +import { getModelScopeToken, MODELSCOPE_HOST, saveModelScopeToken, syncModelScopeServers } from './modelscope' +import { getTokenFluxToken, saveTokenFluxToken, syncTokenFluxServers, TOKENFLUX_HOST } from './tokenflux' + +export interface ProviderConfig { + key: string + name: string + description: string + discoverUrl: string + apiKeyUrl: string + tokenFieldName: string + getToken: () => string | null + saveToken: (token: string) => void + syncServers: (token: string, existingServers: MCPServer[]) => Promise +} + +export const providers: ProviderConfig[] = [ + { + key: 'modelscope', + name: 'ModelScope', + description: 'ModelScope 平台 MCP 服务', + discoverUrl: `${MODELSCOPE_HOST}/mcp?hosted=1&page=1`, + apiKeyUrl: `${MODELSCOPE_HOST}/my/myaccesstoken`, + tokenFieldName: 'modelScopeToken', + getToken: getModelScopeToken, + saveToken: saveModelScopeToken, + syncServers: syncModelScopeServers + }, + { + key: 'tokenflux', + name: 'TokenFlux', + description: 'TokenFlux 平台 MCP 服务', + discoverUrl: `${TOKENFLUX_HOST}/mcps`, + apiKeyUrl: `${TOKENFLUX_HOST}/dashboard/api-keys`, + tokenFieldName: 'tokenfluxToken', + getToken: getTokenFluxToken, + saveToken: saveTokenFluxToken, + syncServers: syncTokenFluxServers + }, + { + key: 'lanyun', + name: '蓝耘科技', + description: '蓝耘科技云平台 MCP 服务', + discoverUrl: 'https://mcp.lanyun.net', + apiKeyUrl: LANYUN_KEY_HOST, + tokenFieldName: 'tokenLanyunToken', + getToken: getTokenLanYunToken, + saveToken: saveTokenLanYunToken, + syncServers: syncTokenLanYunServers + }, + { + key: '302ai', + name: '302.AI', + description: '302.AI 平台 MCP 服务', + discoverUrl: 'https://302.ai', + apiKeyUrl: 'https://dash.302.ai/apis/list', + tokenFieldName: 'token302aiToken', + getToken: getAI302Token, + saveToken: saveAI302Token, + syncServers: syncAi302Servers + }, + { + key: 'bailian', + name: '阿里云百炼', + 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 + } +]