Add httpOnly option to disable SSE fallback for debugging

- Added httpOnly option to UseMcpOptions to skip SSE fallback
- Updated all HTTP transport failure paths to respect httpOnly flag
- Temporarily enabled httpOnly in chat UI for streamable HTTP debugging
- Updated AGENT.md to require frequent commits after changes
This commit is contained in:
Glen Maddern 2025-06-24 22:28:37 +10:00
commit 03d95e70b7
4 changed files with 19 additions and 1 deletions

View file

@ -27,6 +27,10 @@
- Log errors with appropriate levels (debug, info, warn, error)
- Defensive error handling with specific error types when available
## Development Workflow
- **Commit changes frequently** after each logical change or debugging step
- Use descriptive commit messages that explain what was changed and why
### React Patterns
- Use React hooks with useRef for mutable values
- Stable callbacks with useCallback and appropriate dependencies

View file

@ -23,6 +23,7 @@ function McpConnection({
debug: true,
autoRetry: false,
popupFeatures: 'width=500,height=600,resizable=yes,scrollbars=yes',
httpOnly: true, // DEBUG: Only try HTTP transport, no SSE fallback
})
// Update parent component with connection data

View file

@ -26,6 +26,8 @@ export type UseMcpOptions = {
autoReconnect?: boolean | number
/** Popup window features string (dimensions and behavior) for OAuth */
popupFeatures?: string
/** Only try HTTP transport, don't fallback to SSE (useful for debugging) */
httpOnly?: boolean
}
export type UseMcpResult = {

View file

@ -30,6 +30,7 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
debug = false,
autoRetry = false,
autoReconnect = DEFAULT_RECONNECT_DELAY,
httpOnly = false,
} = options
const [state, setState] = useState<UseMcpResult['state']>('discovering')
@ -314,6 +315,11 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
errorMessage === 'Load failed' /* Safari */
if (transportType === 'http' && (is404 || is405 || isLikelyCors)) {
if (httpOnly) {
addLog('warn', `HTTP transport failed (${isLikelyCors ? 'CORS' : is404 ? '404' : '405'}). httpOnly=true, no fallback.`)
failConnection(`HTTP transport failed: ${isLikelyCors ? 'CORS' : is404 ? '404' : '405'}`, errorInstance)
return 'failed'
}
addLog('warn', `HTTP transport failed (${isLikelyCors ? 'CORS' : is404 ? '404' : '405'}). Will attempt fallback to SSE.`)
return 'fallback' // Signal that fallback should be attempted
}
@ -355,7 +361,7 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current)
addLog('error', 'Auth flow failed:', sdkAuthError)
// Auth failed, but still allow fallback to SSE
if (transportType === 'http') {
if (transportType === 'http' && !httpOnly) {
return 'fallback' // Try SSE even after auth failure
} else {
failConnection(
@ -371,6 +377,11 @@ export function useMcp(options: UseMcpOptions): UseMcpResult {
// Don't call failConnection here for HTTP transport - let orchestration handle it
// so that SSE fallback can still be attempted
if (transportType === 'http') {
if (httpOnly) {
addLog('warn', `HTTP transport failed: ${errorMessage}. httpOnly=true, no fallback.`)
failConnection(`HTTP transport failed: ${errorMessage}`, errorInstance)
return 'failed'
}
addLog('warn', `HTTP transport failed: ${errorMessage}. Will attempt fallback to SSE.`)
return 'fallback'
} else {