Zum Inhalt springen

OpenClaw Konfiguration: Kanäle und Richtlinien einstellen

Jeder Channel startet automatisch, sobald sein Konfigurationsabschnitt existiert (außer bei enabled: false).

Alle Kanäle unterstützen DM-Policies und Gruppen-Policies:

DM-PolicyVerhalten
pairing (default)Unbekannte Absender erhalten einen Pairing-Code; der Owner muss bestätigen
allowlistNur Absender in allowFrom (oder gepaarte Allow-Stores)
openErlaubt alle eingehenden DMs (erfordert allowFrom: ["*"])
disabledIgnoriert alle eingehenden DMs
Gruppen-PolicyVerhalten
allowlist (default)Nur Gruppen, die der konfigurierten Allowlist entsprechen
openUmgeht Gruppen-Allowlists (Mention-Gating gilt weiterhin)
disabledBlockiert alle Nachrichten in Gruppen oder Räumen

Verwende channels.modelByChannel, um bestimmte Channel-IDs fest an ein Modell zu binden. Die Werte akzeptieren provider/model oder konfigurierte Modell-Aliase. Das Channel-Mapping greift, wenn eine Session noch kein Modell-Override hat (zum Beispiel durch /model gesetzt).

{
channels: {
modelByChannel: {
discord: {
"123456789012345678": "anthropic/claude-opus-4-6",
},
slack: {
C1234567890: "openai/gpt-4.1",
},
telegram: {
"-1001234567890": "openai/gpt-4.1-mini",
"-1001234567890:topic:99": "anthropic/claude-sonnet-4-6",
},
},
},
}

Verwende channels.defaults für geteilte Gruppen-Policies und Heartbeat-Verhalten über alle Provider hinweg:

{
channels: {
defaults: {
groupPolicy: "allowlist", // open | allowlist | disabled
heartbeat: {
showOk: false,
showAlerts: true,
useIndicator: true,
},
},
},
}
  • channels.defaults.groupPolicy: Fallback-Gruppen-Policy, wenn auf Provider-Ebene keine groupPolicy definiert ist.
  • channels.defaults.heartbeat.showOk: Zeigt gesunde Channel-Stati in der Heartbeat-Ausgabe an.
  • channels.defaults.heartbeat.showAlerts: Zeigt fehlerhafte Stati in der Heartbeat-Ausgabe an.
  • channels.defaults.heartbeat.useIndicator: Erzeugt eine kompakte Heartbeat-Ausgabe im Indikator-Stil.

WhatsApp läuft über den Web-Channel des Gateways (Baileys Web). Es startet automatisch, sobald eine verknüpfte Session existiert.

{
channels: {
whatsapp: {
dmPolicy: "pairing", // pairing | allowlist | open | disabled
allowFrom: ["+15555550123", "+447700900123"],
textChunkLimit: 4000,
chunkMode: "length", // length | newline
mediaMaxMb: 50,
sendReadReceipts: true, // blue ticks (false in self-chat mode)
groups: {
"*": { requireMention: true },
},
groupPolicy: "allowlist",
groupAllowFrom: ["+15551234567"],
},
},
web: {
enabled: true,
heartbeatSeconds: 60,
reconnect: {
initialMs: 2000,
maxMs: 120000,
factor: 1.4,
jitter: 0.2,
maxAttempts: 0,
},
},
}

Multi-Account WhatsApp

