On this page
Configure Haarness
Settings live in a haarness.json file. Put one in your home configuration folder for settings
that apply everywhere, and one in a project for settings that apply only there. Project settings
override yours, and command-line flags override both. The terminal UI, Desktop and the CLI all read
the same files.
Set your default model
Create ~/.config/haarness/haarness.json:
{
"model": "anthropic/claude-sonnet-5-5"
}New chats use that model in the terminal UI, in Desktop and with haarness run, unless you pick
another one there. A chat you already started keeps its own. haarness models lists what you can
choose.
Where settings live
| For | File |
|---|---|
| You, in every project | ~/.config/haarness/haarness.json |
| One project | haarness.json at the project root, or .haarness/haarness.json |
Both files may contain comments, and haarness.jsonc works as a name too. In a Git repository,
Haarness reads project files from the repository root down to the folder you are in; the nearer
file wins, and .haarness/haarness.json wins over haarness.json in the same folder.
A section you set in a project file, such as compaction, replaces the whole section from your
global file. defaults, providers, mcp and tool_availability are merged entry by entry
instead, and a project's permission rules are added after yours.
Other things have their own places:
| What | Where |
|---|---|
| Agents, commands, skills | agents/, commands/ and skills/ in ~/.config/haarness/ or the project's .haarness/ |
| Instructions | ~/.config/haarness/AGENTS.md, and AGENTS.md files in the project |
| Hooks | hooks in haarness.json; see Run commands on chat events |
| Provider credentials | ~/.local/share/haarness/auth.json; never in a project |
haarness.json or config.toml?
Use haarness.json for everything on these pages. haarness provider add, haarness mcp add,
haarness telemetry off and the settings screens in the terminal UI and Desktop write there, and
--project writes to the project's haarness.json.
~/.config/haarness/config.toml holds the terminal UI's own [tui] settings: shortcuts,
background colour and the status line command. See Make it yours.
Settings an older setup keeps in config.toml still work; when both files set the same thing,
haarness.json wins.
Desktop keeps its own window preferences, such as appearance and keyboard shortcuts, on this computer, outside these files.
Settings you might change
{
"small_model": "anthropic/claude-haiku-4-5", // a cheaper model for naming chats
"defaults": {
"reasoning_effort": "high", // none, minimal, low, medium, high, xhigh, max
"output_style": "concise", // concise, explanatory, formal, minimal
"ultracode": false // start new chats in ultracode
},
"compaction": {
"enabled": true, // false: only /compact summarises
"threshold": 0.85 // summarise when the context is this full
},
"snapshots": {
"retention_days": 7 // checkpoints behind /undo and /diff; 0 keeps them all
},
"tool_availability": {
"webfetch": false // hide a tool from the model
}
}| Setting | Does |
|---|---|
default_agent |
Agent for new chats, such as "build" |
small_model |
provider/model that names new chats. Auto's reviewer also uses it when it is on the chat's provider |
defaults.output_style |
A built-in style, or the name of your own file in output-styles/ |
compaction.tail_turns |
Recent turns kept word for word after a summary (default 2) |
snapshots.enabled |
On by default in Git repositories |
lazy_tools.mode |
auto (default), always or off: load rarely used tool descriptions only when needed |
tool_availability |
false hides a tool and blocks calls to it |
auto_review |
How Auto's reviewer model works: model, plain-language allow and block lines, timeout (60 s), or enabled: false. A project can only add block lines or lower timeout |
Permissions and Auto's reviewer, execution budgets, custom providers, MCP servers and hooks are configured in the same file and have their own pages.
Language servers and formatters
Built-in language servers are on and start only when the agent works on a matching file. If one
is not installed, the chat carries on and /status shows it as missing.
{
"lsp": {
"servers": {
"rust": { "enabled": false }, // turn off a built-in
"acme": { // add your own
"command": ["acme-language-server", "--stdio"],
"extensions": [".acme"]
}
}
},
"formatter": {
"enabled": true // off by default
}
}With formatting on, Haarness formats a file after the agent writes or edits it, using the
formatters it finds installed. Add your own under formatter.formatters.<name> with command
(use $FILE for the path) and extensions. Commands are lists of arguments; they never go
through a shell.
Give the agent project instructions
Write your rules in AGENTS.md. Haarness reads ~/.config/haarness/AGENTS.md first, then each
AGENTS.md from the repository root down to the folder you are in. When the agent reads a file in
a subfolder that has its own AGENTS.md, that file is added too.
An AGENTS.md can pull in another file with @docs/rules.md (or @"path with spaces.md").
Imports go at most five levels deep, and files over 40 KiB are skipped. A project file cannot
import a file from outside the folder you opened, and an import never reads a secret file such as
.env.
To add more files or URLs, list them under instructions:
{
"instructions": ["docs/rules/*.md", "~/team/rules.md", "https://example.com/rules.md"]
}A URL that fails to load is skipped.
To change Haarness's own built-in instructions rather than add to them, use a prompt file.
Use my CLAUDE.md files too
Haarness does not read Claude Code files unless you ask it to:
{
"compatibility": {
"claude_code": { "instructions": true }
}
}instructions adds CLAUDE.md files. agents, skills and commands do the same for the
matching .claude/ folders. If a folder has both, AGENTS.md wins.
Changes apply without a restart
Haarness picks up edits to settings, agents, commands, skills, hooks, MCP servers and workflows on its own. If a turn is running, it waits until the turn ends. If an edit is invalid, the previous settings stay in use. Snapshot settings apply the next time the workspace server starts.
Ignore a project's configuration
Open a repository you do not trust with:
haarness --disable-project-configor set HAARNESS_DISABLE_PROJECT_CONFIG=1. Haarness then ignores the project's settings,
AGENTS.md, agents, commands, skills, hooks, MCP servers, workflows, plugins and extensions. Your
own global configuration and the approvals you saved still apply. AGENTS.md files in subfolders
can still reach the model when it reads files there.
Give your team a shared starting setup
Point HAARNESS_SYSTEM_CONFIG_DIR at a folder laid out like ~/.config/haarness: a team's Git
checkout, or a folder your device management installs. Haarness reads this system folder below
everything else, so each person's own settings and the project's still win.
HAARNESS_SYSTEM_CONFIG_DIR=/opt/acme/haarness haarness
haarness doctor # shows "system config: /opt/acme/haarness"It can hold haarness.json, AGENTS.md, agents/, commands/, skills/, output-styles/,
prompts/, themes/ and local plugins in plugins/local/. The path must be absolute.
Haarness never writes into the folder, so it can be read-only. Its items are marked System in
Desktop and system in the terminal UI, with no Remove. Turning off one of its MCP servers saves your
own setting over it, and an agent that tries to edit a file there always asks you first.
Apps started from the Dock, Start menu or a launcher do not see variables from your shell profile.
Set the variable for your whole login session instead, for example with
launchctl setenv HAARNESS_SYSTEM_CONFIG_DIR /opt/acme/haarness on macOS, then open Desktop again.
Move Haarness's folders
Haarness follows XDG_CONFIG_HOME, XDG_DATA_HOME and XDG_CACHE_HOME (absolute paths) on every
system, including macOS. Set HAARNESS_HOME to an absolute path to keep everything under one
folder, for example for a CI job or a second, separate install: configuration, provider
credentials, chats, caches, schedules and the terminal UI's settings. Schedules made there also run
there. Where Haarness keeps its files
lists the folders.
Save and restore your setup
A profile is an archive of your configuration: settings, instructions, agents, commands, skills, hooks, workflows, output styles, themes and the plugins you installed. It never includes credentials or chats.
haarness profile save my-setup # writes my-setup.profile.zip
haarness profile inspect my-setup.profile.zip # show what is inside
haarness profile restore my-setup.profile.zip --dry-run
haarness profile restore my-setup.profile.zip--scope global or --scope local saves only your configuration or only this project's; the
default is both. Restore refuses to overwrite existing files unless you pass --force;
--dry-run lists every file it would add or replace. A profile does not carry your
usage statistics
choice: each computer keeps its own. An MCP secret kept in the keychain travels only as its
${keychain:NAME} reference.
To keep profiles on a Haarness server and restore them on another machine:
export HAARNESS_PROFILE_URL=https://haarness.example
export HAARNESS_PROFILE_TOKEN=…
haarness profile push my-setup.profile.zip
haarness profile search
haarness profile pull <id>Set the token in the environment rather than on the command line, so it stays out of your shell history. The URL must use HTTPS unless it is on your own machine.