Advanced configuration
The structured parts of config.toml — Ollama model providers, MCP servers and their credentials, the built-in browser and computer tools, skills, custom commands, workspace trust, project instructions, and where Cluster Build keeps its state.
This page covers the parts of ~/.cluster/config.toml that go beyond a
single key: nested tables you edit by hand or through a dedicated command,
and where the CLI keeps its state.
For the flat keys and cluster config set, see
Config basics.
Model providers
The cluster provider is built in: it talks to api_url with your Cluster
sign-in. You can add one Ollama provider as a keyless
alternative and choose which one a new session starts on:
default_model_provider = "gpuserver"
default_model = "qwen3.5:9b"
[model_providers.gpuserver]
kind = "ollama"
base_url = "http://gpuserver:11434"base_url is the host root; Cluster Build appends /v1. At most one
provider table is allowed, kind must be "ollama", and
default_model_provider must name either cluster or that table. /model
lists Cluster models and every reachable configured provider, so the
default only sets the startup selection.
MCP servers
Connect the assistant to Model Context Protocol
servers with one [mcp.servers.<name>] table each. The name becomes a log
file name and part of every tool id (mcp__<server>__<tool>), so keep it to
letters, digits, -, and _, and avoid a double underscore.
[mcp.servers.example]
transport = "stdio" # or "streamable_http"
command = "npx" # stdio: executable to launch
args = ["@example/mcp-server"]
read_only_tools = [] # tool names plan mode may still call
enabled = true # false keeps it listed but never connects
startup_timeout_sec = 5 # handshake timeout
tool_timeout_sec = 120 # per tool-call timeoutThe transport-specific fields — env_vars and env for stdio, url and
the auth fields for streamable HTTP — are covered below, and the
sample config shows every field in one place.
MCP tools run under the same workspace trust
decision as native tools — there is no per-call confirmation. Add a server
only when you trust it, and list its safe operations in read_only_tools so
plan mode can still call them.
stdio servers
Cluster Build starts command as a child process when the server is needed.
The executable must be on PATH in the shell where you start cluster;
Python servers commonly use uvx, Node servers npx. For a local checkout,
point command and args at the built executable, such as
command = "node" and args = ["/path/to/server/dist/index.js"].
Pass credentials with env_vars — a list of environment variable names.
Cluster Build reads each value from its own environment at startup and
forwards it to the child under the same name, so only the names live in
config.toml. Use the nested env table for non-secret literals (or, for
backwards compatibility, ${env:VAR} templates). If the same key appears in
both, the explicit env value wins.
[mcp.servers.ups]
transport = "stdio"
command = "npx"
args = ["-y", "ups-mcp"]
startup_timeout_sec = 30
tool_timeout_sec = 120
env_vars = ["UPS_CLIENT_ID", "UPS_CLIENT_SECRET", "UPS_ACCOUNT_NUMBER"]
[mcp.servers.ups.env]
UPS_ENVIRONMENT = "production" # or "sandbox"A stdio child receives only a small default allowlist (such as PATH,
HOME, and SHELL) plus env_vars and env — it does not inherit
arbitrary variables from your shell. If an env_vars entry is unset or
empty, that server is marked unavailable until you fix the environment and
restart.
export UPS_CLIENT_ID=...
export UPS_CLIENT_SECRET=...
export UPS_ACCOUNT_NUMBER=...
cluster mcp test upsStreamable HTTP servers
For a streamable_http server behind authentication, supply a bearer token
with bearer_token_env_var (the name of an environment variable holding the
token) and/or env-backed headers with env_http_headers (header name to
variable name). As with env_vars, only the names are stored; values are
read at startup.
[mcp.servers.tasks]
transport = "streamable_http"
url = "https://tasks.example/mcp"
bearer_token_env_var = "TASKS_MCP_TOKEN"
[mcp.servers.tasks.env_http_headers]
X-Api-Key = "TASKS_API_KEY"The older auth_token and headers fields still work and accept
${env:VAR} templates, but the name-only fields are preferred. All of these
are streamable-HTTP-only — setting them on a stdio server is an error. Set
at most one bearer source (bearer_token_env_var, auth_token, or
oauth_audience), and don't combine bearer auth with an explicit
Authorization header. cluster doctor warns when a server stores a likely
secret inline and points you at the name-only fields, without printing the
value.
Per-user OAuth
For a server whose tools gate on the caller's identity, the CLI can manage a
per-user OAuth token instead of a static credential. Set oauth_audience,
oauth_client, and a non-empty oauth_scopes array (all required together,
streamable-HTTP-only, and mutually exclusive with the bearer fields), then
log in once:
cluster mcp login <server> # browser PKCE login; stores a per-user token
cluster mcp logout <server> # remove the stored tokenThe token lives at ~/.cluster/mcp-auth/<server>.json, separate from your
main cluster login, and is refreshed and injected automatically. Until you
log in, the server connects unauthenticated and fails its handshake. If the
token expires mid-session and the server answers 401, the CLI refreshes it
once, rebuilds the connection, and retries.
Disabling and inspecting servers
Set enabled = false to keep a server in your config but stop connecting to
it. It stays listed in /mcp and cluster mcp list but registers no tools.
cluster mcp list # every configured server; an unresolvable one shows as `crashed` with its error
cluster mcp test <server> # connect to one server; exits non-zero if it can't resolve or connectA single server whose config can't resolve no longer takes down the CLI: it
is listed as crashed while every healthy server and your native tools keep
working. Inside a session, /mcp opens a live manager to reconnect, enable
or disable, authenticate, and inspect a server's tools without restarting.
Built-in browser
A Playwright-backed browser provider is enabled out of the box and appears
in /mcp alongside your own servers. Turn it off, or replace it by
declaring any browser-capability MCP server of your own:
[browser]
enabled = falsecluster config set browser_enabled false writes the same thing. Browser
tools ask before accessing each new HTTP(S) origin and remember accepted
origins only for the current session.
Computer tool
The native computer desktop tool is opt-in and only advertised on
supported graphical sessions (Linux GNOME Wayland, macOS 26+):
[computer]
enabled = true
unattended = false # true suppresses the per-process capture and control promptsSee Computer use for setup.
Tools
[tools.request_user_input]
default_mode = false # true lets the assistant ask clarifying questions outside plan modeThe request_user_input tool is always available in plan mode.
Skills
Skills are reusable instructions the assistant can pull in on demand. Drop a
SKILL.md (YAML frontmatter plus a Markdown body) into its own directory
under ~/.cluster/skills/:
~/.cluster/skills/
my-skill/
SKILL.mdCluster Build discovers skills at startup and loads a skill's body when it is
relevant. Manage discovery with a [skills] table:
[skills]
enabled = true # master switch
disabled = [] # skill directory names to skipInspect them with cluster skills list / cluster skills show <name>, or
/skills in a session.
Custom commands
Custom commands are local prompt shortcuts — explicit macros you invoke
yourself, rather than instructions the model pulls in on its own. Drop a
Markdown file at ~/.cluster/commands/<name>.md:
---
description: Review a requested scope
---
Review $ARGUMENTS carefully and report concrete findings.~/.cluster/commands/review.md then shows up in the slash menu as /review
with a [Command] badge. Running /review src/lib.rs — interactively or
with cluster exec — replaces every $ARGUMENTS in the body before sending
the request. Frontmatter is optional; without description, the first
non-empty body line is used. Only immediate .md files are loaded, and a
built-in slash command always wins a name collision.
Workspace trust
Saved workspace trust decisions
live in config.toml, one [projects."<canonical-root>"] table per
directory. Manage them with cluster trust rather than editing by hand:
cluster trust add [path] # trust a workspace (defaults to the current directory)
cluster trust remove [path]
cluster trust list[projects."/Users/me/src/app"]
trust_level = "trusted"
[projects."/Users/me/src/app/vendor"]
trust_level = "untrusted" # suppresses the prompt and keeps execution disabledThe root is the repository root, so trusting any subdirectory trusts the whole repository; git linked worktrees map to their main checkout. The nearest configured ancestor wins, so an untrusted child can sit under a trusted parent. Cluster refuses to persist trust for the filesystem root or your home directory.
Project instructions
When include_project_instructions is on (the default), Cluster Build sends
instruction files with every request as non-persisted context. It looks for
the first of AGENTS.override.md, AGENTS.md, or CLAUDE.md in each of
these places, in order:
~/.cluster/AGENTS.md— your global instructions.- The repository root.
- Each directory between the root and your current working directory.
Outside a git repository only the working directory is searched. Discovery is bounded: files are truncated once the total budget is spent, and the model sees a truncation marker when that happens.
Config and state locations
Everything Cluster Build stores lives under ~/.cluster/:
| Path | Contents |
|---|---|
config.toml | All settings on this page and Config basics |
auth.json | Your sign-in token (created by cluster login) |
AGENTS.md | Global project instructions |
sessions/ | Saved conversations (cluster sessions ls) |
subagents/ | Transcripts of local child agents, grouped by root session |
tool_outputs/ | Spooled bodies of large tool results |
memories/ | Cross-session memory (MEMORY.md, per-project files, raw extracts) |
skills/ | Your custom skills |
commands/ | Your custom slash commands |
themes/ | User-provided syntax themes |
mcp-auth/ | Per-server MCP OAuth tokens |
logs/ | Rolling cluster.log.<date> files and mcp/<server>.log |
update/ | Auto-update state and lock |
cron/ | Per-project automation state |
history.jsonl | Composer input history |
Config writes use config.lock next to the file for cross-process locking.
The directory and its files are created with owner-only permissions.
Next steps
- Environment variables — one-run overrides, proxies, and logging.
- Sample config.toml — every table above in one annotated file.