@@ -21,6 +21,7 @@ import {
2121 StreamableHTTPClientTransport ,
2222 type StreamableHTTPClientTransportOptions ,
2323} from '@modelcontextprotocol/sdk/client/streamableHttp.js' ;
24+ import { EnvHttpProxyAgent } from 'undici' ;
2425import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js' ;
2526import {
2627 ListResourcesResultSchema ,
@@ -2137,16 +2138,34 @@ function createUrlTransport(
21372138 | StreamableHTTPClientTransportOptions
21382139 | SSEClientTransportOptions ,
21392140) : StreamableHTTPClientTransport | SSEClientTransport {
2140- // Wrap fetch to treat GET 404 as 405 so servers that do not support the
2141- // optional SSE GET stream (e.g. n8n native MCP) are handled gracefully.
2141+ // Create a proxy-aware fetcher that respects NO_PROXY for this MCP server
2142+ // This is especially important for local MCP servers (localhost, 127.0.0.1)
2143+ // when a company proxy is globally configured.
2144+ const noProxy = process . env [ 'NO_PROXY' ] || process . env [ 'no_proxy' ] ;
2145+ const agent = new EnvHttpProxyAgent ( { noProxy } ) ;
2146+
2147+ // Wrap fetch to:
2148+ // 1. Use the proxy-aware agent (respecting NO_PROXY)
2149+ // 2. Treat GET 404 as 405 so servers that do not support the
2150+ // optional SSE GET stream (e.g. n8n native MCP) are handled gracefully.
21422151 // The SDK already silently ignores 405; 404 is semantically equivalent here.
21432152 const baseFetch =
21442153 ( transportOptions as StreamableHTTPClientTransportOptions ) . fetch ??
21452154 globalThis . fetch ;
2155+
21462156 const httpOptions : StreamableHTTPClientTransportOptions = {
21472157 ...transportOptions ,
21482158 fetch : async ( url , init ) => {
2149- const res = await baseFetch ( url , init ) ;
2159+ // If we have an explicit NO_PROXY, we use a proxy-aware dispatcher.
2160+ // We use the global fetch but pass a custom dispatcher in the init options.
2161+ // This avoids manual response reconstruction and dangerous type casts.
2162+ const res = noProxy
2163+ ? await globalThis . fetch ( url , {
2164+ ...init ,
2165+ dispatcher : agent ,
2166+ } as RequestInit )
2167+ : await baseFetch ( url , init ) ;
2168+
21502169 return init ?. method === 'GET' && res . status === 404
21512170 ? new Response ( null , { status : 405 , statusText : 'Method Not Allowed' } )
21522171 : res ;
0 commit comments