fabro/docs/reference/user-configuration.mdx
Bryan Helmkamp ed68c8b1d4 docs: migrate reference and guide examples to v2 config shape
Rewrite every docs/ reference and integration guide example that
previously showed legacy flat TOML (`[llm]`, `[vars]`, `[sandbox]`,
`[setup]`, `[exec]`, `[fabro]`, `[pull_request]`, `[mcp_servers]`,
`[git]`, `[web]`, `[api]`, `[features] retros`, `version = 1`,
top-level `storage_dir`) to use the v2 namespaced schema. Also update
the surrounding prose to describe v2 merge semantics (R22 run.inputs
wholesale replacement, R71 sticky sandbox.env/labels, R30 whole-list
prepare.steps replacement, hook id-based replacement).

Files touched:
- docs/reference/user-configuration.mdx (complete rewrite around
  [cli.*] ownership, [run.*] run-scoped defaults, [cli.target] /
  [cli.exec] / [cli.output] / [cli.updates] / [cli.logging], and
  [run.agent.mcps.<name>] with durations like "10s")
- docs/reference/cli.mdx (settings.toml example uses [cli.exec.*],
  [run.model], [cli.target])
- docs/execution/run-configuration.mdx (full run-config example
  rewritten to use [workflow].graph, [run].goal/working_dir,
  [run.model], [run.prepare.steps], [run.sandbox.daytona.snapshot]
  with Size values, [run.inputs], [run.artifacts], [run.agent.mcps],
  [run.pull_request], [[run.hooks]] with optional id and duration
  timeout; section docs explain the new merge semantics)
- docs/execution/environments.mdx and devcontainers.mdx (sandbox
  examples now use [run.sandbox.*])
- docs/execution/retros.mdx (retros moved to [run.execution] retros
  = true per R31)
- docs/execution/failures.mdx (fallbacks now a single ordered array
  under [run.model].fallbacks)
- docs/workflows/variables.mdx ([vars] → [run.inputs], wholesale
  replacement semantics explained)
- docs/administration/server-configuration.mdx (full reference
  rewritten around [server.listen]/[server.api]/[server.web]/
  [server.auth]/[server.storage]/[server.scheduler]/[server.logging]/
  [server.integrations])
- docs/api-reference/overview.mdx (auth strategies now enabled via
  [server.auth.api.jwt].enabled and [server.auth.api.mtls].enabled;
  listener TLS moved to [server.listen.tls])
- docs/integrations/daytona.mdx, github.mdx (provider config now
  nested under [run.sandbox.daytona] / [server.integrations.github])
- docs/human-tools/ssh-access.mdx (sandbox examples to v2)
- docs/agents/mcp.mdx (Playwright sandbox example to [run.agent.mcps])
- docs/core-concepts/models.mdx (model config and fallbacks array to
  [run.model])

Canonical fabro-cli overrides and server run_manifest now emit
verbose via [cli.output].verbosity = verbose rather than the prior
run.metadata staging. No code changes beyond those Stage 4 fixes that
were already in flight.
2026-04-09 11:30:52 -04:00

372 lines
12 KiB
Text