{
channels: {
whatsapp: {
accounts: {
default: {},
personal: {},
biz: {
// authDir: "~/.openclaw/credentials/whatsapp/biz",
},
},
},
},
}
  • Ausgehende Befehle nutzen standardmäßig den Account default, falls vorhanden; ansonsten die erste konfigurierte Account-ID (sortiert).
  • Die optionale Einstellung channels.whatsapp.defaultAccount überschreibt diese Auswahl, wenn sie einer konfigurierten Account-ID entspricht.
  • Veraltete Single-Account Baileys Auth-Verzeichnisse werden durch openclaw doctor nach whatsapp/default migriert.
  • Overrides pro Account: channels.whatsapp.accounts.<id>.sendReadReceipts, channels.whatsapp.accounts.<id>.dmPolicy, channels.whatsapp.accounts.<id>.allowFrom.
{
channels: {
telegram: {
enabled: true,
botToken: "your-bot-token",
dmPolicy: "pairing",
allowFrom: ["tg:123456789"],
groups: {
"*": { requireMention: true },
"-1001234567890": {
allowFrom: ["@admin"],
systemPrompt: "Keep answers brief.",
topics: {
"99": {
requireMention: false,
skills: ["search"],
systemPrompt: "Stay on topic.",
},
},
},
},
customCommands: [
{ command: "backup", description: "Git backup" },
{ command: "generate", description: "Create an image" },
],
historyLimit: 50,
replyToMode: "first", // off | first | all
linkPreview: true,
streaming: "partial", // off | partial | block | progress (default: off)
actions: { reactions: true, sendMessage: true },
reactionNotifications: "own", // off | own | all
mediaMaxMb: 100,
retry: {
attempts: 3,
minDelayMs: 400,
maxDelayMs: 30000,
jitter: 0.1,
},
network: {
autoSelectFamily: true,
dnsResultOrder: "ipv4first",
},
proxy: "socks5://localhost:9050",
webhookUrl: "https://example.com/telegram-webhook",
webhookSecret: "secret",
webhookPath: "/telegram-webhook",
},
},
}
  • Bot-Token: channels.telegram.botToken oder channels.telegram.tokenFile (nur reguläre Dateien; Symlinks werden abgelehnt), mit TELEGRAM_BOT_TOKEN als Fallback für den Standard-Account.
  • channels.telegram.defaultAccount überschreibt optional die Auswahl des Standard-Accounts.
  • In Multi-Account-Setups (2+ IDs) solltest du einen expliziten Default setzen (channels.telegram.defaultAccount oder channels.telegram.accounts.default), um Fehlleitungen zu vermeiden; openclaw doctor warnt bei Fehlern.
  • configWrites: false blockiert durch Telegram ausgelöste Konfigurationsänderungen (z. B. Supergroup-ID-Migrationen, /config set|unset).
  • Top-Level bindings[] Einträge mit type: "acp" konfigurieren persistente ACP-Bindungen für Forum-Topics (nutze die kanonische chatId:topic:topicId in match.peer.id). Details findest du unter ACP Agents.
  • Telegram Stream-Previews nutzen sendMessage + editMessageText (funktioniert in Direkt- und Gruppen-Chats).
  • Retry-Policy: siehe Retry policy.
{
channels: {
discord: {
enabled: true,
token: "your-bot-token",
mediaMaxMb: 8,
allowBots: false,
actions: {
reactions: true,
stickers: true,
polls: true,
permissions: true,
messages: true,
threads: true,
pins: true,
search: true,
memberInfo: true,
roleInfo: true,
roles: false,
channelInfo: true,
voiceStatus: true,
events: true,
moderation: false,
},
replyToMode: "off", // off | first | all
dmPolicy: "pairing",
allowFrom: ["1234567890", "123456789012345678"],
dm: { enabled: true, groupEnabled: false, groupChannels: ["openclaw-dm"] },
guilds: {
"123456789012345678": {
slug: "friends-of-openclaw",
requireMention: false,
ignoreOtherMentions: true,
reactionNotifications: "own",
users: ["987654321098765432"],
channels: {
general: { allow: true },
help: {
allow: true,
requireMention: true,
users: ["987654321098765432"],
skills: ["docs"],
systemPrompt: "Short answers only.",
},
},
},
},
historyLimit: 20,
textChunkLimit: 2000,
chunkMode: "length", // length | newline
streaming: "off", // off | partial | block | progress (progress maps to partial on Discord)
maxLinesPerMessage: 17,
ui: {
components: {
accentColor: "#5865F2",
},
},
threadBindings: {
enabled: true,
idleHours: 24,
maxAgeHours: 0,
spawnSubagentSessions: false, // opt-in for sessions_spawn({ thread: true })
},
voice: {
enabled: true,
autoJoin: [
{
guildId: "123456789012345678",
channelId: "234567890123456789",
},
],
daveEncryption: true,
decryptionFailureTolerance: 24,
tts: {
provider: "openai",
openai: { voice: "alloy" },
},
},
retry: {
attempts: 3,
minDelayMs: 500,
maxDelayMs: 30000,
jitter: 0.1,
},
},
},
}
  • Token: channels.discord.token, mit DISCORD_BOT_TOKEN als Fallback.
  • Direkte ausgehende Aufrufe mit explizitem Discord-token nutzen diesen; Retry- und Policy-Einstellungen stammen jedoch vom gewählten Account des aktiven Snapshots.
  • Nutze user:<id> (DM) oder channel:<id> (Guild-Channel) für Sendeziele; rein numerische IDs werden abgelehnt.
  • Guild-Slugs sind kleingeschrieben, Leerzeichen werden durch - ersetzt. Channel-Keys nutzen den Slug-Namen (ohne #). Guild-IDs werden bevorzugt.
  • Von Bots verfasste Nachrichten werden standardmäßig ignoriert. allowBots: true aktiviert sie; allowBots: "mentions" akzeptiert nur Nachrichten, die den Bot erwähnen.
  • channels.discord.guilds.<id>.ignoreOtherMentions verwirft Nachrichten, die andere Nutzer oder Rollen erwähnen, aber nicht den Bot (außer @everyone/@here).
  • maxLinesPerMessage (Standard 17) teilt lange Nachrichten auf, selbst wenn sie unter 2000 Zeichen liegen.
  • channels.discord.threadBindings steuert das Discord-Thread-Routing:
    • enabled: Discord-Override für Thread-Features (/focus, /unfocus, etc.)
    • idleHours: Inaktivitäts-Timeout in Stunden (0 deaktiviert)
    • maxAgeHours: Hartes Zeitlimit für Threads in Stunden (0 deaktiviert)
    • spawnSubagentSessions: Aktiviert automatische Thread-Erstellung für sessions_spawn({ thread: true })
  • channels.discord.ui.components.accentColor setzt die Akzentfarbe für Discord-Komponenten.
  • channels.discord.voice aktiviert Sprachkanäle inklusive optionalem Auto-Join und TTS-Overrides.
  • OpenClaw versucht bei Entschlüsselungsfehlern im Voice-Chat eine automatische Wiederherstellung durch Verlassen und erneutes Beitreten.

Reaktions-Benachrichtigungsmodi: off (keine), own (nur Nachrichten des Bots, Standard), all (alle Nachrichten), allowlist (nur von guilds.<id>.users).

{
channels: {
googlechat: {
enabled: true,
serviceAccountFile: "/path/to/service-account.json",
audienceType: "app-url", // app-url | project-number
audience: "https://gateway.example.com/googlechat",
webhookPath: "/googlechat",
botUser: "users/1234567890",
dm: {
enabled: true,
policy: "pairing",
allowFrom: ["users/1234567890"],
},
groupPolicy: "allowlist",
groups: {
"spaces/AAAA": { allow: true, requireMention: true },
},
actions: { reactions: true },
typingIndicator: "message",
mediaMaxMb: 20,
},
},
}
  • Service Account JSON: Entweder inline (serviceAccount) oder als Datei (serviceAccountFile).
  • SecretRef wird ebenfalls unterstützt (serviceAccountRef).
  • Fallbacks für Umgebungsvariablen: GOOGLE_CHAT_SERVICE_ACCOUNT oder GOOGLE_CHAT_SERVICE_ACCOUNT_FILE.
  • Nutze spaces/<spaceId> oder users/<userId> als Sendeziele.
  • channels.googlechat.dangerouslyAllowNameMatching reaktiviert das Matching über E-Mail-Adressen (Kompatibilitätsmodus).
{
channels: {
slack: {
enabled: true,
botToken: "xoxb-...",
appToken: "xapp-...",
dmPolicy: "pairing",
allowFrom: ["U123", "U456", "*"],
dm: { enabled: true, groupEnabled: false, groupChannels: ["G123"] },
channels: {
C123: { allow: true, requireMention: true, allowBots: false },
"#general": {
allow: true,
requireMention: true,
allowBots: false,
users: ["U123"],
skills: ["docs"],
systemPrompt: "Short answers only.",
},
},
historyLimit: 50,
allowBots: false,
reactionNotifications: "own",
reactionAllowlist: ["U123"],
replyToMode: "off", // off | first | all
thread: {
historyScope: "thread", // thread | channel
inheritParent: false,
},
actions: {
reactions: true,
messages: true,
pins: true,
memberInfo: true,
emojiList: true,
},
slashCommand: {
enabled: true,
name: "openclaw",
sessionPrefix: "slack:slash",
ephemeral: true,
},
typingReaction: "hourglass_flowing_sand",
textChunkLimit: 4000,
chunkMode: "length",
streaming: "partial", // off | partial | block | progress (preview mode)
nativeStreaming: true, // use Slack native streaming API when streaming=partial
mediaMaxMb: 20,
},
},
}
  • Socket-Modus erfordert sowohl botToken als auch appToken.
  • HTTP-Modus erfordert botToken plus signingSecret.
  • configWrites: false verhindert Konfigurationsänderungen via Slack.
  • Nutze user:<id> (DM) oder channel:<id> für Sendeziele.
  • typingReaction fügt der eingehenden Nachricht eine temporäre Reaktion hinzu (z. B. "hourglass_flowing_sand"), während die Antwort generiert wird.

Thread-Isolierung: thread.historyScope bestimmt, ob der Verlauf pro Thread (Standard) oder für den gesamten Channel gilt. thread.inheritParent kopiert den Channel-Verlauf in neue Threads.

Mattermost wird als Plugin ausgeliefert: openclaw plugins install @openclaw/mattermost.

{
channels: {
mattermost: {
enabled: true,
botToken: "mm-token",
baseUrl: "https://chat.example.com",
dmPolicy: "pairing",
chatmode: "oncall", // oncall | onmessage | onchar
oncharPrefixes: [">", "!"],
commands: {
native: true, // opt-in
nativeSkills: true,
callbackPath: "/api/channels/mattermost/command",
// Optional explicit URL for reverse-proxy/public deployments
callbackUrl: "https://gateway.example.com/api/channels/mattermost/command",
},
textChunkLimit: 4000,
chunkMode: "length",
},
},
}

Chat-Modi: oncall (reagiert auf @-Erwähnung, Standard), onmessage (jede Nachricht), onchar (Nachrichten mit Trigger-Präfix).

{
channels: {
signal: {
enabled: true,
account: "+15555550123", // optional account binding
dmPolicy: "pairing",
allowFrom: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"],
configWrites: true,
reactionNotifications: "own", // off | own | all | allowlist
reactionAllowlist: ["+15551234567", "uuid:123e4567-e89b-12d3-a456-426614174000"],
historyLimit: 50,
},
},
}
  • channels.signal.account: Bindet den Channel-Start an eine spezifische Signal-Identität.

BlueBubbles ist der empfohlene Weg für iMessage (Plugin-basiert).

{
channels: {
bluebubbles: {
enabled: true,
dmPolicy: "pairing",
// serverUrl, password, webhookPath, group controls, and advanced actions:
// see /channels/bluebubbles
},
},
}

OpenClaw startet imsg rpc (JSON-RPC über stdio). Kein Daemon oder Port nötig.

{
channels: {
imessage: {
enabled: true,
cliPath: "imsg",
dbPath: "~/Library/Messages/chat.db",
remoteHost: "user@gateway-host",
dmPolicy: "pairing",
allowFrom: ["+15555550123", "user@example.com", "chat_id:123"],
historyLimit: 50,
includeAttachments: false,
attachmentRoots: ["/Users/*/Library/Messages/Attachments"],
remoteAttachmentRoots: ["/Users/*/Library/Messages/Attachments"],
mediaMaxMb: 16,
service: "auto",
region: "US",
},
},
}
  • Erfordert “Festplattenvollzugriff” für die Messages-Datenbank.
  • Nutze bevorzugt chat_id:<id> als Ziel. Liste Chats mit imsg chats --limit 20 auf.
  • cliPath kann auf einen SSH-Wrapper zeigen; setze remoteHost für SCP-Dateitransfers.

Microsoft Teams ist Extension-basiert und wird unter channels.msteams konfiguriert.

{
channels: {
msteams: {
enabled: true,
configWrites: true,
// appId, appPassword, tenantId, webhook, team/channel policies:
// see /channels/msteams
},
},
}

IRC ist Extension-basiert und wird unter channels.irc konfiguriert.

{
channels: {
irc: {
enabled: true,
dmPolicy: "pairing",
configWrites: true,
nickserv: {
enabled: true,
service: "NickServ",
password: "${IRC_NICKSERV_PASSWORD}",
register: false,
registerEmail: "bot@example.com",
},
},
},
}

Du kannst mehrere Accounts pro Channel betreiben:

{
channels: {
telegram: {
accounts: {
default: {
name: "Primary bot",
botToken: "123456:ABC...",
},
alerts: {
name: "Alerts bot",
botToken: "987654:XYZ...",
},
},
},
},
}
  • default wird genutzt, wenn keine accountId angegeben ist.
  • Basis-Einstellungen gelten für alle Accounts, sofern sie nicht pro Account überschrieben werden.
  • Nutze bindings[].match.accountId, um Accounts verschiedenen Agenten zuzuweisen.

Viele weitere Kanäle (Feishu, Matrix, LINE, Nostr, etc.) sind als channels.<id> verfügbar. Den vollständigen Index findest du unter Channels.

Gruppen-Nachrichten erfordern standardmäßig eine Erwähnung (Metadata-Mention oder Regex-Muster). Dies gilt für WhatsApp, Telegram, Discord, Google Chat und iMessage.

{
messages: {
groupChat: { historyLimit: 50 },
},
agents: {
list: [{ id: "main", groupChat: { mentionPatterns: ["@openclaw", "openclaw"] } }],
},
}
{
commands: {
native: "auto", // register native commands when supported
text: true, // parse /commands in chat messages
bash: false, // allow ! (alias: /bash)
bashForegroundMs: 2000,
config: false, // allow /config
debug: false, // allow /debug
restart: false, // allow /restart + gateway restart tool
allowFrom: {
"*": ["user1"],
discord: ["user:123"],
},
useAccessGroups: true,
},
}
  • Text-Befehle müssen als eigenständige Nachrichten mit führendem / gesendet werden.
  • bash: true aktiviert ! <cmd> für die Host-Shell (erfordert erhöhte Rechte).
  • config: true aktiviert /config zum Lesen und Schreiben der openclaw.json.

Standard: ~/.openclaw/workspace.

{
agents: { defaults: { workspace: "~/.openclaw/workspace" } },
}

Optionales Repository-Verzeichnis für den System-Prompt. Falls nicht gesetzt, erkennt OpenClaw dies automatisch.

Deaktiviert das automatische Erstellen von Bootstrap-Dateien im Workspace (z. B. AGENTS.md, SOUL.md).

Maximale Pixelgröße für die längste Seite eines Bildes vor dem Senden an den Provider. Standard: 1200.

{
agents: {
defaults: {
models: {
"anthropic/claude-opus-4-6": { alias: "opus" },
"minimax/MiniMax-M2.5": { alias: "minimax" },
},
model: {
primary: "anthropic/claude-opus-4-6",
fallbacks: ["minimax/MiniMax-M2.5"],
},
imageModel: {
primary: "openrouter/qwen/qwen-2.5-vl-72b-instruct:free",
fallbacks: ["openrouter/google/gemini-2.0-flash-vision:free"],
},
pdfModel: {
primary: "anthropic/claude-opus-4-6",
fallbacks: ["openai/gpt-5-mini"],
},
pdfMaxBytesMb: 10,
pdfMaxPages: 20,
thinkingDefault: "low",
verboseDefault: "off",
elevatedDefault: "on",
timeoutSeconds: 600,
mediaMaxMb: 5,
contextTokens: 200000,
maxConcurrent: 3,
},
},
}
  • model: Akzeptiert einen String ("provider/model") oder ein Objekt mit Fallbacks.
  • imageModel: Wird für Bild-Tools oder als Fallback genutzt, wenn das Hauptmodell keine Vision-Features hat.
  • pdfModel: Speziell für das PDF-Tool.
  • maxConcurrent: Maximale parallele Agent-Läufe über alle Sessions hinweg. Standard: 1.

Optionale CLI-Backends für reine Text-Läufe ohne Tool-Calls.

Periodische Heartbeat-Läufe zur Statusprüfung.

{
agents: {
defaults: {
heartbeat: {
every: "30m", // 0m disables
model: "openai/gpt-5.2-mini",
includeReasoning: false,
lightContext: false, // default: false; true keeps only HEARTBEAT.md from workspace bootstrap files
session: "main",
to: "+15555550123",
directPolicy: "allow", // allow (default) | block
target: "none", // default: none | options: last | whatsapp | telegram | discord | ...
prompt: "Read HEARTBEAT.md if it exists...",
ackMaxChars: 300,
suppressToolErrorWarnings: false,
},
},
},
}

Steuert die Zusammenfassung langer Verläufe, um Token zu sparen.

{
agents: {
defaults: {
compaction: {
mode: "safeguard", // default | safeguard
reserveTokensFloor: 24000,
identifierPolicy: "strict", // strict | off | custom
identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // used when identifierPolicy=custom
postCompactionSections: ["Session Startup", "Red Lines"], // [] disables reinjection
model: "openrouter/anthropic/claude-sonnet-4-5", // optional compaction-only model override
memoryFlush: {
enabled: true,
softThresholdTokens: 6000,
systemPrompt: "Session nearing compaction. Store durable memories now.",
prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with NO_REPLY if nothing to store.",
},
},
},
},
}

Entfernt alte Tool-Ergebnisse aus dem Arbeitsspeicher, bevor sie an das LLM gesendet werden.

{
agents: {
defaults: {
blockStreamingDefault: "off", // on | off
blockStreamingBreak: "text_end", // text_end | message_end
blockStreamingChunk: { minChars: 800, maxChars: 1200 },
blockStreamingCoalesce: { idleMs: 1000 },
humanDelay: { mode: "natural" }, // off | natural | custom (use minMs/maxMs)
},
},
}

Optionale Docker-Sandbox für den Agenten.

{
agents: {
list: [
{
id: "main",
default: true,
name: "Main Agent",
workspace: "~/.openclaw/workspace",
agentDir: "~/.openclaw/agents/main/agent",
model: "anthropic/claude-opus-4-6", // or { primary, fallbacks }
params: { cacheRetention: "none" }, // overrides matching defaults.models params by key
identity: {
name: "Samantha",
theme: "helpful sloth",
emoji: "🦥",
avatar: "avatars/samantha.png",
},
groupChat: { mentionPatterns: ["@openclaw"] },
sandbox: { mode: "off" },
runtime: {
type: "acp",
acp: {
agent: "codex",
backend: "acpx",
mode: "persistent",
cwd: "/workspace/openclaw",
},
},
subagents: { allowAgents: ["*"] },
tools: {
profile: "coding",
allow: ["browser"],
deny: ["canvas"],
elevated: { enabled: true },
},
},
],
},
}

Hier definierst du spezifische Agenten mit eigenen Workspaces, Modellen oder Identitäten.


Betreibe mehrere isolierte Agenten in einem Gateway.

{
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" } },
],
}
  • match.channel (erforderlich)
  • match.accountId (optional; * = jeder Account)
  • match.peer (optional; { kind: direct|group|channel, id })

