Configuration
Free and Pro
Thrum keeps its settings in .thrum/config.json in your repository. Every key has a default, so you edit the file only to change something. This page lists the keys you might change. It leaves out internal keys, and it never shows secrets. The email bridge and email notifications need Pro. The Telegram settings work on Free.
Change a setting
Section titled “Change a setting”After setup, ask your coordinator to change a setting. Your coordinator is the agent you talk to, which starts the other agents, hands out work and reports back to you. It edits the file and restarts the daemon (Thrum’s background process) when the change needs that. This is an example conversation. Your coordinator’s wording will differ. Before you have a coordinator, edit the file yourself, as shown below, and run thrum daemon restart when the change needs it.
You: Keep the web UI on port 9999 from now on.Coordinator: Set daemon.ws_port to "9999" in .thrum/config.json and restarted the daemon. The UI address is now on port 9999.Two commands help when you want to look yourself:
| Command | What it does | Who runs it |
|---|---|---|
thrum config show |
Prints the settings in effect and where each value comes from: the file, an environment variable or the default. It works whether or not the daemon is running. | You or the coordinator |
thrum config set <key> <value> |
Sets keys that Thrum shares between paired machines, for example project_name or orchestration.merge_target. It refuses keys that belong to one machine (ports, local paths). Edit those in the file. |
You or the coordinator |
Write a dotted key such as daemon.ws_port as nested JSON in the file:
{ "daemon": { "ws_port": "9999" }}The daemon reads daemon.*, transcripts.* and the backup schedule when it starts. After you change one of them, ask the coordinator to restart the daemon.
Daemon and web UI
Section titled “Daemon and web UI”| Key | Default | What it changes |
|---|---|---|
daemon.ws_port |
"auto" |
The port the web UI is served on. Thrum’s web UI is the page you open in your browser to see your agents and their messages. This is the port in the address on the ui line of thrum daemon status. "auto" reuses the port from the last run when it is still free, and picks a free one otherwise, so the address normally stays the same across restarts. A number in quotes, such as "9999", pins the port. |
daemon.sync_via_git |
off | Whether Thrum shares its data through your Git remote. Set true to turn it on. When the key is absent, Git sync is off. Anyone with access to that remote can read your agents’ messages. |
daemon.log_level |
"info" |
How much the daemon writes to its log. One of debug, info, warn, error. |
daemon.max_message_body_bytes |
1048576 (1 MB) |
The largest message body Thrum accepts when a message is written. A value below 1024 is raised to 1024. A negative value removes the limit. |
daemon.account_usage_quota_axi |
false |
Turns on account usage on this machine: how much of each AI tool’s usage limit you have used, shown in the Accounts section of thrum team. The key name comes from quota-axi, the helper tool that reads the usage. Restart the daemon after a change. See See how much of each AI account you have used. |
daemon.account_usage_runtimes |
claude, codex, cursor, copilot |
The AI tools to read. Add muse, antigravity or opencode to include them. |
project_name |
your repository’s folder name | A short name for the project. Permission-prompt messages come from @supervisor_ plus this name. |
Agents, models and runtimes
Section titled “Agents, models and runtimes”| Key | Default | What it changes |
|---|---|---|
runtime.primary |
the runtime you chose in thrum init |
The AI tool new agents start in, for example claude. A runtime is the AI coding tool an agent runs in, such as Claude Code or Codex. Mix runtimes and models lists the tools. |
runtime.default_model |
none | The model for an agent whose role has no built-in or configured model. |
runtime.default_effort |
none | The effort level that goes with runtime.default_model. |
runtime.role_models.<role>.model |
built-in per-role choice | The model for every new agent with that role, for example reviewer. It applies to Claude-family runtimes only. On other runtimes Thrum ignores it and logs a warning. |
runtime.role_models.<role>.effort |
built-in per-role choice | The effort level for every new agent with that role. Same limit as the model key. |
A model or effort you name when you create an agent wins over these keys. After that, the order is role_models, then the built-in choice for the role, then default_model. If none of them names a model, the AI tool uses its own default.
{ "runtime": { "role_models": { "reviewer": { "model": "opus", "effort": "high" } } }}The model and effort names above are examples. Use names your AI tool accepts.
Worktrees and project settings
Section titled “Worktrees and project settings”| Key | Default | What it changes |
|---|---|---|
worktrees.base_path |
~/.thrum/worktrees/<project>, where <project> is your repository’s folder name |
The folder where the coordinator creates a worktree for each agent. A worktree is a separate checkout of your repository on its own branch. thrum init asks for it and saves your answer. |
worktrees.beads_enabled |
true if the bd program was on your PATH when you ran thrum init, otherwise false |
Whether new worktrees are set up to use Beads, an issue tracker for AI agents that you reach with the bd command. |
worktrees.thrum_enabled |
true |
Whether Thrum writes its hooks into the Claude Code settings of each new worktree. Set false if you manage .claude/settings.json yourself. |
orchestration.merge_target |
the branch you were on when you ran thrum init, or main |
The branch the coordinator merges finished work into. |
orchestration.push_policy |
"push" |
"push" tells agents to push their commits. "local_hold" tells them to keep commits local. Use "local_hold" only if you accept that unpushed work can be lost. |
orchestration. |
"end_only" |
How often an orchestrator (an extra agent that runs the implementers for bigger work) pauses: "per_epic" after each epic, "end_only" only before the merge. Used when the plan and its hand-off message name neither. See Add an orchestrator. |
Permission prompts
Section titled “Permission prompts”| Key | Default | What it changes |
|---|---|---|
permission_supervisors |
["coordinator"] |
Who receives the message when an agent stops at a permission prompt. Each entry is a role ("coordinator"), an agent ("@impl_api") or you ("@user:<your-username>"). For a prompt, a role only helps Thrum find one named coordinator. Answer permission prompts shows the messages. |
permission_human_delay |
"5m" (5 minutes) |
How long a prompt stays on screen after an agent got the message before the @user: entries are told as well. Write it as a duration string, such as "10m". If no agent could receive it, you are told at once. |
permission_approver |
none | One agent or user ("@agent_name" or "@user:<name>") that receives these messages alone. When it is not available, Thrum falls back to permission_supervisors. |
Restart and context
Section titled “Restart and context”These keys control how agents save their place. Keep context when an agent restarts explains the feature.
| Key | Default | What it changes |
|---|---|---|
restart.max_lines |
200 |
The longest snapshot an agent saves before a restart. A snapshot is a note an agent writes before a restart or a compaction, with what it did and what is next. |
restart.graceful_timeout |
300 (seconds) |
How long Thrum waits for an agent to save its own snapshot before it stops waiting. |
restart.context_notice_at |
50 (percent) |
The share of an agent’s context window at which Thrum first tells the agent to save its place. |
restart.context_reminders_at |
[60, 70, 80] |
The shares at which Thrum reminds the agent again. [] turns the reminders off. |
restart.context_compact_at |
90 (percent) |
The share at which Thrum compacts the agent, which shrinks a conversation that has filled its context window so the agent can go on: on Claude Code, Codex, Cursor and opencode it types the compact command into the agent’s tmux pane. tmux keeps each agent running in its own terminal session. Other runtimes get a final reminder to restart. |
restart.auto_disabled_agents |
none | Agent names that Thrum does not compact. They still get the notice, the reminders and a final reminder at the compact point. |
restart.silence_watchdog_seconds |
30 |
How long after a launch or restart Thrum waits for the agent’s terminal to show output before it sends a nudge. A negative value turns the nudge off. |
Terminal size
Section titled “Terminal size”The terminal_mirror block sets the size of the Terminal tab in the web UI and of the tmux sessions that new agents start in. Run agents in tmux shows the tab.
| Key | Default | What it changes |
|---|---|---|
terminal_mirror.default_cols |
180 |
Terminal width in columns. Allowed range 20 to 500. |
terminal_mirror.default_rows |
45 |
Terminal height in rows. Allowed range 5 to 200. |
terminal_mirror.scrollback_lines |
100 |
How many lines of earlier output the Terminal tab is given when it connects. 0 gives none. Allowed range 0 to 2000. |
terminal_mirror is one block, so thrum config set terminal_mirror '{"default_cols":160,"default_rows":40,"scrollback_lines":250}' sets all three keys together.
Scrolling in your own tmux windows is a tmux setting, not a Thrum key. Run agents in tmux has the one line to add to ~/.tmux.conf.
Telegram
Section titled “Telegram”Message your coordinator on Telegram sets these up. Use thrum telegram configure or the Telegram settings in the web UI to change them, not the file. Telegram carries your messages as readable text through its servers, and Thrum adds no encryption of its own.
| Key | Default | What it changes |
|---|---|---|
telegram.token |
none | Your bot’s token. It is a secret: keep it out of chats, screenshots and commits. The bridge is off while this is empty. |
telegram.enabled |
on when a token is set | Set false to turn the bridge off and keep the settings. |
telegram.target |
@coordinator_main in the setup prompt |
The agent that receives your new messages. |
telegram.user_id |
your Git user name, suggested at setup | Your Thrum username. |
telegram.allow_from |
empty | Telegram user IDs that may send messages. Empty blocks everyone. |
telegram.allow_all |
false |
Set true to let any Telegram user send messages to the agent in telegram.target, normally your coordinator. It overrides telegram.allow_from. Leave it false so only the IDs in telegram.allow_from can send. |
telegram.chat_id |
none | The private chat Thrum sends your messages to. It must be one of the allow_from IDs. |
You set up the email bridge in the web UI, in Settings, in the General tab, in the Email Bridge section. See Set up the email bridge. Your password is kept in the vault, an encrypted store on this machine, never in config.json, so editing the file does not change it. The email bridge sends your agents’ messages to your mailbox through your mail provider, and your replies come back the same way. Your mail provider can read those messages. The email bridge needs Pro.
Email notifications
Section titled “Email notifications”You set up email notifications in Settings, General tab, Email notifications. They send a copy of each message addressed to you to your mailbox, through a mail server you choose, and only send. They need Pro. Their password is kept in the vault, never in config.json.
Backups
Section titled “Backups”| Key | Default | What it changes |
|---|---|---|
backup.schedule |
"24h" |
How often the daemon backs up your messages and agent data, as a duration such as "24h". Restart the daemon after you change it. Set "off" to turn scheduled backups off. See Back up and restore your Thrum data. |
backup.dir |
.thrum/backup |
Where backups are written. |
backup.retention.daily |
5 |
Daily backups to keep. |
backup.retention.weekly |
4 |
Weekly backups to keep. |
backup.retention.monthly |
-1 |
Monthly backups to keep. -1 keeps all of them. |
backup.post_backup |
none | A shell command to run after each successful backup, for example to copy the files elsewhere. |
Transcripts
Section titled “Transcripts”Thrum stores agent transcripts so you can search them. The daemon reads these keys at start.
| Key | Default | What it changes |
|---|---|---|
transcripts.enabled |
true |
Whether Thrum records new transcripts. |
transcripts.active_window |
"24h" |
Only sessions seen within this time are followed live. An invalid value falls back to "24h". |
transcripts.bootstrap_on_boot |
true |
Whether Thrum also imports transcripts from before the daemon started. |
transcripts.retention_fence |
false |
Master switch for deleting old transcripts. While it is false, Thrum keeps them all. |
transcripts.retention_max_age |
none | With the fence on, delete sessions older than this, for example "720h" for 30 days. Use hours, not days. |
transcripts.retention_max_bytes |
none | With the fence on, delete the oldest sessions once stored transcripts pass this many bytes. |
Environment variables
Section titled “Environment variables”An environment variable beats config.json.
| Variable | What it does |
|---|---|
THRUM_WS_PORT |
Sets the web UI port for that daemon run. It beats daemon.ws_port. |
THRUM_NO_GIT_SYNC |
Set to 1 or true to force Git sync off, whatever daemon.sync_via_git says. |
Next steps
Section titled “Next steps”- CLI reference: the commands, grouped by who runs them.
- Glossary: the terms used on this page.
- Troubleshooting common errors: what to try when something does not start.