Settings
All settings of efr are in one file, config.toml. This page tells where the file is,
how to change it and when a change applies. The
config.toml reference lists every key with its default.
The file
config.toml is in the config root, ~/.config/efr/config.toml by default.
- The file is optional. A missing file means that every key has its default value.
- Every key is optional.
- An unknown key is an error. So efr tells you about a typo.
- The file holds no secrets. It can live in a dotfiles repository.
To keep the file in a dotfiles repository, make ~/.config/efr/config.toml a symbolic
link to it. efr keeps the link:
- The daemon also watches the file behind the link.
efr config setwrites the file behind the link.efr config editopens the file behind the link. So an editor that saves by replacing the file cannot turn the link into a plain file.
No tool of the agent can write the config directory or the files behind its links. Config protection tells more.
Change a setting
efr config edit # open the file in your editor
efr config set model.name gpt-5.4 # set one key
efr config unset model.name # remove one key; its default applies again
efr config editopens the file in$VISUAL, else$EDITOR, elsevi. A missing file starts as the commented example, which names every key. When you save, efr checks the file. If it has an error, efr shows the error and asksedit it again? [Y/n].efr config set KEY VALUEchanges one key. The value is text, a number,trueorfalse, or a list as words separated by commas. efr keeps your comments and your layout.efr config setandefr config unsetcannot change the arrays of tables:[[permissions.rules]],[[sandbox.allow]],[[network.hosts]]and[[dbus.allow]]. Edit these in the file.
After each change, efr asks the daemon to read the file again and prints the result:
config.toml reloaded; new turns use it
When the daemon does not run, efr says the daemon is not running; it reads the file when it starts.
Check the file
-
efr config checkchecksconfig.toml.efr config check PATHchecks another file. An error names the line, the column and the key, and the command exits with 1:$ efr config check config.toml config.toml: unknown field `idle_minuets`, ... (shell.idle_minuets, line 3, column 1) -
efr config showprints every key with its value and where the value comes from, as TOML with the source in a comment. Then it shows the file that the daemon reads, the last error of a reload and the keys that wait for a restart. -
efrd --print-configprints the settings of the daemon with their sources. The variablesEFR_LOGandEFR_SCREENand theefrdflags--logand--screenwin over the file.
When a change applies
The daemon reads the file again:
- when the file changes,
- on
efr config reload, - on
systemctl --user reload efrd.
A running turn keeps its settings. The next turn uses the new ones. The config.toml reference has an Applies column for each key:
| Applies | When the change takes effect |
|---|---|
live | From the next turn, prompt, tool call or new hidden shell. No restart. |
restart | Only after systemctl --user restart efrd. |
client | Only efr reads the key, each time it runs. |
The keys that need a restart are screen, model.provider, the base URLs, and a few
keys of [openai] and [anthropic], such as openai.originator. For such a key,
efr config reload says restart efrd to apply: <keys> (systemctl --user restart efrd). efr status shows the keys in the restart needed line.
A file with an error changes nothing. The old settings stay. efr status shows the
error in the config error line, and the next prompt in each terminal with a recent
conversation shows one line, such as:
efr: config.toml has an error; the old settings stay: <error> (<key>, line <n>)
While a full mode turn or one of its jobs runs, efrd does not load a change that
loosens permissions. The change stays held until you run efr config reload after the
full work ends. The config hold tells more.
Ask efr to change a setting
You can ask the agent, as in , make gpt-5.4 my default model or
, always allow cargo test in this project. The agent uses its settings tool:
- It reads the settings with no question.
- It changes the file only after you approve the change. The question shows the diff
of the file, in every mode, also in
auto, and also when a rule of yours allows the write. - A change that lets more run without a question is marked "loosens permissions".
- The tool never writes a rule about secrets. It never turns on full mode
(
permissions.allow_full) and never setspermissions.mode = "full". You do that yourself. - A turn from the phone cannot change settings.
The change applies from the next turn. The settings tool tells more.
Settings for one terminal
The file sets the defaults of every terminal. To change the mode, the model or the
effort for one terminal only, type ,mode, ,model or ,effort. ,mode default
clears the choice of the terminal, so the file decides again.
Permission modes and
Models, providers and login tell more.
Colours
By default, efr uses the 16 colours of your terminal's theme. So it follows your
terminal's theme. The [render] table changes this:
[render.colors]sets the colour of one role, such asaccent = "#f2c14e"ormuted = 8.render.palettenames a theme file, such aspalette = "~/path/theme.toml". The path must be absolute or start with~/. The file has a[colors]table with the same roles, and an optionalcode_theme: the path of a.tmThemefile for code. A design system can make this file.[render.colors]wins over the theme file.render.themenames a theme for code blocks and diffs, such ascatppuccin-mocha.theme = "auto"takestheme_darkortheme_lightfrom the background of the terminal. The zsh plugin asks the terminal for its background once, when it loads. SetEFR_TERMINAL_BGtodarkorlightto skip the question.NO_COLORturns colours off.
efr config set render.theme NAME refuses a theme that does not exist.
Where efr keeps its files
efr uses four roots. efr finds each root in this order:
- its own variable:
EFR_CONFIG_DIR,EFR_DATA_DIR,EFR_STATE_DIRorEFR_RUNTIME_DIR, - a directory below
EFR_HOME:config/,data/,state/orruntime/, - the XDG directory:
~/.config/efr,~/.local/share/efr,~/.local/state/efror$XDG_RUNTIME_DIR/efr. WhenXDG_RUNTIME_DIRis not set, the runtime root is/run/user/<uid>/efrif/run/user/<uid>is your own directory with mode 0700.
efr paths shows each root, where it came from and whether it exists. Then it shows
config.toml, the database efr.sqlite, the secrets/ directory, the socket
daemon.sock, and the roots of the daemon. efr paths --json prints the same facts
as JSON.
runtime /run/user/1000/efr (XDG, exists)
daemon.sock /run/user/1000/efr/daemon.sock (exists)
When the daemon uses other roots than your shell, efr paths warns. This occurs, for
example, when only your shell sets EFR_HOME. Give the daemon the same variable with
systemctl --user edit efrd.
Below EFR_HOME, the socket is on the disk. A socket path can be at most 107 bytes.
If the path is longer, the daemon does not start, and efr tells you to set
EFR_RUNTIME_DIR to a shorter directory.
Storage lists every file in the roots.
The JSON schema
efr config schema prints the JSON schema of config.toml. The file
docs/config.schema.json in the repository holds the same schema. The first line of
the example file, #:schema ..., points editors to it, so an editor can complete keys
and check values.