mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-13 19:10:39 +00:00
* refactor discord thread bindings to idle and max-age lifecycle * fix: migrate legacy thread binding expiry and reduce hot-path disk writes * refactor: remove remaining thread-binding ttl legacy paths * fix: harden thread-binding lifecycle persistence * Discord: fix thread binding types in message/reply paths * Infra: handle win32 unknown inode in file identity checks * Infra: relax win32 guarded-open identity checks * Config: migrate threadBindings ttlHours to idleHours * Revert "Infra: relax win32 guarded-open identity checks" This reverts commitde94126771. * Revert "Infra: handle win32 unknown inode in file identity checks" This reverts commit96fc5ddfb3. * Discord: re-read live binding state before sweep unbind * fix: add changelog note for thread binding lifecycle update (#27845) (thanks @osolmaz) --------- Co-authored-by: Onur Solmaz <onur@textcortex.com>
541 lines
18 KiB
Markdown
541 lines
18 KiB
Markdown
---
|
|
summary: "Configuration overview: common tasks, quick setup, and links to the full reference"
|
|
read_when:
|
|
- Setting up OpenClaw for the first time
|
|
- Looking for common configuration patterns
|
|
- Navigating to specific config sections
|
|
title: "Configuration"
|
|
---
|
|
|
|
# Configuration
|
|
|
|
OpenClaw reads an optional <Tooltip tip="JSON5 supports comments and trailing commas">**JSON5**</Tooltip> config from `~/.openclaw/openclaw.json`.
|
|
|
|
If the file is missing, OpenClaw uses safe defaults. Common reasons to add a config:
|
|
|
|
- Connect channels and control who can message the bot
|
|
- Set models, tools, sandboxing, or automation (cron, hooks)
|
|
- Tune sessions, media, networking, or UI
|
|
|
|
See the [full reference](/gateway/configuration-reference) for every available field.
|
|
|
|
<Tip>
|
|
**New to configuration?** Start with `openclaw onboard` for interactive setup, or check out the [Configuration Examples](/gateway/configuration-examples) guide for complete copy-paste configs.
|
|
</Tip>
|
|
|
|
## Minimal config
|
|
|
|
```json5
|
|
// ~/.openclaw/openclaw.json
|
|
{
|
|
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
|
|
channels: { whatsapp: { allowFrom: ["+15555550123"] } },
|
|
}
|
|
```
|
|
|
|
## Editing config
|
|
|
|
<Tabs>
|
|
<Tab title="Interactive wizard">
|
|
```bash
|
|
openclaw onboard # full setup wizard
|
|
openclaw configure # config wizard
|
|
```
|
|
</Tab>
|
|
<Tab title="CLI (one-liners)">
|
|
```bash
|
|
openclaw config get agents.defaults.workspace
|
|
openclaw config set agents.defaults.heartbeat.every "2h"
|
|
openclaw config unset tools.web.search.apiKey
|
|
```
|
|
</Tab>
|
|
<Tab title="Control UI">
|
|
Open [http://127.0.0.1:18789](http://127.0.0.1:18789) and use the **Config** tab.
|
|
The Control UI renders a form from the config schema, with a **Raw JSON** editor as an escape hatch.
|
|
</Tab>
|
|
<Tab title="Direct edit">
|
|
Edit `~/.openclaw/openclaw.json` directly. The Gateway watches the file and applies changes automatically (see [hot reload](#config-hot-reload)).
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
## Strict validation
|
|
|
|
<Warning>
|
|
OpenClaw only accepts configurations that fully match the schema. Unknown keys, malformed types, or invalid values cause the Gateway to **refuse to start**. The only root-level exception is `$schema` (string), so editors can attach JSON Schema metadata.
|
|
</Warning>
|
|
|
|
When validation fails:
|
|
|
|
- The Gateway does not boot
|
|
- Only diagnostic commands work (`openclaw doctor`, `openclaw logs`, `openclaw health`, `openclaw status`)
|
|
- Run `openclaw doctor` to see exact issues
|
|
- Run `openclaw doctor --fix` (or `--yes`) to apply repairs
|
|
|
|
## Common tasks
|
|
|
|
<AccordionGroup>
|
|
<Accordion title="Set up a channel (WhatsApp, Telegram, Discord, etc.)">
|
|
Each channel has its own config section under `channels.<provider>`. See the dedicated channel page for setup steps:
|
|
|
|
- [WhatsApp](/channels/whatsapp) — `channels.whatsapp`
|
|
- [Telegram](/channels/telegram) — `channels.telegram`
|
|
- [Discord](/channels/discord) — `channels.discord`
|
|
- [Slack](/channels/slack) — `channels.slack`
|
|
- [Signal](/channels/signal) — `channels.signal`
|
|
- [iMessage](/channels/imessage) — `channels.imessage`
|
|
- [Google Chat](/channels/googlechat) — `channels.googlechat`
|
|
- [Mattermost](/channels/mattermost) — `channels.mattermost`
|
|
- [MS Teams](/channels/msteams) — `channels.msteams`
|
|
|
|
All channels share the same DM policy pattern:
|
|
|
|
```json5
|
|
{
|
|
channels: {
|
|
telegram: {
|
|
enabled: true,
|
|
botToken: "123:abc",
|
|
dmPolicy: "pairing", // pairing | allowlist | open | disabled
|
|
allowFrom: ["tg:123"], // only for allowlist/open
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Choose and configure models">
|
|
Set the primary model and optional fallbacks:
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
model: {
|
|
primary: "anthropic/claude-sonnet-4-5",
|
|
fallbacks: ["openai/gpt-5.2"],
|
|
},
|
|
models: {
|
|
"anthropic/claude-sonnet-4-5": { alias: "Sonnet" },
|
|
"openai/gpt-5.2": { alias: "GPT" },
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- `agents.defaults.models` defines the model catalog and acts as the allowlist for `/model`.
|
|
- Model refs use `provider/model` format (e.g. `anthropic/claude-opus-4-6`).
|
|
- `agents.defaults.imageMaxDimensionPx` controls transcript/tool image downscaling (default `1200`); lower values usually reduce vision-token usage on screenshot-heavy runs.
|
|
- See [Models CLI](/concepts/models) for switching models in chat and [Model Failover](/concepts/model-failover) for auth rotation and fallback behavior.
|
|
- For custom/self-hosted providers, see [Custom providers](/gateway/configuration-reference#custom-providers-and-base-urls) in the reference.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Control who can message the bot">
|
|
DM access is controlled per channel via `dmPolicy`:
|
|
|
|
- `"pairing"` (default): unknown senders get a one-time pairing code to approve
|
|
- `"allowlist"`: only senders in `allowFrom` (or the paired allow store)
|
|
- `"open"`: allow all inbound DMs (requires `allowFrom: ["*"]`)
|
|
- `"disabled"`: ignore all DMs
|
|
|
|
For groups, use `groupPolicy` + `groupAllowFrom` or channel-specific allowlists.
|
|
|
|
See the [full reference](/gateway/configuration-reference#dm-and-group-access) for per-channel details.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Set up group chat mention gating">
|
|
Group messages default to **require mention**. Configure patterns per agent:
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
list: [
|
|
{
|
|
id: "main",
|
|
groupChat: {
|
|
mentionPatterns: ["@openclaw", "openclaw"],
|
|
},
|
|
},
|
|
],
|
|
},
|
|
channels: {
|
|
whatsapp: {
|
|
groups: { "*": { requireMention: true } },
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- **Metadata mentions**: native @-mentions (WhatsApp tap-to-mention, Telegram @bot, etc.)
|
|
- **Text patterns**: regex patterns in `mentionPatterns`
|
|
- See [full reference](/gateway/configuration-reference#group-chat-mention-gating) for per-channel overrides and self-chat mode.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Configure sessions and resets">
|
|
Sessions control conversation continuity and isolation:
|
|
|
|
```json5
|
|
{
|
|
session: {
|
|
dmScope: "per-channel-peer", // recommended for multi-user
|
|
threadBindings: {
|
|
enabled: true,
|
|
idleHours: 24,
|
|
maxAgeHours: 0,
|
|
},
|
|
reset: {
|
|
mode: "daily",
|
|
atHour: 4,
|
|
idleMinutes: 120,
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- `dmScope`: `main` (shared) | `per-peer` | `per-channel-peer` | `per-account-channel-peer`
|
|
- `threadBindings`: global defaults for thread-bound session routing (Discord supports `/focus`, `/unfocus`, `/agents`, `/session idle`, and `/session max-age`).
|
|
- See [Session Management](/concepts/session) for scoping, identity links, and send policy.
|
|
- See [full reference](/gateway/configuration-reference#session) for all fields.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Enable sandboxing">
|
|
Run agent sessions in isolated Docker containers:
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
sandbox: {
|
|
mode: "non-main", // off | non-main | all
|
|
scope: "agent", // session | agent | shared
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
Build the image first: `scripts/sandbox-setup.sh`
|
|
|
|
See [Sandboxing](/gateway/sandboxing) for the full guide and [full reference](/gateway/configuration-reference#sandbox) for all options.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Set up heartbeat (periodic check-ins)">
|
|
```json5
|
|
{
|
|
agents: {
|
|
defaults: {
|
|
heartbeat: {
|
|
every: "30m",
|
|
target: "last",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- `every`: duration string (`30m`, `2h`). Set `0m` to disable.
|
|
- `target`: `last` | `whatsapp` | `telegram` | `discord` | `none`
|
|
- `directPolicy`: `allow` (default) or `block` for DM-style heartbeat targets
|
|
- See [Heartbeat](/gateway/heartbeat) for the full guide.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Configure cron jobs">
|
|
```json5
|
|
{
|
|
cron: {
|
|
enabled: true,
|
|
maxConcurrentRuns: 2,
|
|
sessionRetention: "24h",
|
|
runLog: {
|
|
maxBytes: "2mb",
|
|
keepLines: 2000,
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
- `sessionRetention`: prune completed isolated run sessions from `sessions.json` (default `24h`; set `false` to disable).
|
|
- `runLog`: prune `cron/runs/<jobId>.jsonl` by size and retained lines.
|
|
- See [Cron jobs](/automation/cron-jobs) for feature overview and CLI examples.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Set up webhooks (hooks)">
|
|
Enable HTTP webhook endpoints on the Gateway:
|
|
|
|
```json5
|
|
{
|
|
hooks: {
|
|
enabled: true,
|
|
token: "shared-secret",
|
|
path: "/hooks",
|
|
defaultSessionKey: "hook:ingress",
|
|
allowRequestSessionKey: false,
|
|
allowedSessionKeyPrefixes: ["hook:"],
|
|
mappings: [
|
|
{
|
|
match: { path: "gmail" },
|
|
action: "agent",
|
|
agentId: "main",
|
|
deliver: true,
|
|
},
|
|
],
|
|
},
|
|
}
|
|
```
|
|
|
|
See [full reference](/gateway/configuration-reference#hooks) for all mapping options and Gmail integration.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Configure multi-agent routing">
|
|
Run multiple isolated agents with separate workspaces and sessions:
|
|
|
|
```json5
|
|
{
|
|
agents: {
|
|
list: [
|
|
{ id: "home", default: true, workspace: "~/.openclaw/workspace-home" },
|
|
{ id: "work", workspace: "~/.openclaw/workspace-work" },
|
|
],
|
|
},
|
|
bindings: [
|
|
{ agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
|
|
{ agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
|
|
],
|
|
}
|
|
```
|
|
|
|
See [Multi-Agent](/concepts/multi-agent) and [full reference](/gateway/configuration-reference#multi-agent-routing) for binding rules and per-agent access profiles.
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Split config into multiple files ($include)">
|
|
Use `$include` to organize large configs:
|
|
|
|
```json5
|
|
// ~/.openclaw/openclaw.json
|
|
{
|
|
gateway: { port: 18789 },
|
|
agents: { $include: "./agents.json5" },
|
|
broadcast: {
|
|
$include: ["./clients/a.json5", "./clients/b.json5"],
|
|
},
|
|
}
|
|
```
|
|
|
|
- **Single file**: replaces the containing object
|
|
- **Array of files**: deep-merged in order (later wins)
|
|
- **Sibling keys**: merged after includes (override included values)
|
|
- **Nested includes**: supported up to 10 levels deep
|
|
- **Relative paths**: resolved relative to the including file
|
|
- **Error handling**: clear errors for missing files, parse errors, and circular includes
|
|
|
|
</Accordion>
|
|
</AccordionGroup>
|
|
|
|
## Config hot reload
|
|
|
|
The Gateway watches `~/.openclaw/openclaw.json` and applies changes automatically — no manual restart needed for most settings.
|
|
|
|
### Reload modes
|
|
|
|
| Mode | Behavior |
|
|
| ---------------------- | --------------------------------------------------------------------------------------- |
|
|
| **`hybrid`** (default) | Hot-applies safe changes instantly. Automatically restarts for critical ones. |
|
|
| **`hot`** | Hot-applies safe changes only. Logs a warning when a restart is needed — you handle it. |
|
|
| **`restart`** | Restarts the Gateway on any config change, safe or not. |
|
|
| **`off`** | Disables file watching. Changes take effect on the next manual restart. |
|
|
|
|
```json5
|
|
{
|
|
gateway: {
|
|
reload: { mode: "hybrid", debounceMs: 300 },
|
|
},
|
|
}
|
|
```
|
|
|
|
### What hot-applies vs what needs a restart
|
|
|
|
Most fields hot-apply without downtime. In `hybrid` mode, restart-required changes are handled automatically.
|
|
|
|
| Category | Fields | Restart needed? |
|
|
| ------------------- | -------------------------------------------------------------------- | --------------- |
|
|
| Channels | `channels.*`, `web` (WhatsApp) — all built-in and extension channels | No |
|
|
| Agent & models | `agent`, `agents`, `models`, `routing` | No |
|
|
| Automation | `hooks`, `cron`, `agent.heartbeat` | No |
|
|
| Sessions & messages | `session`, `messages` | No |
|
|
| Tools & media | `tools`, `browser`, `skills`, `audio`, `talk` | No |
|
|
| UI & misc | `ui`, `logging`, `identity`, `bindings` | No |
|
|
| Gateway server | `gateway.*` (port, bind, auth, tailscale, TLS, HTTP) | **Yes** |
|
|
| Infrastructure | `discovery`, `canvasHost`, `plugins` | **Yes** |
|
|
|
|
<Note>
|
|
`gateway.reload` and `gateway.remote` are exceptions — changing them does **not** trigger a restart.
|
|
</Note>
|
|
|
|
## Config RPC (programmatic updates)
|
|
|
|
<Note>
|
|
Control-plane write RPCs (`config.apply`, `config.patch`, `update.run`) are rate-limited to **3 requests per 60 seconds** per `deviceId+clientIp`. When limited, the RPC returns `UNAVAILABLE` with `retryAfterMs`.
|
|
</Note>
|
|
|
|
<AccordionGroup>
|
|
<Accordion title="config.apply (full replace)">
|
|
Validates + writes the full config and restarts the Gateway in one step.
|
|
|
|
<Warning>
|
|
`config.apply` replaces the **entire config**. Use `config.patch` for partial updates, or `openclaw config set` for single keys.
|
|
</Warning>
|
|
|
|
Params:
|
|
|
|
- `raw` (string) — JSON5 payload for the entire config
|
|
- `baseHash` (optional) — config hash from `config.get` (required when config exists)
|
|
- `sessionKey` (optional) — session key for the post-restart wake-up ping
|
|
- `note` (optional) — note for the restart sentinel
|
|
- `restartDelayMs` (optional) — delay before restart (default 2000)
|
|
|
|
Restart requests are coalesced while one is already pending/in-flight, and a 30-second cooldown applies between restart cycles.
|
|
|
|
```bash
|
|
openclaw gateway call config.get --params '{}' # capture payload.hash
|
|
openclaw gateway call config.apply --params '{
|
|
"raw": "{ agents: { defaults: { workspace: \"~/.openclaw/workspace\" } } }",
|
|
"baseHash": "<hash>",
|
|
"sessionKey": "agent:main:whatsapp:dm:+15555550123"
|
|
}'
|
|
```
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="config.patch (partial update)">
|
|
Merges a partial update into the existing config (JSON merge patch semantics):
|
|
|
|
- Objects merge recursively
|
|
- `null` deletes a key
|
|
- Arrays replace
|
|
|
|
Params:
|
|
|
|
- `raw` (string) — JSON5 with just the keys to change
|
|
- `baseHash` (required) — config hash from `config.get`
|
|
- `sessionKey`, `note`, `restartDelayMs` — same as `config.apply`
|
|
|
|
Restart behavior matches `config.apply`: coalesced pending restarts plus a 30-second cooldown between restart cycles.
|
|
|
|
```bash
|
|
openclaw gateway call config.patch --params '{
|
|
"raw": "{ channels: { telegram: { groups: { \"*\": { requireMention: false } } } } }",
|
|
"baseHash": "<hash>"
|
|
}'
|
|
```
|
|
|
|
</Accordion>
|
|
</AccordionGroup>
|
|
|
|
## Environment variables
|
|
|
|
OpenClaw reads env vars from the parent process plus:
|
|
|
|
- `.env` from the current working directory (if present)
|
|
- `~/.openclaw/.env` (global fallback)
|
|
|
|
Neither file overrides existing env vars. You can also set inline env vars in config:
|
|
|
|
```json5
|
|
{
|
|
env: {
|
|
OPENROUTER_API_KEY: "sk-or-...",
|
|
vars: { GROQ_API_KEY: "gsk-..." },
|
|
},
|
|
}
|
|
```
|
|
|
|
<Accordion title="Shell env import (optional)">
|
|
If enabled and expected keys aren't set, OpenClaw runs your login shell and imports only the missing keys:
|
|
|
|
```json5
|
|
{
|
|
env: {
|
|
shellEnv: { enabled: true, timeoutMs: 15000 },
|
|
},
|
|
}
|
|
```
|
|
|
|
Env var equivalent: `OPENCLAW_LOAD_SHELL_ENV=1`
|
|
</Accordion>
|
|
|
|
<Accordion title="Env var substitution in config values">
|
|
Reference env vars in any config string value with `${VAR_NAME}`:
|
|
|
|
```json5
|
|
{
|
|
gateway: { auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" } },
|
|
models: { providers: { custom: { apiKey: "${CUSTOM_API_KEY}" } } },
|
|
}
|
|
```
|
|
|
|
Rules:
|
|
|
|
- Only uppercase names matched: `[A-Z_][A-Z0-9_]*`
|
|
- Missing/empty vars throw an error at load time
|
|
- Escape with `$${VAR}` for literal output
|
|
- Works inside `$include` files
|
|
- Inline substitution: `"${BASE}/v1"` → `"https://api.example.com/v1"`
|
|
|
|
</Accordion>
|
|
|
|
<Accordion title="Secret refs (env, file, exec)">
|
|
For fields that support SecretRef objects, you can use:
|
|
|
|
```json5
|
|
{
|
|
models: {
|
|
providers: {
|
|
openai: { apiKey: { source: "env", provider: "default", id: "OPENAI_API_KEY" } },
|
|
},
|
|
},
|
|
skills: {
|
|
entries: {
|
|
"nano-banana-pro": {
|
|
apiKey: {
|
|
source: "file",
|
|
provider: "filemain",
|
|
id: "/skills/entries/nano-banana-pro/apiKey",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
channels: {
|
|
googlechat: {
|
|
serviceAccountRef: {
|
|
source: "exec",
|
|
provider: "vault",
|
|
id: "channels/googlechat/serviceAccount",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
```
|
|
|
|
SecretRef details (including `secrets.providers` for `env`/`file`/`exec`) are in [Secrets Management](/gateway/secrets).
|
|
</Accordion>
|
|
|
|
See [Environment](/help/environment) for full precedence and sources.
|
|
|
|
## Full reference
|
|
|
|
For the complete field-by-field reference, see **[Configuration Reference](/gateway/configuration-reference)**.
|
|
|
|
---
|
|
|
|
_Related: [Configuration Examples](/gateway/configuration-examples) · [Configuration Reference](/gateway/configuration-reference) · [Doctor](/gateway/doctor)_
|