From fe65d50ec3ebaed63a976d544dad24c98f1dbd06 Mon Sep 17 00:00:00 2001 From: Glen Maddern Date: Tue, 1 Jul 2025 12:14:32 +1000 Subject: [PATCH] Fixing /sse support (#12) * /sse still not working * Add transport type selector to inspector UI and comprehensive transport testing - Add transport type dropdown to inspector UI (auto, HTTP, SSE) with session storage persistence - Update test framework to support transport type selection in test scenarios - Add comprehensive test cases covering: * Working /mcp endpoints with auto and HTTP transports * SSE endpoint with SSE transport (expected to pass) * SSE endpoint with auto transport (expected to fail - demonstrates current fallback issue) - Test structure now provides clear visibility into transport-specific behavior - All tests properly named and categorized for easy identification of failing scenarios * Gearing up to "make amp do it" * fix: improve SSE fallback logic in auto transport mode - Fix issue where SSE fallback was not attempted when HTTP transport failed - Specific error types (404, 405, CORS) now correctly trigger SSE fallback - Allow SSE fallback even when component state is 'failed' from previous attempts - Maintain proper error handling for non-fallback HTTP errors - All 6 transport scenarios now pass integration tests The core issue was that failConnection() was being called for HTTP errors before returning 'fallback', which set the component state to 'failed' and prevented the orchestration logic from attempting SSE fallback. Now only specific HTTP errors that should trigger fallback avoid calling failConnection immediately, allowing the SSE transport to be attempted as expected. --------- Co-authored-by: Glen Maddern --- .../inspector/src/components/McpServers.tsx | 31 +++++++++-- examples/inspector/vite.config.ts | 4 +- src/react/useMcp.ts | 17 ++++-- test/integration/mcp-connection.test.ts | 54 +++++++++++++++---- test/setup/global-setup.ts | 5 +- 5 files changed, 91 insertions(+), 20 deletions(-) diff --git a/examples/inspector/src/components/McpServers.tsx b/examples/inspector/src/components/McpServers.tsx index e210e34..b99160d 100644 --- a/examples/inspector/src/components/McpServers.tsx +++ b/examples/inspector/src/components/McpServers.tsx @@ -3,14 +3,22 @@ import { useMcp, type Tool } from 'use-mcp/react' import { Info, X, ChevronRight, ChevronDown } from 'lucide-react' // MCP Connection wrapper that only renders when active -function McpConnection({ serverUrl, onConnectionUpdate }: { serverUrl: string; onConnectionUpdate: (data: any) => void }) { +function McpConnection({ + serverUrl, + transportType, + onConnectionUpdate, +}: { + serverUrl: string + transportType: 'auto' | 'http' | 'sse' + onConnectionUpdate: (data: any) => void +}) { // Use the MCP hook with the server URL const connection = useMcp({ url: serverUrl, debug: true, autoRetry: false, popupFeatures: 'width=500,height=600,resizable=yes,scrollbars=yes', - transportType: 'auto', + transportType, }) // Update parent component with connection data @@ -26,6 +34,9 @@ export function McpServers({ onToolsUpdate }: { onToolsUpdate?: (tools: Tool[]) const [serverUrl, setServerUrl] = useState(() => { return sessionStorage.getItem('mcpServerUrl') || '' }) + const [transportType, setTransportType] = useState<'auto' | 'http' | 'sse'>(() => { + return (sessionStorage.getItem('mcpTransportType') as 'auto' | 'http' | 'sse') || 'auto' + }) const [isActive, setIsActive] = useState(false) const [connectionData, setConnectionData] = useState({ @@ -293,6 +304,20 @@ export function McpServers({ onToolsUpdate }: { onToolsUpdate?: (tools: Tool[]) }} disabled={isActive && state !== 'failed'} /> + {state === 'ready' || (isActive && state !== 'not-connected' && state !== 'failed') ? (