]> git.djapps.eu Git - pkg/ggml/sources/llama.cpp/commitdiff
UI : fix SSE transport detection and routing through CORS proxy. Assi… (#24500)
authorHarapan Rachman <redacted>
Wed, 17 Jun 2026 06:26:30 +0000 (13:26 +0700)
committerGitHub <redacted>
Wed, 17 Jun 2026 06:26:30 +0000 (08:26 +0200)
* UI : fix SSE transport detection and routing through CORS proxy. Assisted-by: Antigravity

* ui : replace magic strings with constants in MCP transport handling

tools/ui/src/lib/constants/mcp.ts
tools/ui/src/lib/services/mcp.service.ts
tools/ui/src/lib/utils/mcp.ts

index 918eb9f94b774ea94ab7230a888f26d32f444329..5b11f989e20b1163db3f9cef94207a48b7aaf2c2 100644 (file)
@@ -84,3 +84,8 @@ export const MCP_TRANSPORT_ICONS: Record<MCPTransportType, Component> = {
        [MCPTransportType.STREAMABLE_HTTP]: Globe,
        [MCPTransportType.SSE]: Radio
 };
+
+/** Standard SSE endpoint path indicators */
+export const MCP_SSE_ENDPOINT = '/sse';
+export const MCP_SSE_ENDPOINT_SLASH = '/sse/';
+export const MCP_SSE_ENDPOINT_QUERY = '/sse?';
index d596381aa055c3e53256a85a2a950d64f0d1f845..0aa58dc5d80c7106a6231e12931b4190d0c1fb20 100644 (file)
@@ -16,7 +16,8 @@ import {
        DEFAULT_MCP_CONFIG,
        DEFAULT_CLIENT_VERSION,
        DEFAULT_IMAGE_MIME_TYPE,
-       MCP_PARTIAL_REDACT_HEADERS
+       MCP_PARTIAL_REDACT_HEADERS,
+       CORS_PROXY_ENDPOINT
 } from '$lib/constants';
 import {
        MCPConnectionPhase,
@@ -236,6 +237,36 @@ export class MCPService {
 
                return {
                        fetch: async (input, init) => {
+                               if (useProxy && typeof window !== 'undefined') {
+                                       let requestUrlStr = '';
+                                       if (typeof input === 'string') {
+                                               requestUrlStr = input;
+                                       } else if (input instanceof URL) {
+                                               requestUrlStr = input.href;
+                                       }
+
+                                       if (requestUrlStr) {
+                                               const parsedRequestUrl = new URL(requestUrlStr, window.location.origin);
+                                               if (
+                                                       parsedRequestUrl.origin === window.location.origin &&
+                                                       !parsedRequestUrl.pathname.includes(CORS_PROXY_ENDPOINT)
+                                               ) {
+                                                       const originalConfigUrl = new URL(config.url);
+                                                       const realTargetUrl = new URL(
+                                                               parsedRequestUrl.pathname + parsedRequestUrl.search,
+                                                               originalConfigUrl.origin
+                                                       );
+                                                       const proxiedUrl = buildProxiedUrl(realTargetUrl.href);
+
+                                                       if (typeof input === 'string') {
+                                                               input = proxiedUrl.href;
+                                                       } else if (input instanceof URL) {
+                                                               input = proxiedUrl;
+                                                       }
+                                               }
+                                       }
+                               }
+
                                const startedAt = performance.now();
                                const requestHeaders = new Headers(baseInit.headers);
 
@@ -403,6 +434,32 @@ export class MCPService {
                        };
                }
 
+               if (config.transport === MCPTransportType.SSE) {
+                       const url = useProxy ? buildProxiedUrl(config.url) : new URL(config.url);
+                       const { fetch: diagnosticFetch, disable: stopPhaseLogging } = this.createDiagnosticFetch(
+                               serverName,
+                               config,
+                               requestInit,
+                               url,
+                               useProxy,
+                               onLog
+                       );
+
+                       if (import.meta.env.DEV && import.meta.env.VITE_DEBUG) {
+                               console.log(`[MCPService] Creating SSE transport for ${url.href}`);
+                       }
+
+                       return {
+                               transport: new SSEClientTransport(url, {
+                                       requestInit,
+                                       fetch: diagnosticFetch,
+                                       eventSourceInit: { fetch: diagnosticFetch }
+                               }),
+                               type: MCPTransportType.SSE,
+                               stopPhaseLogging
+                       };
+               }
+
                const url = useProxy ? buildProxiedUrl(config.url) : new URL(config.url);
                const { fetch: diagnosticFetch, disable: stopPhaseLogging } = this.createDiagnosticFetch(
                        serverName,
index 05fe90048f0b2f265d805e6115846527be73b465..7ce7f19fe98d2025de9e1524f2ce063c361b21d1 100644 (file)
@@ -19,7 +19,10 @@ import {
        DISPLAY_NAME_SEPARATOR_REGEX,
        PATH_SEPARATOR,
        RESOURCE_TEXT_CONTENT_SEPARATOR,
-       DEFAULT_RESOURCE_FILENAME
+       DEFAULT_RESOURCE_FILENAME,
+       MCP_SSE_ENDPOINT,
+       MCP_SSE_ENDPOINT_SLASH,
+       MCP_SSE_ENDPOINT_QUERY
 } from '$lib/constants';
 import {
        Database,
@@ -41,10 +44,22 @@ import type { MimeTypeUnion } from '$lib/types/common';
 export function detectMcpTransportFromUrl(url: string): MCPTransportType {
        const normalized = url.trim().toLowerCase();
 
-       return normalized.startsWith(UrlProtocol.WEBSOCKET) ||
+       if (
+               normalized.startsWith(UrlProtocol.WEBSOCKET) ||
                normalized.startsWith(UrlProtocol.WEBSOCKET_SECURE)
-               ? MCPTransportType.WEBSOCKET
-               : MCPTransportType.STREAMABLE_HTTP;
+       ) {
+               return MCPTransportType.WEBSOCKET;
+       }
+
+       if (
+               normalized.endsWith(MCP_SSE_ENDPOINT) ||
+               normalized.endsWith(MCP_SSE_ENDPOINT_SLASH) ||
+               normalized.includes(MCP_SSE_ENDPOINT_QUERY)
+       ) {
+               return MCPTransportType.SSE;
+       }
+
+       return MCPTransportType.STREAMABLE_HTTP;
 }
 
 /**