Summary
--enable-proxy calls setGlobalDispatcher(new EnvHttpProxyAgent()) but this only affects the npm-installed undici instance. On Node.js 22+, globalThis.fetch uses the Node.js built-in undici — a separate instance that is unaffected by setGlobalDispatcher from an npm package.
StreamableHTTPClientTransport.send() (from @modelcontextprotocol/sdk) falls back to globalThis.fetch when no custom fetch is injected:
const response = await (this._fetch ?? fetch)(this._url, init)
So even with --enable-proxy set, all HTTP requests go through the unproxied built-in fetch.
Symptom
The server is reachable through the proxy (no timeout), but the response is missing the Content-Type header because the direct connection hits an unexpected path. mcp-remote throws:
StreamableHTTPError: Streamable HTTP error: Unexpected content type: null
Environment
- Node.js v22+ (tested on v26.0.0)
- OS: macOS with Surge HTTP proxy on
127.0.0.1:6152
- mcp-remote: 0.1.38
- Config:
HTTPS_PROXY=http://127.0.0.1:6152 + --enable-proxy
Reproducer
const { fetch: undici_fetch, EnvHttpProxyAgent, setGlobalDispatcher } = require('undici')
setGlobalDispatcher(new EnvHttpProxyAgent())
// undici fetch correctly uses the proxy:
undici_fetch(url, opts).then(r => console.log(r.headers.get('content-type'))) // ✅ text/event-stream
// globalThis.fetch does NOT — still uses built-in Node.js undici:
globalThis.fetch(url, opts).then(r => console.log(r.headers.get('content-type'))) // ❌ null
Fix
After configuring the dispatcher, also replace globalThis.fetch with undici's fetch:
if (enableProxy) {
setGlobalDispatcher(new EnvHttpProxyAgent())
+ globalThis.fetch = fetch as typeof globalThis.fetch
log('HTTP proxy support enabled ...')
}
fetch is already imported from undici at the top of utils.ts, so this is a one-line fix.
PR with fix and tests: #280
Summary
--enable-proxycallssetGlobalDispatcher(new EnvHttpProxyAgent())but this only affects the npm-installed undici instance. On Node.js 22+,globalThis.fetchuses the Node.js built-in undici — a separate instance that is unaffected bysetGlobalDispatcherfrom an npm package.StreamableHTTPClientTransport.send()(from@modelcontextprotocol/sdk) falls back toglobalThis.fetchwhen no custom fetch is injected:So even with
--enable-proxyset, all HTTP requests go through the unproxied built-in fetch.Symptom
The server is reachable through the proxy (no timeout), but the response is missing the
Content-Typeheader because the direct connection hits an unexpected path. mcp-remote throws:Environment
127.0.0.1:6152HTTPS_PROXY=http://127.0.0.1:6152+--enable-proxyReproducer
Fix
After configuring the dispatcher, also replace
globalThis.fetchwith undici's fetch:if (enableProxy) { setGlobalDispatcher(new EnvHttpProxyAgent()) + globalThis.fetch = fetch as typeof globalThis.fetch log('HTTP proxy support enabled ...') }fetchis already imported from undici at the top ofutils.ts, so this is a one-line fix.PR with fix and tests: #280