Skip to content

Commit 94ecf80

Browse files
CopilotlpcoxCopilot
authored
Clarify MCP localhost rewrite, transport semantics, and reachability under network isolation (#6005)
* Initial plan * docs: clarify MCP transport and localhost reachability rules * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Landon Cox <landon.cox@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 42d0df3 commit 94ecf80

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

.github/aw/github-agentic-workflows.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,47 @@ mcp-servers:
11731173
- custom_function_2
11741174
```
11751175

1176+
### MCP Transport and Reachability
1177+
1178+
MCP server configuration has two layers:
1179+
1180+
1. **Workflow frontmatter (`mcp-servers`)** — author-facing configuration:
1181+
- `command:` + `args:` defines a **stdio** MCP server process.
1182+
- `url:` defines an **HTTP** MCP server endpoint.
1183+
2. **MCP gateway runtime config** — compiler-generated configuration consumed by the gateway.
1184+
- Frontmatter stdio servers are compiled into gateway stdio (stdin/stdout) process entries.
1185+
- Frontmatter `command:` is valid for workflow authors even though the gateway's internal schema differs.
1186+
1187+
#### Localhost rewrite in network isolation mode
1188+
1189+
When network isolation is enabled (i.e., when the MCP gateway runs in a Docker container), loopback HTTP MCP URLs in `mcp-servers` are rewritten by the compiler:
1190+
- `http://localhost:PORT/...`
1191+
- `http://127.0.0.1:PORT/...`
1192+
- `http://[::1]:PORT/...`
1193+
1194+
becomes:
1195+
1196+
- `http://host.docker.internal:PORT/...`
1197+
1198+
This rewrite is required because the MCP gateway runs in a Docker container and cannot reach the host loopback interface directly.
1199+
1200+
#### Host-side HTTP server binding requirement
1201+
1202+
If a workflow starts a local HTTP MCP server in `steps:` and network isolation is enabled, the server must bind to `0.0.0.0` (or another non-loopback interface). Binding only to `127.0.0.1` / `::1` will not be reachable from the gateway via `host.docker.internal`.
1203+
1204+
Compiler/lint behavior:
1205+
- The compiler SHOULD emit a warning when an HTTP MCP server URL is loopback-localhost and the same workflow appears to start a server with `--host 127.0.0.1`, `--bind 127.0.0.1`, `--host ::1`, or `--bind ::1`.
1206+
1207+
#### Network reachability matrix
1208+
1209+
| MCP Type | URL / Address | Network Isolation OFF | Network Isolation ON |
1210+
|----------|----------------|-----------------------|----------------------|
1211+
| HTTP | `localhost:PORT` | ✅ Works directly | ⚠️ Rewritten to `host.docker.internal:PORT`; server must bind `0.0.0.0` |
1212+
| HTTP | `host.docker.internal:PORT` | ✅ Works (when Docker host gateway is available) | ✅ Works; server must bind `0.0.0.0` |
1213+
| HTTP | External URL | ✅ Works | ✅ Works (domain must be permitted by `network.allowed`) |
1214+
| Stdio | `container:` image | ✅ Containerized runtime | ✅ Containerized runtime |
1215+
| Stdio | `command:` + `args:` (frontmatter) | ✅ Compiled to gateway stdio/stdin process config | ✅ Compiled to gateway stdio/stdin process config |
1216+
11761217
### Engine Network Permissions
11771218

11781219
Control network access for AI engines using the top-level `network:` field. If no `network:` permission is specified, it defaults to `network: defaults` which provides access to basic infrastructure only.

0 commit comments

Comments
 (0)