docs: make ${env.X} the canonical variable-expansion syntax

This commit is contained in:
David Gageot committed 2026-06-30 16:20:01 +02:00
1 parent 00aef65c52
commit ab52897758
13 files changed
+42 -35

No files matched your search

+7 -7
View File
@@ -220,7 +220,7 @@ API keys and secrets are read from environment variables — never stored in con
## Variable Expansion in Config Fields
docker-agent uses **two different expansion syntaxes** depending on the field. They are not interchangeable: using the wrong syntax in a field is currently a silent no-op, so the literal string is passed through. Tracking issue: [#2615](https://github.com/docker/docker-agent/issues/2615).
docker-agent expands `${env.VAR}` references in many config fields. This is the **canonical syntax everywhere** — prefer it for every field. Two engines back it: a full JavaScript evaluator for prompt/HTTP fields (where you also get defaults, ternaries, and tool calls), and a simpler path expander for filesystem/env fields (which additionally accepts the legacy `$VAR` / `${VAR}` / `~` shell forms). Picking `${env.VAR}` everywhere always works; the one caveat is that the path expander does not evaluate richer JS expressions. Using a shell-style `$VAR` in a JS-templated field is currently a silent no-op, so the literal string is passed through. Tracking issue: [#2615](https://github.com/docker/docker-agent/issues/2615).
### JavaScript template literals — `${env.VAR}`
@@ -252,9 +252,9 @@ agents:
Undefined variables expand to the empty string.
### Shell-style — `$VAR`, `${VAR}`, `~`
### Path & env fields — `${env.VAR}` (canonical), `$VAR` / `${VAR}` / `~` (aliases)
Used for filesystem paths. Backed by `os.ExpandEnv` plus tilde expansion against the current user's home directory.
Used for filesystem paths and process environment values. Backed by `os.ExpandEnv` plus tilde expansion against the current user's home directory. The canonical `${env.VAR}` form is accepted here too, so a single syntax works across every field; the bare `$VAR` / `${VAR}` shell forms remain supported as aliases.
Applies to:
@@ -268,13 +268,13 @@ agents:
root:
toolsets:
- type: memory
path: "~/notes/${PROJECT}/memory.db"
path: "~/notes/${env.PROJECT}/memory.db"
- type: mcp
command: my-server
working_dir: "$HOME/work"
working_dir: "${env.HOME}/work"
```
The `working_dir`, `path`, and `env` value fields additionally accept the `${env.VAR}` form as an alias for `${VAR}`, so the JS-style syntax works there too. Richer JS expressions (e.g. `${env.VAR || 'default'}`) are still **not** evaluated in these fields.
Unlike the JS-templated fields above, these accept only a plain variable reference: richer JS expressions (e.g. `${env.VAR || 'default'}`) are **not** evaluated here, and the legacy `$VAR` / `${VAR}` forms keep working for backward compatibility.
Model definitions follow the same rule. The `models.<name>.model` and `models.<name>.base_url` fields are expanded when the provider is built, accepting both `${env.VAR}` and `${VAR}`. This is useful when the model id or endpoint is injected by the environment (for example a Docker Compose / DMR setup that exports the model reference as a variable):
@@ -302,7 +302,7 @@ models:
The `~` prefix is meaningful only in path-like fields (`working_dir`, `path`).
When in doubt, prefer `${env.X}` for prompts and headers, and `${X}` (or `$X`) for paths.
Prefer `${env.X}` everywhere. The bare `$X` / `${X}` and `~` forms are accepted only in path and `env` value fields, where they remain supported for backward compatibility.
## Validation
+3 -3
View File
@@ -78,7 +78,7 @@ Browse available tools at the [Docker MCP Catalog](https://hub.docker.com/search
| `tools` | array | Optional: only expose these tools |
| `instruction` | string | Custom instructions injected into the agent's context |
| `config` | any | MCP server-specific configuration (passed during initialization) |
| `working_dir` | string | Working directory for the MCP gateway subprocess. Only applies when the catalog entry runs as a local process (not remote). Relative paths are resolved against the agent's working directory. Supports `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `working_dir` | string | Working directory for the MCP gateway subprocess. Only applies when the catalog entry runs as a local process (not remote). Relative paths are resolved against the agent's working directory. Supports `${env.VAR}` (canonical), plus `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
### Local MCP (stdio)
@@ -100,7 +100,7 @@ toolsets:
| `args` | array | Command arguments |
| `tools` | array | Optional: only expose these tools |
| `env` | object | Environment variables (key-value pairs) |
| `working_dir` | string | Working directory for the MCP server process. Relative paths are resolved against the agent's working directory. Defaults to the agent's working directory when omitted. Supports `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `working_dir` | string | Working directory for the MCP server process. Relative paths are resolved against the agent's working directory. Defaults to the agent's working directory when omitted. Supports `${env.VAR}` (canonical), plus `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `instruction` | string | Custom instructions injected into the agent's context |
| `version` | string | Package reference for [auto-installing](#auto-installing-tools) the command binary |
@@ -499,7 +499,7 @@ agents:
url: "https://internal-api.example.com/mcp"
transport_type: "streamable"
headers:
Authorization: "Bearer ${INTERNAL_TOKEN}"
Authorization: "Bearer ${env.INTERNAL_TOKEN}"
```
<div class="callout callout-warning" markdown="1">
+5 -4
View File
@@ -53,15 +53,16 @@ models:
| `command` | Shell out to a CLI on every refresh (`gcloud auth print-identity-token`, `az account get-access-token`, ...) |
| `url` | Fetch from an HTTP(S) endpoint (cloud metadata servers, GitHub Actions OIDC token URL, ...) |
For `url`, both the URL and any header values support `${VAR}` expansion
against the runtime environment, which lets you wire the GitHub Actions OIDC
For `url`, both the URL and any header values support `${env.VAR}` expansion
against the runtime environment (the legacy `${VAR}` form is also accepted),
which lets you wire the GitHub Actions OIDC
token endpoint without putting secrets in YAML:
```yaml
identity_token:
url: ${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=https://api.anthropic.com
url: ${env.ACTIONS_ID_TOKEN_REQUEST_URL}&audience=https://api.anthropic.com
headers:
Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}
Authorization: bearer ${env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}
response_field: value
```
+1 -1
View File
@@ -22,7 +22,7 @@ toolsets:
name: research_agent
# Optional: custom HTTP headers (typically for auth)
headers:
Authorization: "Bearer ${A2A_TOKEN}"
Authorization: "Bearer ${env.A2A_TOKEN}"
X-Tenant: "acme"
```
+1 -1
View File
@@ -55,7 +55,7 @@ Entries in either list are expanded as follows:
- `"."` — the agent's working directory
- `"~"` or `"~/..."` — the user's home directory
- `"$VAR"` / `"${VAR}"` — environment variable expansion
- `"$VAR"` / `"${VAR}"` / `"${env.VAR}"` — environment variable expansion
- absolute paths — used as-is
- relative paths — anchored at the working directory
+3 -3
View File
@@ -45,7 +45,7 @@ Browse available servers at the [Docker MCP Catalog](https://hub.docker.com/u/mc
| `tools` | array | Optional whitelist — only expose these tools to the model. |
| `instruction` | string | Custom instructions injected into the agent's context. |
| `config` | any | MCP server-specific configuration passed during initialization. |
| `working_dir` | string | Working directory for the MCP gateway subprocess. Only applies when the catalog entry runs as a local process (not remote). Relative paths are resolved against the agent's working directory. Supports `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `working_dir` | string | Working directory for the MCP gateway subprocess. Only applies when the catalog entry runs as a local process (not remote). Relative paths are resolved against the agent's working directory. Supports `${env.VAR}` (canonical), plus `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
## Local MCP (stdio)
@@ -67,7 +67,7 @@ toolsets:
| `args` | array | Command arguments. |
| `tools` | array | Optional whitelist — only expose these tools. |
| `env` | object | Environment variables (key-value pairs). |
| `working_dir` | string | Working directory for the MCP server process. Relative paths are resolved against the agent's working directory. Defaults to the agent's working directory when omitted. Supports `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `working_dir` | string | Working directory for the MCP server process. Relative paths are resolved against the agent's working directory. Defaults to the agent's working directory when omitted. Supports `${env.VAR}` (canonical), plus `~` and shell-style `$VAR`/`${VAR}` expansion ([details]({{ '/configuration/overview/#variable-expansion-in-config-fields' | relative_url }})). |
| `instruction` | string | Custom instructions injected into the agent's context. |
| `version` | string | Package reference for [auto-installing]({{ '/configuration/tools/#auto-installing-tools' | relative_url }}) the command binary. |
@@ -88,7 +88,7 @@ toolsets:
url: "https://mcp.linear.app/mcp"
transport_type: "streamable" # or "sse" for legacy servers
headers:
Authorization: "Bearer ${LINEAR_TOKEN}"
Authorization: "Bearer ${env.LINEAR_TOKEN}"
# Optional: allow OAuth helper requests to reach private/internal IPs.
allow_private_ips: false
tools: ["search_issues", "create_issue"]
+1 -1
View File
@@ -36,7 +36,7 @@ toolsets:
- type: shell
env:
MY_VAR: "value"
PATH: "${PATH}:/custom/bin"
PATH: "${env.PATH}:/custom/bin"
```
### Safer mode
+1 -1
View File
@@ -190,7 +190,7 @@ remote MCP endpoints.
|------|---------------|
| [`custom_provider.yaml`](custom_provider.yaml) | Talking to any OpenAI-compatible endpoint via a custom provider. |
| [`compose-secrets.yaml`](compose-secrets.yaml) | Reading API keys from Docker Compose / Swarm secrets. |
| [`env_placeholders.yaml`](env_placeholders.yaml) | `${ENV_VAR}` substitution inside the YAML. |
| [`env_placeholders.yaml`](env_placeholders.yaml) | `${env.VAR}` substitution inside the YAML. |
| [`model_env_substitution.yaml`](model_env_substitution.yaml) | `${env.VAR}` substitution in a model's `model` / `base_url`. |
| [`nebius.yaml`](nebius.yaml) | Nebius cloud provider. |
| [`grok.yaml`](grok.yaml) | xAI Grok model. |
+5 -4
View File
@@ -78,8 +78,9 @@ providers:
# 4. url: fetch the JWT over HTTP(S).
#
# The example below targets the GitHub Actions OIDC token endpoint.
# Both the URL and the header values are passed through ${VAR} expansion
# against the runtime environment, so secrets like
# Both the URL and the header values are passed through ${env.VAR} expansion
# against the runtime environment (the legacy ${VAR} form is also accepted),
# so secrets like
# ACTIONS_ID_TOKEN_REQUEST_TOKEN are never written to the YAML.
#
# GitHub Actions returns {"value": "<jwt>"}, so we ask the URL source
@@ -93,9 +94,9 @@ providers:
federation_rule_id: fdrl_REPLACE_ME
organization_id: 00000000-0000-0000-0000-000000000000
identity_token:
url: ${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=https://api.anthropic.com
url: ${env.ACTIONS_ID_TOKEN_REQUEST_URL}&audience=https://api.anthropic.com
headers:
Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}
Authorization: bearer ${env.ACTIONS_ID_TOKEN_REQUEST_TOKEN}
response_field: value
models:
+12 -7
View File
@@ -1,9 +1,14 @@
# Example demonstrating environment variable placeholder expansion in commands
#
# This example shows how to use $VARIABLE_NAME or ${VARIABLE_NAME} placeholders
# in command definitions, which are automatically replaced with environment variable
# This example shows how to use ${env.VARIABLE_NAME} placeholders in command
# definitions, which are automatically replaced with environment variable
# values when the agent is loaded.
#
# ${env.X} is the canonical syntax for command, instruction, description, and
# header fields (it is evaluated by a JavaScript template engine, so you also
# get defaults via `|| 'fallback'`, ternaries, etc.). The shell-style $VAR /
# ${VAR} form is NOT expanded in these fields.
#
# Usage:
# export USER=alice
# export PROJECT_NAME=myproject
@@ -25,11 +30,11 @@ agents:
Provide clear, concise, and actionable responses.
commands:
greet: "Say hello to $USER and ask how their day is going"
analyze: "Analyze the project named $PROJECT_NAME in the $ENVIRONMENT environment and provide insights"
status: "Check the status of the service ${SERVICE_NAME} and report any issues"
report: "Generate a comprehensive report for project $PROJECT_NAME owned by $OWNER deployed in $LOCATION"
inspect: "Inspect the contents of the directory at $WORKING_DIR and summarize what you find"
greet: "Say hello to ${env.USER} and ask how their day is going"
analyze: "Analyze the project named ${env.PROJECT_NAME} in the ${env.ENVIRONMENT} environment and provide insights"
status: "Check the status of the service ${env.SERVICE_NAME} and report any issues"
report: "Generate a comprehensive report for project ${env.PROJECT_NAME} owned by ${env.OWNER} deployed in ${env.LOCATION}"
inspect: "Inspect the contents of the directory at ${env.WORKING_DIR} and summarize what you find"
help: "Explain what you can do and how to use environment variable placeholders in commands"
toolsets:
+1 -1
View File
@@ -12,7 +12,7 @@
# "." -> the agent's working directory
# "~" -> the user's home directory
# "~/foo" -> $HOME/foo
# "$VAR" -> environment variable
# "${env.VAR}" -> environment variable (canonical; "$VAR" / "${VAR}" also work)
# absolute -> used as-is
# relative -> joined with the working directory
#
+1 -1
View File
@@ -18,7 +18,7 @@ mcps:
github:
ref: docker:github-official
env:
GITHUB_PERSONAL_ACCESS_TOKEN: "${GITHUB_PERSONAL_ACCESS_TOKEN}"
GITHUB_PERSONAL_ACCESS_TOKEN: "${env.GITHUB_PERSONAL_ACCESS_TOKEN}"
tools:
- create_or_update_file
- search_repositories
+1 -1
View File
@@ -10,4 +10,4 @@ agents:
- type: mcp
ref: docker:brave
env:
brave.api_key: ${BRAVE_API_KEY}
brave.api_key: ${env.BRAVE_API_KEY}