Core config reference forDocumentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
~/.openclaw/openclaw.json. For a task-oriented overview, see Configuration.
Covers the main OpenClaw config surfaces and links out when a subsystem has its own deeper reference. Channel- and plugin-owned command catalogs and deep memory/QMD knobs live on their own pages rather than on this one.
Code truth:
openclaw config schemaprints the live JSON Schema used for validation and Control UI, with bundled/plugin/channel metadata merged in when availableconfig.schema.lookupreturns one path-scoped schema node for drill-down toolingpnpm config:docs:check/pnpm config:docs:genvalidate the config-doc baseline hash against the current schema surface
gateway tool action config.schema.lookup for
exact field-level docs and constraints before edits. Use
Configuration for task-oriented guidance and this page
for the broader field map, defaults, and links to subsystem references.
Dedicated deep references:
- Memory configuration reference for
agents.defaults.memorySearch.*,memory.qmd.*,memory.citations, and dreaming config underplugins.entries.memory-core.config.dreaming - Slash commands for the current built-in + bundled command catalog
- owning channel/plugin pages for channel-specific command surfaces
Channels
Per-channel config keys moved to a dedicated page — see Configuration — channels forchannels.*,
including Slack, Discord, Telegram, WhatsApp, Matrix, iMessage, and other
bundled channels (auth, access control, multi-account, mention gating).
Agent defaults, multi-agent, sessions, and messages
Moved to a dedicated page — see Configuration — agents for:agents.defaults.*(workspace, model, thinking, heartbeat, memory, media, skills, sandbox)multiAgent.*(multi-agent routing and bindings)session.*(session lifecycle, compaction, pruning)messages.*(message delivery, TTS, markdown rendering)talk.*(Talk mode)talk.speechLocale: optional BCP 47 locale id for Talk speech recognition on iOS/macOStalk.silenceTimeoutMs: when unset, Talk keeps the platform default pause window before sending the transcript (700 ms on macOS and Android, 900 ms on iOS)
Tools and custom providers
Tool policy, experimental toggles, provider-backed tool config, and custom provider / base-URL setup moved to a dedicated page — see Configuration — tools and custom providers.Models
Provider definitions, model allowlists, and custom provider setup live in Configuration — tools and custom providers. Themodels root also owns global model-catalog behavior.
models.mode: provider catalog behavior (mergeorreplace).models.providers: custom provider map keyed by provider id.models.pricing.enabled: controls the background pricing bootstrap. Whenfalse, Gateway startup skips OpenRouter and LiteLLM pricing-catalog fetches; configuredmodels.providers.*.models[].costvalues still work for local cost estimates.
MCP
OpenClaw-managed MCP server definitions live undermcp.servers and are
consumed by embedded Pi and other runtime adapters. The openclaw mcp list,
show, set, and unset commands manage this block without connecting to the
target server during config edits.
mcp.servers: named stdio or remote MCP server definitions for runtimes that expose configured MCP tools. Remote entries usetransport: "streamable-http"ortransport: "sse";type: "http"is a CLI-native alias thatopenclaw mcp setandopenclaw doctor --fixnormalize into the canonicaltransportfield.mcp.sessionIdleTtlMs: idle TTL for session-scoped bundled MCP runtimes. One-shot embedded runs request run-end cleanup; this TTL is the backstop for long-lived sessions and future callers.- Changes under
mcp.*hot-apply by disposing cached session MCP runtimes. The next tool discovery/use recreates them from the new config, so removedmcp.serversentries are reaped immediately instead of waiting for idle TTL.
Skills
allowBundled: optional allowlist for bundled skills only (managed/workspace skills unaffected).load.extraDirs: extra shared skill roots (lowest precedence).install.preferBrew: when true, prefer Homebrew installers whenbrewis available before falling back to other installer kinds.install.nodeManager: node installer preference formetadata.openclaw.installspecs (npm|pnpm|yarn|bun).entries.<skillKey>.enabled: falsedisables a skill even if bundled/installed.entries.<skillKey>.apiKey: convenience for skills declaring a primary env var (plaintext string or SecretRef object).
Plugins
- Loaded from
~/.openclaw/extensions,<workspace>/.openclaw/extensions, plusplugins.load.paths. - Discovery accepts native OpenClaw plugins plus compatible Codex bundles and Claude bundles, including manifestless Claude default-layout bundles.
- Config changes require a gateway restart.
allow: optional allowlist (only listed plugins load).denywins.plugins.entries.<id>.apiKey: plugin-level API key convenience field (when supported by the plugin).plugins.entries.<id>.env: plugin-scoped env var map.plugins.entries.<id>.hooks.allowPromptInjection: whenfalse, core blocksbefore_prompt_buildand ignores prompt-mutating fields from legacybefore_agent_start, while preserving legacymodelOverrideandproviderOverride. Applies to native plugin hooks and supported bundle-provided hook directories.plugins.entries.<id>.hooks.allowConversationAccess: whentrue, trusted non-bundled plugins may read raw conversation content from typed hooks such asllm_input,llm_output,before_agent_finalize, andagent_end.plugins.entries.<id>.subagent.allowModelOverride: explicitly trust this plugin to request per-runproviderandmodeloverrides for background subagent runs.plugins.entries.<id>.subagent.allowedModels: optional allowlist of canonicalprovider/modeltargets for trusted subagent overrides. Use"*"only when you intentionally want to allow any model.plugins.entries.<id>.config: plugin-defined config object (validated by native OpenClaw plugin schema when available).- Channel plugin account/runtime settings live under
channels.<id>and should be described by the owning plugin’s manifestchannelConfigsmetadata, not by a central OpenClaw option registry. plugins.entries.firecrawl.config.webFetch: Firecrawl web-fetch provider settings.apiKey: Firecrawl API key (accepts SecretRef). Falls back toplugins.entries.firecrawl.config.webSearch.apiKey, legacytools.web.fetch.firecrawl.apiKey, orFIRECRAWL_API_KEYenv var.baseUrl: Firecrawl API base URL (default:https://api.firecrawl.dev).onlyMainContent: extract only the main content from pages (default:true).maxAgeMs: maximum cache age in milliseconds (default:172800000/ 2 days).timeoutSeconds: scrape request timeout in seconds (default:60).
plugins.entries.xai.config.xSearch: xAI X Search (Grok web search) settings.enabled: enable the X Search provider.model: Grok model to use for search (e.g."grok-4-1-fast").
plugins.entries.memory-core.config.dreaming: memory dreaming settings. See Dreaming for phases and thresholds.enabled: master dreaming switch (defaultfalse).frequency: cron cadence for each full dreaming sweep ("0 3 * * *"by default).model: optional Dream Diary subagent model override. Requiresplugins.entries.memory-core.subagent.allowModelOverride: true; pair withallowedModelsto restrict targets. Model-unavailable errors retry once with the session default model; trust or allowlist failures do not fall back silently.- phase policy and thresholds are implementation details (not user-facing config keys).
- Full memory config lives in Memory configuration reference:
agents.defaults.memorySearch.*memory.backendmemory.citationsmemory.qmd.*plugins.entries.memory-core.config.dreaming
- Enabled Claude bundle plugins can also contribute embedded Pi defaults from
settings.json; OpenClaw applies those as sanitized agent settings, not as raw OpenClaw config patches. plugins.slots.memory: pick the active memory plugin id, or"none"to disable memory plugins.plugins.slots.contextEngine: pick the active context engine plugin id; defaults to"legacy"unless you install and select another engine.
Browser
evaluateEnabled: falsedisablesact:evaluateandwait --fn.tabCleanupreclaims tracked primary-agent tabs after idle time or when a session exceeds its cap. SetidleMinutes: 0ormaxTabsPerSession: 0to disable those individual cleanup modes.ssrfPolicy.dangerouslyAllowPrivateNetworkis disabled when unset, so browser navigation stays strict by default.- Set
ssrfPolicy.dangerouslyAllowPrivateNetwork: trueonly when you intentionally trust private-network browser navigation. - In strict mode, remote CDP profile endpoints (
profiles.*.cdpUrl) are subject to the same private-network blocking during reachability/discovery checks. ssrfPolicy.allowPrivateNetworkremains supported as a legacy alias.- In strict mode, use
ssrfPolicy.hostnameAllowlistandssrfPolicy.allowedHostnamesfor explicit exceptions. - Remote profiles are attach-only (start/stop/reset disabled).
profiles.*.cdpUrlacceptshttp://,https://,ws://, andwss://. Use HTTP(S) when you want OpenClaw to discover/json/version; use WS(S) when your provider gives you a direct DevTools WebSocket URL.remoteCdpTimeoutMsandremoteCdpHandshakeTimeoutMsapply to remote andattachOnlyCDP reachability plus tab-opening requests. Managed loopback profiles keep local CDP defaults.- If an externally managed CDP service is reachable through loopback, set that
profile’s
attachOnly: true; otherwise OpenClaw treats the loopback port as a local managed browser profile and may report local port ownership errors. existing-sessionprofiles use Chrome MCP instead of CDP and can attach on the selected host or through a connected browser node.existing-sessionprofiles can setuserDataDirto target a specific Chromium-based browser profile such as Brave or Edge.existing-sessionprofiles keep the current Chrome MCP route limits: snapshot/ref-driven actions instead of CSS-selector targeting, one-file upload hooks, no dialog timeout overrides, nowait --load networkidle, and noresponsebody, PDF export, download interception, or batch actions.- Local managed
openclawprofiles auto-assigncdpPortandcdpUrl; only setcdpUrlexplicitly for remote CDP. - Local managed profiles can set
executablePathto override the globalbrowser.executablePathfor that profile. Use this to run one profile in Chrome and another in Brave. - Local managed profiles use
browser.localLaunchTimeoutMsfor Chrome CDP HTTP discovery after process start andbrowser.localCdpReadyTimeoutMsfor post-launch CDP websocket readiness. Raise them on slower hosts where Chrome starts successfully but readiness checks race startup. Both values must be positive integers up to120000ms; invalid config values are rejected. - Auto-detect order: default browser if Chromium-based → Chrome → Brave → Edge → Chromium → Chrome Canary.
browser.executablePathandbrowser.profiles.<name>.executablePathboth accept~and~/...for your OS home directory before Chromium launch. Per-profileuserDataDironexisting-sessionprofiles is also tilde-expanded.- Control service: loopback only (port derived from
gateway.port, default18791). extraArgsappends extra launch flags to local Chromium startup (for example--disable-gpu, window sizing, or debug flags).
UI
seamColor: accent color for native app UI chrome (Talk Mode bubble tint, etc.).assistant: Control UI identity override. Falls back to active agent identity.
Gateway
Gateway field details
Gateway field details
mode:local(run gateway) orremote(connect to remote gateway). Gateway refuses to start unlesslocal.port: single multiplexed port for WS + HTTP. Precedence:--port>OPENCLAW_GATEWAY_PORT>gateway.port>18789.bind:auto,loopback(default),lan(0.0.0.0),tailnet(Tailscale IP only), orcustom.- Legacy bind aliases: use bind mode values in
gateway.bind(auto,loopback,lan,tailnet,custom), not host aliases (0.0.0.0,127.0.0.1,localhost,::,::1). - Docker note: the default
loopbackbind listens on127.0.0.1inside the container. With Docker bridge networking (-p 18789:18789), traffic arrives oneth0, so the gateway is unreachable. Use--network host, or setbind: "lan"(orbind: "custom"withcustomBindHost: "0.0.0.0") to listen on all interfaces. - Auth: required by default. Non-loopback binds require gateway auth. In practice that means a shared token/password or an identity-aware reverse proxy with
gateway.auth.mode: "trusted-proxy". Onboarding wizard generates a token by default. - If both
gateway.auth.tokenandgateway.auth.passwordare configured (including SecretRefs), setgateway.auth.modeexplicitly totokenorpassword. Startup and service install/repair flows fail when both are configured and mode is unset. gateway.auth.mode: "none": explicit no-auth mode. Use only for trusted local loopback setups; this is intentionally not offered by onboarding prompts.gateway.auth.mode: "trusted-proxy": delegate browser/user auth to an identity-aware reverse proxy and trust identity headers fromgateway.trustedProxies(see Trusted Proxy Auth). This mode expects a non-loopback proxy source by default; same-host loopback reverse proxies require explicitgateway.auth.trustedProxy.allowLoopback = true. Internal same-host callers can usegateway.auth.passwordas a local direct fallback;gateway.auth.tokenremains mutually exclusive with trusted-proxy mode.gateway.auth.allowTailscale: whentrue, Tailscale Serve identity headers can satisfy Control UI/WebSocket auth (verified viatailscale whois). HTTP API endpoints do not use that Tailscale header auth; they follow the gateway’s normal HTTP auth mode instead. This tokenless flow assumes the gateway host is trusted. Defaults totruewhentailscale.mode = "serve".gateway.auth.rateLimit: optional failed-auth limiter. Applies per client IP and per auth scope (shared-secret and device-token are tracked independently). Blocked attempts return429+Retry-After.- On the async Tailscale Serve Control UI path, failed attempts for the same
{scope, clientIp}are serialized before the failure write. Concurrent bad attempts from the same client can therefore trip the limiter on the second request instead of both racing through as plain mismatches. gateway.auth.rateLimit.exemptLoopbackdefaults totrue; setfalsewhen you intentionally want localhost traffic rate-limited too (for test setups or strict proxy deployments).
- On the async Tailscale Serve Control UI path, failed attempts for the same
- Browser-origin WS auth attempts are always throttled with loopback exemption disabled (defense-in-depth against browser-based localhost brute force).
- On loopback, those browser-origin lockouts are isolated per normalized
Originvalue, so repeated failures from one localhost origin do not automatically lock out a different origin. tailscale.mode:serve(tailnet only, loopback bind) orfunnel(public, requires auth).controlUi.allowedOrigins: explicit browser-origin allowlist for Gateway WebSocket connects. Required when browser clients are expected from non-loopback origins.controlUi.dangerouslyAllowHostHeaderOriginFallback: dangerous mode that enables Host-header origin fallback for deployments that intentionally rely on Host-header origin policy.remote.transport:ssh(default) ordirect(ws/wss). Fordirect,remote.urlmust bews://orwss://.OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1: client-side process-environment break-glass override that allows plaintextws://to trusted private-network IPs; default remains loopback-only for plaintext. There is noopenclaw.jsonequivalent, and browser private-network config such asbrowser.ssrfPolicy.dangerouslyAllowPrivateNetworkdoes not affect Gateway WebSocket clients.gateway.remote.token/.passwordare remote-client credential fields. They do not configure gateway auth by themselves.gateway.push.apns.relay.baseUrl: base HTTPS URL for the external APNs relay used by official/TestFlight iOS builds after they publish relay-backed registrations to the gateway. This URL must match the relay URL compiled into the iOS build.gateway.push.apns.relay.timeoutMs: gateway-to-relay send timeout in milliseconds. Defaults to10000.- Relay-backed registrations are delegated to a specific gateway identity. The paired iOS app fetches
gateway.identity.get, includes that identity in the relay registration, and forwards a registration-scoped send grant to the gateway. Another gateway cannot reuse that stored registration. OPENCLAW_APNS_RELAY_BASE_URL/OPENCLAW_APNS_RELAY_TIMEOUT_MS: temporary env overrides for the relay config above.OPENCLAW_APNS_RELAY_ALLOW_HTTP=true: development-only escape hatch for loopback HTTP relay URLs. Production relay URLs should stay on HTTPS.gateway.handshakeTimeoutMs: pre-auth Gateway WebSocket handshake timeout in milliseconds. Default:15000.OPENCLAW_HANDSHAKE_TIMEOUT_MStakes precedence when set. Increase this on loaded or low-powered hosts where local clients can connect while startup warmup is still settling.gateway.channelHealthCheckMinutes: channel health-monitor interval in minutes. Set0to disable health-monitor restarts globally. Default:5.gateway.channelStaleEventThresholdMinutes: stale-socket threshold in minutes. Keep this greater than or equal togateway.channelHealthCheckMinutes. Default:30.gateway.channelMaxRestartsPerHour: maximum health-monitor restarts per channel/account in a rolling hour. Default:10.channels.<provider>.healthMonitor.enabled: per-channel opt-out for health-monitor restarts while keeping the global monitor enabled.channels.<provider>.accounts.<accountId>.healthMonitor.enabled: per-account override for multi-account channels. When set, it takes precedence over the channel-level override.- Local gateway call paths can use
gateway.remote.*as fallback only whengateway.auth.*is unset. - If
gateway.auth.token/gateway.auth.passwordis explicitly configured via SecretRef and unresolved, resolution fails closed (no remote fallback masking). trustedProxies: reverse proxy IPs that terminate TLS or inject forwarded-client headers. Only list proxies you control. Loopback entries are still valid for same-host proxy/local-detection setups (for example Tailscale Serve or a local reverse proxy), but they do not make loopback requests eligible forgateway.auth.mode: "trusted-proxy".allowRealIpFallback: whentrue, the gateway acceptsX-Real-IPifX-Forwarded-Foris missing. Defaultfalsefor fail-closed behavior.gateway.nodes.pairing.autoApproveCidrs: optional CIDR/IP allowlist for auto-approving first-time node device pairing with no requested scopes. It is disabled when unset. This does not auto-approve operator/browser/Control UI/WebChat pairing, and it does not auto-approve role, scope, metadata, or public-key upgrades.gateway.nodes.allowCommands/gateway.nodes.denyCommands: global allow/deny shaping for declared node commands after pairing and platform allowlist evaluation. UseallowCommandsto opt into dangerous node commands such ascamera.snap,camera.clip, andscreen.record;denyCommandsremoves a command even if a platform default or explicit allow would otherwise include it. After a node changes its declared command list, reject and re-approve that device pairing so the gateway stores the updated command snapshot.gateway.tools.deny: extra tool names blocked for HTTPPOST /tools/invoke(extends default deny list).gateway.tools.allow: remove tool names from the default HTTP deny list.
OpenAI-compatible endpoints
- Chat Completions: disabled by default. Enable with
gateway.http.endpoints.chatCompletions.enabled: true. - Responses API:
gateway.http.endpoints.responses.enabled. - Responses URL-input hardening:
gateway.http.endpoints.responses.maxUrlPartsgateway.http.endpoints.responses.files.urlAllowlistgateway.http.endpoints.responses.images.urlAllowlistEmpty allowlists are treated as unset; usegateway.http.endpoints.responses.files.allowUrl=falseand/orgateway.http.endpoints.responses.images.allowUrl=falseto disable URL fetching.
- Optional response hardening header:
gateway.http.securityHeaders.strictTransportSecurity(set only for HTTPS origins you control; see Trusted Proxy Auth)
Multi-instance isolation
Run multiple gateways on one host with unique ports and state dirs:--dev (uses ~/.openclaw-dev + port 19001), --profile <name> (uses ~/.openclaw-<name>).
See Multiple Gateways.
gateway.tls
enabled: enables TLS termination at the gateway listener (HTTPS/WSS) (default:false).autoGenerate: auto-generates a local self-signed cert/key pair when explicit files are not configured; for local/dev use only.certPath: filesystem path to the TLS certificate file.keyPath: filesystem path to the TLS private key file; keep permission-restricted.caPath: optional CA bundle path for client verification or custom trust chains.
gateway.reload
mode: controls how config edits are applied at runtime."off": ignore live edits; changes require an explicit restart."restart": always restart the gateway process on config change."hot": apply changes in-process without restarting."hybrid"(default): try hot reload first; fall back to restart if required.
debounceMs: debounce window in ms before config changes are applied (non-negative integer).deferralTimeoutMs: optional maximum time in ms to wait for in-flight operations before forcing a restart. Omit it or set0to wait indefinitely and log periodic still-pending warnings.
Hooks
Authorization: Bearer <token> or x-openclaw-token: <token>.
Query-string hook tokens are rejected.
Validation and safety notes:
hooks.enabled=truerequires a non-emptyhooks.token.hooks.tokenmust be distinct fromgateway.auth.token; reusing the Gateway token is rejected.hooks.pathcannot be/; use a dedicated subpath such as/hooks.- If
hooks.allowRequestSessionKey=true, constrainhooks.allowedSessionKeyPrefixes(for example["hook:"]). - If a mapping or preset uses a templated
sessionKey, sethooks.allowedSessionKeyPrefixesandhooks.allowRequestSessionKey=true. Static mapping keys do not require that opt-in.
POST /hooks/wake→{ text, mode?: "now"|"next-heartbeat" }POST /hooks/agent→{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }sessionKeyfrom request payload is accepted only whenhooks.allowRequestSessionKey=true(default:false).
POST /hooks/<name>→ resolved viahooks.mappings- Template-rendered mapping
sessionKeyvalues are treated as externally supplied and also requirehooks.allowRequestSessionKey=true.
- Template-rendered mapping
Mapping details
Mapping details
match.pathmatches sub-path after/hooks(e.g./hooks/gmail→gmail).match.sourcematches a payload field for generic paths.- Templates like
{{messages[0].subject}}read from the payload. transformcan point to a JS/TS module returning a hook action.transform.modulemust be a relative path and stays withinhooks.transformsDir(absolute paths and traversal are rejected).
agentIdroutes to a specific agent; unknown IDs fall back to default.allowedAgentIds: restricts explicit routing (*or omitted = allow all,[]= deny all).defaultSessionKey: optional fixed session key for hook agent runs without explicitsessionKey.allowRequestSessionKey: allow/hooks/agentcallers and template-driven mapping session keys to setsessionKey(default:false).allowedSessionKeyPrefixes: optional prefix allowlist for explicitsessionKeyvalues (request + mapping), e.g.["hook:"]. It becomes required when any mapping or preset uses a templatedsessionKey.deliver: truesends final reply to a channel;channeldefaults tolast.modeloverrides LLM for this hook run (must be allowed if model catalog is set).
Gmail integration
- The built-in Gmail preset uses
sessionKey: "hook:gmail:{{messages[0].id}}". - If you keep that per-message routing, set
hooks.allowRequestSessionKey: trueand constrainhooks.allowedSessionKeyPrefixesto match the Gmail namespace, for example["hook:", "hook:gmail:"]. - If you need
hooks.allowRequestSessionKey: false, override the preset with a staticsessionKeyinstead of the templated default.
- Gateway auto-starts
gog gmail watch serveon boot when configured. SetOPENCLAW_SKIP_GMAIL_WATCHER=1to disable. - Don’t run a separate
gog gmail watch servealongside the Gateway.
Canvas host
- Serves agent-editable HTML/CSS/JS and A2UI over HTTP under the Gateway port:
http://<gateway-host>:<gateway.port>/__openclaw__/canvas/http://<gateway-host>:<gateway.port>/__openclaw__/a2ui/
- Local-only: keep
gateway.bind: "loopback"(default). - Non-loopback binds: canvas routes require Gateway auth (token/password/trusted-proxy), same as other Gateway HTTP surfaces.
- Node WebViews typically don’t send auth headers; after a node is paired and connected, the Gateway advertises node-scoped capability URLs for canvas/A2UI access.
- Capability URLs are bound to the active node WS session and expire quickly. IP-based fallback is not used.
- Injects live-reload client into served HTML.
- Auto-creates starter
index.htmlwhen empty. - Also serves A2UI at
/__openclaw__/a2ui/. - Changes require a gateway restart.
- Disable live reload for large directories or
EMFILEerrors.
Discovery
mDNS (Bonjour)
minimal(default): omitcliPath+sshPortfrom TXT records.full: includecliPath+sshPort.- Hostname defaults to the system hostname when it is a valid DNS label, falling back to
openclaw. Override withOPENCLAW_MDNS_HOSTNAME.
Wide-area (DNS-SD)
~/.openclaw/dns/. For cross-network discovery, pair with a DNS server (CoreDNS recommended) + Tailscale split DNS.
Setup: openclaw dns setup --apply.
Environment
env (inline env vars)
- Inline env vars are only applied if the process env is missing the key.
.envfiles: CWD.env+~/.openclaw/.env(neither overrides existing vars).shellEnv: imports missing expected keys from your login shell profile.- See Environment for full precedence.
Env var substitution
Reference env vars in any config string with${VAR_NAME}:
- Only uppercase names matched:
[A-Z_][A-Z0-9_]*. - Missing/empty vars throw an error at config load.
- Escape with
$${VAR}for a literal${VAR}. - Works with
$include.
Secrets
Secret refs are additive: plaintext values still work.SecretRef
Use one object shape:
providerpattern:^[a-z][a-z0-9_-]{0,63}$source: "env"id pattern:^[A-Z][A-Z0-9_]{0,127}$source: "file"id: absolute JSON pointer (for example"/providers/openai/apiKey")source: "exec"id pattern:^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$source: "exec"ids must not contain.or..slash-delimited path segments (for examplea/../bis rejected)
Supported credential surface
- Canonical matrix: SecretRef Credential Surface
secrets applytargets supportedopenclaw.jsoncredential paths.auth-profiles.jsonrefs are included in runtime resolution and audit coverage.
Secret providers config
fileprovider supportsmode: "json"andmode: "singleValue"(idmust be"value"in singleValue mode).- File and exec provider paths fail closed when Windows ACL verification is unavailable. Set
allowInsecurePath: trueonly for trusted paths that cannot be verified. execprovider requires an absolutecommandpath and uses protocol payloads on stdin/stdout.- By default, symlink command paths are rejected. Set
allowSymlinkCommand: trueto allow symlink paths while validating the resolved target path. - If
trustedDirsis configured, the trusted-dir check applies to the resolved target path. execchild environment is minimal by default; pass required variables explicitly withpassEnv.- Secret refs are resolved at activation time into an in-memory snapshot, then request paths read the snapshot only.
- Active-surface filtering applies during activation: unresolved refs on enabled surfaces fail startup/reload, while inactive surfaces are skipped with diagnostics.
Auth storage
- Per-agent profiles are stored at
<agentDir>/auth-profiles.json. auth-profiles.jsonsupports value-level refs (keyRefforapi_key,tokenReffortoken) for static credential modes.- Legacy flat
auth-profiles.jsonmaps such as{ "provider": { "apiKey": "..." } }are not a runtime format;openclaw doctor --fixrewrites them to canonicalprovider:defaultAPI-key profiles with a.legacy-flat.*.bakbackup. - OAuth-mode profiles (
auth.profiles.<id>.mode = "oauth") do not support SecretRef-backed auth-profile credentials. - Static runtime credentials come from in-memory resolved snapshots; legacy static
auth.jsonentries are scrubbed when discovered. - Legacy OAuth imports from
~/.openclaw/credentials/oauth.json. - See OAuth.
- Secrets runtime behavior and
audit/configure/applytooling: Secrets Management.
auth.cooldowns
billingBackoffHours: base backoff in hours when a profile fails due to true billing/insufficient-credit errors (default:5). Explicit billing text can still land here even on401/403responses, but provider-specific text matchers stay scoped to the provider that owns them (for example OpenRouterKey limit exceeded). Retryable HTTP402usage-window or organization/workspace spend-limit messages stay in therate_limitpath instead.billingBackoffHoursByProvider: optional per-provider overrides for billing backoff hours.billingMaxHours: cap in hours for billing backoff exponential growth (default:24).authPermanentBackoffMinutes: base backoff in minutes for high-confidenceauth_permanentfailures (default:10).authPermanentMaxMinutes: cap in minutes forauth_permanentbackoff growth (default:60).failureWindowHours: rolling window in hours used for backoff counters (default:24).overloadedProfileRotations: maximum same-provider auth-profile rotations for overloaded errors before switching to model fallback (default:1). Provider-busy shapes such asModelNotReadyExceptionland here.overloadedBackoffMs: fixed delay before retrying an overloaded provider/profile rotation (default:0).rateLimitedProfileRotations: maximum same-provider auth-profile rotations for rate-limit errors before switching to model fallback (default:1). That rate-limit bucket includes provider-shaped text such asToo many concurrent requests,ThrottlingException,concurrency limit reached,workers_ai ... quota limit exceeded, andresource exhausted.
Logging
- Default log file:
/tmp/openclaw/openclaw-YYYY-MM-DD.log. - Set
logging.filefor a stable path. consoleLevelbumps todebugwhen--verbose.maxFileBytes: maximum active log file size in bytes before rotation (positive integer; default:104857600= 100 MB). OpenClaw keeps up to five numbered archives beside the active file.redactSensitive/redactPatterns: best-effort masking for console output, file logs, OTLP log records, and persisted session transcript text.redactSensitive: "off"only disables this general log/transcript policy; UI/tool/diagnostic safety surfaces still redact secrets before emission.
Diagnostics
enabled: master toggle for instrumentation output (default:true).flags: array of flag strings enabling targeted log output (supports wildcards like"telegram.*"or"*").stuckSessionWarnMs: age threshold in ms for emitting stuck-session warnings while a session remains in processing state.otel.enabled: enables the OpenTelemetry export pipeline (default:false). For the full configuration, signal catalog, and privacy model, see OpenTelemetry export.otel.endpoint: collector URL for OTel export.otel.tracesEndpoint/otel.metricsEndpoint/otel.logsEndpoint: optional signal-specific OTLP endpoints. When set, they overrideotel.endpointfor that signal only.otel.protocol:"http/protobuf"(default) or"grpc".otel.headers: extra HTTP/gRPC metadata headers sent with OTel export requests.otel.serviceName: service name for resource attributes.otel.traces/otel.metrics/otel.logs: enable trace, metrics, or log export.otel.sampleRate: trace sampling rate0–1.otel.flushIntervalMs: periodic telemetry flush interval in ms.otel.captureContent: opt-in raw content capture for OTEL span attributes. Defaults to off. Booleantruecaptures non-system message/tool content; the object form lets you enableinputMessages,outputMessages,toolInputs,toolOutputs, andsystemPromptexplicitly.OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental: environment toggle for latest experimental GenAI span provider attributes. By default spans keep the legacygen_ai.systemattribute for compatibility; GenAI metrics use bounded semantic attributes.OPENCLAW_OTEL_PRELOADED=1: environment toggle for hosts that already registered a global OpenTelemetry SDK. OpenClaw then skips plugin-owned SDK startup/shutdown while keeping diagnostic listeners active.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, andOTEL_EXPORTER_OTLP_LOGS_ENDPOINT: signal-specific endpoint env vars used when the matching config key is unset.cacheTrace.enabled: log cache trace snapshots for embedded runs (default:false).cacheTrace.filePath: output path for cache trace JSONL (default:$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl).cacheTrace.includeMessages/includePrompt/includeSystem: control what is included in cache trace output (all default:true).
Update
channel: release channel for npm/git installs —"stable","beta", or"dev".checkOnStart: check for npm updates when the gateway starts (default:true).auto.enabled: enable background auto-update for package installs (default:false).auto.stableDelayHours: minimum delay in hours before stable-channel auto-apply (default:6; max:168).auto.stableJitterHours: extra stable-channel rollout spread window in hours (default:12; max:168).auto.betaCheckIntervalHours: how often beta-channel checks run in hours (default:1; max:24).
ACP
enabled: global ACP feature gate (default:true; setfalseto hide ACP dispatch and spawn affordances).dispatch.enabled: independent gate for ACP session turn dispatch (default:true). Setfalseto keep ACP commands available while blocking execution.backend: default ACP runtime backend id (must match a registered ACP runtime plugin). Ifplugins.allowis set, include the backend plugin id (for exampleacpx) or the bundled default plugin will not load.defaultAgent: fallback ACP target agent id when spawns do not specify an explicit target.allowedAgents: allowlist of agent ids permitted for ACP runtime sessions; empty means no additional restriction.maxConcurrentSessions: maximum concurrently active ACP sessions.stream.coalesceIdleMs: idle flush window in ms for streamed text.stream.maxChunkChars: maximum chunk size before splitting streamed block projection.stream.repeatSuppression: suppress repeated status/tool lines per turn (default:true).stream.deliveryMode:"live"streams incrementally;"final_only"buffers until turn terminal events.stream.hiddenBoundarySeparator: separator before visible text after hidden tool events (default:"paragraph").stream.maxOutputChars: maximum assistant output characters projected per ACP turn.stream.maxSessionUpdateChars: maximum characters for projected ACP status/update lines.stream.tagVisibility: record of tag names to boolean visibility overrides for streamed events.runtime.ttlMinutes: idle TTL in minutes for ACP session workers before eligible cleanup.runtime.installCommand: optional install command to run when bootstrapping an ACP runtime environment.
CLI
cli.banner.taglineModecontrols banner tagline style:"random"(default): rotating funny/seasonal taglines."default": fixed neutral tagline (All your chats, one OpenClaw.)."off": no tagline text (banner title/version still shown).
- To hide the entire banner (not just taglines), set env
OPENCLAW_HIDE_BANNER=1.
Wizard
Metadata written by CLI guided setup flows (onboard, configure, doctor):
Identity
Seeagents.list identity fields under Agent defaults.
Bridge (legacy, removed)
Current builds no longer include the TCP bridge. Nodes connect over the Gateway WebSocket.bridge.* keys are no longer part of the config schema (validation fails until removed; openclaw doctor --fix can strip unknown keys).
Legacy bridge config (historical reference)
Legacy bridge config (historical reference)
Cron
sessionRetention: how long to keep completed isolated cron run sessions before pruning fromsessions.json. Also controls cleanup of archived deleted cron transcripts. Default:24h; setfalseto disable.runLog.maxBytes: max size per run log file (cron/runs/<jobId>.jsonl) before pruning. Default:2_000_000bytes.runLog.keepLines: newest lines retained when run-log pruning is triggered. Default:2000.webhookToken: bearer token used for cron webhook POST delivery (delivery.mode = "webhook"), if omitted no auth header is sent.webhook: deprecated legacy fallback webhook URL (http/https) used only for stored jobs that still havenotify: true.
cron.retry
maxAttempts: maximum retries for one-shot jobs on transient errors (default:3; range:0–10).backoffMs: array of backoff delays in ms for each retry attempt (default:[30000, 60000, 300000]; 1–10 entries).retryOn: error types that trigger retries —"rate_limit","overloaded","network","timeout","server_error". Omit to retry all transient types.
cron.failureAlert
enabled: enable failure alerts for cron jobs (default:false).after: consecutive failures before an alert fires (positive integer, min:1).cooldownMs: minimum milliseconds between repeated alerts for the same job (non-negative integer).includeSkipped: count consecutive skipped runs toward the alert threshold (default:false). Skipped runs are tracked separately and do not affect execution-error backoff.mode: delivery mode —"announce"sends via a channel message;"webhook"posts to the configured webhook.accountId: optional account or channel id to scope alert delivery.
cron.failureDestination
- Default destination for cron failure notifications across all jobs.
mode:"announce"or"webhook"; defaults to"announce"when enough target data exists.channel: channel override for announce delivery."last"reuses the last known delivery channel.to: explicit announce target or webhook URL. Required for webhook mode.accountId: optional account override for delivery.- Per-job
delivery.failureDestinationoverrides this global default. - When neither global nor per-job failure destination is set, jobs that already deliver via
announcefall back to that primary announce target on failure. delivery.failureDestinationis only supported forsessionTarget="isolated"jobs unless the job’s primarydelivery.modeis"webhook".
Media model template variables
Template placeholders expanded intools.media.models[].args:
| Variable | Description |
|---|---|
{{Body}} | Full inbound message body |
{{RawBody}} | Raw body (no history/sender wrappers) |
{{BodyStripped}} | Body with group mentions stripped |
{{From}} | Sender identifier |
{{To}} | Destination identifier |
{{MessageSid}} | Channel message id |
{{SessionId}} | Current session UUID |
{{IsNewSession}} | "true" when new session created |
{{MediaUrl}} | Inbound media pseudo-URL |
{{MediaPath}} | Local media path |
{{MediaType}} | Media type (image/audio/document/…) |
{{Transcript}} | Audio transcript |
{{Prompt}} | Resolved media prompt for CLI entries |
{{MaxChars}} | Resolved max output chars for CLI entries |
{{ChatType}} | "direct" or "group" |
{{GroupSubject}} | Group subject (best effort) |
{{GroupMembers}} | Group members preview (best effort) |
{{SenderName}} | Sender display name (best effort) |
{{SenderE164}} | Sender phone number (best effort) |
{{Provider}} | Provider hint (whatsapp, telegram, discord, etc.) |
Config includes ($include)
Split config into multiple files:
- Single file: replaces the containing object.
- Array of files: deep-merged in order (later overrides earlier).
- Sibling keys: merged after includes (override included values).
- Nested includes: up to 10 levels deep.
- Paths: resolved relative to the including file, but must stay inside the top-level config directory (
dirnameofopenclaw.json). Absolute/../forms are allowed only when they still resolve inside that boundary. - OpenClaw-owned writes that change only one top-level section backed by a single-file include write through to that included file. For example,
plugins installupdatesplugins: { $include: "./plugins.json5" }inplugins.json5and leavesopenclaw.jsonintact. - Root includes, include arrays, and includes with sibling overrides are read-only for OpenClaw-owned writes; those writes fail closed instead of flattening the config.
- Errors: clear messages for missing files, parse errors, and circular includes.
Related: Configuration · Configuration Examples · Doctor