---
title: "Settings Configuration"
description: "Configure CLI and shared machine defaults with settings.toml"
---
Fabro loads machine defaults from `~/.fabro/settings.toml`. The file is optional. If it does not exist, Fabro falls back to built-in defaults.
On a same-machine setup, the CLI and server both read this file. On a remote setup, each machine has its own `settings.toml` and reads the sections relevant to that process.
<Note>
Legacy `cli.toml`, `user.toml`, and `server.toml` are ignored with a warning. Rename them to `settings.toml`.
</Note>
## File location
The default path is `~/.fabro/settings.toml`.
Use `fabro server start --config /path/to/settings.toml` if the server should read a different file.
## Schema version
Every Fabro config file must declare its schema version with a top-level `_version` key:
```toml title="settings.toml"
_version = 1
```
Files that omit `_version` are treated as version `1`. The legacy top-level `version` key is no longer accepted and raises a targeted rename hint.
## Who reads what
`settings.toml` uses the same schema as `fabro.toml` and `workflow.toml`, but each process only reads the fields it understands. The top-level schema is strictly namespaced — the only allowed domains are `[project]`, `[workflow]`, `[run]`, `[cli]`, `[server]`, and `[features]`.
| Scope | Examples |
|---|---|
| CLI-only | `[cli.target]`, `[cli.auth]`, `[cli.exec]`, `[cli.output]`, `[cli.updates]`, `[cli.logging]` |
| Shared run defaults | `[run.model]`, `[run.sandbox]`, `[run.checkpoint]`, `[run.inputs]`, `[run.prepare]`, `[run.pull_request]`, `[run.hooks]`, `[run.agent.mcps]` |
| Server-only | `[server.listen]`, `[server.api]`, `[server.web]`, `[server.auth]`, `[server.storage]`, `[server.artifacts]`, `[server.slatedb]`, `[server.scheduler]`, `[server.logging]`, `[server.integrations]` |
`[cli.*]` and `[server.*]` stanzas are owner-specific: they are only consumed from `~/.fabro/settings.toml` (plus process-local flags and env overrides). The same stanzas in `fabro.toml` or `workflow.toml` remain schema-valid but runtime-inert.
See [Server Configuration](/administration/server-configuration) for the server-owned sections.
## Precedence
Shared layered domains (`[project]`, `[workflow]`, `[run]`, `[features]`) use this override order:
1. **CLI flags** — always win
2. **Environment overrides** — Fabro-defined override channels
3. **`workflow.toml`** — per-workflow overrides
4. **`fabro.toml`** — project defaults
5. **`~/.fabro/settings.toml`** — machine defaults
6. **Built-in defaults**
Owner-specific domains (`[cli.*]`, `[server.*]`) use a narrower trust boundary — only CLI flags, env overrides, `~/.fabro/settings.toml`, and built-in defaults apply.
## Full example
```toml title="settings.toml"
_version = 1
[cli.target]
type = "http"
url = "https://fabro.example.com:3000/api/v1"
[cli.target.tls]
cert = "~/.fabro/tls/client.crt"
key = "~/.fabro/tls/client.key"
ca = "~/.fabro/tls/ca.crt"
[cli.exec]
prevent_idle_sleep = true
[cli.exec.model]
provider = "anthropic"
name = "claude-opus-4-6"
[cli.exec.agent]
permissions = "read-write"
[cli.output]
format = "text"
verbosity = "normal"
[cli.updates]
check = true
[cli.logging]
level = "info"
[run.model]
name = "claude-sonnet-4-5"
[run.git.author]
name = "fabro-bot"
email = "fabro-bot@company.com"
[run.pull_request]
enabled = true
[run.agent.mcps.filesystem]
type = "stdio"
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
startup_timeout = "15s"
tool_timeout = "90s"
[run.agent.mcps.filesystem.env]
NODE_ENV = "production"
[run.agent.mcps.sentry]
type = "http"
url = "https://mcp.sentry.dev/mcp"
[run.agent.mcps.sentry.headers]
Authorization = "Bearer sk-xxx"
```
All fields are optional. Include only the sections and keys you want to override. On a same-machine install, this same file can also include server sections such as `[server.web]` and `[server.api]`.
## `[cli.updates]`
Controls whether Fabro runs a daily background check for new releases. The check runs during `run`, `exec`, `init`, and `install` commands and prints a notice to stderr when a newer version is available.
```toml title="settings.toml"
[cli.updates]
check = true
```
| Key | Value | Description |
|---|---|---|
| `check` | `true` | Check for new releases (default) |
| `check` | `false` | Disable automatic upgrade checks |
The `--no-upgrade-check` CLI flag overrides this for a single invocation. See [`fabro upgrade`](/reference/cli#fabro-upgrade) for manual upgrades.
## `[cli.output]`
Generic CLI output defaults.
```toml title="settings.toml"
[cli.output]
format = "text"
verbosity = "verbose"
```
| Key | Values | Default |
|---|---|---|
| `format` | `"text"`, `"json"` | `"text"` |
| `verbosity` | `"quiet"`, `"normal"`, `"verbose"` | `"normal"` |
The `-v` / `--verbose` CLI flag always takes effect regardless of this setting.
## `[cli.exec]` section
Defaults for `fabro exec` sessions.
```toml title="settings.toml"
[cli.exec]
prevent_idle_sleep = true
[cli.exec.model]
provider = "anthropic"
name = "claude-opus-4-6"
[cli.exec.agent]
permissions = "read-write"
```
`[cli.exec.model]` selects the default LLM for exec:
| Key | Description | Values |
|---|---|---|
| `provider` | LLM provider | `"anthropic"`, `"openai"`, `"gemini"`, etc. |
| `name` | Model name | Any model ID from `fabro model list` |
`[cli.exec.agent]` controls agent behavior during exec:
| Key | Description | Values | Default |
|---|---|---|---|
| `permissions` | Tool permission level | `"read-only"`, `"read-write"`, `"full"` | `"read-write"` |
### Permission levels
- **`read-only`** — auto-approves read tools (`read_file`, `grep`, `glob`, `list_dir`) and subagent tools
- **`read-write`** — adds write tools (`write_file`, `edit_file`, `apply_patch`)
- **`full`** — allows all tools including shell commands
Tools outside the permission level are interactively prompted (if a TTY is present) or denied (with `--auto-approve`).
## `[run.model]` section
Defaults for workflow model selection in commands like `fabro run` and `fabro preflight`.
```toml title="settings.toml"
[run.model]
provider = "anthropic"
name = "claude-sonnet-4-5"
fallbacks = ["openai", "gpt-5.4", "gemini/gemini-flash"]
```
| Key | Description | Values | Default |
|---|---|---|---|
| `name` | Model name | Any model ID from `fabro model list` | Per provider |
| `provider` | Provider name | `"anthropic"`, `"openai"`, `"gemini"`, etc. | Auto-inferred from model/catalog |
| `fallbacks` | Ordered list of fallback model references | bare provider, bare alias, or `provider/model` | `[]` |
<Note>
Use `[cli.exec.model]` to configure provider and model for `fabro exec`. Use `[run.model]` for workflow-oriented defaults.
</Note>
## `[cli.logging]` section
Configure the default CLI log level. Precedence: `FABRO_LOG` env var > `--debug` flag > `[cli.logging].level` > `"info"`.
```toml title="settings.toml"
[cli.logging]
level = "info"
```
| Key | Values | Default |
|---|---|---|
| `level` | `"error"`, `"warn"`, `"info"`, `"debug"`, `"trace"` | `"info"` |
Server-side logging is a separate namespace at `[server.logging]`.
## `[run.git.author]`
Customize the git author identity used for checkpoint commits.
```toml title="settings.toml"
[run.git.author]
name = "fabro-bot"
email = "fabro-bot@company.com"
```
| Key | Description | Default |
|---|---|---|
| `name` | Git author name | `"fabro"` |
| `email` | Git author email | `"fabro@local"` |
## `[cli.target]` section
Connection info for commands that target a remote Fabro server.
```toml title="settings.toml"
[cli.target]
type = "http"
url = "https://fabro.example.com:3000/api/v1"
```
| Key | Description |
|---|---|
| `type` | `"http"` or `"unix"` — explicit transport selection |
| `url` | Required for `type = "http"` — the API base URL |
| `path` | Required for `type = "unix"` — the absolute Unix socket path |
`fabro model` uses `[cli.target]` by default when no explicit `--storage-dir` is passed. An explicit `--server` flag overrides the configured target:
```bash
fabro model list --server https://fabro.example.com:3000/api/v1
```
`fabro exec` does not automatically use `[cli.target]`. It only routes model traffic through a Fabro server when you pass `--server` for that invocation.
### `[cli.target.tls]` section
Optional mTLS configuration for authenticating with an HTTP target. When present, the CLI presents a client certificate during the TLS handshake.
```toml title="settings.toml"
[cli.target.tls]
cert = "~/.fabro/tls/client.crt"
key = "~/.fabro/tls/client.key"
ca = "~/.fabro/tls/ca.crt"
```
| Key | Description |
|---|---|
| `cert` | Path to client certificate PEM file |
| `key` | Path to client private key PEM file |
| `ca` | Path to CA certificate PEM file (to verify the server) |
Paths support `~/` expansion.
## `[run.pull_request]`
Enable auto-PR globally so workflows open a GitHub pull request on successful completion.
```toml title="settings.toml"
[run.pull_request]
enabled = true
```
| Key | Description | Default |
|---|---|---|
| `enabled` | Automatically create a PR after successful runs | `false` |
| `draft` | Open the PR as a draft | `true` |
| `auto_merge` | Enable GitHub auto-merge on the created PR (implies `draft = false`) | `false` |
| `merge_strategy` | One of `"squash"`, `"merge"`, `"rebase"` | `"squash"` |
Precedence: `workflow.toml` > `fabro.toml` > `~/.fabro/settings.toml` > built-in default (`false`).
## `[run.agent.mcps]` section
Configure [MCP servers](/agents/mcp) to connect to during agent-driven runs. Each server is a named TOML table under `[run.agent.mcps]`. For `fabro exec`-only MCPs, use `[cli.exec.agent.mcps.*]` with the same shape.
### Stdio transport
Spawn a local process and communicate over stdin/stdout:
```toml title="settings.toml"
[run.agent.mcps.filesystem]
type = "stdio"
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
startup_timeout = "15s"
tool_timeout = "90s"
[run.agent.mcps.filesystem.env]
NODE_ENV = "production"
```
| Key | Description | Default |
|---|---|---|
| `type` | Must be `"stdio"` | — |
| `command` | Array: executable + arguments | — |
| `env` | Additional environment variables for the child process | `{}` |
| `startup_timeout` | Max duration for the MCP handshake (e.g. `"10s"`, `"30s"`) | `"10s"` |
| `tool_timeout` | Max duration for a single tool call (e.g. `"60s"`, `"2m"`) | `"60s"` |
### HTTP transport
Connect to a remote MCP server over Streamable HTTP:
```toml title="settings.toml"
[run.agent.mcps.sentry]
type = "http"
url = "https://mcp.sentry.dev/mcp"
[run.agent.mcps.sentry.headers]
Authorization = "Bearer sk-xxx"
```
| Key | Description | Default |
|---|---|---|
| `type` | Must be `"http"` | — |
| `url` | The MCP server endpoint URL | — |
| `headers` | Optional HTTP headers (for example, for authentication) | `{}` |
| `startup_timeout` | Max duration for the MCP handshake | `"10s"` |
| `tool_timeout` | Max duration for a single tool call | `"60s"` |
### Sandbox transport
Run an MCP server inside the workflow's sandbox and connect via preview URL. Only available with remote sandbox providers ([Daytona](/integrations/daytona)) that support port previews. Typically configured in `workflow.toml` rather than `settings.toml`:
```toml title="workflow.toml"
[run.agent.mcps.playwright]
type = "sandbox"
command = ["npx", "@playwright/mcp@latest", "--port", "3100", "--headless"]
port = 3100
startup_timeout = "60s"
tool_timeout = "2m"
```
| Key | Description | Default |
|---|---|---|
| `type` | Must be `"sandbox"` | — |
| `command` | Array: the command to run inside the sandbox | — |
| `port` | Port the server listens on inside the sandbox | — |
| `env` | Additional environment variables for the server process | `{}` |
| `startup_timeout` | Max duration for startup + MCP handshake | `"10s"` |
| `tool_timeout` | Max duration for a single tool call | `"60s"` |
See [MCP — Sandbox transport](/agents/mcp#sandbox) for how Fabro launches and connects to sandbox MCP servers.