MCP tool manager (#5230)

* MCP tool manager

* Mcp tool manager i18 (#5231)

i18n translations for MCP manager changes
connect #5230

* fix bad i18n key
This commit is contained in:
Timothy Carambat 2026-03-18 15:33:49 -07:00 committed by GitHub
parent f395083978
commit b4b2203bae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 972 additions and 58 deletions

View File

@ -161,3 +161,50 @@ function TextContent({ label, description, labelStyles = {}, hint }) {
</div>
);
}
/**
* Simple toggle switch that doesn't use label/input to avoid focus-scroll issues
*/
export function SimpleToggleSwitch({
className,
enabled,
onChange,
disabled = false,
size = "sm",
}) {
return (
<div
role="switch"
aria-checked={enabled}
tabIndex={0}
onClick={(e) => {
e.stopPropagation();
onChange(!enabled);
}}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
e.stopPropagation();
onChange(!enabled);
}
}}
className={`
relative shrink-0 cursor-pointer rounded-full ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"}
${size === "sm" ? "h-[12px] w-[20px]" : size === "md" ? "h-[16px] w-[28px]" : "h-[19px] w-[36px]"}
transition-colors duration-200
${enabled ? "bg-green-400" : "bg-zinc-500"}
${className}
`}
>
<div
className={`
absolute top-[2px] left-[2px]
${size === "sm" ? "h-[8px] w-[8px]" : size === "md" ? "h-[12px] w-[12px]" : "h-[15px] w-[15px]"}
rounded-full bg-white
transition-transform duration-200
${enabled ? "translate-x-full" : "translate-x-0"}
`}
/>
</div>
);
}

View File

