CLI Override Reference¶
The general CLI override syntax lets a command patch a loaded manifest or in-memory configuration without creating a temporary overlay file:
--override ROOT:PATH=VALUE
Every override is converted to a canonical apiVersion: mas/v1,
kind: Overlay document and is processed by the same normalization, merge,
operator, and validation code as a file overlay. Overrides are applied after
all --overlay files and after legacy inline flags.
Quick examples¶
# Agent field
mas-ctl chat agent.yaml \
--override 'agent:spec.context.role="security reviewer"'
# Add a tool with the existing overlay operator
mas-ctl chat agent.yaml \
--override 'agent:spec.tools={"$op":{"add":["web-search"]}}'
# Select one agent inside a MAS
mas-ctl run-mas mas.yaml \
--override 'mas:spec.agency.agents[id=reviewer].spec.memory=long'
# Fan out to every MAS agent
mas-ctl run-mas mas.yaml \
--override 'mas:spec.agency.agents[*].spec.context.environment=staging'
# Compile an effective manifest
mas-ctl compile mas.yaml \
--override 'mas:spec.models[id=main].model="gpt-test"'
# Benchmark experiment configuration
mas-lab benchmark run experiment.yaml \
--override 'experiment:experiment.run.n_runs=1' \
--override 'experiment:experiment.dataset.limit=2'
# Workspace values are changed only in memory for this invocation
mas-ctl chat agent.yaml \
--override 'workspace:defaults.model="gpt-test"'
# Address a context key containing dots
mas-ctl chat agent.yaml \
--override 'agent:spec.context["key.with.dots"]=value'
# Flavour posture (observability / tool exposure). Does not switch internal
# agents to A2A — that is an infra Application `usage: use` row (`--bind` is
# a shortcut for the same fields).
mas-ctl chat agent.yaml \
--override 'flavour:spec.observability=[native]'
Bind¶
--bind NAME=URI is a shortcut for infra YAML, not a second wiring path.
It expands into --override infra:… and is merged into the same in-memory
Application / ToolServerRegistry document as --infra-ref. There is no
separate bind resolver: chat, tui, run-mas, serve, and compose all
consume the patched infra. --bind is applied first, so an explicit
--override of the same path still wins.
Equivalent forms:
# infra/a2a-agents.yaml — kind: Application
spec:
endpoints:
banking_assistant:
protocol: a2a
usage: use
url: http://127.0.0.1:8080/agents/banking_assistant/
mas-ctl run-mas mas.yaml --infra-ref infra/a2a-agents.yaml
mas-ctl run-mas mas.yaml \
--bind banking_assistant=a2a://127.0.0.1:8080/agents/banking_assistant/
mas-ctl run-mas mas.yaml \
--bind banking_assistant=a2a://127.0.0.1:8080/agents/banking_assistant/ \
--bind fraud_adjudicator=a2a://127.0.0.1:8080/agents/fraud_adjudicator/ \
--bind analyze_transaction_risk=mcp://127.0.0.1:8080/mcp#analyze_transaction_risk \
--bind calculate_fraud_score=mcp://127.0.0.1:8080/mcp#calculate_fraud_score
| Assignment | Expands to (same fields as the infra manifest) |
|---|---|
NAME=a2a://host:port/path/ |
infra:spec.endpoints['NAME']={protocol: a2a, usage: use, url: http://host:port/path/} |
NAME=mcp://host:port/mcp#tool |
infra:spec.tool_servers[id=…]={protocol: mcp, usage: use, url: http://…, tools: [tool]} |
a2a:// / mcp:// are scheme tags; stored URLs are http:// or https://
(a2as:// / mcps://). Two MCP tools on the same origin collapse to one
server. The MAS still names the agency peer, and the agent still lists the
tool; --bind only fills location on the infra document. Flavour stays
local (agent_comm.protocol: agent-local) — Application usage: use is
what routes that peer over A2A.
Manifest tree¶
The path starts at a named root. The root identifies the document before the path walks through its YAML tree.
workspace/config.yaml
|
+-- experiment.yaml ---------------------- experiment:experiment.*
| |
| +-- application (MAS binding)
| +-- scenarios
| +-- dataset
| +-- run / pipeline
|
+-- mas.yaml ----------------------------- mas:spec.*
| |
| +-- spec.agency.agents[id=planner]
| |
| +-- ref: agents/planner.yaml
| +-- inline spec
|
+-- agent.yaml --------------------------- agent:spec.*
| |
| +-- tools, skills, models
| +-- context, memory, governance
|
+-- infra refs --------------------------- infra:spec.*
+-- flavour ------------------------------ flavour:spec.*
The path is explicit because spec.tools can belong to a standalone Agent,
an entry Agent inside a MAS, or an infrastructure provider. The command decides
which roots are loaded; an unavailable root is an error, not a silent no-op.
Supported roots¶
| Root | Typical commands | Meaning |
|---|---|---|
agent |
chat, compile |
Standalone Agent manifest |
mas |
run-mas, compose, compile |
MAS or Workflow manifest |
infra |
chat, run-mas, compose |
Effective merged infrastructure |
flavour |
runtime composition | Effective deployment flavour |
experiment |
mas-lab benchmark run |
Experiment before validation and expansion |
workspace |
chat, run-mas |
In-memory effective workspace/config values |
An entry Agent inside a MAS is addressed through the MAS root:
mas:spec.agency.agents[id=planner].spec.tools
It is deliberately different from:
agent:spec.tools
The latter addresses a standalone Agent document.
Path syntax¶
The path grammar is:
assignment := ROOT ":" path "=" yaml-value
path := segment ("." segment)*
segment := identifier | identifier "[" selector "]"
selector := integer | identity | "*"
identity := key "=" yaml-scalar
Examples:
agent:spec.context.role
agent:spec.models[id=main].model
mas:spec.agency.agents[id=planner].spec.context.role
mas:spec.agency.agents[0].spec.memory
mas:spec.agency.agents[*].spec.context.environment
infra:spec.tool_servers[id=mcp].port
experiment:experiment.run.n_runs
workspace:defaults.model
Identity selectors are preferred over numeric indexes because indexes can move when an overlay adds or removes list entries. A selector that matches no entry fails with an error listing the requested identity. Wildcards expand in manifest order and apply the same operation to every match.
Intermediate path segments must already exist. The final key may be absent
only when the target schema declares it, so
agent:spec.models[*].max_tokens=4096 adds max_tokens to every model row
while a typo such as max_tokenz is rejected.
Quoted mapping-key selectors keep dots and brackets inside a map key instead of treating them as path separators:
agent:spec.context["key.with.dots"]
Values¶
Values are parsed as YAML values after shell parsing:
--override 'agent:spec.enabled=true' # boolean
--override 'agent:spec.max_steps=10' # integer
--override 'agent:spec.temperature=0.2' # number
--override 'agent:spec.name="qa agent"' # string
--override 'agent:spec.tags=[qa,fast]' # list
--override 'agent:spec.params={mode: safe}' # map
Quote the entire assignment in the shell when it contains $, brackets,
spaces, braces, or quotes. The value is validated again against the target
schema after merge.
Operators¶
The same $op forms accepted by file overlays are accepted by CLI overrides
where the target field's x-merge strategy supports them:
# Replace a collection
--override 'agent:spec.tools={"$op":{"replace":["calculator"]}}'
# Append to a list
--override 'agent:spec.tools={"$op":{"add":["web-search"]}}'
# Remove from a list
--override 'agent:spec.tools={"$op":{"remove":["calculator"]}}'
# Clear a collection
--override 'agent:spec.skills={"$op":{"clear":true}}'
# Merge a mapping
--override 'agent:spec.context={"$op":{"merge":{"role":"reviewer"}}}'
Raw values use the field's normal overlay behavior. For example, a raw list
means replacement for a list_ops field, while a named list uses its schema
declared identity strategy.
Grouping overrides in an overlay manifest¶
An Overlay manifest can carry an ordered spec.overrides list when the same
selector-based changes should be reused by scenarios or several commands. Each
item uses the same ROOT:PATH=VALUE syntax as the CLI, and is applied after the
manifest's regular spec.patch:
apiVersion: mas/v1
kind: Overlay
metadata:
name: review-policy
spec:
target: {kind: MAS}
patch: {}
overrides:
- 'mas:spec.agency.agents[id=reviewer].spec.memory=long'
- 'mas:spec.agency.agents[*].spec.context.environment=staging'
The root must match the overlay target kind. Identity selectors and wildcards
operate on entries already present in the effective document; an unmatched
selector is an error. The overlay is still validated as a normal mas/v1
Overlay, and source manifests remain unchanged.
Priority¶
The effective order is:
workspace/config defaults
< base manifest
< file overlays in argument order
< legacy shortcut flags (`--bind` expands to `--override infra:…` here)
< --override arguments in argument order
< runtime defaults for fields still absent
The later CLI override wins when the field strategy allows multiple writes. Conflicting wildcard operations or unsupported operations fail rather than using accidental dictionary ordering.
Legacy shortcuts¶
Existing flags remain supported:
| Existing flag | Equivalent intent |
|---|---|
--tool NAME |
Add NAME to agent:spec.tools |
--skill NAME |
Add NAME to agent:spec.skills |
--memory ID |
Replace agent:spec.memory |
--set KEY=VALUE |
Set an Agent context value |
--bind NAME=URI |
Shortcut for Application / ToolServerRegistry usage: use on the merged infra document |
--max-tokens N |
Alias of --override 'agent:spec.models[*].max_tokens=N', placed before explicit --override values (chat, tui) |
--overlay PATH |
Load a file Overlay before CLI values |
--scenario-id ID |
Benchmark selection shortcut |
--dataset-item ID |
Benchmark dataset selection shortcut |
These flags remain the compatibility interface for common operations. General
--override is the explicit interface when the path, root, selector, or merge
operation matters.
References and safety¶
Overrides never rewrite source YAML files or config.yaml. They operate on the
effective in-memory document for one command invocation.
For ref-based MAS agents, address the entry through the MAS path. The document must be materialized by the command before a nested field can be selected. Use an explicit identity selector rather than relying on list position:
mas-ctl run-mas mas.yaml \
--override 'mas:spec.agency.agents[id=planner].spec.context.role=planner'
Invalid roots, paths, selectors, operations, or final schema values fail before runtime execution. Diagnostics include the original override expression and the failing root/path.
Schemas may mark a field with x-cli: {allowed: false} to protect generated or
runtime-owned values. Such a path is rejected before merge.
Related references: