Skip to content
DocsHaarness CLI
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-config

or 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.