# Config

> The config file, how to change it, and every core key with type and default.

Source: https://nodecode.ai/docs/config
Updated: 2026-10-06

## File

| Fact | Value |
| --- | --- |
| Path | `~/.nodecode/config.jsonc` |
| Format | JSONC: JSON with comments. |
| Scope | One per home. The home is `~/.nodecode/`, or a profile's folder. |
| Missing file | Allowed. Every key has a default or is optional. |

The other files of the home are listed in [Files](https://nodecode.ai/docs/files).

## Change it

Edit the file, or use eval. See [Eval](https://nodecode.ai/docs/eval).

```lisp
(config-get '("channels" "discord"))
(config-set '("channels" "discord") '(:require_mention nil))
(config-set '("providers" "old") :remove)
```

| Form | Does |
| --- | --- |
| `(config-get)` | Returns the whole config. |
| `(config-get PATH)` | Returns the value at PATH. PATH is a list of keys, or one key. |
| `(config-set PATH VALUE)` | Writes VALUE at PATH. Returns the change as one line. |
| `(config-set PATH :remove)` | Removes the member at PATH. |

| Rule | Detail |
| --- | --- |
| Comments | Kept. Every other byte of the file is kept too. |
| Object value | Merged member by member. It never removes a member. |
| Other value | Replaces the member. |
| Write | Atomic. The file mode is kept. |
| Secrets on read | A key ending in `api_key`, `token`, `secret` or `password` reads as `[set]`. |
| Secrets on write | `config-set` refuses to write `[set]` over a secret. |
| Whole section | A section read with secrets cannot be written back whole. Write single members. |

## Apply a change

| Keys | Read | Apply with |
| --- | --- | --- |
| Cell sections | When the cell starts. | `(restart-cells)` or `(restart-cells "NAME")` in eval. |
| `providers`, `failover` | At the start of each turn, when the file changed. | The next turn. |
| `general.default_model`, `general.auxiliary_model` | When the organism boots. An organism is a running Nodecode. | A restart, or `/models` and `/model-aux`. |
| `workspace.captures` | When the gateway starts. The gateway is the local server shells attach to. | A restart. |
| `general.theme` | When the shell starts. | `/themes`, or a new shell. |

`(restart-cells)` stops the cells, reads the file again and starts them.

## general

| Key | Type | Default |
| --- | --- | --- |
| `general.default_model` | Object: `provider`, `model`, optional `effort` | None. The build default applies. |
| `general.auxiliary_model` | Same object | None. Side work runs on the session's model. |
| `general.theme` | String | `Tungstene`. A `/themes` pick outranks it. |

See [Models and providers](https://nodecode.ai/docs/models).

## providers

One entry per provider id, under `providers.<id>`.

| Key | Type | Default |
| --- | --- | --- |
| `sdk` | `openai-completions`, `openai-responses`, `anthropic` or `google` | None |
| `base_url` | String | By dialect. See [Models and providers](https://nodecode.ai/docs/models). |
| `api_key` | String. A leading `!` runs a shell command. | None |
| `display_name` | String | The id |
| `models[].id` | String | None |
| `models[].context_window` | Integer above 0 | None |
| `models[].sdk` | A dialect, for this model only | The provider's `sdk` |
| `proxy` | String | None |
| `request_max_retries` | Integer, 0 or more | 4 |
| `stream_max_retries` | Integer, 0 or more | 5 |
| `stream_idle_timeout_ms` | Integer above 0 | 120000 |
| `stream_rerun_ceiling_seconds` | Number, 0 or more. `0` disables it. | 120 |
| `reasoning_summary` | String. `off`, `none` or `false` disables it. | `auto` |
| `session_token`, `access_key_id`, `secret_access_key` | String | None |

`session_token`, `access_key_id` and `secret_access_key` only mark the provider as having credentials. No request sends them.

## failover

| Key | Type | Default |
| --- | --- | --- |
| `failover.chain` | Array of `{provider, model}` | None: no failover |

## gateway and workspace

| Key | Type | Default |
| --- | --- | --- |
| `gateway.operator_token` | String | None. Read after the environment and the `operator-token` file. |
| `workspace.captures` | Boolean | `true`. `false` turns workspace snapshots off. |

See [Gateway](https://nodecode.ai/docs/gateway) and [Sessions and undo](https://nodecode.ai/docs/sessions).

## update

| Key | Type | Default |
| --- | --- | --- |
| `update.mode` | `auto`, `ask` or `off` | `auto` on an installed build. `off` on a checkout build. |
| `update.channel` | String | `stable` |
| `update.check_minutes` | Integer, 1 or more | 360 with a release feed. 30 without one. |
| `update.url` | String: a release host | The host this build was installed from. |
| `update.feed` | String: the feed address, or `off` | Beside the release host. |

See [Updates](https://nodecode.ai/docs/updates).

## request_bodies

Nodecode keeps the exact body of each model call in the store.

| Key | Type | Default |
| --- | --- | --- |
| `request_bodies.keep_mb` | Integer, 0 or more. `0` keeps none. | 256 |

Past the limit the oldest bodies go.

## notify

A desktop notice when a turn ends. The section's presence turns it on.

| Key | Type | Default |
| --- | --- | --- |
| `notify.command` | Array of strings: the command and its arguments. `{title}` and `{body}` are filled in. | `notify-send` on Linux, a toast on Windows and WSL, `osascript` on macOS |
| `notify.scope` | `attached` or `all` | `attached`: only when a shell received the turn's end |

A cancelled turn sends no notice.

## Cell sections

> **The cells key is ignored.** Nodecode does not read a top-level `cells` key. It posts a warning when it finds one. A folder under `cells/` loads because it is there.

A cell is a folder of code under `~/.nodecode/cells/`. Each cell reads its own section.

Every cell section takes `enabled`, a boolean, default `true`. `"enabled": false` stops that cell from starting.

A cell declares its section in its own code. `/setup` shows it as a panel. See [Cell API](https://nodecode.ai/docs/cell-api#section).
