From be0e840333f3552f25c0a2852a35e9a562b95db6 Mon Sep 17 00:00:00 2001 From: Manoj Aggarwal Date: Fri, 16 Jan 2026 11:44:10 -0800 Subject: [PATCH] consolidate list of mcp tools in the success box --- .../components/mcp-connect-form.tsx | 171 +++++++++++------- .../components/mcp-config.tsx | 54 ++++-- 2 files changed, 146 insertions(+), 79 deletions(-) diff --git a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/mcp-connect-form.tsx b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/mcp-connect-form.tsx index 34a07c6f5..6bfb5c883 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/mcp-connect-form.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connect-forms/components/mcp-connect-form.tsx @@ -1,6 +1,6 @@ "use client"; -import { CheckCircle2, Server, XCircle } from "lucide-react"; +import { CheckCircle2, ChevronDown, ChevronUp, Server, XCircle } from "lucide-react"; import { type FC, useRef, useState } from "react"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { Button } from "@/components/ui/button"; @@ -30,12 +30,13 @@ export const MCPConnectForm: FC = ({ onSubmit, isSubmitting }) const [configJson, setConfigJson] = useState(DEFAULT_CONFIG); const [jsonError, setJsonError] = useState(null); const [isTesting, setIsTesting] = useState(false); - const [testResults, setTestResults] = useState | null>(null); + errors?: string[]; + } | null>(null); const parseConfigs = (): { configs: MCPServerWithName[] | null; error: string | null } => { try { @@ -105,44 +106,56 @@ export const MCPConnectForm: FC = ({ onSubmit, isSubmitting }) if (!configs || error) { setJsonError(error); - setTestResults([{ - name: "Parse Error", + setTestResult({ status: "error", message: error || "Invalid configuration", tools: [], - }]); + }); return; } setIsTesting(true); - setTestResults(null); + setTestResult(null); setJsonError(null); - const results: Array<{ - name: string; - status: "success" | "error"; - message: string; - tools: MCPToolDefinition[]; - }> = []; + const allTools: MCPToolDefinition[] = []; + const errors: string[] = []; for (const config of configs) { try { const result = await connectorsApiService.testMCPConnection(config); - results.push({ - name: config.name, - ...result, - }); + if (result.status === "success") { + allTools.push(...result.tools); + } else { + errors.push(`${config.name}: ${result.message}`); + } } catch (error) { - results.push({ - name: config.name, - status: "error", - message: error instanceof Error ? error.message : "Failed to connect to MCP server", - tools: [], - }); + errors.push(`${config.name}: ${error instanceof Error ? error.message : "Failed to connect"}`); } } - setTestResults(results); + if (errors.length === 0) { + setTestResult({ + status: "success", + message: `Successfully connected to ${configs.length} server${configs.length !== 1 ? 's' : ''}. Found ${allTools.length} tool${allTools.length !== 1 ? 's' : ''}.`, + tools: allTools, + }); + } else if (allTools.length > 0) { + setTestResult({ + status: "success", + message: `Partially successful. Connected ${allTools.length} tool${allTools.length !== 1 ? 's' : ''}.`, + tools: allTools, + errors, + }); + } else { + setTestResult({ + status: "error", + message: "Failed to connect to all servers", + tools: [], + errors, + }); + } + setIsTesting(false); }; @@ -226,47 +239,75 @@ export const MCPConnectForm: FC = ({ onSubmit, isSubmitting }) - {testResults && testResults.length > 0 && ( -
- {testResults.map((result, index) => ( - - {result.status === "success" ? ( - - ) : ( - - )} -
- - {result.name}: {result.status === "success" ? "Connected" : "Failed"} - - - {result.message} - {result.status === "success" && result.tools.length > 0 && ( -
-

- Found {result.tools.length} tools: -

-
    - {result.tools.map((tool, i) => ( -
  • - {tool.name}: {tool.description} -
  • - ))} -
-
+ {testResult && ( + + {testResult.status === "success" ? ( + + ) : ( + + )} +
+
+ + {testResult.status === "success" ? "Connection Successful" : "Connection Failed"} + + {testResult.tools.length > 0 && ( +
- - ))} -
+ + )} +
+ + {testResult.message} + {testResult.errors && testResult.errors.length > 0 && ( +
+

Errors:

+ {testResult.errors.map((err, i) => ( +
• {err}
+ ))} +
+ )} + {showDetails && testResult.tools.length > 0 && ( +
+

+ Available tools: +

+
    + {testResult.tools.map((tool, i) => ( +
  • {tool.name}
  • + ))} +
+
+ )} +
+
+ )} diff --git a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/mcp-config.tsx b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/mcp-config.tsx index a8618aeaf..dcd20cefd 100644 --- a/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/mcp-config.tsx +++ b/surfsense_web/components/assistant-ui/connector-popup/connector-configs/components/mcp-config.tsx @@ -1,6 +1,6 @@ "use client"; -import { CheckCircle2, Server, XCircle } from "lucide-react"; +import { CheckCircle2, ChevronDown, ChevronUp, Server, XCircle } from "lucide-react"; import type { FC } from "react"; import { useEffect, useState } from "react"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; @@ -23,6 +23,7 @@ export const MCPConfig: FC = ({ connector, onConfigChange, onNam const [configJson, setConfigJson] = useState(""); const [jsonError, setJsonError] = useState(null); const [isTesting, setIsTesting] = useState(false); + const [showDetails, setShowDetails] = useState(false); const [testResult, setTestResult] = useState<{ status: "success" | "error"; message: string; @@ -283,22 +284,47 @@ export const MCPConfig: FC = ({ connector, onConfigChange, onNam ) : ( )} -
- - {testResult.status === "success" ? "Connection Successful" : "Connection Failed"} - - +
+
+ + {testResult.status === "success" ? "Connection Successful" : "Connection Failed"} + + {testResult.tools.length > 0 && ( + + )} +
+ {testResult.message} - {testResult.status === "success" && testResult.tools.length > 0 && ( -
-

- Found {testResult.tools.length} tools: + {showDetails && testResult.status === "success" && testResult.tools.length > 0 && ( +

+

+ Found {testResult.tools.length} tool{testResult.tools.length !== 1 ? 's' : ''}:

-
    +
      {testResult.tools.map((tool, i) => ( -
    • - {tool.name}: {tool.description} -
    • +
    • {tool.name}
    • ))}