feat: align MCP config with MCPG spec — container/HTTP transport#157
feat: align MCP config with MCPG spec — container/HTTP transport#157jamesadevine merged 11 commits intomainfrom
Conversation
Replace command-based MCP configuration with MCPG-native fields:
- **types.rs**: Replace `command` with `container`, `entrypoint`,
`entrypoint-args`, `url`, `headers`, `mounts` in McpOptions
- **standalone.rs**: Update McpgServerConfig and generate_mcpg_config()
to emit container/entrypointArgs (stdio) or url/headers (HTTP)
- **standalone.rs**: Add generate_mcpg_docker_env() for env passthrough
- Auto-maps SC_READ_TOKEN → AZURE_DEVOPS_EXT_PAT when permissions.read
is configured
- Forwards passthrough env vars ("") to MCPG via -e flags
- **base.yml**: Add {{ mcpg_docker_env }} marker for env forwarding
- **common.rs**: Update is_custom_mcp() to check container/url
- **onees.rs**: Update custom MCP detection for 1ES target
Tests:
- New fixture: azure-devops-mcp-agent.md (container-based ADO MCP)
- 4 new integration tests: fixture compilation, container config,
HTTP config, env passthrough
- 8 new unit tests: container/HTTP/entrypoint/mounts/env generation
- Update existing tests for new field names
Docs:
- New example: examples/azure-devops-mcp.md (ADO work item triage)
- Update AGENTS.md MCP section with container/HTTP docs and auth model
Aligns with MCPG Gateway Specification v1.13.0 §3.2.1 (containerization
requirement) and gh-aw front matter format.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Good direction — the MCPG spec alignment is correct and needed. One security issue needs addressing before merge; one missing documentation item. Findings🔒 Security Concerns
|
- Validate env var names against [A-Za-z_][A-Za-z0-9_]* to prevent
Docker flag injection via user-controlled front matter keys
- Document {{ mcpg_docker_env }} template marker in AGENTS.md
- Warn when env: is configured on HTTP MCPs (silently ignored)
- Add unit tests for env var name validation and injection rejection
- Update {{ mcpg_config }} docs for container/url (was command)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Core refactoring is well-structured and mostly correct, but there is one reproducible runtime bug in the bash generation that would silently break MCPG startup whenever any env passthrough is configured. Findings🐛 Bugs / Logic Issues
🔒 Security Concerns
|
- Fix broken bash line continuation when {{ mcpg_docker_env }} is
non-empty or empty — restructured template so marker outputs
include trailing backslash, validated with bash -n
- Add validate_mount_source() — warns on sensitive host path prefixes
(/etc, /root, /home, /proc, /sys, docker.sock)
- Add validate_mcp_url() — warns if URL doesn't use http(s):// scheme
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good overall — the core Findings🐛 Bugs / Logic Issues
🔒 Security Concerns
|
- Skip HTTP MCPs in generate_mcpg_docker_env (no child container to
forward env vars to)
- Warn when both container and url are set on same MCP entry
- Escalate docker.sock mount warning to eprintln (container escape risk)
- Remove undocumented ${VAR} passthrough — only empty string ("")
triggers env passthrough, matching AGENTS.md documentation
- Add indentation cross-reference comment for base.yml alignment
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Solid implementation with good test coverage — has a security gap in the Findings🔒 Security Concerns
|
- Add validate_docker_args() — scans args for --privileged, -v, --cap-add, --security-opt and other privilege escalation flags - Add warn_potential_secrets() — warns when env var names containing 'token', 'secret', 'key', 'password', 'pat' have inline values instead of passthrough; warns on Authorization headers in plaintext - Change validate_mcp_url to use eprintln! for consistency with other compile-time warnings (was log::warn, invisible without --verbose) - Change HTTP MCP env warning to eprintln! for consistency Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good overall — the MCPG spec alignment is correct and the new security validation helpers are a nice addition. A few issues worth addressing before merge. Findings🐛 Bugs / Logic Issues
🔒 Security Concerns
|
- Remove dead /var/run/docker.sock from SENSITIVE_MOUNT_PREFIXES
(already caught by contains("docker.sock") early return)
- Fix prefix check: /etc no longer matches /etc-configs (require
exact match or trailing /)
- Fix Docker args: handle split-form flags (--pid host, --network
host, --ipc host) in addition to --flag=value form
- Scope ADO token auto-map: only inject AZURE_DEVOPS_EXT_PAT when
a container MCP actually requests it via env passthrough, not
whenever permissions.read is set
- Add test for dedup edge case: auto-mapped SC_READ_TOKEN form wins
over bare passthrough, appears exactly once
- Add test for no-request case: permissions.read without MCP
requesting AZURE_DEVOPS_EXT_PAT does not inject the token
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep both main's test_safe_outputs_enabled_tools_in_compiled_output and our Azure DevOps MCP integration tests.
Move {{ mcpg_docker_env }} to its own indented line in base.yml so
replace_with_indent handles alignment automatically. Removes
hardcoded 12-space indentation from generate_mcpg_docker_env() —
future template reformats won't silently break bash syntax.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good with a few things worth addressing before merge — one notable inconsistency in Findings🐛 Bugs / Logic Issues
🔒 Security Concerns
|
… arg - Add validate_container_image() — rejects image names with unexpected characters (defense-in-depth against injection) - Expand DANGEROUS_DOCKER_FLAGS with --user/-u, --add-host, --entrypoint - Fix warn_potential_secrets call: pass &opts.headers instead of empty HashMap for container MCPs - Add inline comment explaining lone backslash in empty env case - Add case-insensitivity note on validate_mount_source Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good overall — solid alignment with MCPG spec, well-tested, good security instincts in the validation layer. Two issues worth addressing before merge. Findings🔒 Security Concerns
🐛 Bugs / Logic Issues
|
- Emit eprintln warning when container MCP has AZURE_DEVOPS_EXT_PAT passthrough but permissions.read is not configured (token would be empty at runtime, causing silent auth failure) - Remove --network host from AGENTS.md args example (contradicts DANGEROUS_DOCKER_FLAGS warning, bypasses AWF proxy) - Add entrypoint: field hint to --entrypoint Docker args warning Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good overall — the MCPG spec alignment is well-implemented and the security validation helpers are thorough. A few issues worth addressing before merge. Findings🐛 Bugs / Logic Issues
🔒 Security Concerns
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Rust PR ReviewSummary: Looks good overall — well-structured migration with strong test coverage, but two issues worth a follow-up. Findings🐛 Bugs / Logic Issues
📝 Documentation Inaccuracies
✅ What Looks Good
|
Summary
Aligns the compiler's MCP configuration with the MCPG Gateway Specification v1.13.0 and gh-aw's front matter format. The Azure DevOps MCP is now a first-class use case.
Problem
Our compiler generated
command/argsin the MCPG config JSON, but MCPG's JSON stdin format only supportscontainerfor stdio servers (spec §3.2.1). External MCPs never actually worked — thecommandfield was silently rejected by MCPG.Changes
Core compiler:
types.rs: Replacedcommandwithcontainer,entrypoint,entrypoint-args,url,headers,mountsinMcpOptionsstandalone.rs: UpdatedMcpgServerConfigandgenerate_mcpg_config()to emit MCPG-native JSON (container/entrypointArgsfor stdio,url/headersfor HTTP)standalone.rs: Addedgenerate_mcpg_docker_env()for env passthroughbase.yml: Added{{ mcpg_docker_env }}template markerAuth model:
permissions.readis configured, the compiler auto-mapsSC_READ_TOKEN→AZURE_DEVOPS_EXT_PATon the MCPG Docker containerenv: { AZURE_DEVOPS_EXT_PAT: "" }in front matter — zero manual wiring""valueTests (all 651 pass):
New files:
examples/azure-devops-mcp.md— Full reference example (ADO work item triage agent)tests/fixtures/azure-devops-mcp-agent.md— Integration test fixtureExample: Azure DevOps MCP Configuration