> ## Documentation Index
> Fetch the complete documentation index at: https://graph.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Configuration

> config.toml, section by section

Config is layered TOML — later wins, tables deep-merge:

1. `~/.config/graph/config.toml` (global)
2. `./.graph/config.toml` (project)
3. Environment variables (`GRAPH_STORAGE`, `GRAPH_LOG`)
4. 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_dir` carrying literal `${VAR}` text would be silently wrong everywhere.

## `[settings]`

```toml theme={null}
[settings]
data_dir = "~/.local/share/graph"   # where threads and the shape cache live
max_agent_iterations = 15           # agent-loop tool rounds per turn
planning_attempts = 2               # plan_and_execute replan budget
```

## `[providers.*]`

```toml theme={null}
[providers.anthropic]
type = "anthropic"                  # anthropic | openai | openai_compat | bedrock
api_key = "${ANTHROPIC_API_KEY}"

[providers.local]
type = "openai_compat"
base_url = "http://localhost:11434/v1"    # Ollama, vLLM, LM Studio…

[providers.bedrock]                 # roadmap
type = "bedrock"
region = "us-east-1"
profile = "default"
```

Provider behavior — structured-output mechanisms, retries, and the `bedrock` roadmap status — is covered in [Models & providers](/models/models-and-providers#providers).

## `[models]` — per-role assignment

Each pipeline role resolves to a model, falling back to `default`:

```toml theme={null}
[models]
default = { provider = "anthropic", model = "claude-sonnet-5" }
chat    = { provider = "anthropic", model = "claude-sonnet-5" }
planner = { provider = "anthropic", model = "claude-sonnet-5" }
solver  = { provider = "anthropic", model = "claude-haiku-4-5", temperature = 0.4 }
repair  = { provider = "anthropic", model = "claude-haiku-4-5" }
```

| Role      | Used for                                                     |
| --------- | ------------------------------------------------------------ |
| `chat`    | the agent loop (`ask`/`chat`)                                |
| `planner` | `plan_and_execute` plan authoring                            |
| `solver`  | plan report synthesis                                        |
| `repair`  | one-shot JSON repair when structured output fails to parse   |
| `judge`   | yes/no verdicts for [inferred exit gates](/plans/exit-gates) |

Where each role fires, and the usual cost setup, are in [Models & providers](/models/models-and-providers#roles).

### `fallbacks` — provider failover

Any model entry (a role or a named model) can carry an ordered list of failover candidates, used when its provider is having an outage:

```toml theme={null}
[models.chat]
provider = "anthropic"
model = "claude-sonnet-5"
fallbacks = [
    { provider = "openai", model = "gpt-5" },
    { provider = "local", model = "llama3", temperature = 0.3 },
]
```

Each candidate names its own provider **and** model; `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](/models/models-and-providers#provider-failover).

## `[models.named]` — named models

Beyond the fixed roles, any number of **named models** — referenceable wherever a model name is accepted: a [prompt tool](/tools/user-defined)'s `model` field, or [`builtin__infer`](/tools/builtins#builtin-infer)'s `model` input.

```toml theme={null}
[models.named.nano]
provider = "anthropic"
model = "claude-haiku-4-5"
description = "fast and cheap; small self-contained tasks like per-item map bodies"
```

The `description` is a planner-facing routing signal, and names resolve in exactly three places — the full story, including the no-shadowing and no-silent-fallback rules, is in [Models & providers](/models/models-and-providers#named-models).

## `[mcp.*]`

See [MCP servers](/tools/mcp-servers) for full detail.

```toml theme={null}
[mcp.<name>]
command = "…"            # stdio — XOR with url
args = ["…"]
env = { KEY = "${VAR}" }
url = "https://…"        # streamable HTTP
headers = { Authorization = "Bearer ${VAR}" }
include_tools = ["…"]    # optional allowlist
exclude_tools = ["…"]    # optional blocklist

[mcp.<name>.tool_overrides.<tool>]
description = "…"
output_schema = { … }    # declare shapes the server omits
output_example = { … }   # optional worked example, shown to the planner
```

## `[plans]` and `[tools]`

```toml theme={null}
[plans]
paths = ["./.graph/plans", "~/.config/graph/plans"]

[tools]
paths = ["./.graph/tools", "~/.config/graph/tools"]
packs = []              # bundled tool packs to enable, e.g. ["github", "slack"]
```

`packs` enables the opt-in [built-in tool packs](/tools/builtins) — 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`).

## `[storage]`

```toml theme={null}
[storage]
backend = "file"        # default: plain files under data_dir
# backend = "memory"    # ephemeral (CI); or GRAPH_STORAGE=memory
```

## `[user]`

Injected into the agent's and planner's context:

```toml theme={null}
[user]
name = "Tyler"
context = "CEO and technical architect of LaunchNotes. Primary Linear team: LaunchNotes."
timezone = "America/Chicago"
```

## `[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.

```toml theme={null}
[prompts]
# Base system prompt for the chat/ask agent loop. The current date/time
# and the [user] name/context are still appended after it.
chat = """
You are graph, a command-line assistant for release engineering.
Lead with the answer; keep formatting terminal-friendly.
"""

# Addendum appended to the chat prompt inside `graph workbench`.
workbench = """
# Plan workbench
Operate on the draft plan with the workbench__* tools...
"""
```

The `workbench` override is the agent's only description of the `workbench__*` tools — how to draft, edit, validate, run, and save the plan in the side pane. Start from the built-in text (written into the file by `graph config init`) rather than writing from scratch, or the agent will stop using the workbench correctly.

## `[workbench]`

```toml theme={null}
[workbench]
log_path = "~/logs/graph-workbench.log"   # default: <data_dir>/workbench.log
```

Where the [workbench's debug log](/workbench/plan-workbench#debug-logging) is written (tilde-expanded). The `GRAPH_WORKBENCH_LOG` environment variable overrides both.


## Related topics

- [Models & providers](/models/models-and-providers.md)
- [Built-ins](/tools/builtins.md)
- [Scripting contract](/reference/scripting-contract.md)
- [Changelog](/changelog.md)
