Clarify JSON vs TOML variable expansion semantics in configuration docs#4210
Clarify JSON vs TOML variable expansion semantics in configuration docs#4210
Conversation
Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/fd0e45c0-e370-4aa5-95c2-7f0f978e71ef Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates configuration documentation to accurately describe how ${VAR_NAME} environment-variable expansion differs between JSON stdin configs and TOML file configs, aligning docs with current implementation behavior.
Changes:
- Scoped
${VAR_NAME}expansion rules by config format (JSON stdin vs TOML). - Clarified that JSON stdin performs global pre-parse expansion and fails fast on undefined vars.
- Added TOML notes about the limited expansion scope and
envguidance.
Show a summary per file
| File | Description |
|---|---|
| docs/CONFIGURATION.md | Adjusts variable-expansion and env documentation to distinguish JSON stdin global expansion from TOML’s limited expansion scope. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (1)
docs/CONFIGURATION.md:362
- The TOML bullet about using an empty string
""for “host environment passthrough to containerenv” doesn’t match how TOML server configs are executed: TOML servers usecommand/argsdirectly, and[servers.<name>.env]sets the backend process environment (not container env flags). For Docker passthrough, document usingargswith-e KEY(no=) and ensuringKEYexists in the gateway process environment, rather thanKEY = "".
- Server `env` values, `url`, `args`, `gateway.api_key`, and other non-tracing fields are not expanded
- For host environment passthrough to container `env`, use an empty string `""` value
- Files reviewed: 1/1 changed files
- Comments generated: 3
| - **`env`** (optional): Environment variables | ||
| - Set to `""` (empty string) for passthrough from host environment | ||
| - Set to `"value"` for explicit value | ||
| - Use `"${VAR_NAME}"` for environment variable expansion (fails if undefined) | ||
| - Use `"${VAR_NAME}"` for environment variable expansion (JSON stdin format only; fails if undefined) | ||
| - **TOML note**: For passthrough, use `""` (empty string) or provide explicit values; `${VAR_NAME}` syntax is not expanded in TOML server `env` values |
There was a problem hiding this comment.
The TOML guidance here implies that setting a server env value to an empty string provides passthrough from the host env. In the TOML (file) path, [servers.<name>.env] is passed as process environment for the backend command (e.g., the docker CLI), so KEY = "" will set KEY to an empty value (overriding host), not passthrough. To pass a host env var into a Docker container from TOML, use args with -e KEY and ensure KEY is present in the gateway process environment (or set an explicit value in [servers.<name>.env]).
This issue also appears on line 361 of the same file.
See below for a potential fix:
- Set to `"value"` for an explicit value
- Use `"${VAR_NAME}"` for environment variable expansion (JSON stdin format only; fails if undefined)
- **TOML note**: `${VAR_NAME}` syntax is not expanded in TOML server `env` values
- **TOML note**: Setting a value to `""` in `[servers.<name>.env]` sets that variable to an empty string for the backend command; it does **not** passthrough the host value
- **TOML note**: To pass a host environment variable through to a Docker container, add `-e KEY` to `args` and ensure `KEY` is present in the gateway process environment, or set an explicit value in `[servers.<name>.env]`
| - Variable expansion with `${VAR_NAME}` is only supported in `[gateway.opentelemetry]` and legacy `[gateway.tracing]` fields | ||
| - Server `env` values, `url`, `args`, `gateway.api_key`, and other non-tracing fields are not expanded |
There was a problem hiding this comment.
This says TOML ${VAR_NAME} expansion is supported in legacy [gateway.tracing], but the TOML loader only expands tracing variables when [gateway.opentelemetry] is present (see internal/config/config_core.go where expandTracingVariables is only called on Gateway.Opentelemetry). Either update the docs to say expansion is limited to [gateway.opentelemetry] only, or update the loader to also expand/validate variables for legacy [gateway.tracing].
| - Variable expansion with `${VAR_NAME}` is only supported in `[gateway.opentelemetry]` and legacy `[gateway.tracing]` fields | |
| - Server `env` values, `url`, `args`, `gateway.api_key`, and other non-tracing fields are not expanded | |
| - Variable expansion with `${VAR_NAME}` is only supported in `[gateway.opentelemetry]` fields | |
| - Server `env` values, `url`, `args`, `gateway.api_key`, legacy `[gateway.tracing]`, and other non-opentelemetry fields are not expanded |
| - Uses `command` and `args` fields directly (e.g., `command = "docker"`) | ||
| - Variable expansion with `${VAR_NAME}` is only supported in `[gateway.opentelemetry]` and legacy `[gateway.tracing]` fields | ||
| - Server `env` values, `url`, `args`, `gateway.api_key`, and other non-tracing fields are not expanded | ||
| - For host environment passthrough to container `env`, use an empty string `""` value |
There was a problem hiding this comment.
After stating that TOML does not expand ${VAR_NAME} in non-tracing fields, this doc still contains other TOML-relevant examples that suggest ${VAR} works (e.g., mounts source description and the gateway.domain row). To avoid contradictory guidance, consider updating those references to be JSON-only / tracing-only (or otherwise scoping them) so the file is internally consistent.
| - For host environment passthrough to container `env`, use an empty string `""` value | |
| - For host environment passthrough to container `env` in TOML, use an empty string `""` value; do not use `${VAR_NAME}` in `env` because non-tracing TOML fields are not expanded |
Nightly docs reconciliation found
docs/CONFIGURATION.mddescribing${VAR_NAME}expansion as a common rule across config formats, which does not match implementation. JSON stdin supports global expansion, while TOML expansion is scoped to tracing fields only.Validation Rules: scope expansion by format
${VAR_NAME}across the full config pre-parse.[gateway.opentelemetry]/ legacy[gateway.tracing], and does not apply to serverenv,url,args,gateway.api_key, or other non-tracing fields.""values inenv.Server
envfield: remove format ambiguityenvfield docs to mark"${VAR_NAME}"expansion as JSON-only.""passthrough or explicit literal values.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
example.com/tmp/go-build392378076/b509/launcher.test /tmp/go-build392378076/b509/launcher.test -test.testlogfile=/tmp/go-build392378076/b509/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true rotocol/go-sdk@v1.5.0/internal/json/json.go -I x_amd64/vet --gdwarf-5 ls -o x_amd64/vet -I g_.a 6572790/b298/ x_amd64/vet -pthread go-sdk/oauthex -fmessage-length-bool x_amd64/vet(dns block)/tmp/go-build3156868184/b513/launcher.test /tmp/go-build3156868184/b513/launcher.test -test.testlogfile=/tmp/go-build3156868184/b513/testlog.txt -test.paniconexit0 -test.timeout=10m0s(dns block)invalid-host-that-does-not-exist-12345.com/tmp/go-build392378076/b491/config.test /tmp/go-build392378076/b491/config.test -test.testlogfile=/tmp/go-build392378076/b491/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true /http2/ascii.go /http2/ciphers.go x_amd64/vet -p nal/protolazy 6572790/b166/ x_amd64/vet ctor�� g_.a ache/go/1.25.9/x64/src/net x_amd64/vet 6572790/b166/(dns block)/tmp/go-build3156868184/b495/config.test /tmp/go-build3156868184/b495/config.test -test.testlogfile=/tmp/go-build3156868184/b495/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build4079831004/b530/vet.cfg _.a -trimpath 64/pkg/tool/linux_amd64/vet -p net/http/httptradocker-cli-plugin-metadata -lang=go1.25 64/pkg/tool/linux_amd64/vet 6572�� github.com/segmentio/asm/ascii cfg 64/pkg/tool/linux_amd64/vet -I /tmp/go-build126-atomic -I z_uFmMN/LVIzfV5b-buildtags(dns block)nonexistent.local/tmp/go-build392378076/b509/launcher.test /tmp/go-build392378076/b509/launcher.test -test.testlogfile=/tmp/go-build392378076/b509/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true rotocol/go-sdk@v1.5.0/internal/json/json.go -I x_amd64/vet --gdwarf-5 ls -o x_amd64/vet -I g_.a 6572790/b298/ x_amd64/vet -pthread go-sdk/oauthex -fmessage-length-bool x_amd64/vet(dns block)/tmp/go-build3156868184/b513/launcher.test /tmp/go-build3156868184/b513/launcher.test -test.testlogfile=/tmp/go-build3156868184/b513/testlog.txt -test.paniconexit0 -test.timeout=10m0s(dns block)slow.example.com/tmp/go-build392378076/b509/launcher.test /tmp/go-build392378076/b509/launcher.test -test.testlogfile=/tmp/go-build392378076/b509/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true rotocol/go-sdk@v1.5.0/internal/json/json.go -I x_amd64/vet --gdwarf-5 ls -o x_amd64/vet -I g_.a 6572790/b298/ x_amd64/vet -pthread go-sdk/oauthex -fmessage-length-bool x_amd64/vet(dns block)/tmp/go-build3156868184/b513/launcher.test /tmp/go-build3156868184/b513/launcher.test -test.testlogfile=/tmp/go-build3156868184/b513/testlog.txt -test.paniconexit0 -test.timeout=10m0s(dns block)this-host-does-not-exist-12345.com/tmp/go-build392378076/b518/mcp.test /tmp/go-build392378076/b518/mcp.test -test.testlogfile=/tmp/go-build392378076/b518/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg 64/src/encoding/-ifaceassert x_amd64/vet -I /tmp/go-build126--version -I x_amd64/vet -I .cfg IGNd/Tg562pv10lsiLQzsIGNd x_amd64/vet --gdwarf-5 e/jsonschema-go/inspect -o x_amd64/vet(dns block)/tmp/go-build3156868184/b522/mcp.test /tmp/go-build3156868184/b522/mcp.test -test.testlogfile=/tmp/go-build3156868184/b522/testlog.txt -test.paniconexit0 -test.timeout=10m0s 6572�� GOOS_linux -D 64/pkg/tool/linu-nilfunc -D GOAMD64_v1 -o 64/pkg/tool/linu-importcfg(dns block)If you need me to access, download, or install something from one of these locations, you can either: