= ({ accessToken, selectedServers, onChange
{name}
{detailServer.description ?? "MCP server"}
- {detailServer.auth_type === AUTH_TYPE.OAUTH2 ? (
- oauthConnected.has(detailServer.server_id) ? (
+ {isAutoConnectedAuthType(detailServer.auth_type) && (
+
+
+ Connected via your organization sign-in
+
+ )}
+ {!isAutoConnectedAuthType(detailServer.auth_type) &&
+ (detailServer.auth_type === AUTH_TYPE.OAUTH2 ? (
+ oauthConnected.has(detailServer.server_id) ? (
+
+ ) : (
+ {
+ setOauthConnected((prev) => new Set(prev).add(id));
+ }}
+ variant="button"
+ />
+ )
+ ) : (
- ) : (
- {
- setOauthConnected((prev) => new Set(prev).add(id));
- }}
- variant="button"
- />
- )
- ) : (
-
- )}
+ ))}
Information
@@ -513,22 +520,32 @@ const MCPAppsPanel: React.FC = ({ accessToken, selectedServers, onChange
) : null}
- {server.auth_type === AUTH_TYPE.OAUTH2 ? (
- oauthConnected.has(server.server_id) ? (
-
- ) : (
- {
- setOauthConnected((prev) => new Set(prev).add(id));
- }}
- variant="badge"
- />
- )
- ) : isConnected ? (
-
- ) : null}
+ {(() => {
+ if (isAutoConnectedAuthType(server.auth_type)) {
+ return ;
+ }
+ if (server.auth_type === AUTH_TYPE.OAUTH2) {
+ if (oauthConnected.has(server.server_id)) {
+ return ;
+ }
+ return (
+ {
+ setOauthConnected((prev) => new Set(prev).add(id));
+ }}
+ variant="badge"
+ />
+ );
+ }
+ if (isConnected) {
+ return (
+
+ );
+ }
+ return null;
+ })()}
);
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx b/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx
index 7ce803d583c..bdc4840091a 100644
--- a/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_tools/types.test.tsx
@@ -231,3 +231,19 @@ describe("credentialAuthClass", () => {
expect(credentialAuthClass(null)).toBeNull();
});
});
+
+describe("id_jag auth type", () => {
+ it("classifies oauth2_id_jag as the id_jag oauth mode", async () => {
+ const { getMcpOAuthMode, AUTH_TYPE } = await import("./types");
+ expect(getMcpOAuthMode({ auth_type: AUTH_TYPE.OAUTH2_ID_JAG })).toBe("id_jag");
+ });
+
+ it("auto-connects only oauth2_id_jag servers in the Apps grid", async () => {
+ const { isAutoConnectedAuthType, AUTH_TYPE } = await import("./types");
+ expect(isAutoConnectedAuthType(AUTH_TYPE.OAUTH2_ID_JAG)).toBe(true);
+ expect(isAutoConnectedAuthType(AUTH_TYPE.OAUTH2)).toBe(false);
+ expect(isAutoConnectedAuthType(AUTH_TYPE.OAUTH2_TOKEN_EXCHANGE)).toBe(false);
+ expect(isAutoConnectedAuthType(null)).toBe(false);
+ expect(isAutoConnectedAuthType(undefined)).toBe(false);
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/mcp_tools/types.tsx b/ui/litellm-dashboard/src/components/mcp_tools/types.tsx
index dd7ed2bfbe4..497ce24cab2 100644
--- a/ui/litellm-dashboard/src/components/mcp_tools/types.tsx
+++ b/ui/litellm-dashboard/src/components/mcp_tools/types.tsx
@@ -40,6 +40,7 @@ export const AUTH_TYPE = {
BASIC: "basic",
OAUTH2: "oauth2",
OAUTH2_TOKEN_EXCHANGE: "oauth2_token_exchange",
+ OAUTH2_ID_JAG: "oauth2_id_jag",
AWS_SIGV4: "aws_sigv4",
TRUE_PASSTHROUGH: "true_passthrough",
OAUTH_DELEGATE: "oauth_delegate",
@@ -161,7 +162,14 @@ export const MCP_OAUTH2_FLOW_M2M = "client_credentials";
export const MCP_OAUTH2_FLOW_INTERACTIVE = "authorization_code";
-export type McpOAuthMode = "m2m" | "passthrough" | "authorization_code" | "token_exchange";
+export type McpOAuthMode = "m2m" | "passthrough" | "authorization_code" | "token_exchange" | "id_jag";
+
+/** Enterprise-managed authorization: the user's one SSO login is the only interaction, tokens
+ * mint via back-channel exchange, so the Apps grid renders these servers as already connected
+ * with no connect affordance. */
+export function isAutoConnectedAuthType(authType?: string | null): boolean {
+ return authType === AUTH_TYPE.OAUTH2_ID_JAG;
+}
// Classify an OAuth MCP server into the mode that decides how the tool list is
// authenticated. token_exchange (RFC 8693 / OBO) is its own auth_type
@@ -180,6 +188,7 @@ export function getMcpOAuthMode(s: {
delegate_auth_to_upstream?: boolean | null;
}): McpOAuthMode | null {
if (s.auth_type === AUTH_TYPE.OAUTH2_TOKEN_EXCHANGE) return "token_exchange";
+ if (s.auth_type === AUTH_TYPE.OAUTH2_ID_JAG) return "id_jag";
if (s.auth_type !== AUTH_TYPE.OAUTH2) return null;
if (s.oauth2_flow === MCP_OAUTH2_FLOW_M2M) return "m2m";
return s.delegate_auth_to_upstream ? "passthrough" : "authorization_code";