import { useCallback, useMemo } from "react"; import { Button } from "@/components/ui/button"; import { DebugInspectorOAuthClientProvider } from "../lib/auth"; import { auth } from "@modelcontextprotocol/sdk/client/auth.js"; import { AlertCircle } from "lucide-react"; import { AuthDebuggerState } from "../lib/auth-types"; import { OAuthFlowProgress } from "./OAuthFlowProgress"; import { OAuthStateMachine } from "../lib/oauth-state-machine"; export interface AuthDebuggerProps { serverUrl: string; onBack: () => void; authState: AuthDebuggerState; updateAuthState: (updates: Partial) => void; } interface StatusMessageProps { message: { type: "error" | "success" | "info"; message: string }; } const StatusMessage = ({ message }: StatusMessageProps) => { let bgColor: string; let textColor: string; let borderColor: string; switch (message.type) { case "error": bgColor = "bg-red-50"; textColor = "text-red-700"; borderColor = "border-red-200"; break; case "success": bgColor = "bg-green-50"; textColor = "text-green-700"; borderColor = "border-green-200"; break; case "info": default: bgColor = "bg-blue-50"; textColor = "text-blue-700"; borderColor = "border-blue-200"; break; } return (

{message.message}

); }; const AuthDebugger = ({ serverUrl: serverUrl, onBack, authState, updateAuthState, }: AuthDebuggerProps) => { const startOAuthFlow = useCallback(() => { if (!serverUrl) { updateAuthState({ statusMessage: { type: "error", message: "Please enter a server URL in the sidebar before authenticating", }, }); return; } updateAuthState({ oauthStep: "metadata_discovery", authorizationUrl: null, statusMessage: null, latestError: null, }); }, [serverUrl, updateAuthState]); const stateMachine = useMemo( () => new OAuthStateMachine(serverUrl, updateAuthState), [serverUrl, updateAuthState], ); const proceedToNextStep = useCallback(async () => { if (!serverUrl) return; try { updateAuthState({ isInitiatingAuth: true, statusMessage: null, latestError: null, }); await stateMachine.executeStep(authState); } catch (error) { console.error("OAuth flow error:", error); updateAuthState({ latestError: error instanceof Error ? error : new Error(String(error)), }); } finally { updateAuthState({ isInitiatingAuth: false }); } }, [serverUrl, authState, updateAuthState, stateMachine]); const handleQuickOAuth = useCallback(async () => { if (!serverUrl) { updateAuthState({ statusMessage: { type: "error", message: "Please enter a server URL in the sidebar before authenticating", }, }); return; } updateAuthState({ isInitiatingAuth: true, statusMessage: null }); try { const serverAuthProvider = new DebugInspectorOAuthClientProvider( serverUrl, ); await auth(serverAuthProvider, { serverUrl: serverUrl }); updateAuthState({ statusMessage: { type: "info", message: "Starting OAuth authentication process...", }, }); } catch (error) { console.error("OAuth initialization error:", error); updateAuthState({ statusMessage: { type: "error", message: `Failed to start OAuth flow: ${error instanceof Error ? error.message : String(error)}`, }, }); } finally { updateAuthState({ isInitiatingAuth: false }); } }, [serverUrl, updateAuthState]); const handleClearOAuth = useCallback(() => { if (serverUrl) { const serverAuthProvider = new DebugInspectorOAuthClientProvider( serverUrl, ); serverAuthProvider.clear(); updateAuthState({ oauthTokens: null, oauthStep: "metadata_discovery", latestError: null, oauthClientInfo: null, authorizationCode: "", validationError: null, oauthMetadata: null, statusMessage: { type: "success", message: "OAuth tokens cleared successfully", }, }); // Clear success message after 3 seconds setTimeout(() => { updateAuthState({ statusMessage: null }); }, 3000); } }, [serverUrl, updateAuthState]); return (

Authentication Settings

Configure authentication settings for your MCP server connection.

OAuth Authentication

Use OAuth to securely authenticate with the MCP server.

{authState.statusMessage && ( )} {authState.loading ? (

Loading authentication status...

) : (
{authState.oauthTokens && (

Access Token:

{authState.oauthTokens.access_token.substring(0, 25)}...
)}

Choose "Guided" for step-by-step instructions or "Quick" for the standard automatic flow.

)}
); }; export default AuthDebugger;