~/.config/graph/config.toml(global)./.graph/config.toml(project)- Environment variables (
GRAPH_STORAGE,GRAPH_LOG) - CLI flags
${VAR} in any string value resolves from the environment at load time. An unset variable never silently becomes an empty string — but when it errors depends on where it sits:
- Inside
[providers.*]or[mcp.*]the error is deferred to the moment that provider or server is actually used: the value keeps its literal${VAR}text, everything that doesn’t need the secret (plan authoring, listing,graph mcp serve, key-free plans) keeps working, and the first call that does need it fails naming the variable and the config path that references it. - Anywhere else (paths, prompts, settings) an unset variable still fails the load immediately — a
data_dircarrying literal${VAR}text would be silently wrong everywhere.
version
1. Each layer is migrated to the current version on its own before the two merge, so the global and project files may sit at different versions. graph config check reports each file’s version, and graph config migrate (or --global) rewrites a file to the current one with its comments intact. A file outside the binary’s support window is refused by name, with the version it found and the versions the binary reads.
[settings]
[providers.*]
bedrock roadmap status — is covered in Models & providers.
[models.<role>] — model roles
Every model is a role: one [models.<role>] table per name, all with the same keys. The standard roles are the ones graph’s own calls resolve through, falling back to default; any other name is a custom role.
Custom roles are selectable by name from a prompt tool’s
model field, builtin__infer’s model input, and an infer gate’s model override; they never fall back. Where each role fires, the usual cost setup, and the selection rules are in Models & providers.
fallbacks — provider failover
Any role can carry an ordered list of failover candidates, used when its provider is having an outage:
temperature optionally overrides. Every referenced provider must exist under [providers] (checked at startup). When failover triggers, what carries over, and where fallbacks apply are in Models & providers.
[mcp.*]
See MCP servers for full detail.
[plans] and [tools]
packs enables the opt-in built-in tool packs — tool definitions that ship inside the binary, served under the builtin__ namespace. The llm and data packs are always on; packs adds the rest (github, slack).
[pricing] — per-model token prices
What each model costs, in USD per million tokens, keyed by the model id exactly as written in [models] — that string is what goes on the wire.
cost_usd rather than guessing a rate. That is deliberate — published prices change, and a stale table that quietly reports the wrong dollar figure is worse than reporting none. Price only the models you care about: an unpriced model contributes tokens to the report and nothing to the cost.
cache_write and cache_read default to the standard 1.25× and 0.10× multipliers on input. Set them when a provider prices caching differently.
Where the numbers surface: what a run spent.
[storage]
[user]
Injected into the agent’s and planner’s context:
[prompts]
System-prompt overrides. Each field replaces the built-in text wholesale; leave a field unset (or delete it) to keep the default. For additive context, use [user].context instead.
graph config init writes this section out pre-filled with the built-in defaults, so the usual starting point is editing those in place. A field left in the file pins that prompt at the written text — delete it to track the shipped default across releases.
workbench override covers framing and policy only — how the agent should behave in the workbench, when it may run or save, whether it reads the project. The rules describing what each workbench__* tool does to the draft are appended after it and cannot be overridden, so an override can change the agent’s manners without breaking its grip on the draft. Every tool also carries its own description, which the override never replaces.
[workbench]
GRAPH_WORKBENCH_LOG environment variable overrides both.