Reworking auth flow. Still buggy.

'auto' now works for http servers, sse needs 'sse' setting.
This commit is contained in:
Glen Maddern 2025-06-27 22:25:45 +10:00
commit effb28af19
2 changed files with 14 additions and 30 deletions

View file

@ -10,6 +10,7 @@ function McpConnection({ serverUrl, onConnectionUpdate }: { serverUrl: string; o
debug: true, debug: true,
autoRetry: false, autoRetry: false,
popupFeatures: 'width=500,height=600,resizable=yes,scrollbars=yes', popupFeatures: 'width=500,height=600,resizable=yes,scrollbars=yes',
transportType: 'auto'
}) })
// Update parent component with connection data // Update parent component with connection data

View file

@ -359,37 +359,27 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
} catch (sdkAuthError) { } catch (sdkAuthError) {
if (!isMountedRef.current) return 'failed' if (!isMountedRef.current) return 'failed'
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current) if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current)
addLog('error', 'Auth flow failed:', sdkAuthError) // Use stable failConnection
// Auth failed, but still allow fallback to SSE failConnection(
if (transportType === 'http') { `Failed to initiate authentication: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
return 'fallback' // Try SSE even after auth failure sdkAuthError instanceof Error ? sdkAuthError : undefined,
} else { )
failConnection( return 'failed' // Auth initiation failed
`Failed to initiate authentication: ${sdkAuthError instanceof Error ? sdkAuthError.message : String(sdkAuthError)}`,
sdkAuthError instanceof Error ? sdkAuthError : undefined,
)
return 'failed' // Auth initiation failed for SSE
}
} }
} }
// Handle other connection errors // Handle other connection errors
// Don't call failConnection here for HTTP transport - let orchestration handle it // Use stable failConnection
// so that SSE fallback can still be attempted failConnection(`Failed to connect via ${transportType.toUpperCase()}: ${errorMessage}`, errorInstance)
if (transportType === 'http') { return 'fallback' // If our logic above is wrong, we'd prevent HTTPs servers from ever working. So always fall back as a last resort.
addLog('warn', `HTTP transport failed: ${errorMessage}.`)
return 'fallback'
} else {
// For SSE transport, we can fail immediately since there's no further fallback
failConnection(`Failed to connect via ${transportType.toUpperCase()}: ${errorMessage}`, errorInstance)
return 'failed'
}
} }
} // End of tryConnectWithTransport helper } // End of tryConnectWithTransport helper
// --- Orchestrate Connection Attempts --- // --- Orchestrate Connection Attempts ---
let finalStatus: 'success' | 'auth_redirect' | 'failed' | 'fallback' = 'failed' // Default to failed let finalStatus: 'success' | 'auth_redirect' | 'failed' | 'fallback' = 'failed' // Default to failed
console.log({transportType})
if (transportType === 'sse') { if (transportType === 'sse') {
// SSE only - skip HTTP entirely // SSE only - skip HTTP entirely
addLog('debug', 'Using SSE-only transport mode') addLog('debug', 'Using SSE-only transport mode')
@ -402,9 +392,8 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
// Auto mode - try HTTP first, fallback to SSE // Auto mode - try HTTP first, fallback to SSE
addLog('debug', 'Using auto transport mode (HTTP with SSE fallback)') addLog('debug', 'Using auto transport mode (HTTP with SSE fallback)')
const httpResult = await tryConnectWithTransport('http') const httpResult = await tryConnectWithTransport('http')
// 2. Try SSE only if HTTP requested fallback and we haven't failed/redirected
// Try SSE only if HTTP requested fallback and we haven't redirected if (httpResult === 'fallback' && isMountedRef.current && stateRef.current !== 'failed' && stateRef.current !== 'authenticating') {
if (httpResult === 'fallback' && isMountedRef.current && stateRef.current !== 'authenticating') {
const sseResult = await tryConnectWithTransport('sse') const sseResult = await tryConnectWithTransport('sse')
finalStatus = sseResult // Use SSE result as final status finalStatus = sseResult // Use SSE result as final status
} else { } else {
@ -412,12 +401,6 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
} }
} }
// If we still have 'fallback' status, convert to 'failed' since no more transports to try
if (finalStatus === 'fallback') {
finalStatus = 'failed'
failConnection('All transport methods failed')
}
// --- Finalize Connection State --- // --- Finalize Connection State ---
// Set connectingRef based on the final outcome. // Set connectingRef based on the final outcome.
// It should be false if 'success' or 'failed'. // It should be false if 'success' or 'failed'.