Skip to content

WIP: Add proxy support for MCP transports and OAuth calls#78

Draft
MQ37 wants to merge 2 commits intomainfrom
claude/fix-mcpc-proxy-timeout-cEyn3
Draft

WIP: Add proxy support for MCP transports and OAuth calls#78
MQ37 wants to merge 2 commits intomainfrom
claude/fix-mcpc-proxy-timeout-cEyn3

Conversation

@MQ37
Copy link
Collaborator

@MQ37 MQ37 commented Mar 16, 2026

Summary

This PR fixes HTTP proxy support (HTTP_PROXY/HTTPS_PROXY environment variables) for MCP server connections, OAuth token refresh, and x402 payment signing. Previously, these operations bypassed the global proxy dispatcher because the MCP SDK's StreamableHTTPClientTransport manages its own HTTP connections and doesn't respect undici's setGlobalDispatcher().

Key Changes

  • New module src/lib/proxy-fetch.ts: Provides a proxy-aware fetch function that explicitly routes through EnvHttpProxyAgent, ensuring proxy support works everywhere including inside the MCP SDK transport and OAuth utility calls

    • initProxyFetch(): Initializes the proxy agent with optional TLS settings (must be called once at process startup)
    • proxyFetch(): A fetch wrapper that routes through the configured HTTP proxy, with fallback to a default agent if initialization wasn't called
  • Updated src/core/transports.ts: Injects the proxy-aware proxyFetch function into StreamableHTTPClientTransport options so MCP server HTTP connections respect proxy environment variables

  • Updated src/lib/auth/oauth-utils.ts: Replaced native fetch calls with proxyFetch in OAuth discovery and token refresh operations

  • Updated entry points (src/cli/index.ts and src/bridge/index.ts): Call initProxyFetch() at startup to initialize the proxy agent with the same insecure TLS settings as the global dispatcher

  • Updated src/bridge/index.ts: Cast proxyFetch to FetchLike when creating the x402 fetch middleware to ensure payment signing requests also respect proxy settings

  • Updated test (test/unit/lib/auth/oauth-utils.test.ts): Changed mock to spy on proxyFetchModule.proxyFetch instead of global fetch

Implementation Details

The solution uses undici's EnvHttpProxyAgent which respects HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables. By explicitly passing this agent as the dispatcher option to fetch calls, we ensure proxy routing works for all HTTP operations regardless of how the HTTP client is configured internally.

https://claude.ai/code/session_01PFhD1k8hSaXZ3Crmwb9ure

The MCP SDK's StreamableHTTPClientTransport uses its own internal fetch
that ignores undici's global dispatcher, so HTTP_PROXY/HTTPS_PROXY env
vars were silently bypassed for all MCP server traffic, OAuth token
refresh, and x402 payment signing.

Add a proxy-aware fetch utility (src/lib/proxy-fetch.ts) that explicitly
routes through EnvHttpProxyAgent, and inject it into:
- StreamableHTTPClientTransport via its `fetch` option
- OAuth discovery and token refresh calls
- x402 fetch middleware base fetch

https://claude.ai/code/session_01PFhD1k8hSaXZ3Crmwb9ure
@MQ37 MQ37 changed the title Add proxy support for MCP transports and OAuth calls WIP: Add proxy support for MCP transports and OAuth calls Mar 16, 2026
@jancurn
Copy link
Member

jancurn commented Mar 16, 2026

Let's merge:

setGlobalDispatcher(
    new EnvHttpProxyAgent(insecure ? { connect: { rejectUnauthorized: false } } : {})
  );
  initProxyFetch({ insecure });

Into a single helper function, to have this functionality in just one place.

Also, let's ensure our E2E tests cover this - they should have caught this bug before

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants