---
title: "Configuration"
description: "Every setting the daemon reads: the four layers and which wins, the TOML blocks with their defaults, and the environment variables that override them."
canonical: "https://scalebrowser.net/docs/ops/configuration"
---

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

# Configuration

> Every setting the daemon reads: the four layers and which wins, the TOML blocks with their defaults, and the environment variables that override them.

Four layers, later ones win:

1. built-in defaults
2. a TOML file, passed with `--config`
3. environment variables
4. command-line flags

Every field has a default, so a daemon with no configuration at all starts and serves.

## The top level
| Key                  | Default                    | What it does                                                                             |
| -------------------- | -------------------------- | ------------------------------------------------------------------------------------------ |
| `bind_addr`          | `127.0.0.1:8787`           | The native API: REST, MCP over HTTP, the CDP WebSocket. Non-loopback requires `[tls]`.    |
| `adspower_bind`      | off                        | The [AdsPower adapter](/docs/adspower). Loopback only, and off until you set it.          |
| `data_dir`           | `%ProgramData%\Scalebrowser`  | Database, engines, profile directories, the at-rest key. |
| `engines_dir`        | follows `data_dir`         | Set it only to split the tree deliberately. Once set, it stops following.                 |
| `profiles_dir`       | follows `data_dir`         | Same.                                                                                     |
| `bearer_token`       | generated on first start   | The token clients send.                                                                    |
| `engine_feed_url`    | none                       | A signed engine feed to check at startup. Without one the daemon never reaches out and `engine install` is the only path in. |
| `webui_dir`          | the embedded bundle        | Serve the management interface from a directory instead.                                  |
| `ja4t_reflector_url` | none                       | An endpoint that reports the TCP fingerprint it saw. Fetched **through** the proxy during a check, which is the only way to learn the exit device's fingerprint. |
| `error_reporting`    | `false`                    | Crash reports. Off by default: on an anti-detect product, telemetry nobody asked for is a surprise that costs the relationship. |
| `error_dsn`          | none                       | Where they go. Empty disables reporting whatever the flag says.                            |
| `log_json`           | `false`                    | Machine-readable log lines. On where something parses them, off where a person reads them.  |

## `[secret]`
Where the at-rest master key comes from. One of the two:

| Key        | What it does                                    |
| ---------- | ------------------------------------------------- |
| `key_env`  | Name of the environment variable holding it.     |
| `key_file` | Path to a file holding it.                       |

## `[capacity]`
Hard limits, so a launch is refused rather than the host running out of memory.

| Key               | Default | What it does                                    |
| ----------------- | ------- | ------------------------------------------------- |
| `max_concurrent`  | `64`    | Browsers on this machine at once.                |
| `ram_budget_mb`   | `24576` | Memory the pool may use.                         |
| `vram_budget_mb`  | none    | Video memory, when you want a ceiling on it.     |

Three limits apply to a launch and the strictest wins: these two, and the host's measured free memory. Exceeding any of them is error `4003`.

## `[tls]`
| Key          | What it does                          |
| ------------ | --------------------------------------- |
| `cert_path`  | PEM certificate chain.                 |
| `key_path`   | PEM private key.                       |

Required for a non-loopback bind, optional on loopback, and honoured there too if set. 

## `[mcp]`
Everything here is decided server-side. No tool call can widen the catalog or leave read-only mode.

| Key                   | Default    | What it does                                                                            |
| --------------------- | ---------- | ----------------------------------------------------------------------------------------- |
| `profiles`            | `["core"]` | Which [tool profiles](/docs/agents/tools) are served.                                    |
| `read_only`           | `false`    | Mutating tools are neither listed nor executed.                                          |
| `lease_ttl_secs`      | `900`      | How long a reservation lives by default.                                                  |
| `lease_ttl_max_secs`  | `14400`    | Ceiling on what a caller may ask for. Four hours.                                         |
| `url_allowlist`       | `[]`       | Exceptions to the `open_page` address rule. Exact hosts or `host:port`.                   |
| `artifact_quota`      | `256`      | How many artifacts are kept per profile.                                                  |
| `artifact_max_bytes`  | 24 MiB     | Ceiling on one artifact.                                                                  |
| `artifact_ttl_secs`   | `14400`    | Retention. Matches the lease ceiling, so an artifact from the start of a long run is still there at the end. |
| `allowed_hosts`       | `[]`       | Extra `Host` values the MCP transport accepts, on top of loopback and the configured bind. |
| `snapshot_full_every` | `5`        | Force a full page map every N steps. `0` disables it.                                     |
| `transcribe_command`  | `[]`       | Your program for [audio challenges](/docs/agents/verification). One argument in, text out. |
| `inbox_command`       | `[]`       | Your program for [non-IMAP inboxes](/docs/inboxes), such as an SMS service.                |
| `inbox_require_proxy` | `false`    | Refuse an inbox read that would leave over this machine's own connection.                 |

