From 6f0f895b5b959f8ae3b0b8f22f44382a62952bf2 Mon Sep 17 00:00:00 2001 From: Tin Chi Lo Date: Mon, 15 Jun 2026 16:15:49 -0700 Subject: [PATCH] feat(ui): add Integrations tab to MCP server view with Claude Cowork connect URL Adds an Integrations tab between MCP Tools and Settings on the MCP server detail page, visible to all users. It surfaces a copyable Claude Cowork connect URL built from getProxyBaseUrl and the server alias or name. When delegate_auth_to_upstream is true, it also shows a Dynamic Client Registration note so the user knows to leave auth fields empty. Bumps the post-OAuth-edit redirect tab index from 2 to 3 since inserting Integrations at index 2 shifts Settings to 3. --- .../components/mcp_tools/mcp_server_view.tsx | 49 ++++++++++++++++++- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_view.tsx b/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_view.tsx index 3ee5676235a..93fa99291fc 100644 --- a/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_view.tsx +++ b/ui/litellm-dashboard/src/components/mcp_tools/mcp_server_view.tsx @@ -9,6 +9,7 @@ import MCPServerEdit, { EDIT_OAUTH_UI_STATE_KEY } from "./mcp_server_edit"; import { getSecureItem } from "@/utils/secureStorage"; import MCPServerCostDisplay from "./mcp_server_cost_display"; import { getMaskedAndFullUrl } from "./utils"; +import { getProxyBaseUrl } from "@/components/networking"; import { copyToClipboard as utilCopyToClipboard } from "@/utils/dataUtils"; import { CheckIcon, CopyIcon } from "lucide-react"; import { Button as AntdButton } from "antd"; @@ -55,12 +56,12 @@ export const MCPServerView: React.FC = ({ initialTabIndex = 0, }) => { // Open the editing Settings tab on first render when returning from the edit OAuth - // redirect, so the "token fetched" feedback shows where the user left off (Settings=2). + // redirect, so the "token fetched" feedback shows where the user left off (Settings=3). const returningFromEditOAuth = isReturningFromEditOAuth(isProxyAdmin, mcpServer.server_id); const [editing, setEditing] = useState(isEditing || returningFromEditOAuth); const [showFullUrl, setShowFullUrl] = useState(false); const [copiedStates, setCopiedStates] = useState>({}); - const [selectedTabIndex, setSelectedTabIndex] = useState(returningFromEditOAuth ? 2 : initialTabIndex); + const [selectedTabIndex, setSelectedTabIndex] = useState(returningFromEditOAuth ? 3 : initialTabIndex); const handleSuccess = (updated: MCPServer) => { setEditing(false); @@ -70,6 +71,10 @@ export const MCPServerView: React.FC = ({ const urlValue = mcpServer.url ?? ""; const { maskedUrl, hasToken } = urlValue ? getMaskedAndFullUrl(urlValue) : { maskedUrl: "—", hasToken: false }; + const coworkServerIdentifier = mcpServer.alias || mcpServer.server_name || mcpServer.server_id; + const coworkUrl = `${getProxyBaseUrl()}/${coworkServerIdentifier}/mcp`; + const isUpstreamDelegated = mcpServer.delegate_auth_to_upstream === true; + const renderUrlWithToggle = (url: string | null | undefined, showFull: boolean) => { if (!url) return "—"; if (!hasToken) return url; @@ -151,6 +156,7 @@ export const MCPServerView: React.FC = ({ {[ Overview, MCP Tools, + Integrations, ...(isProxyAdmin ? [Settings] : []), ]} @@ -219,6 +225,45 @@ export const MCPServerView: React.FC = ({ /> + {/* Integrations Panel */} + + + Claude Cowork + + Add this MCP server to Claude Cowork by pasting the URL below into the connector setup. + + +
+ Server URL +
+ {coworkUrl} + : } + onClick={() => copyToClipboard(coworkUrl, "mcp-cowork-url")} + className={`transition-all duration-200 ${ + copiedStates["mcp-cowork-url"] + ? "text-green-600 bg-green-50 border-green-200" + : "text-gray-400 hover:text-gray-600 hover:bg-gray-100" + }`} + /> +
+
+ + {isUpstreamDelegated && ( +
+ OAuth: Dynamic Client Registration + + This server delegates authentication upstream, so Claude Cowork completes the OAuth flow directly + with the provider through Dynamic Client Registration. Leave the auth fields empty; no LiteLLM key + header is needed. + +
+ )} +
+
+ {/* Settings Panel */}