Summary
In network-isolation (sandbox) mode with the MCP gateway topology, the agent container's NO_PROXY does not include the MCP gateway hostname (awmg-mcpg). As a result, the engine's native streamable-HTTP MCP connection to the gateway (e.g. Claude Code connecting to the safeoutputs server) is routed through Squid and denied, and the MCP server is reported as failed at session init on every run.
Observed on AWF v0.27.27; the relevant code is unchanged at HEAD (v0.27.31).
What happens
At agent session start, Claude Code attempts to connect to the gateway-mounted MCP server:
POST http://awmg-mcpg:8080/mcp/safeoutputs
Because awmg-mcpg is not in the agent container's NO_PROXY, Node/undici routes the request through Squid (HTTP_PROXY=http://172.30.0.10:3128). Squid denies it — twice over:
awmg-mcpg is not in allowed_domains (and can't reasonably be added by users via the workflow network: allowlist, since it's an internal AWF/gh-aw hostname), and
- port
8080 is not in Safe_ports (only 80, 443, and the api-proxy ports 10000–10004), so http_access deny !Safe_ports matches first regardless of any domain allowlisting.
Squid access log (one of these on every run):
1783920376.644 172.30.0.20:43452 awmg-mcpg:8080 -:- 1.1 POST 403 TCP_DENIED:HIER_NONE http://awmg-mcpg:8080/mcp/safeoutputs "claude-code/2.1.201 (sdk-cli)"
Claude Code session init:
"mcp_servers":[{"name":"safeoutputs","status":"failed"}]
Agent container environment (from docker-compose.redacted.yml audit artifact):
HTTP_PROXY: http://172.30.0.10:3128
HTTPS_PROXY: http://172.30.0.10:3128
NO_PROXY: localhost,127.0.0.1,::1,0.0.0.0,172.30.0.10,172.30.0.20,172.30.0.30,api-proxy
Root cause
buildProxyEnvironment in src/services/agent-environment/proxy-environment.ts adds only the Squid IP, agent IP, and (when the API proxy is enabled) proxyIp + the api-proxy hostname to NO_PROXY. Topology peers attached to awf-net — notably the MCP gateway awmg-mcpg (and awmg-cli-proxy) that gh-aw asks AWF to connect (buildAWFTopologyAttachList in gh-aw's pkg/workflow/awf_config.go) — are never exempted.
The existing code comment already identifies the constraint:
Include both IP and Docker service hostname — Node.js undici matches NO_PROXY against the request hostname string, not the resolved IP.
The same treatment is needed for attached topology-peer hostnames.
Impact
Functionally the runs survive: gh-aw's prompt directs the agent to the MCP CLI bridge (safeoutputs …, etc.), which bypasses the proxy and works. But:
- every run reports the MCP server as
failed and logs a spurious TCP_DENIED, which pollutes firewall-audit review (each run looks like it has a blocked exfiltration attempt);
- any engine flow that relies on the native MCP connection to gateway-mounted servers (rather than the CLI bridge) silently loses those tools;
- users cannot self-fix via workflow
network: config because of the Safe_ports interaction described above.
Suggested fix
When AWF attaches topology peers to awf-net (network-isolation mode), append each peer's hostname (and, if known, IP) to the agent container's NO_PROXY/no_proxy in buildProxyEnvironment — mirroring the existing api-proxy handling. Gateway traffic is intra-network and shouldn't traverse Squid at all.
Environment
- AWF v0.27.27 (containers pinned by digest), reproduced identically across runs; code unchanged at v0.27.31 HEAD
- gh-aw compiled workflow, engine: claude (claude-code 2.1.201), MCP gateway mode with
safeoutputs mounted at http://awmg-mcpg:8080/mcp/safeoutputs
- Ubuntu GitHub-hosted runner (ubuntu-latest)
Summary
In network-isolation (sandbox) mode with the MCP gateway topology, the agent container's
NO_PROXYdoes not include the MCP gateway hostname (awmg-mcpg). As a result, the engine's native streamable-HTTP MCP connection to the gateway (e.g. Claude Code connecting to thesafeoutputsserver) is routed through Squid and denied, and the MCP server is reported asfailedat session init on every run.Observed on AWF v0.27.27; the relevant code is unchanged at HEAD (v0.27.31).
What happens
At agent session start, Claude Code attempts to connect to the gateway-mounted MCP server:
Because
awmg-mcpgis not in the agent container'sNO_PROXY, Node/undici routes the request through Squid (HTTP_PROXY=http://172.30.0.10:3128). Squid denies it — twice over:awmg-mcpgis not inallowed_domains(and can't reasonably be added by users via the workflownetwork:allowlist, since it's an internal AWF/gh-aw hostname), and8080is not inSafe_ports(only 80, 443, and the api-proxy ports 10000–10004), sohttp_access deny !Safe_portsmatches first regardless of any domain allowlisting.Squid access log (one of these on every run):
Claude Code session init:
Agent container environment (from
docker-compose.redacted.ymlaudit artifact):Root cause
buildProxyEnvironmentinsrc/services/agent-environment/proxy-environment.tsadds only the Squid IP, agent IP, and (when the API proxy is enabled)proxyIp+ theapi-proxyhostname toNO_PROXY. Topology peers attached toawf-net— notably the MCP gatewayawmg-mcpg(andawmg-cli-proxy) that gh-aw asks AWF to connect (buildAWFTopologyAttachListin gh-aw'spkg/workflow/awf_config.go) — are never exempted.The existing code comment already identifies the constraint:
The same treatment is needed for attached topology-peer hostnames.
Impact
Functionally the runs survive: gh-aw's prompt directs the agent to the MCP CLI bridge (
safeoutputs …, etc.), which bypasses the proxy and works. But:failedand logs a spuriousTCP_DENIED, which pollutes firewall-audit review (each run looks like it has a blocked exfiltration attempt);network:config because of theSafe_portsinteraction described above.Suggested fix
When AWF attaches topology peers to
awf-net(network-isolation mode), append each peer's hostname (and, if known, IP) to the agent container'sNO_PROXY/no_proxyinbuildProxyEnvironment— mirroring the existingapi-proxyhandling. Gateway traffic is intra-network and shouldn't traverse Squid at all.Environment
safeoutputsmounted athttp://awmg-mcpg:8080/mcp/safeoutputs