Cluster Build

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.

View as Markdown

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 timeout

The 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 ups

Streamable 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 token

The 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 connect

A 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 = false

cluster 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 prompts

See Computer use for setup.

Tools

[tools.request_user_input]
default_mode = false   # true lets the assistant ask clarifying questions outside plan mode

The 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.md

Cluster 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 skip

Inspect 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 disabled

The 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:

  1. ~/.cluster/AGENTS.md — your global instructions.
  2. The repository root.
  3. 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/:

PathContents
config.tomlAll settings on this page and Config basics
auth.jsonYour sign-in token (created by cluster login)
AGENTS.mdGlobal 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.jsonlComposer 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

On this page