@ -62,6 +62,11 @@ const TRANSLATIONS = {
search: "بحث",
username_requirements:
"يجب أن يتكون اسم المستخدم من 2 إلى 32 حرفًا، ويبدأ بحرف صغير، ويحتوي فقط على حروف وأرقام وعلامات التسطير والنقاط.",
on: "على",
none: "لا",
stopped: "توقف",
loading: "تحميل",
refresh: "استعيد/جدد",
},
settings: {
title: "إعدادات المثيل",
@ -317,6 +322,26 @@ const TRANSLATIONS = {
default_skill:
"افتراضيًا، يتم تفعيل هذه الميزة، ولكن يمكنك تعطيلها إذا لم ترغب في أن تكون متاحة للممثل.",
},
mcp: {
title: "خوادم نظام MCP",
"loading-from-config": "تحميل خوادم MCP من ملف التكوين",
"learn-more": "اعرف المزيد عن خوادم MCP.",
"no-servers-found": "لم يتم العثور على أي خوادم MCP.",
"tool-warning":
"لتحقيق أفضل أداء، ضع في اعتبارك تعطيل الأدوات غير الضرورية للحفاظ على السياق.",
"stop-server": "أوقف خادم MCP",
"start-server": "ابدأ خادم MCP",
"delete-server": "حذف خادم MCP",
"tool-count-warning":
"يحتوي هذا خادم MCP على <b> أدوات مُفعّلة</b> والتي ستستهلك السياق في كل محادثة. <br /> ضع في اعتبارك تعطيل الأدوات غير المرغوب فيها لتوفير السياق.",
"startup-command": "أمر البدء",
command: "الأمر",
arguments: "حجج",
"not-running-warning":
"هذا الخادم الخاص بـ MCP غير قيد التشغيل - قد يكون متوقفًا أو يواجه مشكلة عند التشغيل.",
"tool-call-arguments": "وسائط استدعاء الدالة",
"tools-enabled": "الأدوات مفعّلة",
},
},
recorded: {
title: "محادثات مساحة العمل",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Hledat",
username_requirements:
"Uživatelské jméno musí mít 232 znaků, začínat malým písmenem a obsahovat pouze malá písmena, číslice, podtržítka, pomlčky a tečky.",
on: "Na",
none: "Žádné",
stopped: "Zastaveno",
loading: "Načítání",
refresh: "Obnovit",
},
home: {
welcome: "Vítejte",
@ -333,6 +338,26 @@ const TRANSLATIONS = {
default_skill:
"Výchozí nastavení je, že tato schopnost je aktivní, ale můžete ji vypnout, pokud nechcete, aby ji mohl využít zástupce.",
},
mcp: {
title: "Servery společnosti MCP",
"loading-from-config": "Načítání serverů MCP z konfiguračního souboru",
"learn-more": "Zjistěte více o serverech MCP.",
"no-servers-found": "Nebyl nalezen žádný server pro správu MCP.",
"tool-warning":
"Pro optimální výkon zvažte vypnutí nepoužívaných nástrojů, abyste ušetřili zdroje.",
"stop-server": "Zastavte server MCP",
"start-server": "Spustit server MCP",
"delete-server": "Odstranit server MCP",
"tool-count-warning":
"Tento server pro správu chatů má povolené nástroje <b>{{count}}, které spotřebovávají kontext v každém chatu. </b> Zvažte vypnutí nepotřebných nástrojů, abyste ušetřili kontext.",
"startup-command": "Příkaz pro spuštění",
command: "Příkaz",
arguments: "Argumenty",
"not-running-warning":
"Tento server pro správu MCP není aktivní buď byl vypnut, nebo se při spuštění vyskytuje chyba.",
"tool-call-arguments": "Argumenty pro volání nástroje",
"tools-enabled": "nástroje jsou aktivovány",
},
},
recorded: {
title: "Chaty pracovních prostorů",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Søg",
username_requirements:
"Brugernavnet skal bestå af 2-32 tegn, starte med et lille bogstav, og kun indeholde små bogstaver, tal, understregninger, bindestreger og punktummer.",
on: "Om",
none: "Ingen",
stopped: "Stoppet",
loading: "Indlæsning",
refresh: "Opfrisk",
},
settings: {
title: "Instansindstillinger",
@ -321,6 +326,26 @@ const TRANSLATIONS = {
default_skill:
"Som standard er denne funktion aktiveret, men du kan deaktivere den, hvis du ikke ønsker, at den skal være tilgængelig for agenten.",
},
mcp: {
title: "MCP-servere",
"loading-from-config": "Indlæsning af MCP-servere fra konfigurationsfil",
"learn-more": "Lær mere om MCP-servere.",
"no-servers-found": "Ingen MCP-servere fundet",
"tool-warning":
"For den bedste ydeevne, overvej at deaktivere unødvendige værktøjer for at bevare konteksten.",
"stop-server": "Afbryd MCP-serveren",
"start-server": "Start MCP-serveren",
"delete-server": "Slet MCP-serveren",
"tool-count-warning":
"Denne MCP-server har <b>aktiverede</b>værktøjer, som vil forbruge kontekst i hvert chat-session.<br />Overvej at deaktivere uønskede værktøjer for at spare på konteksten.",
"startup-command": "Startkommando",
command: "Instruktion",
arguments: "Argumenter",
"not-running-warning":
"Denne MCP-server kører ikke den kan være stoppet, eller den kan opleve fejl ved opstart.",
"tool-call-arguments": "Argumenter til værktøjsopkald",
"tools-enabled": "værktøjer er aktiveret",
},
},
recorded: {
title: "Arbejdsområde-chat",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Suchen",
username_requirements:
"Der Benutzername muss 2-32 Zeichen lang sein, mit einem Kleinbuchstaben beginnen und darf nur Kleinbuchstaben, Zahlen, Unterstriche, Bindestriche und Punkte enthalten.",
on: "Über",
none: "Keine",
stopped: "Gestoppt",
loading: "Laden",
refresh: "Erfrischen",
},
settings: {
title: "Instanzeinstellungen",
@ -326,6 +331,27 @@ const TRANSLATIONS = {
},
"performance-warning":
"Die Leistung von LLMs, die keine explizite Unterstützung für das Aufrufen von Tools bieten, hängt stark von den Fähigkeiten und der Genauigkeit des Modells ab. Einige Fähigkeiten können eingeschränkt oder nicht funktionsfähig sein.",
mcp: {
title: "MCP-Servern",
"loading-from-config":
"Laden von MCP-Servern aus einer Konfigurationsdatei",
"learn-more": "Erfahren Sie mehr über MCP-Server.",
"no-servers-found": "Keine MCP-Server gefunden",
"tool-warning":
"Für die beste Leistung sollten Sie unnötige Werkzeuge deaktivieren, um den Kontext zu schonen.",
"stop-server": "MCP-Server stoppen",
"start-server": "MCP-Server starten",
"delete-server": "MCP-Server löschen",
"tool-count-warning":
"Dieser MCP-Server hat <b>{{count}} Tools aktiviert, </b> die Kontext verbrauchen werden, wenn eine Chat-Sitzung stattfindet. <br /> Erwägen Sie, unerwünschte Tools zu deaktivieren, um Kontext zu sparen.",
"startup-command": "Startbefehl",
command: "Befehl",
arguments: "Argumente",
"not-running-warning":
"Dieser MCP-Server ist nicht aktiv er kann gestoppt sein oder bei der Startsequenz einen Fehler aufweisen.",
"tool-call-arguments": "Argumente für die Funktionsaufrufe",
"tools-enabled": "Werkzeuge aktiviert",
},
},
recorded: {
title: "Workspace-Chats",

View File

@ -59,9 +59,14 @@ const TRANSLATIONS = {
optional: "Optional",
yes: "Yes",
no: "No",
on: "On",
none: "None",
stopped: "Stopped",
search: "Search",
username_requirements:
"Username must be 2-32 characters, start with a lowercase letter, and only contain lowercase letters, numbers, underscores, hyphens, and periods.",
loading: "Loading",
refresh: "Refresh",
},
home: {
welcome: "Welcome",
@ -332,6 +337,26 @@ const TRANSLATIONS = {
default_skill:
"By default, this skill is enabled, but you can disable it if you don't want it to be available to the agent.",
},
mcp: {
title: "MCP Servers",
"loading-from-config": "Loading MCP Servers from configuration file",
"learn-more": "Learn more about MCP Servers.",
"no-servers-found": "No MCP servers found",
"tool-warning":
"For the best performance, consider disabling unwanted tools to conserve context.",
"tools-enabled": "tools enabled",
"stop-server": "Stop MCP Server",
"start-server": "Start MCP Server",
"delete-server": "Delete MCP Server",
"tool-count-warning":
"This MCP server has <b>{{count}} tools enabled</b> that will consume context in every chat.<br />Consider disabling unwanted tools to conserve context.",
"startup-command": "Startup Command",
command: "Command",
arguments: "Arguments",
"not-running-warning":
"This MCP server is not running - it may be stopped or experiencing an error on startup.",
"tool-call-arguments": "Tool call arguments",
},
},
recorded: {
title: "Workspace Chats",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Buscar",
username_requirements:
"El nombre de usuario debe tener entre 2 y 32 caracteres, comenzar con una letra minúscula y solo contener letras minúsculas, números, guiones bajos, guiones y puntos.",
on: "Sobre",
none: "Ninguno",
stopped: "Parado",
loading: "Cargando",
refresh: "Renovar; revitalizar",
},
settings: {
title: "Ajustes de la instancia",
@ -330,6 +335,27 @@ const TRANSLATIONS = {
default_skill:
"Por defecto, esta función está activada, pero puede desactivarla si no desea que esté disponible para el agente.",
},
mcp: {
title: "Servidores MCP",
"loading-from-config":
"Cargar servidores MCP desde el archivo de configuración",
"learn-more": "Aprenda más sobre los servidores MCP.",
"no-servers-found": "No se encontraron servidores MCP.",
"tool-warning":
"Para obtener el mejor rendimiento, considere desactivar las herramientas innecesarias para conservar el contexto.",
"stop-server": "Detener el servidor MCP",
"start-server": "Iniciar el servidor MCP",
"delete-server": "Eliminar el servidor MCP",
"tool-count-warning":
"Este servidor de MCP tiene <b> herramientas habilitadas</b> que consumirán contexto en cada conversación.<br /> Considere desactivar las herramientas no deseadas para ahorrar contexto.",
"startup-command": "Comando inicial",
command: "Órden",
arguments: "Argumentos",
"not-running-warning":
"Este servidor de MCP no está funcionando; podría estar detenido o estar experimentando un error al iniciarse.",
"tool-call-arguments": "Argumentos de llamada de función",
"tools-enabled": "herramientas habilitadas",
},
},
recorded: {
title: "Chats del espacio de trabajo",

View File

@ -63,6 +63,11 @@ const TRANSLATIONS = {
search: "otsing",
username_requirements:
"Kasutajanimi peab olema 232 tähemärki, algama väiketähega ning sisaldama ainult väiketähti, numbreid, alakriipse, sidekriipse ja punkte.",
on: "On",
none: "Ei",
stopped: "Peatas",
loading: "Laadimine",
refresh: "Värskendada",
},
settings: {
title: "Instantsi seaded",
@ -316,6 +321,26 @@ const TRANSLATIONS = {
default_skill:
"Vaikimisi on see funktsioon lubatud, kuid saate seda välja lülitada, kui ei soovi, et see oleks saadaval kaagentile.",
},
mcp: {
title: "MCP-serverid",
"loading-from-config": "MCP-serverid laaditakse konfiguraadifailist",
"learn-more": "Lisateabe saamiseks tutvuge MCP-serveridega.",
"no-servers-found": "MCP-servereid ei leitud.",
"tool-warning":
"Parima tulemuse saavutamiseks, võtke kaalutluseks, et välja lülitada tarbetud vahendid, et säilitada kontekst.",
"stop-server": "Lülitage MCP-server välja",
"start-server": "Alusta MCP-serverit",
"delete-server": "Kasuta MCP-serveri kustutamise funktsiooni",
"tool-count-warning":
"See MCP server on lubanud <b>_, mis tarbivad konteksti igas vestluses.</b> Selle asemel võid soovimatuid tööriistu välja lülitada, et säästa konteksti.",
"startup-command": "Alustamine",
command: "Juhendamine",
arguments: "Argumentid",
"not-running-warning":
"See MCP-server ei tööta see võib olla peatatud või alguses võib tekkida viga.",
"tool-call-arguments": '"Tooli käivitamise argumentid"',
"tools-enabled": "vahendid on lubatud",
},
},
recorded: {
title: "Tööruumi vestlused",

View File

@ -65,6 +65,11 @@ const TRANSLATIONS = {
search: "جستجو",
username_requirements:
"نام کاربری باید 2 تا 32 کاراکتر باشد، با حرف کوچک شروع شود و فقط شامل حروف کوچک، اعداد، زیرخط، خط تیره و نقطه باشد.",
on: "در",
none: "هیچ",
stopped: "متوقف شده",
loading: "بارگذاری",
refresh: "تازه‌سازی کردن",
},
settings: {
title: "تنظیمات سامانه",
@ -319,6 +324,26 @@ const TRANSLATIONS = {
default_skill:
"به طور پیش‌فرض، این قابلیت فعال است، اما می‌توانید آن را غیرفعال کنید اگر نمی‌خواهید این قابلیت برای نمایندگی در دسترس باشد.",
},
mcp: {
title: "سرورهای MCP",
"loading-from-config": "بارگذاری سرورهای MCP از طریق فایل پیکربندی",
"learn-more": "در مورد سرورهای MCP اطلاعات بیشتری کسب کنید.",
"no-servers-found": "هیچ سرور MCP یافت نشد.",
"tool-warning":
"برای به دست آوردن بهترین عملکرد، می‌توانید ابزارهایی که نیاز ندارید را غیرفعال کنید تا از منابع و اطلاعات موجود بهره‌برداری بهتری داشته باشید.",
"stop-server": "متوقف کردن سرور MCP",
"start-server": "شروع سرور MCP",
"delete-server": "حذف سرور MCP",
"tool-count-warning":
"این سرور MCP دارای ابزارهای <b> با قابلیت {{count}} است که در هر چت، از فضای مورد استفاده (context) بهره می‌برند. </b> برای صرفه‌جویی در فضای مورد استفاده، توصیه می‌شود این ابزارهای غیرضروری را غیرفعال کنید.",
"startup-command": "دستورالعمل اولیه",
command: "دستورالعمل",
arguments: "استدلال‌ها، بحث‌ها، دلایل",
"not-running-warning":
"این سرور MCP در حال اجرا نیست - ممکن است متوقف شده باشد یا در هنگام راه‌اندازی با مشکل مواجه شده باشد.",
"tool-call-arguments": "آرگومان‌های فراخوانی ابزار",
"tools-enabled": "ابزارهای فعال",
},
},
recorded: {
title: "گفتگوهای فضای کاری",

View File

@ -63,6 +63,11 @@ const TRANSLATIONS = {
search: "Rechercher",
username_requirements:
"Le nom d'utilisateur doit comporter entre 2 et 32 caractères, commencer par une lettre minuscule et ne contenir que des lettres minuscules, des chiffres, des tirets bas, des tirets et des points.",
on: "Sur",
none: "Aucun",
stopped: "Arrêté",
loading: "Chargement",
refresh: "Rafraîchir",
},
settings: {
title: "Paramètres de l'instance",
@ -320,6 +325,27 @@ const TRANSLATIONS = {
default_skill:
"Par défaut, cette fonctionnalité est activée, mais vous pouvez la désactiver si vous ne souhaitez pas qu'elle soit disponible pour l'agent.",
},
mcp: {
title: "Serveurs MCP",
"loading-from-config":
"Chargement des serveurs MCP à partir du fichier de configuration",
"learn-more": "En savoir plus sur les serveurs MCP.",
"no-servers-found": "Aucun serveur MCP n'a été trouvé.",
"tool-warning":
"Pour obtenir les meilleures performances, envisagez de désactiver les outils inutiles afin de préserver le contexte.",
"stop-server": "Arrêter le serveur MCP",
"start-server": "Démarrer le serveur MCP",
"delete-server": "Supprimer le serveur MCP",
"tool-count-warning":
"Ce serveur MCP a <b> des outils {{count}} activés</b> qui consommeront du contexte dans chaque conversation.<br /> Envisagez de désactiver les outils inutiles pour préserver le contexte.",
"startup-command": "Commande de démarrage",
command: "Ordre",
arguments: "Arguments",
"not-running-warning":
"Ce serveur MCP n'est pas en cours de fonctionnement ; il peut être arrêté ou rencontrer une erreur lors du démarrage.",
"tool-call-arguments": "Arguments des appels de fonctions/outils",
"tools-enabled": "outils activés",
},
},
recorded: {
title: "Chats de l'espace de travail",

View File

@ -61,6 +61,11 @@ const TRANSLATIONS = {
search: "חיפוש",
username_requirements:
"שם המשתמש חייב להיות באורך 2-32 תווים, להתחיל באות קטנה ולהכיל רק אותיות קטנות, מספרים, קווים תחתונים, מקפים ונקודות.",
on: "על",
none: "אין",
stopped: "עצר",
loading: "טעינה",
refresh: "רענן",
},
settings: {
title: "הגדרות מופע",
@ -318,6 +323,26 @@ const TRANSLATIONS = {
default_skill:
"כברירת מחדל, הכישורים הזה מופעל, אך ניתן להשבית אותו אם אינכם רוצים שהוא יהיה זמין עבור הסוכן.",
},
mcp: {
title: "שרתי MCP",
"loading-from-config": "טעינת שרתי MCP מהקובץ בתצורה",
"learn-more": "למידע נוסף על שרתי MCP.",
"no-servers-found": "לא נמצאו שרתי MCP.",
"tool-warning":
"על מנת להשיג את הביצועים הטובים ביותר, שקלו לבטל כלים לא רצויים כדי לחסוך במשאבים.",
"stop-server": "עצור את שרת ה-MCP",
"start-server": "הפעל שרת MCP",
"delete-server": "מחיקת שרת ה-MCP",
"tool-count-warning":
"שרת ה-MCP הזה כולל <b>כלי{{count}} שפעילים, אשר יצרוך מידע הקשר בכל צ'אט. </b> מומלץ לבטל את הכליות הלא רצויות כדי לחסוך במידע ההקשר.",
"startup-command": "פקודת התחלה",
command: "פקודה",
arguments: "טיעונים",
"not-running-warning":
"שרת ה-MCP הזה אינו פועל ייתכן שהוא מושבת או שהוא חווה תקלה בעת ההפעלה.",
"tool-call-arguments": "ארגומנטים לפונקציות",
"tools-enabled": "הכלים פעלו/היו זמינים",
},
},
recorded: {
title: "צ'אטים של סביבת עבודה",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Cerca",
username_requirements:
"Il nome utente deve essere compreso tra 2 e 32 caratteri, iniziare con una lettera minuscola e contenere solo lettere minuscole, numeri, trattini bassi, trattini e punti.",
on: "Su",
none: "Nessuno",
stopped: "Arrestato",
loading: "Caricamento",
refresh: "Rinfresca",
},
settings: {
title: "Impostazioni istanza",
@ -323,6 +328,27 @@ const TRANSLATIONS = {
default_skill:
"Per impostazione predefinita, questa funzionalità è attiva, ma è possibile disabilitarla se non si desidera che sia disponibile per l'agente.",
},
mcp: {
title: "Server MCP",
"loading-from-config":
"Caricamento dei server MCP da file di configurazione",
"learn-more": "Scopri di più sui server MCP.",
"no-servers-found": "Nessun server MCP trovato.",
"tool-warning":
"Per ottenere le migliori prestazioni, si consiglia di disattivare gli strumenti non necessari per preservare il contesto.",
"stop-server": "Arrestare il server MCP",
"start-server": "Avvia il server MCP",
"delete-server": "Elimina il server MCP",
"tool-count-warning":
"Questo server MCP ha <b> alcune funzionalità abilitate</b> che consumano contesto in ogni chat.<br /> Considera di disabilitare le funzionalità indesiderate per preservare il contesto.",
"startup-command": "Comando di avvio",
command: "Ordine",
arguments: "Argomentazioni",
"not-running-warning":
"Questo server MCP non è attivo; potrebbe essere stato interrotto o potrebbe essere in fase di avvio con errori.",
"tool-call-arguments": "Argomenti delle chiamate di funzioni",
"tools-enabled": "strumenti abilitati",
},
},
recorded: {
title: "Chat dell'area di lavoro",

View File

@ -63,6 +63,11 @@ const TRANSLATIONS = {
search: "検索",
username_requirements:
"ユーザー名は2〜32文字で、小文字で始まり、小文字、数字、アンダースコア、ハイフン、ピリオドのみを含む必要があります。",
on: "~について",
none: "なし",
stopped: "停止",
loading: "読み込み中",
refresh: "リフレッシュ",
},
settings: {
title: "インスタンス設定",
@ -315,6 +320,26 @@ const TRANSLATIONS = {
default_skill:
"デフォルトでは、この機能は有効になっていますが、エージェントに利用させたくない場合は、無効にすることができます。",
},
mcp: {
title: "MCP サーバー",
"loading-from-config": "構成ファイルからMCPサーバーを読み込む",
"learn-more": "MCP サーバーに関する詳細情報を入手してください。",
"no-servers-found": "MCP サーバーは見つかりませんでした",
"tool-warning":
"最高のパフォーマンスを得るためには、不要なツールを無効にして、コンテキストを維持することを検討してください。",
"stop-server": "MCP サーバーの停止",
"start-server": "MCP サーバーを開始する",
"delete-server": "MCP サーバーを削除",
"tool-count-warning":
"このMCPサーバーには、<b>のツールが有効になっており、これらはチャットのコンテキストを消費します</b>。コンテキストを節約するために、不要なツールを無効にすることを検討してください。",
"startup-command": "起動コマンド",
command: "指示",
arguments: "議論",
"not-running-warning":
"このMCPサーバーは稼働していません。停止しているか、起動時にエラーが発生している可能性があります。",
"tool-call-arguments": "ツール呼び出しの引数",
"tools-enabled": "ツールが有効化されました",
},
},
recorded: {
title: "ワークスペースチャット履歴",

View File

@ -62,6 +62,11 @@ const TRANSLATIONS = {
search: "검색",
username_requirements:
"사용자 이름은 2-32자여야 하고, 소문자로 시작해야 하며, 소문자, 숫자, 밑줄, 하이픈, 마침표만 포함할 수 있습니다.",
on: "~에 대해",
none: "없음",
stopped: "멈춤",
loading: "로딩 중",
refresh: "새롭게",
},
settings: {
title: "인스턴스 설정",
@ -319,6 +324,26 @@ const TRANSLATIONS = {
default_skill:
"기본적으로 이 기능은 활성화되어 있지만, 에이전트에게 이 기능을 사용하지 않도록 설정할 수도 있습니다.",
},
mcp: {
title: "MCP 서버",
"loading-from-config": "구성 파일에서 MCP 서버 로드",
"learn-more": "MCP 서버에 대해 더 자세히 알아보세요.",
"no-servers-found": "MCP 서버를 찾을 수 없습니다.",
"tool-warning":
"최상의 성능을 위해, 불필요한 도구를 비활성화하여 컨텍스트를 보존하는 것을 고려해 보세요.",
"stop-server": "MCP 서버 중단",
"start-server": "MCP 서버 시작",
"delete-server": "MCP 서버 삭제",
"tool-count-warning":
"이 MCP 서버에는 <b>에 설정된 {{count}} 도구가 있으며, 이는 모든 채팅에서 컨텍스트를 소비합니다. </b> 불필요한 도구를 비활성화하여 컨텍스트를 절약하는 것을 고려해 보세요.",
"startup-command": "시작 명령어",
command: "명령",
arguments: "논쟁",
"not-running-warning":
"이 MCP 서버는 현재 실행 상태가 아닙니다. 중단되었거나, 시작 시 오류가 발생했을 수 있습니다.",
"tool-call-arguments": "툴 호출 인자",
"tools-enabled": "도구 사용 기능 활성화",
},
},
recorded: {
title: "워크스페이스 채팅",

View File

@ -63,6 +63,11 @@ const TRANSLATIONS = {
search: "Meklēšana",
username_requirements:
"Lietotājvārdam jābūt 232 rakstzīmju garam, jāsākas ar mazo burtu un jāsatur tikai mazie burti, cipari, apakšsvītras, domuzīmes un punkti.",
on: "Par",
none: "Nav",
stopped: "Apstājās",
loading: "Ielāde",
refresh: "Atjaunot",
},
settings: {
title: "Instances iestatījumi",
@ -324,6 +329,26 @@ const TRANSLATIONS = {
default_skill:
"Par iestatījumu, šī spēja ir aktivizēta, taču jūs varat to izslēgt, ja nevēlaties, lai tā būtu pieejama aģentam.",
},
mcp: {
title: "MCP serveri",
"loading-from-config": "Ielādot MCP serverus no konfigūrācijas faila",
"learn-more": "Uzziniet vairāk par MCP serveriem.",
"no-servers-found": "Neizdevās atrast kādus MCP serverus.",
"tool-warning":
"Lai nodrošinātu optimālu darbību, apsveriet iespēju atspēlot nevajadzīgus rīkus, lai saglabātu kontekstu.",
"stop-server": "Aizvert MCP serveri",
"start-server": "Sākt MCP serveri",
"delete-server": "Dzēst MCP serveri",
"tool-count-warning":
"Šis MCP servers ir aktivizētas <b> instrumenti, kas izmantos kontekstu katrā sarunā.</b> Iespējams, ir labāk deaktivizēt nevēlamus instrumentus, lai saglabātu kontekstu.",
"startup-command": "Sākuma komanda",
command: "Instrukcijas",
arguments: "Pamatatpersonas",
"not-running-warning":
"Šis MCP servers darbojas iespējams, tas ir izslēgts vai piedzīvo kļūdu, kad tiek ieslēgts.",
"tool-call-arguments": "Parametri, kas tiek nosūtīti rīkam",
"tools-enabled": "rīki atļauti",
},
},
recorded: {
title: "Darba telpas sarunas",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Zoeken",
username_requirements:
"De gebruikersnaam moet 2-32 tekens bevatten, beginnen met een kleine letter en mag alleen kleine letters, cijfers, underscores, koppeltekens en punten bevatten.",
on: "Over",
none: "Geen",
stopped: "Gestopt",
loading: "Laad",
refresh: "Verfrissen",
},
settings: {
title: "Instelling Instanties",
@ -319,6 +324,26 @@ const TRANSLATIONS = {
default_skill:
"Standaard is deze functie ingeschakeld, maar u kunt deze uitschakelen als u niet wilt dat de agent er gebruik van kan maken.",
},
mcp: {
title: "MCP-servers",
"loading-from-config": "MCP-servers laden vanuit een configuratiebestand",
"learn-more": "Meer informatie over MCP-servers.",
"no-servers-found": "Geen MCP-servers gevonden.",
"tool-warning":
"Om de beste prestaties te garanderen, overweeg dan om ongewenste tools uit te schakelen om de context te behouden.",
"stop-server": "Stoppen met de MCP-server",
"start-server": "Start de MCP-server",
"delete-server": "Verwijder de MCP-server",
"tool-count-warning":
"Deze MCP-server heeft <b> bepaalde tools ingeschakeld</b> die context gebruiken in elke chat. <br /> Overweeg om ongewenste tools uit te schakelen om context te besparen.",
"startup-command": "Startcommando",
command: "Instructie",
arguments: "Argumenten",
"not-running-warning":
"Deze MCP-server is niet actief deze kan zijn uitgeschakeld of een fout ervaren tijdens het opstarten.",
"tool-call-arguments": "Argumenten voor het aanroepen van een tool",
"tools-enabled": "hulpmiddelen zijn geactiveerd",
},
},
recorded: {
title: "Werkruimte Chats",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Wyszukaj",
username_requirements:
"Nazwa użytkownika musi mieć od 2 do 32 znaków, zaczynać się małą literą i zawierać tylko małe litery, cyfry, podkreślenia, myślniki i kropki.",
on: "Na",
none: "Brak",
stopped: "Zatrzymano",
loading: "Ładowanie",
refresh: "Odświeżyć",
},
settings: {
title: "Ustawienia instancji",
@ -325,6 +330,26 @@ const TRANSLATIONS = {
default_skill:
"Domyślnie, ta umiejętność jest włączona, ale można ją wyłączyć, jeśli nie chcemy, aby była dostępna dla agenta.",
},
mcp: {
title: "Serwery MCP",
"loading-from-config": "Ładowanie serwerów MCP z pliku konfiguracyjnego",
"learn-more": "Dowiedz się więcej o serwerach MCP.",
"no-servers-found": "Nie znaleziono serwerów MCP.",
"tool-warning":
"Aby uzyskać najlepsze wyniki, rozważ wyłączenie niepotrzebnych narzędzi, aby zminimalizować zakłócenia.",
"stop-server": "Zatrzymaj serwer MCP",
"start-server": "Uruchom serwer MCP",
"delete-server": "Usuń serwer MCP",
"tool-count-warning":
"Ten serwer MCP ma włączone <b> narzędzia, które będą zużywać kontekst w każdej rozmowie.</b> Rozważ wyłączenie niepotrzebnych narzędzi, aby oszczędzać kontekst.",
"startup-command": "Polecenie uruchamiające",
command: "Rozkaz",
arguments: "Argumenty",
"not-running-warning":
"Ten serwer MCP nie działa może być zatrzymany lub może występować w nim błąd podczas uruchamiania.",
"tool-call-arguments": "Argumenty wywoływania funkcji",
"tools-enabled": "narzędzia są aktywne",
},
},
recorded: {
title: "Czaty w obszarach roboczych",

View File

@ -63,6 +63,11 @@ const TRANSLATIONS = {
search: "Pesquisar",
username_requirements:
"O nome de usuário deve ter de 2 a 32 caracteres, começar com uma letra minúscula e conter apenas letras minúsculas, números, sublinhados, hífens e pontos.",
on: "Sobre",
none: "Nenhum",
stopped: "Parado",
loading: "Carregando",
refresh: "Atualizar",
},
settings: {
title: "Configurações da Instância",
@ -323,6 +328,27 @@ const TRANSLATIONS = {
default_skill:
"Por padrão, essa habilidade está ativada, mas você pode desativá-la se não quiser que ela esteja disponível para o agente.",
},
mcp: {
title: "Servidores MCP",
"loading-from-config":
"Carregar servidores MCP a partir do arquivo de configuração",
"learn-more": "Saiba mais sobre os servidores MCP.",
"no-servers-found": "Nenhum servidor MCP encontrado.",
"tool-warning":
"Para obter o melhor desempenho, considere desativar as ferramentas desnecessárias para preservar o contexto.",
"stop-server": "Pare o servidor MCP",
"start-server": "Iniciar o servidor MCP",
"delete-server": "Excluir o servidor MCP",
"tool-count-warning":
"Este servidor MCP tem as seguintes ferramentas habilitadas: {{count}}, que consumirão contexto em cada conversa.</b> Considere desativar as ferramentas indesejadas para economizar contexto.",
"startup-command": "Comando de inicialização",
command: "Ordem",
arguments: "Argumentos",
"not-running-warning":
"Este servidor MCP não está em funcionamento pode estar parado ou estar apresentando um erro durante a inicialização.",
"tool-call-arguments": "Argumentos de chamada de ferramenta",
"tools-enabled": "ferramentas ativadas",
},
},
recorded: {
title: "Chats do Workspace",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Caută",
username_requirements:
"Numele de utilizator trebuie să aibă între 2 și 32 de caractere, să înceapă cu o literă mică și să conțină doar litere mici, cifre, liniuțe de subliniere, cratime și puncte.",
on: "În",
none: "Niciunul",
stopped: "Oprit",
loading: "Încărcare",
refresh: "Reîmprospătează",
},
settings: {
title: "Setările instanței",
@ -770,6 +775,27 @@ const TRANSLATIONS = {
default_skill:
"Implicit, această funcție este activată, dar puteți dezactiva-o dacă nu doriți ca agentul să o utilizeze.",
},
mcp: {
title: "Servere MCP",
"loading-from-config":
"Încărcarea serverelor MCP din fișierul de configurare",
"learn-more": "Aflați mai multe despre serverele MCP.",
"no-servers-found": "Nu au fost găsite servere MCP.",
"tool-warning":
"Pentru cele mai bune rezultate, luați în considerare dezactivarea instrumentelor nedorite, pentru a economisi resurse.",
"stop-server": "Închideți serverul MCP",
"start-server": "Pornește serverul MCP",
"delete-server": "Șterge serverul MCP",
"tool-count-warning":
"Acest server MCP are activate<b> instrumentele menționate</b>, care vor consuma context în fiecare sesiune de chat.<br />Luați în considerare dezactivarea instrumentelor nedorite pentru a economisi context.",
"startup-command": "Comanda de pornire",
command: "Ordine",
arguments: "Argumente",
"not-running-warning":
"Acest server MCP nu este în funcționare ar putea fi oprit sau ar putea întâmpina o eroare la pornire.",
"tool-call-arguments": "Argumente pentru apelarea unei funcții",
"tools-enabled": "instrumentele sunt activate",
},
},
recorded: {
title: "Conversații spațiu de lucru",

View File

@ -63,6 +63,11 @@ const TRANSLATIONS = {
search: "Поиск",
username_requirements:
"Имя пользователя должно содержать от 2 до 32 символов, начинаться со строчной буквы и содержать только строчные буквы, цифры, символы подчёркивания, дефисы и точки.",
on: "О",
none: "Нет",
stopped: "Остановлен",
loading: "Загрузка",
refresh: "Обновить",
},
settings: {
title: "Настройки экземпляра",
@ -318,6 +323,26 @@ const TRANSLATIONS = {
default_skill:
"По умолчанию, эта функция включена, но вы можете отключить ее, если не хотите, чтобы она была доступна для агента.",
},
mcp: {
title: "Серверы MCP",
"loading-from-config": "Загрузка серверов MCP из конфигурационного файла",
"learn-more": "Узнайте больше о серверах MCP.",
"no-servers-found": "Не найдено серверов MCP.",
"tool-warning":
"Для достижения наилучших результатов, рассмотрите возможность отключения неиспользуемых инструментов, чтобы сохранить контекст.",
"stop-server": "Остановить сервер MCP",
"start-server": "Запустить сервер MCP",
"delete-server": "Удалить сервер MCP",
"tool-count-warning":
"Этот сервер MCP имеет включенные <b> инструменты, которые потребляют контекст в каждом чате.</b> Рассмотрите возможность отключения нежелательных инструментов для экономии контекста.",
"startup-command": "Команда для запуска",
command: "Приказ",
arguments: "Аргументы",
"not-running-warning":
"Этот сервер MCP не работает он может быть остановлен или возникла ошибка при запуске.",
"tool-call-arguments": "Аргументы для вызова функции",
"tools-enabled": "инструменты включены/активированы",
},
},
recorded: {
title: "Чаты рабочего пространства",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Ara",
username_requirements:
"Kullanıcı adı 2-32 karakter uzunluğunda olmalı, küçük harfle başlamalı ve yalnızca küçük harfler, rakamlar, alt çizgiler, tireler ve noktalar içermelidir.",
on: "On",
none: "Yok",
stopped: "Durdu",
loading: "Yükleniyor",
refresh: "Tazelemek",
},
settings: {
title: "Instance Ayarları",
@ -318,6 +323,26 @@ const TRANSLATIONS = {
default_skill:
"Varsayılan olarak bu özellik etkinleştirilmiştir, ancak ajanın kullanmasına izin vermek istemiyorsanız, bu özelliği devre dışı bırakabilirsiniz.",
},
mcp: {
title: "MCP Sunucuları",
"loading-from-config": "MCP sunarlarını yapılandırma dosyasından yükleme",
"learn-more": "MCP sunucuları hakkında daha fazla bilgi edinin.",
"no-servers-found": "Hiçbir MCP sunucusu bulunamadı.",
"tool-warning":
"En iyi performansı elde etmek için, gereksiz araçları devre dışı bırakarak bağlamı korumayı düşünebilirsiniz.",
"stop-server": "MCP sunucusunu durdurun",
"start-server": "MCP sunucusunu başlatın",
"delete-server": "MCP sunucusunu sil",
"tool-count-warning":
"Bu MCP sunucusu, <b> özelliklerini etkinleştirmiş durumda ve bu özellikler her etkileşimde bağlamı tüketebilir. </b> Bağlamı korumak için istenmeyen özellikleri devre dışı bırakmayı düşünebilirsiniz.",
"startup-command": "Başlangıç Komutu",
command: "Emir",
arguments: "Tartışmalar",
"not-running-warning":
"Bu MCP sunucusu çalışmıyor olabilir ki durdurulmuş veya başlatma sırasında bir hata yaşıyor olabilir.",
"tool-call-arguments": "Araç çağrı argümanları",
"tools-enabled": "gerektiren araçlar etkinleştirildi",
},
},
recorded: {
title: "Çalışma Alanı Sohbetleri",

View File

@ -64,6 +64,11 @@ const TRANSLATIONS = {
search: "Tìm kiếm",
username_requirements:
"Tên người dùng phải có 2-32 ký tự, bắt đầu bằng chữ cái thường và chỉ chứa chữ cái thường, số, dấu gạch dưới, dấu gạch ngang và dấu chấm.",
on: "Về",
none: "Không",
stopped: "Dừng",
loading: "Đang tải",
refresh: "Tái tạo",
},
settings: {
title: "Cài đặt hệ thống",
@ -317,6 +322,26 @@ const TRANSLATIONS = {
default_skill:
"Theo mặc định, kỹ năng này được kích hoạt, nhưng bạn có thể tắt nó nếu không muốn nó được sử dụng bởi người đại diện.",
},
mcp: {
title: "Máy chủ MCP",
"loading-from-config": "Tải các máy chủ MCP từ tệp cấu hình",
"learn-more": "Tìm hiểu thêm về máy chủ MCP.",
"no-servers-found": "Không tìm thấy máy chủ MCP.",
"tool-warning":
"Để đạt hiệu suất tốt nhất, hãy cân nhắc việc tắt các công cụ không cần thiết để tiết kiệm tài nguyên.",
"stop-server": "Tắt máy chủ MCP",
"start-server": "Khởi động máy chủ MCP",
"delete-server": "Xóa máy chủ MCP",
"tool-count-warning":
"Máy chủ MCP này có các công cụ <b> được kích hoạt, {{count}} và chúng sẽ tiêu thụ ngữ cảnh trong mọi cuộc trò chuyện.</b> Hãy cân nhắc việc tắt các công cụ không cần thiết để tiết kiệm ngữ cảnh.",
"startup-command": "Lệnh khởi động",
command: "Lệnh",
arguments: "Luận điểm",
"not-running-warning":
"Máy chủ MCP này không hoạt động có thể nó đã bị tắt hoặc đang gặp lỗi khi khởi động.",
"tool-call-arguments": "Tham số khi gọi hàm/thao tác",
"tools-enabled": "các công cụ đã được kích hoạt",
},
},
recorded: {
title: "Hội thoại không gian làm việc",

View File

@ -60,6 +60,11 @@ const TRANSLATIONS = {
search: "搜索",
username_requirements:
"用户名必须为 2-32 个字符,以小写字母开头,只能包含小写字母、数字、下划线、连字符和句点。",
on: "关于",
none: "没有",
stopped: "停止",
loading: "正在加载…",
refresh: "重新开始;更新",
},
settings: {
title: "设置",
@ -309,6 +314,25 @@ const TRANSLATIONS = {
default_skill:
"默认情况下,这项技能已启用。但是,如果您不想让该技能被代理使用,您可以将其禁用。",
},
mcp: {
title: "MCP 服务器",
"loading-from-config": "从配置文件加载 MCP 服务器",
"learn-more": "了解更多关于 MCP 服务器的信息。",
"no-servers-found": "未找到任何 MCP 服务器",
"tool-warning": "为了获得最佳性能,建议禁用不必要的工具,以节省上下文。",
"stop-server": "停止 MCP 服务器",
"start-server": "启动 MCP 服务器",
"delete-server": "删除 MCP 服务器",
"tool-count-warning":
"这个 MCP 服务器启用了 <b> 工具,这些工具会在每次聊天中使用上下文信息。</b> 建议禁用不需要的工具,以节省上下文。<br />",
"startup-command": "启动命令",
command: "命令",
arguments: "争论",
"not-running-warning":
"这个 MCP 服务器目前处于停止状态,可能是因为在启动时出现了错误或被手动停止。",
"tool-call-arguments": "工具调用的参数",
"tools-enabled": "工具已启用",
},
},
recorded: {
title: "工作区聊天历史记录",

View File

@ -60,6 +60,11 @@ const TRANSLATIONS = {
search: "搜尋",
username_requirements:
"使用者名稱必須為 2-32 個字元,以小寫字母開頭,且只能包含小寫字母、數字、底線、連字號和句點。",
on: "關於",
none: "沒有",
stopped: "停止",
loading: "載入",
refresh: "重新整理",
},
settings: {
title: "系統設定",
@ -298,6 +303,25 @@ const TRANSLATIONS = {
},
default_skill: "這項技能預設為啟用;若不希望智慧代理人使用,也可以停用。",
},
mcp: {
title: "MCP 伺服器",
"loading-from-config": "從設定檔中載入 MCP 伺服器",
"learn-more": "了解更多關於 MCP 伺服器的資訊。",
"no-servers-found": "未找到任何 MCP 伺服器",
"tool-warning": "為了獲得最佳效能,建議關閉不必要的工具,以節省資源。",
"stop-server": "停止 MCP 伺服器",
"start-server": "啟動 MCP 伺服器",
"delete-server": "刪除 MCP 伺服器",
"tool-count-warning":
"這個 MCP 伺服器已啟用 <b> 工具,這些工具會消耗聊天中的語境 </b>。建議停用不需要的工具,以節省語境。",
"startup-command": "啟動指令",
command: "指令",
arguments: "辯論",
"not-running-warning":
"這個 MCP 伺服器目前處於停止狀態,可能是因為已停止運作,或是啟動時出現錯誤。",
"tool-call-arguments": "工具呼叫的參數",
"tools-enabled": "已啟用工具",
},
},
recorded: {
title: "工作區對話紀錄",

View File

@ -71,6 +71,27 @@ const MCPServers = {
error: e.message,
}));
},
/**
* Toggle a tool's suppression status for an MCP server
* @param {string} serverName - The name of the MCP server
* @param {string} toolName - The name of the tool to toggle
* @param {boolean} enabled - Whether the tool should be enabled (true) or suppressed (false)
* @returns {Promise<{success: boolean, error: string | null, suppressedTools: string[]}>}
*/
toggleTool: async (serverName, toolName, enabled) => {
return await fetch(`${API_BASE}/mcp-servers/toggle-tool`, {
method: "POST",
headers: baseHeaders(),
body: JSON.stringify({ serverName, toolName, enabled }),
})
.then((res) => res.json())
.catch((e) => ({
success: false,
error: e.message,
suppressedTools: [],
}));
},
};
export default MCPServers;

View File

@ -1,13 +1,14 @@
import React, { useState, useEffect, useRef } from "react";
import showToast from "@/utils/toast";
import { CaretDown, Gear } from "@phosphor-icons/react";
import { CaretDown, Gear, Warning } from "@phosphor-icons/react";
import MCPLogo from "@/media/agents/mcp-logo.svg";
import { titleCase } from "text-case";
import truncate from "truncate";
import MCPServers from "@/models/mcpServers";
import pluralize from "pluralize";
import { SimpleToggleSwitch } from "@/components/lib/Toggle";
import { useTranslation, Trans } from "react-i18next";
function ManageServerMenu({ server, toggleServer, onDelete }) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
const [running, setRunning] = useState(server.running);
const menuRef = useRef(null);
@ -85,7 +86,9 @@ function ManageServerMenu({ server, toggleServer, onDelete }) {
className="border-none flex items-center rounded-lg gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
>
<span className="text-sm">
{running ? "Stop MCP Server" : "Start MCP Server"}
{running
? t("agent.mcp.stop-server")
: t("agent.mcp.start-server")}
</span>
</button>
<button
@ -93,7 +96,7 @@ function ManageServerMenu({ server, toggleServer, onDelete }) {
onClick={deleteServer}
className="border-none flex items-center rounded-lg gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
>
<span className="text-sm">Delete MCP Server</span>
<span className="text-sm">{t("agent.mcp.delete-server")}</span>
</button>
</div>
)}
@ -101,11 +104,26 @@ function ManageServerMenu({ server, toggleServer, onDelete }) {
);
}
export default function ServerPanel({ server, toggleServer, onDelete }) {
export default function ServerPanel({
server,
toggleServer,
onDelete,
onToggleTool,
}) {
const { t } = useTranslation();
const suppressedTools = server.config?.anythingllm?.suppressedTools || [];
const enabledToolCount = server.tools.filter(
(tool) => !suppressedTools.includes(tool.name)
).length;
return (
<>
<div className="p-2">
<div className="flex flex-col gap-y-[18px] max-w-[800px]">
<ToolCountWarningBanner
server={server}
enabledToolCount={enabledToolCount}
/>
<div className="flex w-full justify-between">
<div className="flex items-center gap-x-2">
<img src={MCPLogo} className="w-6 h-6 light:invert" />
@ -114,8 +132,8 @@ export default function ServerPanel({ server, toggleServer, onDelete }) {
</label>
{server.tools.length > 0 && (
<p className="text-theme-text-secondary text-sm">
{server.tools.length} {pluralize("tool", server.tools.length)}{" "}
available
{enabledToolCount}/{server.tools.length}{" "}
{t("agent.mcp.tools-enabled")}
</p>
)}
</div>
@ -128,25 +146,52 @@ export default function ServerPanel({ server, toggleServer, onDelete }) {
</div>
<RenderServerConfig config={server.config} />
<RenderServerStatus server={server} />
<RenderServerTools tools={server.tools} />
<RenderServerTools
serverName={server.name}
tools={server.tools}
suppressedTools={suppressedTools}
onToggleTool={onToggleTool}
/>
</div>
</div>
</>
);
}
function ToolCountWarningBanner({ server, enabledToolCount }) {
if (server.tools.length <= 10) return null;
if (enabledToolCount <= 10) return null;
return (
<div className="flex items-center gap-x-2 p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-lg">
<Warning className="h-5 w-5 text-yellow-500 shrink-0" weight="fill" />
<p className="text-yellow-500 text-sm">
<Trans
i18nKey={`agent.mcp.tool-count-warning`}
values={{ count: enabledToolCount }}
components={{ b: <b />, br: <br /> }}
/>
</p>
</div>
);
}
function RenderServerConfig({ config = null }) {
const { t } = useTranslation();
if (!config) return null;
return (
<div className="flex flex-col gap-y-2">
<p className="text-theme-text-primary text-sm">Startup Command</p>
<p className="text-theme-text-primary text-sm">
{t("agent.mcp.startup-command")}
</p>
<div className="bg-theme-bg-primary rounded-lg p-4">
<p className="text-theme-text-secondary text-sm text-left">
<span className="font-bold">Command:</span> {config.command}
<span className="font-bold">{t("agent.mcp.command")}:</span>{" "}
{config.command}
</p>
<p className="text-theme-text-secondary text-sm text-left">
<span className="font-bold">Arguments:</span>{" "}
{config.args ? config.args.join(" ") : "None"}
<span className="font-bold">{t("agent.mcp.arguments")}:</span>{" "}
{config.args ? config.args.join(" ") : t("common.none")}
</p>
</div>
</div>
@ -154,12 +199,12 @@ function RenderServerConfig({ config = null }) {
}
function RenderServerStatus({ server }) {
const { t } = useTranslation();
if (server.running || !server.error) return null;
return (
<div className="flex flex-col gap-y-2">
<p className="text-theme-text-primary text-sm">
This MCP server is not running - it may be stopped or experiencing an
error on startup.
{t("agent.mcp.not-running-warning")}
</p>
<div className="bg-theme-bg-primary rounded-lg p-4">
<p className="text-red-500 text-sm font-mono">{server.error}</p>
@ -168,41 +213,70 @@ function RenderServerStatus({ server }) {
);
}
function RenderServerTools({ tools = [] }) {
function RenderServerTools({
serverName,
tools = [],
suppressedTools = [],
onToggleTool,
}) {
if (tools.length === 0) return null;
return (
<div className="flex flex-col gap-y-2">
<div className="flex flex-col gap-y-2">
{tools.map((tool) => (
<ServerTool key={tool.name} tool={tool} />
<ServerTool
key={tool.name}
serverName={serverName}
tool={tool}
enabled={!suppressedTools.includes(tool.name)}
onToggle={onToggleTool}
/>
))}
</div>
</div>
);
}
function ServerTool({ tool }) {
function ServerTool({ serverName, tool, enabled, onToggle }) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
return (
<button
type="button"
onClick={() => setOpen(!open)}
className="flex flex-col gap-y-2 px-4 py-2 rounded-lg border border-theme-text-secondary"
className={`flex flex-col gap-y-2 px-4 py-2 rounded-lg border ${
enabled
? "border-theme-text-secondary"
: "border-theme-text-secondary/50 opacity-60"
}`}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-x-2">
<p className="text-theme-text-primary font-mono font-bold text-sm">
<div className="flex items-center gap-x-2 min-w-0 flex-1">
<SimpleToggleSwitch
size="md"
enabled={enabled}
onChange={(newEnabled) =>
onToggle?.(serverName, tool.name, newEnabled)
}
/>
<p className="text-theme-text-primary font-mono font-bold text-sm shrink-0">
{tool.name}
</p>
{!open && (
<p className="text-theme-text-secondary text-sm">
{truncate(tool.description, 70)}
<p className="text-theme-text-secondary text-sm truncate">
{tool.description}
</p>
)}
</div>
<div className="border-none text-theme-text-secondary hover:text-cta-button">
<CaretDown size={16} />
<div className="flex items-center gap-x-3">
<div
className={`border-none text-theme-text-secondary hover:text-cta-button transition-transform duration-200 ${
open ? "rotate-180" : ""
}`}
>
<CaretDown size={16} />
</div>
</div>
</div>
{open && (
@ -214,7 +288,7 @@ function ServerTool({ tool }) {
</div>
<div className="flex flex-col gap-y-2">
<p className="text-theme-text-primary text-sm text-left">
Tool call arguments
{t("agent.mcp.tool-call-arguments")}
</p>
<div className="flex flex-col gap-y-2">
{Object.entries(tool.inputSchema?.properties || {}).map(

View File

@ -1,15 +1,18 @@
import { useState, useEffect } from "react";
import { titleCase } from "text-case";
import { BookOpenText, ArrowClockwise } from "@phosphor-icons/react";
import { BookOpenText, ArrowClockwise, Warning } from "@phosphor-icons/react";
import { Tooltip } from "react-tooltip";
import MCPLogo from "@/media/agents/mcp-logo.svg";
import MCPServers from "@/models/mcpServers";
import showToast from "@/utils/toast";
import { useTranslation } from "react-i18next";
export function MCPServerHeader({
setMcpServers,
setSelectedMcpServer,
children,
}) {
const { t } = useTranslation();
const [loadingMcpServers, setLoadingMcpServers] = useState(false);
useEffect(() => {
async function fetchMCPServers() {
@ -49,7 +52,7 @@ export function MCPServerHeader({
<div className="text-theme-text-primary flex items-center justify-between gap-x-2 mt-4">
<div className="flex items-center gap-x-2">
<img src={MCPLogo} className="w-6 h-6 light:invert" alt="MCP Logo" />
<p className="text-lg font-medium">MCP Servers</p>
<p className="text-lg font-medium">{t("agent.mcp.title")}</p>
</div>
<div className="flex items-center gap-x-3">
<a
@ -71,7 +74,9 @@ export function MCPServerHeader({
className={loadingMcpServers ? "animate-spin" : ""}
/>
<p className="text-sm">
{loadingMcpServers ? "Loading..." : "Refresh"}
{loadingMcpServers
? `${t("common.loading")}...`
: t("common.refresh")}
</p>
</button>
</div>
@ -87,17 +92,18 @@ export function MCPServersList({
selectedServer,
handleClick,
}) {
const { t } = useTranslation();
if (isLoading) {
return (
<div className="text-theme-text-secondary text-center text-xs flex flex-col gap-y-2">
<p>Loading MCP Servers from configuration file...</p>
<p>{t("agent.mcp.loading-from-config")}...</p>
<a
href="https://docs.anythingllm.com/mcp-compatibility/overview"
target="_blank"
rel="noopener noreferrer"
className="text-theme-text-secondary underline hover:text-cta-button"
>
Learn more about MCP Servers.
{t("agent.mcp.learn-more")}
</a>
</div>
);
@ -106,14 +112,14 @@ export function MCPServersList({
if (servers.length === 0) {
return (
<div className="text-theme-text-secondary text-center text-xs flex flex-col gap-y-2">
<p>No MCP servers found</p>
<p>{t("agent.mcp.no-servers-found")}</p>
<a
href="https://docs.anythingllm.com/mcp-compatibility/overview"
target="_blank"
rel="noopener noreferrer"
className="text-theme-text-secondary underline hover:text-cta-button"
>
Learn more about MCP Servers.
{t("agent.mcp.learn-more")}
</a>
</div>
);
@ -122,33 +128,60 @@ export function MCPServersList({
return (
<div className="bg-theme-bg-secondary text-white rounded-xl w-full md:min-w-[360px]">
{servers.map((server, index) => (
<div
<MCPServerItem
key={server.name}
className={`py-3 px-4 flex items-center justify-between ${
index === 0 ? "rounded-t-xl" : ""
} ${
index === servers.length - 1
? "rounded-b-xl"
: "border-b border-white/10"
} cursor-pointer transition-all duration-300 hover:bg-theme-bg-primary ${
selectedServer?.name === server.name
? "bg-white/10 light:bg-theme-bg-sidebar"
: ""
}`}
onClick={() => handleClick?.(server)}
>
<div className="text-sm font-light">
{titleCase(server.name.replace(/[_-]/g, " "))}
</div>
<div className="flex items-center gap-x-2">
<div
className={`text-sm text-theme-text-secondary font-medium ${server.running ? "text-green-500" : "text-red-500"}`}
>
{server.running ? "On" : "Stopped"}
</div>
</div>
</div>
server={server}
isFirst={index === 0}
isLast={index === servers.length - 1}
isSelected={selectedServer?.name === server.name}
handleClick={() => handleClick?.(server)}
/>
))}
<Tooltip
id="mcp-server-warning"
place="bottom"
delayShow={300}
className="tooltip !text-xs"
content={t("agent.mcp.tool-warning")}
/>
</div>
);
}
function MCPServerItem({ server, isFirst, isLast, isSelected, handleClick }) {
const { t } = useTranslation();
const suppressedTools = server.config?.anythingllm?.suppressedTools || [];
const enabledToolCount = server.tools.length - suppressedTools.length;
const showWarning = enabledToolCount > 10;
const running = server.running;
return (
<div
className={`py-3 px-4 flex items-center justify-between ${
isFirst ? "rounded-t-xl" : ""
} ${
isLast ? "rounded-b-xl" : "border-b border-white/10"
} cursor-pointer transition-all duration-300 hover:bg-theme-bg-primary ${
isSelected ? "bg-white/10 light:bg-theme-bg-sidebar" : ""
}`}
onClick={handleClick}
>
<div className="flex items-center gap-x-2 text-sm font-light">
{showWarning && (
<Warning
data-tooltip-id="mcp-server-warning"
className="h-4 w-4 text-yellow-500"
/>
)}
{titleCase(server.name.replace(/[_-]/g, " "))}
</div>
<div className="flex items-center gap-x-2">
<div
className={`text-sm text-theme-text-secondary font-medium ${running ? "text-green-500" : "text-red-500"}`}
>
{running ? t("common.on") : t("common.stopped")}
</div>
</div>
</div>
);
}

View File

@ -4,6 +4,7 @@ import Sidebar from "@/components/SettingsSidebar";
import { isMobile } from "react-device-detect";
import Admin from "@/models/admin";
import System from "@/models/system";
import MCPServers from "@/models/mcpServers";
import showToast from "@/utils/toast";
import {
CaretLeft,
@ -234,6 +235,49 @@ export default function AdminAgents() {
);
};
const handleMCPToolToggle = async (serverName, toolName, enabled) => {
const { success, error, suppressedTools } = await MCPServers.toggleTool(
serverName,
toolName,
enabled
);
if (!success) {
showToast(error || "Failed to toggle tool.", "error", { clear: true });
return;
}
setMcpServers((prev) =>
prev.map((server) => {
if (server.name !== serverName) return server;
return {
...server,
config: {
...server.config,
anythingllm: {
...server.config?.anythingllm,
suppressedTools,
},
},
};
})
);
setSelectedMcpServer((prev) => {
if (!prev || prev.name !== serverName) return prev;
return {
...prev,
config: {
...prev.config,
anythingllm: {
...prev.config?.anythingllm,
suppressedTools,
},
},
};
});
};
if (loading) {
return (
<div
@ -365,6 +409,7 @@ export default function AdminAgents() {
server={selectedMcpServer}
toggleServer={toggleMCP}
onDelete={handleMCPServerDelete}
onToggleTool={handleMCPToolToggle}
/>
) : selectedFlow ? (
<FlowPanel
@ -557,6 +602,7 @@ export default function AdminAgents() {
server={selectedMcpServer}
toggleServer={toggleMCP}
onDelete={handleMCPServerDelete}
onToggleTool={handleMCPToolToggle}
/>
) : selectedFlow ? (
<FlowPanel

View File

@ -95,6 +95,33 @@ function mcpServersEndpoints(app) {
}
}
);
app.post(
"/mcp-servers/toggle-tool",
[validatedRequest, flexUserRoleValid([ROLES.admin])],
async (request, response) => {
try {
const { serverName, toolName, enabled } = reqBody(request);
const result = await new MCPCompatibilityLayer().toggleToolSuppression(
serverName,
toolName,
enabled
);
return response.status(200).json({
success: result.success,
error: result.error,
suppressedTools: result.suppressedTools,
});
} catch (error) {
console.error("Error toggling MCP tool:", error);
return response.status(500).json({
success: false,
error: error.message,
suppressedTools: [],
});
}
}
);
}
module.exports = { mcpServersEndpoints };

View File

@ -130,6 +130,66 @@ class MCPHypervisor {
return true;
}
/**
* Update the suppressed tools for an MCP server
* @param {string} serverName - The name of the MCP server
* @param {string} toolName - The name of the tool to toggle
* @param {boolean} enabled - Whether the tool should be enabled (true) or suppressed (false)
* @returns {{success: boolean, error: string | null, suppressedTools: string[]}}
*/
updateSuppressedTools(serverName, toolName, enabled) {
const servers = safeJsonParse(
fs.readFileSync(this.mcpServerJSONPath, "utf8"),
{ mcpServers: {} }
);
if (!servers.mcpServers[serverName]) {
return {
success: false,
error: `MCP server ${serverName} not found in config file.`,
suppressedTools: [],
};
}
const server = servers.mcpServers[serverName];
if (!server.anythingllm) server.anythingllm = {};
if (!Array.isArray(server.anythingllm.suppressedTools))
server.anythingllm.suppressedTools = [];
const suppressedTools = server.anythingllm.suppressedTools;
if (enabled) {
const index = suppressedTools.indexOf(toolName);
if (index > -1) suppressedTools.splice(index, 1);
} else {
if (!suppressedTools.includes(toolName)) suppressedTools.push(toolName);
}
server.anythingllm.suppressedTools = suppressedTools;
servers.mcpServers[serverName] = server;
fs.writeFileSync(
this.mcpServerJSONPath,
JSON.stringify(servers, null, 2),
"utf8"
);
this.log(
`MCP server ${serverName} tool ${toolName} ${enabled ? "enabled" : "suppressed"}`
);
return { success: true, error: null, suppressedTools };
}
/**
* Get the suppressed tools for an MCP server
* @param {string} serverName - The name of the MCP server
* @returns {string[]} - Array of suppressed tool names
*/
getSuppressedTools(serverName) {
const config = this.mcpServerConfigs.find((s) => s.name === serverName);
return config?.server?.anythingllm?.suppressedTools || [];
}
/**
* Reload the MCP servers - can be used to reload the MCP servers without restarting the server or app
* and will also apply changes to the config file if any where made.

View File

@ -39,6 +39,22 @@ class MCPCompatibilityLayer extends MCPHypervisor {
}
if (!tools || !tools.length) return null;
const suppressedTools = this.getSuppressedTools(name);
const totalTools = tools.length;
tools = tools.filter((tool) => !suppressedTools.includes(tool.name));
const suppressedCount = totalTools - tools.length;
if (suppressedCount > 0) {
this.log(
`MCP server ${name}: ${suppressedCount} tool(s) suppressed, ${tools.length} tool(s) enabled`
);
}
if (!tools.length) {
this.log(`MCP server ${name}: All tools are suppressed, skipping`);
return null;
}
const plugins = [];
for (const tool of tools) {
plugins.push({
@ -238,5 +254,16 @@ class MCPCompatibilityLayer extends MCPHypervisor {
return `[Unserializable: ${e.message}]`;
}
}
/**
* Toggle tool suppression for an MCP server
* @param {string} serverName - The name of the MCP server
* @param {string} toolName - The name of the tool to toggle
* @param {boolean} enabled - Whether the tool should be enabled (true) or suppressed (false)
* @returns {Promise<{success: boolean, error: string | null, suppressedTools: string[]}>}
*/
async toggleToolSuppression(serverName, toolName, enabled) {
return this.updateSuppressedTools(serverName, toolName, enabled);
}
}
module.exports = MCPCompatibilityLayer;