Die Reihenfolge der Übereinstimmung ist deterministisch: Spezifische Peer-Matches gewinnen vor Account-Matches, welche wiederum vor Channel-weiten Bindungen gewinnen.


{
session: {
scope: "per-sender",
dmScope: "main", // main | per-peer | per-channel-peer | per-account-channel-peer
identityLinks: {
alice: ["telegram:123456789", "discord:987654321012345678"],
},
reset: {
mode: "daily", // daily | idle
atHour: 4,
idleMinutes: 60,
},
resetByType: {
thread: { mode: "daily", atHour: 4 },
direct: { mode: "idle", idleMinutes: 240 },
group: { mode: "idle", idleMinutes: 120 },
},
resetTriggers: ["/new", "/reset"],
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
parentForkMaxTokens: 100000, // skip parent-thread fork above this token count (0 disables)
maintenance: {
mode: "warn", // warn | enforce
pruneAfter: "30d",
maxEntries: 500,
rotateBytes: "10mb",
resetArchiveRetention: "30d", // duration or false
maxDiskBytes: "500mb", // optional hard budget
highWaterBytes: "400mb", // optional cleanup target
},
threadBindings: {
enabled: true,
idleHours: 24, // default inactivity auto-unfocus in hours (`0` disables)
maxAgeHours: 0, // default hard max age in hours (`0` disables)
},
mainKey: "main", // legacy (runtime always uses "main")
agentToAgent: { maxPingPongTurns: 5 },
sendPolicy: {
rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
default: "allow",
},
},
}
  • dmScope: Bestimmt, wie DMs gruppiert werden (z. B. per-channel-peer für isolierte Postfächer).
  • identityLinks: Verknüpft Identitäten über verschiedene Kanäle hinweg für eine gemeinsame Session.
  • reset: Definiert, wann eine Session zurückgesetzt wird (täglich oder nach Inaktivität).
  • maintenance: Automatische Bereinigung des Session-Speichers.
  • threadBindings: Globale Standards für Thread-basierte Features.

AI Setup Assistant

{
messages: {
responsePrefix: "🦞", // or "auto"
ackReaction: "👀",
ackReactionScope: "group-mentions", // group-mentions | group-all | direct | all
removeAckAfterReply: false,
queue: {
mode: "collect", // steer | followup | collect | steer-backlog | steer+backlog | queue | interrupt
debounceMs: 1000,
cap: 20,
drop: "summarize", // old | new | summarize
byChannel: {
whatsapp: "collect",
telegram: "collect",
},
},
inbound: {
debounceMs: 2000, // 0 disables
byChannel: {
whatsapp: 5000,
slack: 1500,
},
},
},
}

Du kannst Präfixe pro Channel oder Account überschreiben: channels.<channel>.responsePrefix, channels.<channel>.accounts.<id>.responsePrefix.

Die Auflösung folgt dieser Hierarchie (spezifisch gewinnt): Account → Channel → Global. Ein leerer String "" deaktiviert das Präfix und stoppt die Kaskade. "auto" leitet den Namen aus {identity.name} ab.

Template-Variablen:

VariableBeschreibungBeispiel
{model}Kurzer Modellnameclaude-opus-4-6
{modelFull}Vollständige Modell-IDanthropic/claude-opus-4-6
{provider}Provider-Nameanthropic
{thinkingLevel}Aktuelles Thinking-Levelhigh, low, off
{identity.name}Name der Agent-Identität(entspricht "auto")

Bei Variablen wird nicht zwischen Groß- und Kleinschreibung unterschieden. {think} dient als Alias für {thinkingLevel}.

  • Standardmäßig wird die identity.emoji des aktiven Agents verwendet, ansonsten "👀". Nutze "" zum Deaktivieren.
  • Overrides pro Channel: channels.<channel>.ackReaction, channels.<channel>.accounts.<id>.ackReaction.
  • Auflösungsreihenfolge: Account → Channel → messages.ackReaction → Identity-Fallback.
  • Scope: group-mentions (Standard), group-all, direct, all.
  • removeAckAfterReply: Entfernt die Bestätigung nach der Antwort (nur für Slack, Discord, Telegram und Google Chat).

Diese Funktion fasst schnell aufeinanderfolgende Textnachrichten desselben Absenders in einem einzigen Agent-Turn zusammen. Medien und Anhänge werden sofort verarbeitet. Control-Befehle umgehen das Debouncing.

{
messages: {
tts: {
auto: "always", // off | always | inbound | tagged
mode: "final", // final | all
provider: "elevenlabs",
summaryModel: "openai/gpt-4.1-mini",
modelOverrides: { enabled: true },
maxTextLength: 4000,
timeoutMs: 30000,
prefsPath: "~/.openclaw/settings/tts.json",
elevenlabs: {
apiKey: "elevenlabs_api_key",
baseUrl: "https://api.elevenlabs.io",
voiceId: "voice_id",
modelId: "eleven_multilingual_v2",
seed: 42,
applyTextNormalization: "auto",
languageCode: "en",
voiceSettings: {
stability: 0.5,
similarityBoost: 0.75,
style: 0.0,
useSpeakerBoost: true,
speed: 1.0,
},
},
openai: {
apiKey: "openai_api_key",
baseUrl: "https://api.openai.com/v1",
model: "gpt-4o-mini-tts",
voice: "alloy",
},
},
},
}
  • auto steuert automatisches TTS. /tts off|always|inbound|tagged überschreibt dies pro Session.
  • summaryModel überschreibt agents.defaults.model.primary für automatische Zusammenfassungen.
  • modelOverrides ist standardmäßig aktiviert; modelOverrides.allowProvider ist standardmäßig false (Opt-in).
  • API-Keys nutzen als Fallback ELEVENLABS_API_KEY/XI_API_KEY oder OPENAI_API_KEY.
  • openai.baseUrl überschreibt den OpenAI TTS-Endpunkt. Die Reihenfolge ist: Konfiguration, dann OPENAI_TTS_BASE_URL, dann https://api.openai.com/v1.
  • Wenn openai.baseUrl auf einen Nicht-OpenAI-Endpunkt zeigt, behandelt OpenClaw diesen als OpenAI-kompatiblen TTS-Server und lockert die Validierung für Modell und Stimme.

Standardwerte für den Talk-Modus (macOS, iOS und Android).

{
talk: {
voiceId: "elevenlabs_voice_id",
voiceAliases: {
Clawd: "EXAVITQu4vr4xnSDxMaL",
Roger: "CwhRBWXzGAHq8TQ4Fs17",
},
modelId: "eleven_v3",
outputFormat: "mp3_44100_128",
apiKey: "elevenlabs_api_key",
silenceTimeoutMs: 1500,
interruptOnSpeech: true,
},
}
  • Voice-IDs fallen auf ELEVENLABS_VOICE_ID oder SAG_VOICE_ID zurück.
  • apiKey und providers.*.apiKey akzeptieren Plaintext-Strings oder SecretRef-Objekte.
  • Der ELEVENLABS_API_KEY Fallback greift nur, wenn kein Talk-API-Key konfiguriert ist.
  • voiceAliases erlaubt die Nutzung von freundlichen Namen in Talk-Direktiven.
  • silenceTimeoutMs steuert, wie lange der Talk-Modus nach Stille wartet, bevor das Transkript gesendet wird. Ohne Wert gelten die Plattform-Standards (700 ms auf macOS und Android, 900 ms auf iOS).