<Warning>

**`url_allowlist` empty is the safe state.** Empty means `open_page` permits public `http` and `https` only: no `file:`, no loopback, no private or link-local networks, no cloud metadata address. Every entry you add is a door into your own network that an agent can walk through.

</Warning>

## `[observability]`
| Key                  | Default            | What it does                                                          |
| -------------------- | ------------------ | ----------------------------------------------------------------------- |
| `sample_interval_ms` | `3000`             | Cadence of the background sampler behind `GET /v1/metrics`.            |
| `enable_prometheus`  | `false`            | The opt-in scrape endpoint.                                            |
| `prometheus_bind`    | `127.0.0.1:9464`   | Its listener. Unauthenticated plaintext; keep it on loopback.          |

## `[runs]`
| Key                  | Default | What it does                                                        |
| -------------------- | ------- | --------------------------------------------------------------------- |
| `shots`              | `true`  | Keep a still per step in the [activity trail](/docs/agents/runs).    |
| `shots_max_gb`       | `20`    | Disk ceiling for them.                                                |
| `shots_max_age_days` | `30`    | Retention.                                                            |
| `page_watcher`       | `true`  | Follow what the bound tab is showing.                                 |

## `[exit]`
The [exit-address rule](/docs/proxies#one-address-one-profile).

| Key               | Default                                    | What it does                                                    |
| ----------------- | ------------------------------------------ | ----------------------------------------------------------------- |
| `enabled`         | `true`                                     | The whole rule.                                                  |
| `probe_url`       | `https://probe.scalebrowser.net/v1/addr`   | Where the address is measured.                                   |
| `neighbour_hard`  | `false`                                    | Treat two addresses in one IPv4 `/24` as a collision, not advice. |
| `heartbeat_secs`  | `30`                                       | Keep-alive beat, where a provider documents an idle cut-off.      |
| `check_secs`      | `120`                                      | Address check.                                                   |
| `max_draws`       | `5`                                        | How many session tags a start may try before refusing with `4013`. |

## `[sync]` and `[remote]`
[Profile sync](/docs/sync) and [remote access](/docs/agents/remote) have their own blocks. Both have a switch in the management app, and for remote access that switch is the one to use: the daemon reads it on every beat, so it takes effect without a restart.

## Environment variables
Every one of these overrides the TOML.

| Variable                         | Sets                                             |
| -------------------------------- | -------------------------------------------------- |
| `SCALEBROWSER_BEARER_TOKEN`      | The API token clients send.                       |
| `SCALEBROWSER_MASTER_KEY`        | The at-rest key.                                  |
| `SCALEBROWSER_API_TOKEN`         | The pairing token for this machine.               |
| `SCALEBROWSER_DATA_DIR`          | `data_dir`.                                        |
| `SCALEBROWSER_ENGINES_DIR`       | `engines_dir`.                                     |
| `SCALEBROWSER_PROFILES_DIR`      | `profiles_dir`.                                    |
| `SCALEBROWSER_BIND_ADDR`         | `bind_addr`.                                       |
| `SCALEBROWSER_ADSPOWER_BIND`     | `adspower_bind`. Takes the word `off`.             |
| `SCALEBROWSER_WEBUI_DIR`         | `webui_dir`.                                       |
| `SCALEBROWSER_ENGINE_FEED_URL`   | `engine_feed_url`.                                 |
| `SCALEBROWSER_CONTROL_PLANE_URL` | Where the account lives.                           |
| `SCALEBROWSER_MCP_PROFILES`      | `[mcp] profiles`, comma separated.                 |
| `SCALEBROWSER_MCP_READ_ONLY`     | `[mcp] read_only`.                                 |
| `SCALEBROWSER_ENABLE_PROMETHEUS` | `[observability] enable_prometheus`.               |
| `SCALEBROWSER_PROMETHEUS_BIND`   | `[observability] prometheus_bind`.                 |
| `SCALEBROWSER_SAMPLE_INTERVAL_MS`| `[observability] sample_interval_ms`.              |
| `SCALEBROWSER_ERROR_DSN`         | `error_dsn`.                                       |
| `SCALEBROWSER_ERROR_REPORTING`   | `error_reporting`.                                 |

Two more are about the host rather than the daemon: `SB_HOST_GPU_CLASS` and `SB_HOST_GPU_VENDOR` skip the boot GPU probe.

<Warning>

**Never set `SB_HOST_GPU_CLASS` on a machine you are actually running profiles on**, unless you also set the vendor. The skipped probe never learns which GPU family the host has, and the profile can then ship a GPU string from the wrong one, which is a contradiction a page finds in one comparison.

</Warning>

## Next
- [CLI reference](/docs/ops/cli): the flags and subcommands.
- [Troubleshooting](/docs/ops/troubleshooting): what these settings look like when one is wrong.
- [MCP server](/docs/agents/mcp-server): what `[mcp]` does to an agent.
