fabro/docs/public/reference/user-configuration.mdx
Bryan Helmkamp 5f49cdf9da
Delete fabro-model and document the lithos catalog overlay
fabro-model's ids and billing rollup now live in fabro-types, and its
pricing, catalog, provider TOMLs, and legacy index are replaced by the
lithos built-in catalog plus the Fabro policy layer.

Regenerate the configuration reference for the `[llm]` overlay and
`metadata.fabro`, and rewrite the SDK, models, and integration docs for
the lithos provider and model shapes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-09 17:26:57 -06:00

418 lines
18 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.
The CLI and server each read the sections relevant to their own process. On a remote deployment, the CLI machine and the server machine each have their own `settings.toml`.
<Note>
Fabro only reads `settings.toml`. Older `cli.toml`, `user.toml`, and `server.toml` filenames are no longer part of the supported config surface.
</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/project.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]`, `[llm]`, `[cli]`, and `[server]`.
| Scope | Examples |
|---|---|
| CLI-only | `[cli.target]`, `[cli.auth]`, `[cli.exec]`, `[cli.output]`, `[cli.updates]`, `[cli.logging]` |
| Server-side run policy | `[run.model]`, `[run.environment]`, `[environments.<slug>]`, `[run.checkpoint]`, `[run.inputs]`, `[run.prepare]`, `[run.pull_request]`, `[run.integrations.github]`, `[run.hooks]`, `[run.agent.mcps]` |
| Shared LLM catalog | `[llm]`, a lithos-llm catalog overlay: `[llm.providers.<id>]`, `[llm.providers.<id>.models.<id>]`, and Fabro policy under `metadata.fabro` |
| 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/project.toml` or `workflow.toml` remain schema-valid but runtime-inert.
`fabro run` and `fabro create` do not copy the CLI machine's `[run]` or
`[environments]` tables into an intent request. They warn with only the file
path and affected key names when those tables are present. Put workflow-owned
behavior in `workflow.toml` and configure placement in environments managed by
the target server. The server may still use its own active `settings.toml`
independently.
See [Server Configuration](/administration/server-configuration) for the server-owned sections.
## Precedence
For CLI-created workflow runs, sparse CLI flags override immutable
`workflow.toml` behavior. The CLI does not layer local project or machine run
defaults into the request. A target server resolves its own server-side policy
and environment catalog during admission.
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/api/v1"
[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"
[llm.providers.proxy]
display_name = "Acme Gateway"
adapter = "openai-compatible"
codec = "openai-chat"
base_url = "https://llm-gateway.example.com/v1"
auth = { type = "bearer" }
aliases = ["gateway"]
default_model = "team-code-large"
[llm.providers.proxy.metadata.fabro]
agent_profile = "anthropic"
credentials = ["env:ACME_GATEWAY_API_KEY", "vault:ACME_GATEWAY_API_KEY"]
[llm.providers.proxy.metadata.fabro.extra_headers]
x-portkey-api-key = "{{ secrets.PORTKEY_API_KEY }}"
x-portkey-config = "@bedrock-prod"
[llm.providers.proxy.models."team-code-large"]
display_name = "Team Code Large"
aliases = ["team-code"]
api_model = "provider-wire-model-name"
limits = { context_tokens = 200000, max_output_tokens = 32000 }
capabilities = { text = true, tools = true, reasoning = true, reasoning_effort = { low = true, medium = true, high = true } }
protocol_options = { reasoning_effort_levels = true }
pricing = { input_usd_micros_per_million = 1500000, output_usd_micros_per_million = 8000000 }
```
All fields are optional. Include only the sections and keys you want to override. A single file can still include both CLI and server sections when you run both processes on one machine, but explicit remote targets do not read remote server state from the local machine.
<Note>
The `[run]` schemas below remain valid for a server's own active configuration,
but they are not CLI-side defaults for `fabro run` or `fabro create`. Put
automatic pull-request settings and other workflow-owned behavior in
`workflow.toml`; there is no compatibility request field or CLI global default.
</Note>
{/* generated:options */}
## `[cli.target]`
Connection info for commands that target a remote Fabro server.
```toml title="settings.toml"
[cli.target]
type = "http"
url = "https://fabro.example.com/api/v1"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `type` | `"http"` \| `"unix"` | None | Explicit transport selection. |
| `url` | string | None | Required for `type = "http"`; the API base URL. |
| `path` | string | None | Required for `type = "unix"`; the absolute Unix socket path. |
## `[llm]`
The `[llm]` table is a [lithos-llm](https://docs.rs/lithos-llm) catalog
overlay. Fabro builds its model catalog from three layers: the lithos built-in
providers and models, Fabro's policy layer, and this table. Later layers win;
tables merge key by key and every other value replaces. Fabro does not
interpret the table itself. lithos validates it when the catalog is built, and
rejects unknown provider or model fields.
Fabro-specific policy lives under `metadata.fabro` on a provider or model.
lithos carries that namespace verbatim.
```toml title="settings.toml"
[llm.providers.proxy]
display_name = "Acme Gateway"
adapter = "openai-compatible"
codec = "openai-chat"
base_url = "https://llm-gateway.example.com/v1"
auth = { type = "bearer" }
priority = 50
aliases = ["gateway"]
default_model = "team-code-large"
[llm.providers.proxy.metadata.fabro]
enabled = true
agent_profile = "anthropic"
credentials = ["env:ACME_GATEWAY_API_KEY", "vault:ACME_GATEWAY_API_KEY"]
[llm.providers.proxy.metadata.fabro.extra_headers]
x-portkey-api-key = "{{ secrets.PORTKEY_API_KEY }}"
x-portkey-config = "@bedrock-prod"
[llm.providers.proxy.models."team-code-large"]
display_name = "Team Code Large"
aliases = ["team-code"]
api_model = "provider-wire-model-name"
limits = { context_tokens = 200000, max_output_tokens = 32000 }
capabilities = { text = true, tools = true, reasoning = true, caching = true, reasoning_effort = { low = true, medium = true, high = true } }
protocol_options = { reasoning_effort_levels = true }
pricing = { input_usd_micros_per_million = 1500000, output_usd_micros_per_million = 8000000, cached_input_usd_micros_per_million = 300000 }
[llm.providers.proxy.models."team-code-large".metadata.fabro]
family = "team-code"
small_default = true
estimated_output_tps = 80
```
## `[llm.providers.<id>]`
Define or override an LLM provider. The keys are the lithos provider record.
| Key | Type / values | Default | Description |
|---|---|---|---|
| `display_name` | string | required for new providers | Human-readable provider name. |
| `adapter` | string | required for new providers | lithos adapter id: `anthropic`, `openai`, `gemini`, `openai-compatible`, or `bedrock`. |
| `codec` | string | required for new providers | Wire codec: `anthropic-messages`, `openai-responses`, `openai-chat`, `gemini-generate`, or `bedrock-converse`. |
| `base_url` | string | required for new providers | Provider API base URL. The `openai-compatible` adapter appends `/v1/chat/completions` unless the URL already ends in a version segment. |
| `auth` | table | required for new providers | Auth scheme: `{ type = "bearer" }`, `{ type = "header", name = "x-api-key" }`, `{ type = "headers" }`, `{ type = "none" }`, or `{ type = "aws" }`. |
| `priority` | integer | `0` | Higher-priority ready providers win unqualified model and default selection. |
| `aliases` | array<string> | `[]` | Additional provider names accepted by model routing and fallback config. |
| `default_model` | string | None | The provider's default model id. |
| `allow_passthrough` | boolean | `false` | Whether `provider/model` selectors may name models the catalog does not list. |
| `default_headers` | table | `{}` | Literal headers attached to every request. Secret-bearing headers belong in `metadata.fabro.extra_headers`. |
## `[llm.providers.<id>.metadata.fabro]`
Fabro's provider policy. Every key is optional.
| Key | Type / values | Default | Description |
|---|---|---|---|
| `enabled` | boolean | `true` | Set `false` to hide a provider from Fabro. Several built-in providers ship disabled. |
| `agent_profile` | `"anthropic"` \| `"openai"` \| `"gemini"` \| `"kimi"` \| `"gpt56"` | derived from `adapter` | Agent profile for models on this provider. |
| `api_key_url` | string | None | Where an operator obtains an API key. |
| `credentials` | array<string> | `[]` | Ordered credential refs: `vault:<NAME>`, `env:<NAME>`, or `aws_sigv4`. The first that resolves wins. |
| `extra_headers` | table | `{}` | Extra request headers. Values are literal text or `{{ secrets.NAME }}` interpolation strings resolved against the vault. |
## `[llm.providers.<provider>.models.<model-id>]`
Define or override one provider's offering of a model. The table key is the
model id Fabro users reference. An offering's identity is the pair
`(provider, model id)`, so different providers may use the same id and
aliases. `api_model` is the string sent to the provider and defaults to the id.
| Key | Type / values | Default | Description |
|---|---|---|---|
| `display_name` | string | required for new models | Human-readable model name. |
| `aliases` | array<string> | `[]` | Additional selectors. Aliases may repeat across providers. |
| `api_model` | string | model id | Wire model identifier sent to this provider. |
| `limits` | `{ context_tokens, max_output_tokens }` | None | Token limits. |
| `capabilities` | table | unknown | Per-capability `true`, `false`, or `"unknown"`: `text`, `images`, `audio`, `documents`, `tools`, `reasoning`, `caching`, `cache_routing`, `sampling`, plus `tool_choice = { required, named }`, `response_format = { json_object, json_schema }`, `reasoning_effort = { minimal, low, medium, high, xhigh, max }`, and `speed = { fast, balanced, economical }`. |
| `protocol_options` | table | `{}` | Encoding flags: `reasoning_effort_levels`, `cache_breakpoints`, `system_turns`. |
| `pricing` | table | None | USD micros per million tokens: `input_usd_micros_per_million`, `output_usd_micros_per_million`, `cached_input_usd_micros_per_million`, `cache_write_usd_micros_per_million`, plus optional `long_context` and `speed` tiers. |
## `[llm.providers.<provider>.models.<model-id>.metadata.fabro]`
Fabro's model policy. Every key is optional.
| Key | Type / values | Default | Description |
|---|---|---|---|
| `enabled` | boolean | `true` | Set `false` to hide a model from Fabro. |
| `agent_profile` | profile name | provider profile | Agent profile override for this model. |
| `family` | string | model id | Family label for display and grouping. |
| `training` | string | None | Training data cutoff label. |
| `knowledge_cutoff` | string | None | Public knowledge cutoff label. |
| `estimated_output_tps` | number | None | Estimated output tokens per second. |
| `small_default` | boolean | `false` | Preferred for small utility calls such as generated run titles. |
| `probe` | boolean | `false` | Preferred for provider connectivity probes. |
| `reasoning_by_default` | boolean | reasoning models with effort levels: `true` | Whether requests reason when no `reasoning_effort` is supplied. |
## `[cli.updates]`
`[cli.updates]` — upgrade check toggle
```toml title="settings.toml"
[cli.updates]
check = true
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `check` | boolean | true | Check for new Fabro releases during supported CLI commands. |
## `[cli.output]`
`[cli.output]` — generic CLI output defaults
```toml title="settings.toml"
[cli.output]
format = "text"
verbosity = "verbose"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `format` | "text" \| "json" | "text" | Output format for commands that support machine-readable output. |
| `verbosity` | "quiet" \| "normal" \| "verbose" | "normal" | Default output verbosity. |
## `[cli.exec]`
`[cli.exec]` — `fabro exec` defaults
```toml title="settings.toml"
[cli.exec]
prevent_idle_sleep = true
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `prevent_idle_sleep` | boolean | false | Prevent idle sleep on macOS while an exec run is in flight. |
## `[cli.exec.model]`
```toml title="settings.toml"
[cli.exec.model]
provider = "anthropic"
name = "claude-opus-4-6"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `name` | string | None | Model name for `fabro exec`. |
| `provider` | string | None | LLM provider for `fabro exec`. |
## `[cli.exec.agent]`
```toml title="settings.toml"
[cli.exec.agent]
permissions = "read-write"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `mcps` | table | None | Agent-scoped MCP entries for `fabro exec`. |
| `permissions` | "read-only" \| "read-write" \| "full" | "read-write" | Tool permission level for `fabro exec`. |
## `[run.model]`
`[run.model]` — provider-neutral default model selection
```toml title="settings.toml"
[run.model]
provider = "anthropic"
name = "claude-sonnet-4-5"
[run.model.fallbacks]
"claude-sonnet-4-5" = ["openrouter:kimi-k3", "gpt-terra"]
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `fallbacks` | table<string, array<string>> | {} | Model-keyed fallback chains. Each value is an ordered list of bare<br />providers, bare model IDs or aliases, or provider-qualified<br />`provider:selector` values. A qualified selector may be a model ID,<br />alias, or provider API ID. Legacy `provider/model` values remain<br />accepted. Each list supports the `...` splice marker at layering time.<br />Fabro selects one chain from the original requested model. A fallback<br />target never activates another model's chain.<br /><br />Model keys stay unresolved in this sparse layer because `fabro<br />validate` is offline and has no server model catalog. |
| `name` | string | None | Model name for workflow runs. |
| `provider` | string | None | Provider name for workflow model selection. |
## `[cli.logging]`
`[cli.logging]` — process-owned logging configuration for the CLI
```toml title="settings.toml"
[cli.logging]
level = "info"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `level` | "error" \| "warn" \| "info" \| "debug" \| "trace" | "info" | Default CLI log level. |
## `[run.git.author]`
```toml title="settings.toml"
[run.git.author]
name = "fabro-bot"
email = "fabro-bot@company.com"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `email` | string | "fabro@local" | Git author email for checkpoint commits. |
| `name` | string | "fabro" | Git author name for checkpoint commits. |
## `[run.pull_request]`
`[run.pull_request]` — provider-neutral PR behavior
```toml title="settings.toml"
[run.pull_request]
enabled = true
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `auto_merge` | boolean | false | Enable GitHub auto-merge for created pull requests. Implies `draft =<br />false`. |
| `draft` | boolean | true | Open created pull requests as drafts. |
| `enabled` | boolean | false | Automatically create a PR after successful runs. |
| `merge_strategy` | "merge" \| "squash" \| "rebase" | "squash" | Merge method to configure for the pull request. |
## `[run.agent]`
`[run.agent]` — agent knobs only (Fabro tools and MCPs)
```toml title="settings.toml"
[run.agent]
fabro_tools = true
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `fabro_tools` | boolean | false | Allow workflow agents to use Fabro run-management tools. |
| `mcps` | table | None | Agent-scoped MCP server entries, keyed by name. |
## `[run.agent.mcps.<name>]`
Configure MCP servers for workflow agents. For `fabro exec`-only MCPs, use `[cli.exec.agent.mcps.<name>]` with the same shape.
```toml title="settings.toml"
[run.agent.mcps.filesystem]
type = "stdio"
command = ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
startup_timeout = "15s"
tool_timeout = "90s"
```
| Key | Type / values | Default | Description |
|---|---|---|---|
| `type` | `"stdio"` \| `"http"` \| `"sandbox"` | None | MCP transport type. |
| `command` | array<string> | None | Command and arguments for `stdio` or `sandbox` transports. |
| `script` | string | None | Shell script alternative to `command` for process-launching transports. A `stdio` script runs on the host through `sh -c`; a `sandbox` script is evaluated inside the sandbox by non-login Bash. |
| `url` | string | None | Remote MCP URL for `http` transport. |
| `port` | integer | None | Sandbox port for `sandbox` transport. |
| `env` | table | `{}` | Additional environment variables for process-launching transports. |
| `headers` | table | `{}` | HTTP headers for `http` transport. |
| `startup_timeout` | duration | `"10s"` | Max duration for startup and MCP handshake. |
| `tool_timeout` | duration | `"60s"` | Max duration for a single MCP tool call. |
See [MCP](/agents/mcp) for transport-specific examples.
{/* /generated:options */}