tools.profile legt eine Basis-Allowlist fest, bevor tools.allow/tools.deny angewendet werden:

Das lokale Onboarding setzt bei neuen Konfigurationen standardmäßig tools.profile: "coding" (bestehende explizite Profile bleiben erhalten).

ProfilEnthalten
minimalNur session_status
codinggroup:fs, group:runtime, group:sessions, group:memory, image
messaginggroup:messaging, sessions_list, sessions_history, sessions_send, session_status
fullKeine Einschränkungen (entspricht “nicht gesetzt”)
GruppeTools
group:runtimeexec, process (bash wird als Alias für exec akzeptiert)
group:fsread, write, edit, apply_patch
group:sessionssessions_list, sessions_history, sessions_send, sessions_spawn, session_status
group:memorymemory_search, memory_get
group:webweb_search, web_fetch
group:uibrowser, canvas
group:automationcron, gateway
group:messagingmessage
group:nodesnodes
group:openclawAlle integrierten Tools (ohne Provider-Plugins)

Globale Richtlinien für Tools (Deny gewinnt). Groß-/Kleinschreibung wird ignoriert, * Wildcards werden unterstützt. Dies gilt auch, wenn die Docker-Sandbox deaktiviert ist.

{
tools: { deny: ["browser", "canvas"] },
}

Einschränkung von Tools für spezifische Provider oder Modelle. Reihenfolge: Basis-Profil → Provider-Profil → Allow/Deny.

{
tools: {
profile: "coding",
byProvider: {
"google-antigravity": { profile: "minimal" },
"openai/gpt-5.2": { allow: ["group:fs", "sessions_list"] },
},
},
}

Steuert den privilegierten Zugriff (Host-Exec):

{
tools: {
elevated: {
enabled: true,
allowFrom: {
whatsapp: ["+15555550123"],
discord: ["1234567890123", "987654321098765432"],
},
},
},
}
  • Overrides pro Agent (agents.list[].tools.elevated) können den Zugriff nur weiter einschränken.
  • /elevated on|off|ask|full speichert den Status pro Session; Inline-Direktiven gelten für eine einzelne Nachricht.
  • Privilegiertes exec läuft auf dem Host und umgeht das Sandboxing.
{
tools: {
exec: {
backgroundMs: 10000,
timeoutSec: 1800,
cleanupMs: 1800000,
notifyOnExit: true,
notifyOnExitEmptySuccess: false,
applyPatch: {
enabled: false,
allowModels: ["gpt-5.2"],
},
},
},
}

Sicherheitsprüfungen für Tool-Loops sind standardmäßig deaktiviert. Setze enabled: true, um die Erkennung zu aktivieren. Einstellungen können global in tools.loopDetection definiert und pro Agent unter agents.list[].tools.loopDetection überschrieben werden.

{
tools: {
loopDetection: {
enabled: true,
historySize: 30,
warningThreshold: 10,
criticalThreshold: 20,
globalCircuitBreakerThreshold: 30,
detectors: {
genericRepeat: true,
knownPollNoProgress: true,
pingPong: true,
},
},
},
}
  • historySize: Maximale Tool-Call-Historie für die Loop-Analyse.
  • warningThreshold: Schwellenwert für Warnungen bei sich wiederholenden Mustern ohne Fortschritt.
  • criticalThreshold: Höherer Schwellenwert zum Blockieren kritischer Loops.
  • globalCircuitBreakerThreshold: Hard-Stop-Limit für jeden Durchlauf ohne Fortschritt.
  • detectors.genericRepeat: Warnt bei wiederholten Aufrufen desselben Tools mit identischen Argumenten.
  • detectors.knownPollNoProgress: Warnt/Blockiert bei bekannten Poll-Tools (process.poll, command_status etc.).
  • detectors.pingPong: Warnt/Blockiert bei abwechselnden Mustern ohne Fortschritt.
  • Wenn warningThreshold >= criticalThreshold oder criticalThreshold >= globalCircuitBreakerThreshold, schlägt die Validierung fehl.
{
tools: {
web: {
search: {
enabled: true,
apiKey: "brave_api_key", // oder BRAVE_API_KEY env
maxResults: 5,
timeoutSeconds: 30,
cacheTtlMinutes: 15,
},
fetch: {
enabled: true,
maxChars: 50000,
maxCharsCap: 50000,
timeoutSeconds: 30,
cacheTtlMinutes: 15,
userAgent: "custom-ua",
},
},
},
}

Konfiguriert das Verständnis für eingehende Medien (Bild, Audio und Video):

{
tools: {
media: {
concurrency: 2,
audio: {
enabled: true,
maxBytes: 20971520,
scope: {
default: "deny",
rules: [{ action: "allow", match: { chatType: "direct" } }],
},
models: [
{ provider: "openai", model: "gpt-4o-mini-transcribe" },
{ type: "cli", command: "whisper", args: ["--model", "base", "{{MediaPath}}"] },
],
},
video: {
enabled: true,
maxBytes: 52428800,
models: [{ provider: "google", model: "gemini-3-flash-preview" }],
},
},
},
}
Felder für Media-Modell-Einträge

Provider-Eintrag (type: "provider" oder weggelassen):

  • provider: API-Provider-ID (openai, anthropic, google/gemini, groq etc.)
  • model: Modell-ID Override
  • profile / preferredProfile: Profilauswahl aus auth-profiles.json

CLI-Eintrag (type: "cli"):

  • command: Auszuführende Datei
  • args: Argumente mit Templates (unterstützt {{MediaPath}}, {{Prompt}}, {{MaxChars}} etc.)

Gemeinsame Felder:

  • capabilities: Optionale Liste (image, audio, video). Standards: openai/anthropic/minimax → image, google → image+audio+video, groq → audio.
  • prompt, maxChars, maxBytes, timeoutSeconds, language: Overrides pro Eintrag.
  • Bei Fehlern wird der nächste Eintrag versucht.

Die Provider-Authentifizierung folgt der Standardreihenfolge: auth-profiles.json → Umgebungsvariablen → models.providers.*.apiKey.

{
tools: {
agentToAgent: {
enabled: false,
allow: ["home", "work"],
},
},
}

Steuert, welche Sessions von den Session-Tools (sessions_list, sessions_history, sessions_send) adressiert werden können.

Standard: tree (aktuelle Session + davon erzeugte Sessions, wie Subagents).

{
tools: {
sessions: {
// "self" | "tree" | "agent" | "all"
visibility: "tree",
},
},
}

Hinweise:

  • self: Nur der Key der aktuellen Session.
  • tree: Aktuelle Session + Sessions, die von ihr gestartet wurden (Subagents).
  • agent: Jede Session, die zur aktuellen Agent-ID gehört.
  • all: Jede Session. Cross-Agent-Targeting erfordert weiterhin tools.agentToAgent.
  • Sandbox-Einschränkung: Wenn die aktuelle Session gesandboxt ist und agents.defaults.sandbox.sessionToolsVisibility="spawned", wird die Sichtbarkeit auf tree erzwungen, selbst wenn tools.sessions.visibility="all" konfiguriert ist.

Steuert die Unterstützung für Inline-Anhänge in sessions_spawn.

{
tools: {
sessions_spawn: {
attachments: {
enabled: false, // opt-in: set true to allow inline file attachments
maxTotalBytes: 5242880, // 5 MB total across all files
maxFiles: 50,
maxFileBytes: 1048576, // 1 MB per file
retainOnSessionKeep: false, // keep attachments when cleanup="keep"
},
},
},
}

Hinweise:

  • Anhänge werden nur für runtime: "subagent" unterstützt. Die ACP-Runtime lehnt diese ab.
  • Dateien werden im Workspace des Child-Agents unter .openclaw/attachments/<uuid>/ mit einer .manifest.json abgelegt.
  • Inhalte von Anhängen werden automatisch aus der Transkript-Persistenz entfernt.
  • Base64-Inputs werden streng validiert.
  • Dateiberechtigungen sind 0700 für Verzeichnisse und 0600 für Dateien.
  • Cleanup folgt der cleanup-Policy: delete entfernt Anhänge immer; keep behält sie nur bei retainOnSessionKeep: true.
{
agents: {
defaults: {
subagents: {
model: "minimax/MiniMax-M2.5",
maxConcurrent: 1,
runTimeoutSeconds: 900,
archiveAfterMinutes: 60,
},
},
},
}
  • model: Standardmodell für erzeugte Sub-Agents. Falls nicht angegeben, erben diese das Modell des Aufrufers.
  • runTimeoutSeconds: Standard-Timeout für sessions_spawn, wenn der Tool-Call keinen Wert angibt. 0 bedeutet kein Timeout.
  • Tool-Richtlinie pro Subagent: tools.subagents.tools.allow / tools.subagents.tools.deny.

OpenClaw nutzt den pi-coding-agent Modell-Katalog. Du kannst eigene Provider über models.providers in der Konfiguration oder unter ~/.openclaw/agents/<agentId>/agent/models.json hinzufügen.

{
models: {
mode: "merge", // merge (default) | replace
providers: {
"custom-proxy": {
baseUrl: "http://localhost:4000/v1",
apiKey: "LITELLM_KEY",
api: "openai-completions", // openai-completions | openai-responses | anthropic-messages | google-generative-ai
models: [
{
id: "llama-3.1-8b",
name: "Llama 3.1 8B",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 32000,
},
],
},
},
},
}
  • Nutze authHeader: true + headers für spezielle Authentifizierungsanforderungen.
  • Überschreibe das Agent-Konfigurationsverzeichnis mit OPENCLAW_AGENT_DIR (oder PI_CODING_AGENT_DIR).
  • Merge-Priorität bei identischen Provider-IDs:
    • baseUrl-Werte aus der models.json des Agents gewinnen.
    • apiKey-Werte des Agents gewinnen nur, wenn der Provider nicht über SecretRef verwaltet wird.
    • SecretRef-verwaltete Keys werden aus den Quell-Markern (ENV_VAR_NAME für Env-Refs) aktualisiert, statt aufgelöste Secrets zu speichern.
    • Leere oder fehlende Werte fallen auf models.providers in der Konfiguration zurück.
    • Bei contextWindow/maxTokens wird der höhere Wert zwischen expliziter Konfiguration und Katalog verwendet.
    • Nutze models.mode: "replace", wenn die Konfiguration die models.json vollständig überschreiben soll.
  • models.mode: Verhalten des Katalogs (merge oder replace).
  • models.providers: Map für eigene Provider, indiziert nach Provider-ID.
  • models.providers.*.api: Request-Adapter (openai-completions, anthropic-messages etc.).
  • models.providers.*.apiKey: Zugangsdaten (SecretRef bevorzugt).
  • models.providers.*.auth: Strategie (api-key, token, oauth, aws-sdk).
  • models.providers.*.injectNumCtxForOpenAICompat: Injiziert options.num_ctx für Ollama + openai-completions (Standard: true).
  • models.providers.*.authHeader: Erzwingt den Transport der Credentials im Authorization-Header.
  • models.providers.*.baseUrl: Basis-URL der Upstream-API.
  • models.providers.*.headers: Zusätzliche statische Header für Proxy-Routing.
  • models.providers.*.models: Explizite Katalogeinträge für Provider-Modelle.
  • models.providers.*.models.*.compat.supportsDeveloperRole: Optionaler Kompatibilitätshinweis.
  • models.bedrockDiscovery: Einstellungen für die automatische Bedrock-Erkennung.

