Problem
As surfaced in github/gh-aw#44113, the current MCP server configuration specification has gaps around how stdio and HTTP MCP servers behave under different network isolation modes. This leads to confusing failure modes and implicit compiler behaviors that aren't documented anywhere.
Specific gaps
-
Localhost HTTP MCP servers under network isolation — When sandbox.agent.sudo: false (network isolation enabled), an HTTP MCP server configured with url: http://localhost:PORT/mcp silently gets rewritten to http://host.docker.internal:PORT/mcp by the compiler (rewriteLocalhostToDockerHost). However:
- The spec never documents this rewrite behavior
- Authors aren't told their server process must bind to
0.0.0.0 (not 127.0.0.1) to be reachable from the gateway container via host.docker.internal
- There's no validation or warning when a server in the same workflow binds to
--host 127.0.0.1 while the URL will be rewritten to host.docker.internal
-
Stdio vs HTTP transport confusion for local servers — The workflow frontmatter supports command: for stdio servers (e.g., command: "uvx") but the MCP gateway spec says command: is NOT supported and requires container:. The relationship between frontmatter-level config and what the gateway actually receives is unclear.
-
No unified "network reachability" section — There's no spec section that explains: "If your MCP server runs on the host and you're in network isolation mode, here are the constraints on addressing, binding, and transport selection."
Proposal: Clearer and stronger stdin/MCP configuration spec
1. Document the localhost rewrite rule
Add a section to the MCP gateway spec (or a new dedicated spec) that explicitly states:
When network isolation is enabled (sandbox.agent.sudo: false), the compiler rewrites loopback URLs (localhost, 127.0.0.1, ::1) in HTTP MCP server configurations to host.docker.internal. This is required because the MCP gateway runs inside a Docker container and cannot reach the runner's loopback interface.
2. Specify server binding requirements
Document that any host-side MCP server process started in workflow steps: MUST bind to 0.0.0.0 (all interfaces) when network isolation is active, because host.docker.internal resolves to the Docker bridge IP, not 127.0.0.1.
Add a compile-time lint or warning when:
- An HTTP MCP server URL contains localhost AND
- The same workflow starts a server process with
--host 127.0.0.1 or --bind 127.0.0.1
3. Add a "Network Reachability Matrix"
A clear table documenting what works in each mode:
| MCP Type |
URL / Address |
Network Isolation OFF |
Network Isolation ON |
| HTTP |
localhost:PORT |
✅ Works directly |
⚠️ Rewritten to host.docker.internal:PORT — server must bind 0.0.0.0 |
| HTTP |
host.docker.internal:PORT |
✅ Works (if Docker available) |
✅ Works — server must bind 0.0.0.0 |
| HTTP |
External URL |
✅ Works |
✅ Works (domain must be in allowlist) |
| Stdio |
container: image |
✅ Containerized |
✅ Containerized |
| Stdio |
command: (frontmatter) |
✅ Compiled to gateway stdin config |
❓ Unclear — needs specification |
4. Reconcile frontmatter command: vs gateway spec
The frontmatter allows command: "uvx" + args: [...] for stdio servers, but the gateway spec says command: is unsupported. The compiler clearly bridges this gap (likely converting to container execution), but this translation should be explicitly specified so authors understand what happens to their config.
Context
Problem
As surfaced in github/gh-aw#44113, the current MCP server configuration specification has gaps around how stdio and HTTP MCP servers behave under different network isolation modes. This leads to confusing failure modes and implicit compiler behaviors that aren't documented anywhere.
Specific gaps
Localhost HTTP MCP servers under network isolation — When
sandbox.agent.sudo: false(network isolation enabled), an HTTP MCP server configured withurl: http://localhost:PORT/mcpsilently gets rewritten tohttp://host.docker.internal:PORT/mcpby the compiler (rewriteLocalhostToDockerHost). However:0.0.0.0(not127.0.0.1) to be reachable from the gateway container viahost.docker.internal--host 127.0.0.1while the URL will be rewritten tohost.docker.internalStdio vs HTTP transport confusion for local servers — The workflow frontmatter supports
command:for stdio servers (e.g.,command: "uvx") but the MCP gateway spec sayscommand:is NOT supported and requirescontainer:. The relationship between frontmatter-level config and what the gateway actually receives is unclear.No unified "network reachability" section — There's no spec section that explains: "If your MCP server runs on the host and you're in network isolation mode, here are the constraints on addressing, binding, and transport selection."
Proposal: Clearer and stronger stdin/MCP configuration spec
1. Document the localhost rewrite rule
Add a section to the MCP gateway spec (or a new dedicated spec) that explicitly states:
2. Specify server binding requirements
Document that any host-side MCP server process started in workflow
steps:MUST bind to0.0.0.0(all interfaces) when network isolation is active, becausehost.docker.internalresolves to the Docker bridge IP, not127.0.0.1.Add a compile-time lint or warning when:
--host 127.0.0.1or--bind 127.0.0.13. Add a "Network Reachability Matrix"
A clear table documenting what works in each mode:
localhost:PORThost.docker.internal:PORT— server must bind0.0.0.0host.docker.internal:PORT0.0.0.0container:imagecommand:(frontmatter)4. Reconcile frontmatter
command:vs gateway specThe frontmatter allows
command: "uvx"+args: [...]for stdio servers, but the gateway spec sayscommand:is unsupported. The compiler clearly bridges this gap (likely converting to container execution), but this translation should be explicitly specified so authors understand what happens to their config.Context
Daily Factworkflow that combinedlocalhostMCP URL with network isolationhost.docker.internaland changing server binding from127.0.0.1to0.0.0.0