Describe the bug
Azure MCP honors HTTP_PROXY / HTTPS_PROXY, but its custom NO_PROXY handling is incompatible with standard hostname, leading-dot suffix, and CIDR entries.
AddHttpClientServices reads ALL_PROXY, HTTP_PROXY, HTTPS_PROXY, and NO_PROXY. HttpClientFactoryConfigurator.CreateProxy then creates a WebProxy, converts each NO_PROXY entry with ConvertGlobToRegex, and assigns the result to WebProxy.BypassList:
The conversion anchors the supplied entry itself. For example:
api.loganalytics.io -> ^api\.loganalytics\.io$
.ods.opinsights.azure.com -> ^\.ods\.opinsights\.azure\.com$
10.0.0.0/8 -> ^10\.0\.0\.0/8$
However, .NET WebProxy.BypassList contains regular expressions evaluated against a formatted URL such as https://api.loganalytics.io or https://workspace.ods.opinsights.azure.com, not only Uri.Host. Therefore the exact-host and standard leading-dot suffix expressions above do not match. CIDRs are treated as literal strings and also do not match addresses in their range.
A raw glob such as *.ods.opinsights.azure.com may appear to work accidentally because its leading .* can consume the URL scheme and hostname prefix, but standard NO_PROXY implementations use .ods.opinsights.azure.com for suffix matching. Callers also cannot work around the mismatch by supplying a WebProxy URL regex because ConvertGlobToRegex escapes regex metacharacters before assignment.
This custom parser also bypasses the platform HttpEnvironmentProxy implementation. .NET 11 added native IPv4/IPv6 CIDR support for NO_PROXY in dotnet/runtime#131397, but current Azure MCP still performs its own conversion. Azure MCP reads only uppercase variables as well, while .NET checks lowercase names first on case-sensitive platforms.
The implementation is present in the Azure.Mcp.Server-2.0.1 tag and remains on current main.
Expected behavior
Standard NO_PROXY values should bypass the proxy:
api.loganalytics.io for that exact hostname
.ods.opinsights.azure.com for the domain and its subdomains
10.0.0.0/8 for IP destinations within that network when supported by the target runtime
- lowercase and uppercase environment names according to platform/.NET precedence
Preferably Azure MCP should delegate environment-proxy parsing to .NET instead of maintaining a divergent parser. If a custom proxy remains necessary, it should implement the same hostname, suffix, CIDR, casing, and precedence semantics explicitly.
Actual behavior
With HTTPS_PROXY configured, requests covered by exact-host, standard leading-dot suffix, or CIDR NO_PROXY entries still go through the proxy.
Observed examples include:
api.loganalytics.io
api.loganalytics.azure.com
api.applicationinsights.io
.ods.opinsights.azure.com
10.0.0.0/8
Reproduction Steps
-
Start Azure MCP on Linux with a proxy that logs requests:
HTTP_PROXY=http://proxy.example:3128 \
HTTPS_PROXY=http://proxy.example:3128 \
NO_PROXY=api.loganalytics.io,.ods.opinsights.azure.com,10.0.0.0/8 \
npx -y @azure/mcp@2.0.1 server start --namespace monitor --mode all --read-only
-
Invoke Monitor tools that call Log Analytics or Application Insights, or otherwise exercise a destination covered by the configured entries.
-
Observe those requests reaching the proxy despite the matching NO_PROXY entries.
-
The behavior follows directly from testing the generated regexes against the URL strings used by WebProxy.BypassList.
Environment
Describe the bug
Azure MCP honors
HTTP_PROXY/HTTPS_PROXY, but its customNO_PROXYhandling is incompatible with standard hostname, leading-dot suffix, and CIDR entries.AddHttpClientServicesreadsALL_PROXY,HTTP_PROXY,HTTPS_PROXY, andNO_PROXY.HttpClientFactoryConfigurator.CreateProxythen creates aWebProxy, converts eachNO_PROXYentry withConvertGlobToRegex, and assigns the result toWebProxy.BypassList:The conversion anchors the supplied entry itself. For example:
However, .NET
WebProxy.BypassListcontains regular expressions evaluated against a formatted URL such ashttps://api.loganalytics.ioorhttps://workspace.ods.opinsights.azure.com, not onlyUri.Host. Therefore the exact-host and standard leading-dot suffix expressions above do not match. CIDRs are treated as literal strings and also do not match addresses in their range.A raw glob such as
*.ods.opinsights.azure.commay appear to work accidentally because its leading.*can consume the URL scheme and hostname prefix, but standardNO_PROXYimplementations use.ods.opinsights.azure.comfor suffix matching. Callers also cannot work around the mismatch by supplying aWebProxyURL regex becauseConvertGlobToRegexescapes regex metacharacters before assignment.This custom parser also bypasses the platform
HttpEnvironmentProxyimplementation. .NET 11 added native IPv4/IPv6 CIDR support forNO_PROXYin dotnet/runtime#131397, but current Azure MCP still performs its own conversion. Azure MCP reads only uppercase variables as well, while .NET checks lowercase names first on case-sensitive platforms.The implementation is present in the
Azure.Mcp.Server-2.0.1tag and remains on currentmain.Expected behavior
Standard
NO_PROXYvalues should bypass the proxy:api.loganalytics.iofor that exact hostname.ods.opinsights.azure.comfor the domain and its subdomains10.0.0.0/8for IP destinations within that network when supported by the target runtimePreferably Azure MCP should delegate environment-proxy parsing to .NET instead of maintaining a divergent parser. If a custom proxy remains necessary, it should implement the same hostname, suffix, CIDR, casing, and precedence semantics explicitly.
Actual behavior
With
HTTPS_PROXYconfigured, requests covered by exact-host, standard leading-dot suffix, or CIDRNO_PROXYentries still go through the proxy.Observed examples include:
Reproduction Steps
Start Azure MCP on Linux with a proxy that logs requests:
Invoke Monitor tools that call Log Analytics or Application Insights, or otherwise exercise a destination covered by the configured entries.
Observe those requests reaching the proxy despite the matching
NO_PROXYentries.The behavior follows directly from testing the generated regexes against the URL strings used by
WebProxy.BypassList.Environment
@azure/mcp@2.0.1mainretains the same custom parser