diff --git a/apps/webapp/app/components/logs/virtual-logs-list.tsx b/apps/webapp/app/components/logs/virtual-logs-list.tsx index 9d294ff..ab3bf42 100644 --- a/apps/webapp/app/components/logs/virtual-logs-list.tsx +++ b/apps/webapp/app/components/logs/virtual-logs-list.tsx @@ -1,8 +1,6 @@ import { useEffect, useRef, useState } from "react"; import { - List, InfiniteLoader, - WindowScroller, AutoSizer, CellMeasurer, CellMeasurerCache, @@ -12,21 +10,15 @@ import { import { type LogItem } from "~/hooks/use-logs"; import { Badge } from "~/components/ui/badge"; import { Card, CardContent } from "~/components/ui/card"; -import { AlertCircle, ChevronDown, XCircle } from "lucide-react"; +import { AlertCircle } from "lucide-react"; import { cn } from "~/lib/utils"; import { ScrollManagedList } from "../virtualized-list"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogClose, -} from "../ui/dialog"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "../ui/dialog"; import { Button } from "../ui"; // --- LogTextCollapse component --- -function LogTextCollapse({ text }: { text?: string }) { +function LogTextCollapse({ text, error }: { text?: string; error?: string }) { const [dialogOpen, setDialogOpen] = useState(false); // Show collapse if text is long (by word count) @@ -52,38 +44,60 @@ function LogTextCollapse({ text }: { text?: string }) { } return ( -
-

+

+

+ {displayText} +

+ {isLong && ( + <> + + + + + Log Details + + +
+

+ {text} +

+
+
+
+ + )} +
+
- {displayText} -

- {isLong && ( - <> - - - - - Log Details - - -
-

- {text} -

-
-
-
- - )} -
+ {isLong && ( + + )} + {error && ( +
+ + + {error} + +
+ )} +
+ ); } @@ -169,26 +183,7 @@ function LogItemRenderer( - - -
-
- {log.processedAt && ( - - Processed: {new Date(log.processedAt).toLocaleString()} - - )} -
- - {log.error && ( -
- - - {log.error} - -
- )} -
+ diff --git a/packages/mcp-proxy/src/core/mcp-remote-client.ts b/packages/mcp-proxy/src/core/mcp-remote-client.ts index e525393..cbaf920 100644 --- a/packages/mcp-proxy/src/core/mcp-remote-client.ts +++ b/packages/mcp-proxy/src/core/mcp-remote-client.ts @@ -116,33 +116,8 @@ export function createMCPProxy( bridgeOptions ); - // Set up timeout - const timeoutId = config.timeout - ? setTimeout(() => { - bridge?.close().catch(console.error); - if (!resolve) return; - resolve( - new Response( - JSON.stringify({ - error: "Request timeout", - }), - { - status: 408, - headers: { "Content-Type": "application/json" }, - } - ) - ); - }, config.timeout) - : null; - // Start only the client transport (server is already started) await clientTransport.start(); - - // Clean up after a reasonable time (since HTTP is request/response) - setTimeout(() => { - if (timeoutId) clearTimeout(timeoutId); - bridge?.close().catch(console.error); - }, 1000); } catch (error) { console.error("MCP Transport Proxy Error:", error); @@ -186,32 +161,16 @@ export function createMCPProxy( // Create transport based on strategy (don't start yet) let transport: SSEClientTransport | StreamableHTTPClientTransport; - // For SSE, we need eventSourceInit for authentication - const eventSourceInit = { - fetch: (url: string | URL, init?: RequestInit) => { - return fetch(url, { - ...init, - headers: { - ...(init?.headers as Record | undefined), - ...headers, - Accept: "text/event-stream", - } as Record, - }); - }, - }; - switch (transportStrategy) { case "sse-only": transport = new SSEClientTransport(url, { authProvider, requestInit: { headers }, - eventSourceInit, }); break; case "http-only": transport = new StreamableHTTPClientTransport(url, { - authProvider, requestInit: { headers }, }); break; @@ -222,7 +181,6 @@ export function createMCPProxy( transport = new SSEClientTransport(url, { authProvider, requestInit: { headers }, - eventSourceInit, }); } catch (error) { console.warn("SSE transport failed, falling back to HTTP:", error); @@ -237,7 +195,6 @@ export function createMCPProxy( // Try HTTP first, fallback to SSE on error try { transport = new StreamableHTTPClientTransport(url, { - authProvider, requestInit: { headers }, }); } catch (error) { @@ -245,7 +202,6 @@ export function createMCPProxy( transport = new SSEClientTransport(url, { authProvider, requestInit: { headers }, - eventSourceInit, }); } break; diff --git a/packages/mcp-proxy/src/utils/mcp-transport-bridge.ts b/packages/mcp-proxy/src/utils/mcp-transport-bridge.ts index 57ed266..c341790 100644 --- a/packages/mcp-proxy/src/utils/mcp-transport-bridge.ts +++ b/packages/mcp-proxy/src/utils/mcp-transport-bridge.ts @@ -9,8 +9,8 @@ export function createMCPTransportBridge( serverTransport: Transport, options: { debug?: boolean; - onMessage?: (direction: 'client-to-server' | 'server-to-client', message: any) => void; - onError?: (error: Error, source: 'client' | 'server') => void; + onMessage?: (direction: "client-to-server" | "server-to-client", message: any) => void; + onError?: (error: Error, source: "client" | "server") => void; } = {} ) { let clientClosed = false; @@ -23,23 +23,25 @@ export function createMCPTransportBridge( // Forward messages from client to server clientTransport.onmessage = (message: any) => { - log('[Client→Server]', message.method || message.id); - onMessage?.('client-to-server', message); - - serverTransport.send(message).catch(error => { - logError('Error sending to server:', error); - onError?.(error, 'server'); + console.log(JSON.stringify(message)); + log("[Client→Server]", message.method || message.id); + onMessage?.("client-to-server", message); + + serverTransport.send(message).catch((error) => { + logError("Error sending to server:", error); + onError?.(error, "server"); }); }; // Forward messages from server to client serverTransport.onmessage = (message: any) => { - log('[Server→Client]', message.method || message.id); - onMessage?.('server-to-client', message); - - clientTransport.send(message).catch(error => { - logError('Error sending to client:', error); - onError?.(error, 'client'); + console.log(JSON.stringify(message)); + log("[Server→Client]", message.method || message.id); + onMessage?.("server-to-client", message); + + clientTransport.send(message).catch((error) => { + logError("Error sending to client:", error); + onError?.(error, "client"); }); }; @@ -47,30 +49,30 @@ export function createMCPTransportBridge( clientTransport.onclose = () => { if (serverClosed) return; clientClosed = true; - log('Client transport closed, closing server transport'); - serverTransport.close().catch(error => { - logError('Error closing server transport:', error); + log("Client transport closed, closing server transport"); + serverTransport.close().catch((error) => { + logError("Error closing server transport:", error); }); }; serverTransport.onclose = () => { if (clientClosed) return; serverClosed = true; - log('Server transport closed, closing client transport'); - clientTransport.close().catch(error => { - logError('Error closing client transport:', error); + log("Server transport closed, closing client transport"); + clientTransport.close().catch((error) => { + logError("Error closing client transport:", error); }); }; // Error handling clientTransport.onerror = (error: Error) => { - logError('Client transport error:', error); - onError?.(error, 'client'); + logError("Client transport error:", error); + onError?.(error, "client"); }; serverTransport.onerror = (error: Error) => { - logError('Server transport error:', error); - onError?.(error, 'server'); + logError("Server transport error:", error); + onError?.(error, "server"); }; return { @@ -79,13 +81,10 @@ export function createMCPTransportBridge( */ start: async () => { try { - await Promise.all([ - clientTransport.start(), - serverTransport.start() - ]); - log('MCP transport bridge started successfully'); + await Promise.all([clientTransport.start(), serverTransport.start()]); + log("MCP transport bridge started successfully"); } catch (error) { - logError('Error starting transport bridge:', error); + logError("Error starting transport bridge:", error); throw error; } }, @@ -95,13 +94,10 @@ export function createMCPTransportBridge( */ close: async () => { try { - await Promise.all([ - clientTransport.close(), - serverTransport.close() - ]); - log('MCP transport bridge closed successfully'); + await Promise.all([clientTransport.close(), serverTransport.close()]); + log("MCP transport bridge closed successfully"); } catch (error) { - logError('Error closing transport bridge:', error); + logError("Error closing transport bridge:", error); throw error; } }, @@ -111,6 +107,6 @@ export function createMCPTransportBridge( */ get isClosed() { return clientClosed || serverClosed; - } + }, }; -} \ No newline at end of file +} diff --git a/packages/mcp-proxy/src/utils/mcp-transport.ts b/packages/mcp-proxy/src/utils/mcp-transport.ts index ed5d9e4..bbac32d 100644 --- a/packages/mcp-proxy/src/utils/mcp-transport.ts +++ b/packages/mcp-proxy/src/utils/mcp-transport.ts @@ -83,5 +83,7 @@ export class RemixMCPTransport implements Transport { onmessage: (message: any) => void = () => {}; onclose: () => void = () => {}; - onerror: (error: Error) => void = () => {}; + async onerror(error: Error) { + console.log(error); + } }