Cerebras (GLM 4.6 / 4.7)

{
env: { CEREBRAS_API_KEY: "sk-..." },
agents: {
defaults: {
model: {
primary: "cerebras/zai-glm-4.7",
fallbacks: ["cerebras/zai-glm-4.6"],
},
models: {
"cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" },
"cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" },
},
},
},
models: {
mode: "merge",
providers: {
cerebras: {
baseUrl: "https://api.cerebras.ai/v1",
apiKey: "${CEREBRAS_API_KEY}",
api: "openai-completions",
models: [
{ id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" },
{ id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" },
],
},
},
},
}

Nutze cerebras/zai-glm-4.7 für Cerebras; zai/glm-4.7 für direkten Zugriff auf Z.AI.

OpenCode

{
agents: {
defaults: {
model: { primary: "opencode/claude-opus-4-6" },
models: { "opencode/claude-opus-4-6": { alias: "Opus" } },
},
},
}

Setze OPENCODE_API_KEY (oder OPENCODE_ZEN_API_KEY). Nutze opencode/... für den Zen-Katalog oder opencode-go/... für den Go-Katalog. Shortcut: openclaw onboard --auth-choice opencode-zen.

Z.AI (GLM-4.7)

{
agents: {
defaults: {
model: { primary: "zai/glm-4.7" },
models: { "zai/glm-4.7": {} },
},
},
}

Setze ZAI_API_KEY. z.ai/* und z-ai/* werden als Aliase akzeptiert. Shortcut: openclaw onboard --auth-choice zai-api-key.

Moonshot AI (Kimi)

{
env: { MOONSHOT_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "moonshot/kimi-k2.5" },
models: { "moonshot/kimi-k2.5": { alias: "Kimi K2.5" } },
},
},
models: {
mode: "merge",
providers: {
moonshot: {
baseUrl: "https://api.moonshot.ai/v1",
apiKey: "${MOONSHOT_API_KEY}",
api: "openai-completions",
models: [
{
id: "kimi-k2.5",
name: "Kimi K2.5",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 256000,
maxTokens: 8192,
},
],
},
},
},
}

Für den China-Endpunkt: baseUrl: "https://api.moonshot.cn/v1" oder openclaw onboard --auth-choice moonshot-api-key-cn.

Kimi Coding

{
env: { KIMI_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "kimi-coding/k2p5" },
models: { "kimi-coding/k2p5": { alias: "Kimi K2.5" } },
},
},
}

Anthropic-kompatibler, integrierter Provider. Shortcut: openclaw onboard --auth-choice kimi-code-api-key.

Synthetic (Anthropic-kompatibel)

{
env: { SYNTHETIC_API_KEY: "sk-..." },
agents: {
defaults: {
model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" },
models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } },
},
},
models: {
mode: "merge",
providers: {
synthetic: {
baseUrl: "https://api.synthetic.new/anthropic",
apiKey: "${SYNTHETIC_API_KEY}",
api: "anthropic-messages",
models: [
{
id: "hf:MiniMaxAI/MiniMax-M2.5",
name: "MiniMax M2.5",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 192000,
maxTokens: 65536,
},
],
},
},
},
}

Die Base-URL sollte /v1 weglassen. Shortcut: openclaw onboard --auth-choice synthetic-api-key.

MiniMax M2.5 (direkt)

{
agents: {
defaults: {
model: { primary: "minimax/MiniMax-M2.5" },
models: {
"minimax/MiniMax-M2.5": { alias: "Minimax" },
},
},
},
models: {
mode: "merge",
providers: {
minimax: {
baseUrl: "https://api.minimax.io/anthropic",
apiKey: "${MINIMAX_API_KEY}",
api: "anthropic-messages",
models: [
{
id: "MiniMax-M2.5",
name: "MiniMax M2.5",
reasoning: false,
input: ["text"],
cost: { input: 15, output: 60, cacheRead: 2, cacheWrite: 10 },
contextWindow: 200000,
maxTokens: 8192,
},
],
},
},
},
}

Setze MINIMAX_API_KEY. Shortcut: openclaw onboard --auth-choice minimax-api.

Lokale Modelle (LM Studio)

Siehe Local Models. TL;DR: Betreibe MiniMax M2.5 via LM Studio Responses API auf leistungsstarker Hardware; behalte gehostete Modelle als Fallback.

AI Setup Assistant

{
skills: {
allowBundled: ["gemini", "peekaboo"],
load: {
extraDirs: ["~/Projects/agent-scripts/skills"],
},
install: {
preferBrew: true,
nodeManager: "npm", // npm | pnpm | yarn
},
entries: {
"nano-banana-pro": {
apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // or plaintext string
env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" },
},
peekaboo: { enabled: true },
sag: { enabled: false },
},
},
}
  • allowBundled: Optionale Allowlist nur für gebündelte Skills (verwaltete Skills oder Workspace Skills sind davon nicht betroffen).
  • entries.<skillKey>.enabled: false deaktiviert einen Skill, selbst wenn er gebündelt oder installiert ist.
  • entries.<skillKey>.apiKey: Eine praktische Option für Skills, die eine primäre Umgebungsvariable deklarieren (entweder als Plaintext-String oder als SecretRef Objekt).

{
plugins: {
enabled: true,
allow: ["voice-call"],
deny: [],
load: {
paths: ["~/Projects/oss/voice-call-extension"],
},
entries: {
"voice-call": {
enabled: true,
hooks: {
allowPromptInjection: false,
},
config: { provider: "twilio" },
},
},
},
}
  • Plugins werden aus ~/.openclaw/extensions, <workspace>/.openclaw/extensions sowie den unter plugins.load.paths angegebenen Pfaden geladen.
  • Änderungen an der Konfiguration erfordern einen Neustart des Gateway.
  • allow: Optionale Allowlist (nur die aufgelisteten Plugins werden geladen). deny hat im Zweifelsfall Vorrang.
  • plugins.entries.<id>.apiKey: Ein praktisches Feld für API-Keys auf Plugin-Ebene (sofern vom Plugin unterstützt).
  • plugins.entries.<id>.env: Eine Map für Umgebungsvariablen mit Plugin-Scope.
  • plugins.entries.<id>.hooks.allowPromptInjection: Wenn dieser Wert auf false steht, blockiert der Core before_prompt_build und ignoriert Felder zur Prompt-Mutation aus dem veralteten before_agent_start. Die Legacy-Optionen modelOverride und providerOverride bleiben dabei erhalten.
  • plugins.entries.<id>.config: Ein vom Plugin definiertes Konfigurationsobjekt (validiert durch das Plugin-Schema).
  • plugins.slots.memory: Hier wählst du die ID des aktiven Memory-Plugins aus oder nutzt "none", um Memory-Plugins zu deaktivieren.
  • plugins.slots.contextEngine: Hier wählst du die ID des aktiven Context Engine Plugins; standardmäßig wird "legacy" verwendet, außer du installierst und aktivierst eine andere Engine.
  • plugins.installs: Von der CLI verwaltete Metadaten für Installationen, die von openclaw plugins update genutzt werden.
    • Enthält Felder wie source, spec, sourcePath, installPath, version, resolvedName, resolvedVersion, resolvedSpec, integrity, shasum, resolvedAt, installedAt.
    • Du solltest plugins.installs.* als verwalteten Status betrachten; verwende lieber CLI-Befehle anstatt manueller Bearbeitungen.

Siehe Plugins.


{
browser: {
enabled: true,
evaluateEnabled: true,
defaultProfile: "chrome",
ssrfPolicy: {
dangerouslyAllowPrivateNetwork: true, // default trusted-network mode
// allowPrivateNetwork: true, // legacy alias
// hostnameAllowlist: ["*.example.com", "example.com"],
// allowedHostnames: ["localhost"],
},
profiles: {
openclaw: { cdpPort: 18800, color: "#FF4500" },
work: { cdpPort: 18801, color: "#0066CC" },
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" },
},
color: "#FF4500",
// headless: false,
// noSandbox: false,
// extraArgs: [],
// relayBindHost: "0.0.0.0", // only when the extension relay must be reachable across namespaces (for example WSL2)
// executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser",
// attachOnly: false,
},
}
  • evaluateEnabled: false deaktiviert act:evaluate und wait --fn.
  • ssrfPolicy.dangerouslyAllowPrivateNetwork ist standardmäßig auf true gesetzt (Trusted-Network-Modell).
  • Setze ssrfPolicy.dangerouslyAllowPrivateNetwork: false für eine strikte Browser-Navigation, die nur öffentliche Netzwerke zulässt.
  • ssrfPolicy.allowPrivateNetwork wird weiterhin als Legacy-Alias unterstützt.
  • Im strikten Modus kannst du ssrfPolicy.hostnameAllowlist und ssrfPolicy.allowedHostnames für explizite Ausnahmen nutzen.
  • Remote-Profile sind “attach-only” (Start, Stopp und Reset sind deaktiviert).
  • Reihenfolge der automatischen Erkennung: Standard-Browser (falls Chromium-basiert) → Chrome → Brave → Edge → Chromium → Chrome Canary.
  • Control Service: Läuft nur über Loopback (der Port wird von gateway.port abgeleitet, Standard ist 18791).
  • extraArgs: Fügt zusätzliche Launch-Flags für den lokalen Chromium-Start hinzu (zum Beispiel --disable-gpu, Fenstergrößen oder Debug-Flags).
  • relayBindHost: Ändert die Adresse, an der das Chrome Extension Relay lauscht. Lass dieses Feld leer für reinen Loopback-Zugriff. Setze eine explizite Non-Loopback-Adresse wie 0.0.0.0 nur dann, wenn das Relay eine Namespace-Grenze überschreiten muss (zum Beispiel bei WSL2) und das Host-Netzwerk bereits vertrauenswürdig ist.

{
ui: {
seamColor: "#FF4500",
assistant: {
name: "OpenClaw",
avatar: "CB", // emoji, short text, image URL, or data URI
},
},
}
  • seamColor: Akzentfarbe für das UI-Chrome der nativen App (Farbe der Talk Mode Bubble etc.).
  • assistant: Überschreibt die Identität der Control UI. Falls nicht gesetzt, wird auf die Identität des aktiven Agents zurückgegriffen.
{
gateway: {
mode: "local", // local | remote
port: 18789,
bind: "loopback",
auth: {
mode: "token", // none | token | password | trusted-proxy
token: "your-token",
// password: "your-password", // or OPENCLAW_GATEWAY_PASSWORD
// trustedProxy: { userHeader: "x-forwarded-user" }, // for mode=trusted-proxy; see /gateway/trusted-proxy-auth
allowTailscale: true,
rateLimit: {
maxAttempts: 10,
windowMs: 60000,
lockoutMs: 300000,
exemptLoopback: true,
},
},
tailscale: {
mode: "off", // off | serve | funnel
resetOnExit: false,
},
controlUi: {
enabled: true,
basePath: "/openclaw",
// root: "dist/control-ui",
// allowedOrigins: ["https://control.example.com"], // required for non-loopback Control UI
// dangerouslyAllowHostHeaderOriginFallback: false, // dangerous Host-header origin fallback mode
// allowInsecureAuth: false,
// dangerouslyDisableDeviceAuth: false,
},
remote: {
url: "ws://gateway.tailnet:18789",
transport: "ssh", // ssh | direct
token: "your-token",
// password: "your-password",
},
trustedProxies: ["10.0.0.1"],
// Optional. Default false.
allowRealIpFallback: false,
tools: {
// Additional /tools/invoke HTTP denies
deny: ["browser"],
// Remove tools from the default HTTP deny list
allow: ["gateway"],
},
},
}
Gateway-Details
  • mode: local (Gateway ausführen) oder remote (Verbindung zu einem Remote-Gateway). Das Gateway startet nur, wenn local eingestellt ist.
  • port: Ein einzelner, gemultiplexter Port für WS + HTTP. Die Priorität ist: --port > OPENCLAW_GATEWAY_PORT > gateway.port > 18789.
  • bind: auto, loopback (Standard), lan (0.0.0.0), tailnet (nur Tailscale IP) oder custom.
  • Legacy bind Aliases: Verwende die Bind-Modus-Werte in gateway.bind (auto, loopback, lan, tailnet, custom) und keine Host-Aliases wie 0.0.0.0 oder localhost.
  • Docker-Hinweis: Der Standard-Bind loopback hört auf 127.0.0.1 innerhalb des Containers. Bei Docker-Bridge-Networking (-p 18789:18789) kommt der Traffic über eth0 an, wodurch das Gateway nicht erreichbar ist. Nutze --network host oder setze bind: "lan" (oder bind: "custom" mit customBindHost: "0.0.0.0"), um auf allen Interfaces zu hören.
  • Auth: Standardmäßig erforderlich. Binds, die nicht über Loopback laufen, benötigen ein gemeinsames Token oder Passwort. Der Onboarding-Wizard generiert automatisch ein Token.
  • Wenn du sowohl gateway.auth.token als auch gateway.auth.password konfiguriert hast (einschließlich SecretRefs), musst du gateway.auth.mode explizit auf token oder password setzen. Der Start sowie die Installation schlagen fehl, wenn beides konfiguriert, aber kein Modus festgelegt ist.
  • gateway.auth.mode: "none": Modus ohne Authentifizierung. Nutze dies nur für vertrauenswürdige lokale Loopback-Setups. Diese Option wird im Onboarding nicht angeboten.
  • gateway.auth.mode: "trusted-proxy": Delegiert die Authentifizierung an einen Identity-aware Reverse Proxy. Das Gateway vertraut dann den Identity-Headern von IPs in gateway.trustedProxies (siehe Trusted Proxy Auth).
  • gateway.auth.allowTailscale: Wenn true, können Tailscale Serve Identity-Header für die Control UI oder WebSocket-Auth genutzt werden (verifiziert via tailscale whois). HTTP-API-Endpoints benötigen weiterhin Token oder Passwort. Dieser tokenlose Flow setzt voraus, dass der Gateway-Host vertrauenswürdig ist. Standardmäßig true, wenn tailscale.mode = "serve".
  • gateway.auth.rateLimit: Optionaler Limiter für fehlgeschlagene Logins. Er gilt pro Client-IP und Auth-Scope. Blockierte Versuche erhalten einen 429-Fehler mit Retry-After.
    • gateway.auth.rateLimit.exemptLoopback ist standardmäßig true. Setze es auf false, wenn du Localhost-Traffic ebenfalls limitieren willst (etwa für Tests).
  • WebSocket-Auth-Versuche aus dem Browser werden immer gedrosselt, wobei die Loopback-Ausnahme deaktiviert ist (Schutz gegen Brute-Force-Angriffe aus dem Browser auf Localhost).
  • tailscale.mode: serve (nur Tailnet, Loopback-Bind) oder funnel (öffentlich, erfordert Auth).
  • controlUi.allowedOrigins: Explizite Allowlist für Browser-Origins bei Gateway-WebSocket-Verbindungen. Erforderlich, wenn Browser-Clients von Nicht-Loopback-Origins kommen.
  • controlUi.dangerouslyAllowHostHeaderOriginFallback: Ein gefährlicher Modus, der den Host-Header als Fallback für die Origin-Policy nutzt.
  • remote.transport: ssh (Standard) oder direct (ws/wss). Bei direct muss remote.url mit ws:// oder wss:// beginnen.
  • OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1: Ein clientseitiger Override, der unverschlüsseltes ws:// zu vertrauenswürdigen privaten IPs erlaubt. Standardmäßig bleibt unverschlüsselter Traffic auf Loopback beschränkt.
  • gateway.remote.token / .password sind Felder für Remote-Client-Zugangsdaten. Sie konfigurieren nicht die Authentifizierung des Gateways selbst.
  • Lokale Gateway-Aufrufe können gateway.remote.* als Fallback nutzen, wenn gateway.auth.* nicht gesetzt ist.
  • Wenn gateway.auth.token / gateway.auth.password via SecretRef konfiguriert und nicht auflösbar ist, schlägt der Vorgang sicherheitshalber fehl (kein Fallback auf Remote-Daten).
  • trustedProxies: IPs von Reverse Proxies, die TLS terminieren. Liste hier nur Proxies auf, die du selbst kontrollierst.
  • allowRealIpFallback: Wenn true, akzeptiert das Gateway X-Real-IP, falls X-Forwarded-For fehlt. Standard ist false.
  • gateway.tools.deny: Zusätzliche Tools, die für HTTP POST /tools/invoke blockiert werden.
  • gateway.tools.allow: Entfernt Tools von der Standard-Sperrliste.
  • Chat Completions: Standardmäßig deaktiviert. Aktiviere sie mit gateway.http.endpoints.chatCompletions.enabled: true.
  • Responses API: gateway.http.endpoints.responses.enabled.
  • Absicherung der Responses URL-Eingabe:
    • gateway.http.endpoints.responses.maxUrlParts
    • gateway.http.endpoints.responses.files.urlAllowlist
    • gateway.http.endpoints.responses.images.urlAllowlist
  • Optionaler Security-Header:
    • gateway.http.securityHeaders.strictTransportSecurity (nur für HTTPS-Origins setzen, die du kontrollierst; siehe Trusted Proxy Auth)

Du kannst mehrere Gateways auf einem Host mit unterschiedlichen Ports und Verzeichnissen betreiben:

Terminal-Fenster
OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \
OPENCLAW_STATE_DIR=~/.openclaw-a \
openclaw gateway --port 19001

Hilfreiche Flags: --dev (nutzt ~/.openclaw-dev + Port 19001), --profile <name> (nutzt ~/.openclaw-<name>).

Siehe Multiple Gateways.


{
hooks: {
enabled: true,
token: "shared-secret",
path: "/hooks",
maxBodyBytes: 262144,
defaultSessionKey: "hook:ingress",
allowRequestSessionKey: false,
allowedSessionKeyPrefixes: ["hook:"],
allowedAgentIds: ["hooks", "main"],
presets: ["gmail"],
transformsDir: "~/.openclaw/hooks/transforms",
mappings: [
{
match: { path: "gmail" },
action: "agent",
agentId: "hooks",
wakeMode: "now",
name: "Gmail",
sessionKey: "hook:gmail:{{messages[0].id}}",
messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}",
deliver: true,
channel: "last",
model: "openai/gpt-5.2-mini",
},
],
},
}

Authentifizierung: Authorization: Bearer <token> oder x-openclaw-token: <token>.

Endpoints:

  • POST /hooks/wake → { text, mode?: "now"|"next-heartbeat" }
  • POST /hooks/agent → { message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }
    • sessionKey aus dem Request-Payload wird nur akzeptiert, wenn hooks.allowRequestSessionKey=true ist (Standard: false).
  • POST /hooks/<name> → wird über hooks.mappings aufgelöst.
Mapping-Details
  • match.path prüft den Sub-Pfad nach /hooks (z. B. /hooks/gmail → gmail).
  • match.source prüft ein Payload-Feld für generische Pfade.
  • Templates wie {{messages[0].subject}} lesen Daten aus dem Payload.
  • transform kann auf ein JS/TS-Modul verweisen, das eine Hook-Action zurückgibt.
    • transform.module muss ein relativer Pfad sein und innerhalb von hooks.transformsDir bleiben.
  • agentId leitet an einen bestimmten Agenten weiter; unbekannte IDs nutzen den Standard.
  • allowedAgentIds: Schränkt das Routing ein (* erlaubt alles, [] verbietet alles).
  • defaultSessionKey: Optionaler fester Session-Key für Agenten-Runs ohne expliziten sessionKey.
  • allowRequestSessionKey: Erlaubt es Aufrufern von /hooks/agent, den sessionKey zu setzen.
  • allowedSessionKeyPrefixes: Optionale Allowlist für Präfixe von sessionKey-Werten, z. B. ["hook:"].
  • deliver: true sendet die Antwort an einen Channel; channel ist standardmäßig last.
  • model überschreibt das LLM für diesen Hook-Run.
{
hooks: {
gmail: {
account: "openclaw@gmail.com",
topic: "projects/<project-id>/topics/gog-gmail-watch",
subscription: "gog-gmail-watch-push",
pushToken: "shared-push-token",
hookUrl: "http://127.0.0.1:18789/hooks/gmail",
includeBody: true,
maxBytes: 20000,
renewEveryMinutes: 720,
serve: { bind: "127.0.0.1", port: 8788, path: "/" },
tailscale: { mode: "funnel", path: "/gmail-pubsub" },
model: "openrouter/meta-llama/llama-3.3-70b-instruct:free",
thinking: "off",
},
},
}
  • Das Gateway startet gog gmail watch serve beim Booten automatisch, wenn es konfiguriert ist. Nutze OPENCLAW_SKIP_GMAIL_WATCHER=1, um dies zu deaktivieren.
  • Führe keinen separaten gog gmail watch serve Prozess neben dem Gateway aus.

{
canvasHost: {
root: "~/.openclaw/workspace/canvas",
liveReload: true,
// enabled: false, // or OPENCLAW_SKIP_CANVAS_HOST=1
},
}
  • Stellt vom Agenten editierbares HTML/CSS/JS und A2UI über HTTP auf dem Gateway-Port bereit:
    • http://<gateway-host>:<gateway.port>/__openclaw__/canvas/
    • http://<gateway-host>:<gateway.port>/__openclaw__/a2ui/
  • Nur lokal: Behalte gateway.bind: "loopback" bei.
  • Bei anderen Binds benötigen Canvas-Routen eine Gateway-Authentifizierung (Token/Passwort/Trusted-Proxy).
  • Node WebViews senden meist keine Auth-Header. Sobald ein Node verbunden ist, stellt das Gateway Node-spezifische Capability-URLs für den Zugriff bereit.
  • Capability-URLs sind an die aktive Node-Session gebunden und laufen schnell ab. Ein IP-basierter Fallback findet nicht statt.
  • Injiziert einen Live-Reload-Client in das bereitgestellte HTML.
  • Erstellt automatisch eine index.html, falls das Verzeichnis leer ist.
  • Änderungen erfordern einen Neustart des Gateways.
  • Deaktiviere Live-Reload bei sehr großen Verzeichnissen oder EMFILE-Fehlern.

{
discovery: {
mdns: {
mode: "minimal", // minimal | full | off
},
},
}
  • minimal (Standard): Lässt cliPath + sshPort in den TXT-Records weg.
  • full: Enthält cliPath + sshPort.
  • Der Hostname ist standardmäßig openclaw. Du kannst ihn mit OPENCLAW_MDNS_HOSTNAME überschreiben.
{
discovery: {
wideArea: { enabled: true },
},
}

Schreibt eine Unicast DNS-SD Zone unter ~/.openclaw/dns/. Für die netzwerkübergreifende Erkennung empfiehlt sich die Kombination mit einem DNS-Server (wie CoreDNS) und Tailscale Split DNS.

Einrichtung: openclaw dns setup --apply.

AI Setup Assistant

{
env: {
OPENROUTER_API_KEY: "sk-or-...",
vars: {
GROQ_API_KEY: "gsk-...",
},
shellEnv: {
enabled: true,
timeoutMs: 15000,
},
},
}
  • Inline-Umgebungsvariablen werden nur angewendet, wenn der Key im Prozess-Environment fehlt.
  • .env-Dateien: CWD .env + ~/.openclaw/.env (keine davon überschreibt bestehende Variablen).
  • shellEnv: Importiert fehlende erwartete Keys aus deinem Login-Shell-Profil.
  • Siehe Environment für die vollständige Rangfolge.

Referenziere Umgebungsvariablen in jedem Config-String mit ${VAR_NAME}:

{
gateway: {
auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" },
},
}
  • Nur Großbuchstaben werden gematcht: [A-Z_][A-Z0-9_]*.
  • Fehlende oder leere Variablen lösen beim Laden der Config einen Fehler aus.
  • Nutze $${VAR} als Escape-Sequenz für ein literales ${VAR}.
  • Funktioniert mit $include.

Secret-Referenzen sind additiv: Plaintext-Werte funktionieren weiterhin.

Nutze diese Objektstruktur:

{ source: "env" | "file" | "exec", provider: "default", id: "..." }

Validierung:

  • provider-Muster: ^[a-z][a-z0-9_-]{0,63}$
  • source: "env" ID-Muster: ^[A-Z][A-Z0-9_]{0,127}$
  • source: "file" ID: absoluter JSON-Pointer (zum Beispiel "/providers/openai/apiKey")
  • source: "exec" ID-Muster: ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$
  • source: "exec" IDs dürfen keine durch Slashes getrennten Pfadsegmente wie . oder .. enthalten (zum Beispiel wird a/../b abgelehnt).
  • Kanonische Matrix: SecretRef Credential Surface
  • secrets apply zielt auf unterstützte Credential-Pfade in der openclaw.json ab.
  • Referenzen in auth-profiles.json sind in der Runtime-Auflösung und der Audit-Abdeckung enthalten.
{
secrets: {
providers: {
default: { source: "env" }, // optional explicit env provider
filemain: {
source: "file",
path: "~/.openclaw/secrets.json",
mode: "json",
timeoutMs: 5000,
},
vault: {
source: "exec",
command: "/usr/local/bin/openclaw-vault-resolver",
passEnv: ["PATH", "VAULT_ADDR"],
},
},
defaults: {
env: "default",
file: "filemain",
exec: "vault",
},
},
}

Anmerkungen:

  • Der file-Provider unterstützt mode: "json" und mode: "singleValue" (die id muss im singleValue-Modus "value" sein).
  • Der exec-Provider erfordert einen absoluten command-Pfad und nutzt Protokoll-Payloads über stdin/stdout.
  • Standardmäßig werden Symlink-Pfade für Befehle abgelehnt. Setze allowSymlinkCommand: true, um Symlinks zu erlauben, während der aufgelöste Zielpfad validiert wird.
  • Wenn trustedDirs konfiguriert ist, gilt der Check für vertrauenswürdige Verzeichnisse für den aufgelösten Zielpfad.
  • Die Child-Environment von exec ist standardmäßig minimal; übergib benötigte Variablen explizit mit passEnv.
  • Secret-Referenzen werden zum Aktivierungszeitpunkt in einen In-Memory-Snapshot aufgelöst; Request-Pfade lesen danach nur noch diesen Snapshot.
  • Die Filterung der aktiven Bereiche erfolgt während der Aktivierung: Nicht aufgelöste Referenzen auf aktivierten Bereichen führen zum Scheitern von Startup oder Reload, während inaktive Bereiche mit einer Diagnose übersprungen werden.
{
auth: {
profiles: {
"anthropic:me@example.com": { provider: "anthropic", mode: "oauth", email: "me@example.com" },
"anthropic:work": { provider: "anthropic", mode: "api_key" },
},
order: {
anthropic: ["anthropic:me@example.com", "anthropic:work"],
},
},
}
  • Profile pro Agent werden unter <agentDir>/auth-profiles.json gespeichert.
  • auth-profiles.json unterstützt Referenzen auf Wertebene (keyRef für api_key, tokenRef für token).
  • Statische Zugangsdaten zur Laufzeit stammen aus Snapshots im Arbeitsspeicher; veraltete statische auth.json-Einträge werden bereinigt, sobald sie gefunden werden.
  • Veraltete OAuth-Importe erfolgen aus ~/.openclaw/credentials/oauth.json.
  • Schau dir OAuth an.
  • Details zum Laufzeitverhalten von Secrets sowie zu den Tools für audit/configure/apply findest du unter Secrets Management.
{
logging: {
level: "info",
file: "/tmp/openclaw/openclaw.log",
consoleLevel: "info",
consoleStyle: "pretty", // pretty | compact | json
redactSensitive: "tools", // off | tools
redactPatterns: ["\\bTOKEN\\b\\s*[=:]\\s*([\"']?)([^\\s\"']+)\\1"],
},
}
  • Die Standard-Logdatei ist /tmp/openclaw/openclaw-YYYY-MM-DD.log, du kannst aber über logging.file einen festen Pfad definieren.
  • Der consoleLevel springt automatisch auf debug, wenn du das Flag --verbose nutzt.

Du kannst das Erscheinungsbild deines CLI-Banners direkt in der Konfiguration anpassen. Das ist hilfreich, wenn du eine minimalistische Ausgabe bevorzugst oder die Standard-Sprüche ändern möchtest.

{
cli: {
banner: {
taglineMode: "off", // random | default | off
},
},
}
  • cli.banner.taglineMode steuert den Stil der Tagline im Banner:
    • "random" (Standard): Zeigt rotierende, lustige oder saisonale Sprüche.
    • "default": Nutzt eine feste, neutrale Tagline (All your chats, one OpenClaw.).
    • "off": Deaktiviert den Tagline-Text (Titel und Version des Banners werden weiterhin angezeigt).
  • Um das gesamte Banner auszublenden (nicht nur die Taglines), setzt du die env OPENCLAW_HIDE_BANNER=1.

Die CLI-Wizards (onboard, configure, doctor) speichern Metadaten über ihre Ausführung. Diese Informationen helfen dir dabei, den Überblick über deine Konfigurationsschritte zu behalten:

{
wizard: {
lastRunAt: "2026-01-01T00:00:00.000Z",
lastRunVersion: "2026.1.4",
lastRunCommit: "abc1234",
lastRunCommand: "configure",
lastRunMode: "local",
},
}
{
agents: {
list: [
{
id: "main",
identity: {
name: "Samantha",
theme: "helpful sloth",
emoji: "🦥",
avatar: "avatars/samantha.png",
},
},
],
},
}

Wird vom macOS Onboarding-Assistenten geschrieben. Leitet Standardwerte ab:

  • messages.ackReaction von identity.emoji (fällt zurück auf 👀)
  • mentionPatterns von identity.name/identity.emoji
  • avatar akzeptiert: Workspace-relativen Pfad, http(s) URL oder data: URI

Aktuelle Builds enthalten die TCP-Bridge nicht mehr. Nodes verbinden sich über den Gateway WebSocket. bridge.* Keys sind nicht mehr Teil des Config-Schemas (die Validierung schlägt fehl, bis du sie entfernst; openclaw doctor --fix kann unbekannte Keys automatisch entfernen).

Veraltete Bridge-Konfiguration (historische Referenz)

{
"bridge": {
"enabled": true,
"port": 18790,
"bind": "tailnet",
"tls": {
"enabled": true,
"autoGenerate": true
}
}
}
{
cron: {
enabled: true,
maxConcurrentRuns: 2,
webhook: "https://example.invalid/legacy", // deprecated fallback for stored notify:true jobs
webhookToken: "replace-with-dedicated-token", // optional bearer token for outbound webhook auth
sessionRetention: "24h", // duration string or false
runLog: {
maxBytes: "2mb", // default 2_000_000 bytes
keepLines: 2000, // default 2000
},
},
}
  • sessionRetention: Legt fest, wie lange abgeschlossene isolierte Cron-Run-Sessions aufbewahrt werden, bevor sie aus der sessions.json gelöscht werden. Steuert auch das Bereinigen archivierter gelöschter Cron-Transkripte. Standard: 24h; setze false, um dies zu deaktivieren.
  • runLog.maxBytes: Maximale Größe pro Run-Log-Datei (cron/runs/<jobId>.jsonl) vor dem Kürzen. Standard: 2_000_000 Bytes.
  • runLog.keepLines: Die neuesten Zeilen, die beim Kürzen des Run-Logs behalten werden. Standard: 2000.
  • webhookToken: Bearer-Token für die Cron-Webhook-Zustellung per POST (delivery.mode = "webhook"). Falls weggelassen, wird kein Auth-Header gesendet.
  • webhook: Veraltete (deprecated) Legacy-Fallback-Webhook-URL (http/https), die nur für gespeicherte Jobs verwendet wird, die noch notify: true gesetzt haben.

Siehe Cron Jobs.


Template-Platzhalter, die in tools.media.models[].args ersetzt werden:

VariableBeschreibung
{{Body}}Vollständiger Inhalt der eingehenden Nachricht
{{RawBody}}Rohdaten des Inhalts (keine History/Sender-Wrapper)
{{BodyStripped}}Inhalt ohne Gruppen-Erwähnungen
{{From}}Absender-ID
{{To}}Ziel-ID
{{MessageSid}}Channel-Nachrichten-ID
{{SessionId}}UUID der aktuellen Session
{{IsNewSession}}"true", wenn eine neue Session erstellt wurde
{{MediaUrl}}Pseudo-URL der eingehenden Media-Datei
{{MediaPath}}Lokaler Pfad zur Media-Datei
{{MediaType}}Media-Typ (image/audio/document/…)
{{Transcript}}Audio-Transkript
{{Prompt}}Aufgelöster Media-Prompt für CLI-Einträge
{{MaxChars}}Aufgelöste maximale Zeichenanzahl für CLI-Einträge
{{ChatType}}"direct" oder "group"
{{GroupSubject}}Gruppen-Betreff (Best Effort)
{{GroupMembers}}Vorschau der Gruppenmitglieder (Best Effort)
{{SenderName}}Anzeigename des Absenders (Best Effort)
{{SenderE164}}Telefonnummer des Absenders (Best Effort)
{{Provider}}Provider-Hinweis (whatsapp, telegram, discord, etc.)

Teile deine Konfiguration in mehrere Dateien auf:

~/.openclaw/openclaw.json
{
gateway: { port: 18789 },
agents: { $include: "./agents.json5" },
broadcast: {
$include: ["./clients/mueller.json5", "./clients/schmidt.json5"],
},
}

Merge-Verhalten:

  • Einzelne Datei: Ersetzt das enthaltende Objekt.
  • Array von Dateien: Deep-Merge in der Reihenfolge (spätere überschreiben frühere).
  • Gleichrangige Keys: Werden nach den Includes gemergt (überschreiben inkludierte Werte).
  • Verschachtelte Includes: Bis zu 10 Ebenen tief möglich.
  • Pfade: Werden relativ zur inkludierenden Datei aufgelöst, müssen aber innerhalb des Haupt-Konfigurationsverzeichnisses bleiben (dirname von openclaw.json). Absolute oder ../ Formen sind nur erlaubt, wenn sie innerhalb dieser Grenze bleiben.
  • Fehler: Klare Fehlermeldungen bei fehlenden Dateien, Parse-Fehlern und zirkulären Includes.

Verwandte Themen: Configuration · Configuration Examples · Doctor

#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"
{
channels: {
telegram: {
dmHistoryLimit: 30,
dms: {
"123456789": { historyLimit: 50 },
},
},
},
}
{
channels: {
whatsapp: {
allowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } },
},
},
agents: {
list: [
{
id: "main",
groupChat: { mentionPatterns: ["reisponde", "@openclaw"] },
},
],
},
}
{
agents: { defaults: { repoRoot: "~/Projects/openclaw" } },
}
{
agents: { defaults: { skipBootstrap: true } },
}
{
agents: { defaults: { bootstrapMaxChars: 20000 } },
}
{
agents: { defaults: { bootstrapTotalMaxChars: 150000 } },
}
{
agents: { defaults: { bootstrapPromptTruncationWarning: "once" } }, // off | once | always
}
{
agents: { defaults: { imageMaxDimensionPx: 1200 } },
}
{
agents: { defaults: { userTimezone: "America/Chicago" } },
}
{
agents: { defaults: { timeFormat: "auto" } }, // auto | 12 | 24
}
{
agents: {
defaults: {
cliBackends: {
"claude-cli": {
command: "/opt/homebrew/bin/claude",
},
"my-cli": {
command: "my-cli",
args: ["--json"],
output: "json",
modelArg: "--model",
sessionArg: "--session",
sessionMode: "existing",
systemPromptArg: "--system",
systemPromptWhen: "first",
imageArg: "--image",
imageMode: "repeat",
},
},
},
},
}
{
agents: {
defaults: {
contextPruning: {
mode: "cache-ttl", // off | cache-ttl
ttl: "1h", // duration (ms/s/m/h), default unit: minutes
keepLastAssistants: 3,
softTrimRatio: 0.3,
hardClearRatio: 0.5,
minPrunableToolChars: 50000,
softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 },
hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" },
tools: { deny: ["browser", "canvas"] },
},
},
},
}
{
agents: {
defaults: {
typingMode: "instant", // never | instant | thinking | message
typingIntervalSeconds: 6,
},
},
}
{
agents: {
defaults: {
sandbox: {
mode: "non-main", // off | non-main | all
scope: "agent", // session | agent | shared
workspaceAccess: "none", // none | ro | rw
workspaceRoot: "~/.openclaw/sandboxes",
docker: {
image: "openclaw-sandbox:bookworm-slim",
containerPrefix: "openclaw-sbx-",
workdir: "/workspace",
readOnlyRoot: true,
tmpfs: ["/tmp", "/var/tmp", "/run"],
network: "none",
user: "1000:1000",
capDrop: ["ALL"],
env: { LANG: "C.UTF-8" },
setupCommand: "apt-get update && apt-get install -y git curl jq",
pidsLimit: 256,
memory: "1g",
memorySwap: "2g",
cpus: 1,
ulimits: {
nofile: { soft: 1024, hard: 2048 },
nproc: 256,
},
seccompProfile: "/path/to/seccomp.json",
apparmorProfile: "openclaw-sandbox",
dns: ["1.1.1.1", "8.8.8.8"],
extraHosts: ["internal.service:10.0.0.5"],
binds: ["/home/user/source:/source:rw"],
},
browser: {
enabled: false,
image: "openclaw-sandbox-browser:bookworm-slim",
network: "openclaw-sandbox-browser",
cdpPort: 9222,
cdpSourceRange: "172.21.0.1/32",
vncPort: 5900,
noVncPort: 6080,
headless: false,
enableNoVnc: true,
allowHostControl: false,
autoStart: true,
autoStartTimeoutMs: 12000,
},
prune: {
idleHours: 24,
maxAgeDays: 7,
},
},
},
},
tools: {
sandbox: {
tools: {
allow: [
"exec",
"process",
"read",
"write",
"edit",
"apply_patch",
"sessions_list",
"sessions_history",
"sessions_send",
"sessions_spawn",
"session_status",
],
deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"],
},
},
},
}
Terminal-Fenster
scripts/sandbox-setup.sh # main sandbox image
scripts/sandbox-browser-setup.sh # optional browser image
{
agents: {
list: [
{
id: "personal",
workspace: "~/.openclaw/workspace-personal",
sandbox: { mode: "off" },
},
],
},
}
{
agents: {
list: [
{
id: "family",
workspace: "~/.openclaw/workspace-family",
sandbox: { mode: "all", scope: "agent", workspaceAccess: "ro" },
tools: {
allow: [
"read",
"sessions_list",
"sessions_history",
"sessions_send",
"sessions_spawn",
"session_status",
],
deny: ["write", "edit", "apply_patch", "exec", "process", "browser"],
},
},
],
},
}
{
agents: {
list: [
{
id: "public",
workspace: "~/.openclaw/workspace-public",
sandbox: { mode: "all", scope: "agent", workspaceAccess: "none" },
tools: {
allow: [
"sessions_list",
"sessions_history",
"sessions_send",
"sessions_spawn",
"session_status",
"whatsapp",
"telegram",
"slack",
"discord",
"gateway",
],
deny: [
"read",
"write",
"edit",
"apply_patch",
"exec",
"process",
"browser",
"canvas",
"nodes",
"cron",
"gateway",
"image",
],
},
},
],
},
}
OpenClaw

OpenClaw Expert

Noch festgefahren?

Wenn diese Seite nicht hilft, frage OpenClaw Expert nach Schritt-fuer-Schritt-Loesungen.