Mehdi Mehdi
โ† writing
May 3, 2026 post #ai#thinking

OpenClaw Master Guide

This guide covers how to get the most out of OpenClaw โ€” from the Control UI to advanced concepts like model routing, memory systems, and cost optimization. All information is sourced from the official OpenClaw documentation.


Table of Contents

  1. Getting Started with the Control UI
  2. Agents and Workspaces
  3. Memory Systems
  4. Model Routing and Selection
  5. Token Usage and Cost Monitoring
  6. Prompt Caching and Optimization
  7. Sessions and Context Management
  8. Sub-Agents and Background Work
  9. Scheduling and Automation
  10. Skills and Extensibility
  11. Multi-Agent Routing
  12. Security Best Practices

1. Getting Started with the Control UI

The Control UI is OpenClaw’s browser-based dashboard. It gives you a graphical interface for chatting with agents, managing sessions, editing config, and monitoring system health.

Opening the Dashboard

If your Gateway is running locally:

http://127.0.0.1:18789/

Or use the CLI shortcut:

openclaw dashboard

This opens the browser and copies the clean link to your clipboard.

First Connection โ€” Device Pairing

When you connect from a new browser, the Gateway requires a one-time pairing approval. You’ll see:

disconnected (1008): pairing required

To approve:

openclaw devices list
openclaw devices approve <requestId>

Once approved, the device is remembered. Each browser profile generates a unique device ID.

What You Can Do in the Control UI

Language Support

The UI localizes on first load based on your browser locale. Override it in:

Overview -> Gateway Access -> Language

Supported locales: en, zh-CN, pt-BR, de, es, ja-JP, ko, fr, tr, uk, id, pl

For secure remote access, use Tailscale Serve:

openclaw gateway --tailscale serve

Then open:

https://<magicdns>/

Tailscale Serve proxies the connection with HTTPS and authenticates via identity headers when gateway.auth.allowTailscale: true.

Chat Behavior

Hosted Embeds

Assistant messages can render [embed ...] shortcodes. The iframe sandbox policy is controlled by:

{
  gateway: {
    controlUi: {
      embedSandbox: "scripts", // strict | scripts | trusted
    },
  },
}

External http(s) embed URLs are blocked by default. Enable with gateway.controlUi.allowExternalEmbedUrls: true.


2. Agents and Workspaces

An agent is a fully scoped “brain” with its own workspace, auth, persona, and session store.

The Agent Workspace

The workspace is the agent’s home directory. It lives at:

~/.openclaw/workspace           (default)
~/.openclaw/workspace-<agentId> (for named agents)

Key Workspace Files

FilePurpose
AGENTS.mdOperating instructions โ€” how the agent should behave, use memory, prioritize tasks
SOUL.mdPersona, tone, boundaries โ€” this is where you give the agent a voice
USER.mdWho the user is, how to address them
IDENTITY.mdAgent’s name, vibe, emoji
TOOLS.mdLocal tool notes and conventions
HEARTBEAT.mdOptional checklist for heartbeat runs (keep it short)
BOOTSTRAP.mdOne-time first-run ritual โ€” delete after complete
memory/YYYY-MM-DD.mdDaily memory log โ€” one file per day
MEMORY.mdCurated long-term memory โ€” loaded every DM session

Giving Your Agent Personality โ€” SOUL.md

SOUL.md is short for “soul” and determines how the agent feels to talk to. Edit it to control:

Good SOUL.md rules are sharp and behavioral:

- Have opinions. Commit to a take instead of hedging.
- Brevity is mandatory. One sentence when one sentence suffices.
- Call out bad ideas early. Charm over cruelty.
- Be the assistant you'd actually want to talk to at 2am.

Bad rules are vague and corporate:

- Maintain professionalism at all times
- Provide comprehensive and thoughtful assistance

Backing Up the Workspace

Treat the workspace as private memory. Put it in a private git repo:

cd ~/.openclaw/workspace
git init
git add .
git commit -m "Add agent workspace"
git remote add origin <private-repo-url>
git push -u origin main

Do not commit secrets, .env files, or anything under ~/.openclaw/.

Multiple Agents

Create additional agents with:

openclaw agents add coding

Each agent gets its own workspace, agentDir, and session store. Route inbound messages to specific agents via bindings (see Multi-Agent Routing).


3. Memory Systems

OpenClaw remembers things by writing plain Markdown files. There is no hidden state โ€” memory is durable because it’s on disk.

Memory Files

FilePurposeLoaded In
MEMORY.mdLong-term curated facts, decisions, preferencesEvery DM session
memory/YYYY-MM-DD.mdDaily notes โ€” running context and observationsToday + yesterday automatically
DREAMS.mdDream Diary โ€” memory consolidation review log (experimental)Not auto-loaded

Memory Tools

The agent has two tools for working with memory:

Both are auto-loaded by the active memory plugin (default: memory-core).

How Memory Search Works

When an embedding provider is configured, memory_search uses hybrid search:

Query โ†’ [Embedding โ†’ Vector Search]  โ†’ Weighted Merge โ†’ Top Results
     โ†’ [Tokenize โ†’ BM25 Search]      โ†’

Supported Embedding Providers

ProviderIDAPI Key Needed
OpenAIopenaiYes
GeminigeminiYes (supports image/audio indexing)
VoyagevoyageYes
MistralmistralYes
BedrockbedrockNo (AWS credential chain)
OllamaollamaNo (local)
LocallocalNo (GGUF model, ~0.6 GB)

OpenClaw auto-detects your embedding provider from available API keys. If you have OpenAI, Gemini, Voyage, or Mistral configured, memory search is enabled automatically.

Improving Search Quality

For large note collections, enable temporal decay and MMR diversity:

{
  agents: {
    defaults: {
      memorySearch: {
        query: {
          hybrid: {
            mmr: { enabled: true },
            temporalDecay: { enabled: true },
          },
        },
      },
    },
  },
}

Memory Backends

OpenClaw supports three memory backends:

BackendDescription
builtin (default)SQLite-based. Works out of the box with keyword + vector + hybrid search. No extra dependencies.
qmdLocal-first sidecar with reranking, query expansion, and ability to index directories outside the workspace.
honchoAI-native cross-session memory with user modeling and multi-agent awareness. Requires plugin install.

Dreaming (Experimental)

Dreaming is a background memory consolidation system that moves strong short-term signals into durable memory (MEMORY.md).

Opt-in and disabled by default.

Phases:

PhasePurposeWrites to MEMORY.md?
LightSorts and stages recent short-term materialNo
DeepScores and promotes durable candidatesYes
REMReflects on themes and recurring ideasNo

Enable dreaming:

{
  plugins: {
    entries: {
      "memory-core": {
        config: {
          dreaming: {
            enabled: true,
            frequency: "0 3 * * *",
          },
        },
      },
    },
  },
}

Deep ranking uses six weighted signals:

SignalWeight
Frequency0.24
Relevance0.30
Query diversity0.15
Recency0.15
Consolidation0.10
Conceptual richness0.06

CLI workflow:

openclaw memory promote           # Preview candidates
openclaw memory promote --apply   # Apply promotions
openclaw memory promote-explain "router vlan"  # Why would this promote?
openclaw memory status --deep     # Deep status overview

Memory Wiki (Companion Plugin)

The memory-wiki plugin compiles durable knowledge into a wiki vault with:

It sits beside the active memory plugin โ€” it doesn’t replace it.


4. Model Routing and Selection

OpenClaw selects models in this order:

  1. Primary model (agents.defaults.model.primary)
  2. Fallbacks in agents.defaults.model.fallbacks (in order)
  3. Provider auth failover inside a provider before moving to the next model

Configuring Models

{
  agents: {
    defaults: {
      model: {
        primary: "anthropic/claude-opus-4-6",
        fallbacks: [
          "anthropic/claude-sonnet-4-6",
          "openrouter/openai/gpt-5.4",
        ],
      },
      models: {
        "anthropic/claude-opus-4-6": { alias: "Opus" },
        "anthropic/claude-sonnet-4-6": { alias: "Sonnet" },
        "openrouter/openai/gpt-5.4": { alias: "GPT-5" },
      },
    },
  },
}

Switching Models in Chat

Use /model in any chat:

/model           # Show numbered picker
/model list      # List available models
/model 3         # Select option #3
/model anthropic/claude-sonnet-4-6
/model status    # Show detailed auth + endpoint info

Notes:

Auth Profiles and Rotation

OpenClaw uses auth profiles for both API keys and OAuth tokens. They live in:

~/.openclaw/agents/<agentId>/agent/auth-profiles.json

When a provider has multiple profiles, OpenClaw rotates them:

  1. Explicit config: auth.order[provider]
  2. Round-robin: OAuth profiles first, then API keys, ordered by lastUsed (oldest first)
  3. Cooldown/disabled profiles are moved to the end

OpenClaw pins the chosen auth profile per session to keep provider caches warm. It doesn’t rotate on every request. The pinned profile is reused until:

Cooldowns

When a profile fails due to rate limits or timeouts, OpenClaw marks it in cooldown with exponential backoff:

Billing failures (insufficient credits) are treated as disabled with longer backoff:

Model Scan (OpenRouter Free Models)

openclaw models scan inspects OpenRouter’s free model catalog:

openclaw models scan                        # List candidates
openclaw models scan --set-default          # Set primary from first selection
openclaw models scan --min-params 70        # Minimum 70B parameters
openclaw models scan --max-age-days 90      # Skip models older than 90 days
openclaw models scan --no-probe             # Skip live probes (metadata only)

Probing requires an OpenRouter API key. Results rank by: image support โ†’ tool latency โ†’ context size โ†’ parameter count.

Per-Agent Model Overrides

Each agent in a multi-agent setup can have its own model:

{
  agents: {
    list: [
      {
        id: "chat",
        model: "anthropic/claude-sonnet-4-6",
      },
      {
        id: "deep-work",
        model: "anthropic/claude-opus-4-6",
      },
    ],
  },
}

Route via bindings (see Multi-Agent Routing).


5. Token Usage and Cost Monitoring

OpenClaw tracks token usage and estimated costs across multiple surfaces.

Per-Session Cost Snapshot โ€” /status

Type /status in any chat to see:

If live session metadata is sparse, /status recovers counters from the latest transcript usage entry.

/usage full    # Appends usage footer with estimated cost
/usage tokens  # Shows tokens only
/usage off     # Disables footer
/usage cost    # Local cost summary from session logs

Notes:

CLI Usage Windows โ€” Provider Quotas

openclaw status --usage
openclaw channels list           # Shows usage alongside provider config

Human output is normalized to X% left. Current usage-window providers:

Usage auth comes from provider-specific hooks, or falls back to matching OAuth/API-key credentials from auth profiles, env, or config.

Where Costs Come From

FeatureMay Incur CostNotes
Core model responsesYesPrimary source of usage
Media understanding (audio/image/video)YesUses model/provider APIs
Image generationYesOpenAI, Google, fal, MiniMax
Video generationYesQwen
Memory embeddingsYesOpenAI, Gemini, Voyage, Mistral
Web searchDependsBrave ($5/1k requests with $5 free credit), Exa, Firecrawl, etc.
Web fetch (Firecrawl)YesIf API key present
Talk mode (speech)YesElevenLabs
SkillsDependsThird-party APIs via skill apiKey
Compaction summarizationYesUses current model
Model scan/probeYesOpenRouter API key when probing

6. Prompt Caching and Optimization

Prompt caching lets model providers reuse unchanged prompt prefixes (system instructions, tools, stable context) across turns instead of re-processing them. This reduces both token cost and response latency.

Cache Retention Setting

agents:
  defaults:
    params:
      cacheRetention: "long"  # none | short | long

cacheRetention can be set at three levels (merge order):

  1. agents.defaults.params โ€” global default
  2. agents.defaults.models["provider/model"].params โ€” per-model override
  3. agents.list[].params โ€” per-agent override

Merge rule: later level overrides by key.

Provider Behavior

ProvidercacheReadcacheWriteNotes
Anthropic (direct)YesYesshort = 5min ephemeral, long = 1h TTL
Anthropic VertexYesYesSame TTL behavior as direct
OpenAI (direct)Yes0 (not exposed)Automatic caching on supported models; uses prompt_cache_key and prompt_cache_retention: "24h" for long
Amazon BedrockYes (Claude only)YesNon-Anthropic models forced to none
OpenRouter AnthropicYesYesInjects cache_control markers when targeting verified OpenRouter routes
Google GeminiYesN/AManages cachedContents resources for system prompts

OpenAI-Specific Note

OpenAI caching is automatic on supported recent models โ€” no block-level cache markers needed. However, OpenAI often behaves like an initial-prefix cache rather than Anthropic-style moving full-history reuse. In live probes, stable prefix turns land near a 4864 cached-token plateau, while tool-heavy transcripts plateau near 4608 cached tokens.

System-Prompt Cache Boundary

OpenClaw splits the system prompt into:

If you see unexpected cacheWrite spikes after a config or workspace change, check whether the change lands above or below the cache boundary. Moving volatile content below the boundary often resolves the issue.

Heartbeat Keep-Warm

Keep cache windows warm with periodic heartbeat runs:

agents:
  defaults:
    heartbeat:
      every: "55m"

Per-agent heartbeat is supported at agents.list[].heartbeat.

Context Pruning โ€” cache-ttl Mode

Trim old tool-result context after cache TTL windows so post-idle requests don’t re-cache oversized history:

agents:
  defaults:
    contextPruning:
      mode: "cache-ttl"
      ttl: "1h"

Cache Diagnostics

OpenClaw exposes cache-trace diagnostics for embedded agent runs. For normal diagnostics, use:

/status
/usage full

Live regression tests keep combined gates for Anthropic and OpenAI:

OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache

Tuning Patterns

Mixed traffic (recommended default):

agents:
  defaults:
    model:
      primary: "anthropic/claude-opus-4-6"
    models:
      "anthropic/claude-opus-4-6":
        params:
          cacheRetention: "long"
  list:
    - id: "research"
      default: true
      heartbeat:
        every: "55m"
    - id: "alerts"
      params:
        cacheRetention: "none"   # Disable caching on bursty notifier agents

Cost-first baseline:

  1. Set baseline cacheRetention: "short"
  2. Enable contextPruning.mode: "cache-ttl"
  3. Keep heartbeat below your TTL only for agents that benefit from warm caches

7. Sessions and Context Management

OpenClaw organizes conversations into sessions. Each message routes to a session based on its source.

Session Routing

SourceBehavior
Direct messages (DMs)Shared session by default
Group chatsIsolated per group
Rooms/channelsIsolated per room
Cron jobsFresh session per run
WebhooksIsolated per hook

DM Isolation โ€” Critical for Multi-User Setups

By default, all DMs share one session. This is dangerous for multi-user setups โ€” Alice’s private messages would be visible to Bob.

Enable per-user isolation:

{
  session: {
    dmScope: "per-channel-peer",  // isolate by channel + sender
  },
}

Options:

Link identities across channels for the same person:

{
  session: {
    identityLinks: [
      {
        channel: "telegram",
        peer: "8691846182",
        linkTo: { channel: "whatsapp", peer: "+33612345678" },
      },
    ],
  },
}

Session Lifecycle and Resets

Sessions are reused until they expire:

When both daily and idle resets are configured, whichever expires first wins.

Session Maintenance

OpenClaw automatically bounds session storage:

{
  session: {
    maintenance: {
      mode: "enforce",   // warn | enforce
      pruneAfter: "30d",
      maxEntries: 500,
    },
  },
}

Preview with:

openclaw sessions cleanup --dry-run

Where Sessions Live

Compaction

When a conversation approaches the model’s context limit, OpenClaw compacts older messages into a summary.

Auto-compaction is on by default. It runs when:

Before compacting, OpenClaw automatically runs a silent memory flush to remind the agent to save important notes to MEMORY.md. This prevents context loss.

Manual compaction:

/compact                         # Force compaction
/compact Focus on API design decisions  # Guide the summary

Using a different model for compaction:

{
  agents: {
    defaults: {
      compaction: {
        model: "openrouter/anthropic/claude-sonnet-4-6",
      },
    },
  },
}

Useful when your primary model is local or small and you want better summaries.

Compaction vs Pruning:

CompactionPruning
What it doesSummarizes older conversationTrims old tool results
Saved?Yes (in session transcript)No (in-memory only)
ScopeEntire conversationTool results only

Session pruning is a lighter-weight complement that trims tool output without summarizing.


8. Sub-Agents and Background Work

Sub-agents are background agent runs spawned from an existing agent run. They run in their own isolation and announce results back to the requester chat when finished. Each sub-agent run is tracked as a background task.

Spawn a Sub-Agent

/subagents spawn <agentId> <task>
/subagents spawn linus "Refactor the auth module"
/subagents spawn linus "Refactor the auth module" --model openrouter/openai/gpt-5.4-mini --thinking off

The spawn command is non-blocking โ€” it returns a run ID immediately. Completion is push-based โ€” the sub-agent announces its result when done.

Do not poll /subagents list or sessions_history in a loop waiting for completion. That’s wasteful. Completion will announce itself.

Manage Sub-Agents

/subagents list                          # List active sub-agents
/subagents kill <id|#|all>              # Kill a sub-agent
/subagents log <id|#> [limit] [tools]   # View sub-agent logs
/subagents info <id|#>                  # Run metadata (status, timestamps, session id)
/subagents send <id|#> <message>        # Send a message to a sub-agent
/subagents steer <id|#> <message>       # Steer a sub-agent's direction

Thread-Bound Sub-Agent Sessions

For persistent thread-bound sessions (not one-shot), use the sessions_spawn tool directly or the /focus slash command:

/focus <subagent-label>
/unfocus
/agents

Use Cases for Sub-Agents

Cost Note

Each sub-agent has its own context and token usage. For heavy or repetitive tasks, set a cheaper model for sub-agents:

{
  agents: {
    defaults: {
      subagents: {
        model: "openrouter/openai/gpt-5.4-mini",
      },
    },
  },
}

9. Scheduling and Automation

OpenClaw has a built-in cron scheduler that persists jobs, wakes the agent at the right time, and can deliver output back to a chat channel or webhook.

Quick Start

# One-shot reminder
openclaw cron add \
  --name "Reminder" \
  --at "2026-04-15T16:00:00Z" \
  --session main \
  --system-event "Reminder: check the cron docs" \
  --wake now \
  --delete-after-run

# Check jobs
openclaw cron list

# See run history
openclaw cron runs --id <job-id>

Schedule Types

KindCLI FlagDescription
at--atOne-shot timestamp (ISO 8601 or relative like 20m)
every--everyFixed interval
cron--cron5-field or 6-field cron expression with optional --tz

Timestamps without a timezone are treated as UTC. Add --tz America/New_York for local wall-clock scheduling.

Note: Day-of-month and day-of-week use OR logic. 0 9 15 * 1 means “9 AM on the 15th OR 9 AM every Monday” โ€” not both. Use Croner’s + modifier (0 9 15 * +1) to require both conditions.

Execution Styles

Style--session ValueRuns InBest For
Main sessionmainNext heartbeat turnReminders, system events
IsolatedisolatedDedicated cron:<jobId>Reports, background chores
Current sessioncurrentBound at creationContext-aware recurring work
Custom sessionsession:custom-idPersistent named sessionWorkflows that build on history

Delivery and Output

For isolated jobs, choose a delivery mode:

ModeWhat Happens
announceDeliver summary to target channel (default for isolated)
webhookPOST finished event payload to a URL
noneInternal only, no delivery

Example โ€” recurring job with Slack delivery:

openclaw cron add \
  --name "Morning brief" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize overnight updates." \
  --announce \
  --channel slack \
  --to "channel:C1234567890"

Webhooks

Enable HTTP webhook endpoints for external triggers:

{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
  },
}

POST to wake the main session:

curl -X POST http://127.0.0.1:18789/hooks/wake \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"text":"New email received","mode":"now"}'

POST to run an isolated agent turn:

curl -X POST http://127.0.0.1:18789/hooks/agent \
  -H 'Authorization: Bearer SECRET' \
  -H 'Content-Type: application/json' \
  -d '{"message":"Summarize inbox","name":"Email"}'

Gmail PubSub Integration

Wire Gmail inbox triggers to OpenClaw:

openclaw webhooks gmail setup --account me@gmail.com

This writes hooks.gmail config, enables the Gmail preset, and uses Tailscale Funnel for the push endpoint.

When hooks.enabled=true and hooks.gmail.account is set, the Gateway auto-starts gog gmail watch serve on boot.


10. Skills and Extensibility

Skills teach the agent how to use tools. Each skill is a directory with a SKILL.md file containing YAML frontmatter and instructions.

Skill Locations and Precedence

OpenClaw loads skills from these sources (highest precedence first):

  1. <workspace>/skills โ€” workspace-specific skills
  2. <workspace>/.agents/skills โ€” project agent skills
  3. ~/.agents/skills โ€” personal agent skills
  4. ~/.openclaw/skills โ€” managed/local skills
  5. Bundled skills โ€” shipped with the install
  6. skills.load.extraDirs โ€” extra shared folders (lowest)

If a skill name conflicts across locations, workspace wins.

Installing Skills from ClawHub

ClawHub is the public skills registry: https://clawhub.ai

openclaw skills install <skill-slug>      # Install into workspace
openclaw skills update --all              # Update all installed skills

Native openclaw skills install installs into the active workspace skills/ directory.

Skill Format

SKILL.md must include YAML frontmatter:

---
name: image-lab
description: Generate or edit images via a provider-backed image workflow
metadata: {"openclaw": {"requires": {"bins": ["uv"]}, "primaryEnv": "GEMINI_API_KEY"}}
---

# Instructions

This skill teaches the agent how to use the image-lab tool...

Gating โ€” Load-Time Filters

Skills can be gated by environment requirements:

---
name: my-skill
description: Does something cool
metadata: {"openclaw": {"requires": {"bins": ["git"], "env": ["MY_API_KEY"], "config": ["browser.enabled"]}}}
---

Fields under metadata.openclaw:

Per-Agent Skill Allowlists

Skill location and skill visibility are separate controls.

{
  agents: {
    defaults: {
      skills: ["github", "weather"],
    },
    list: [
      { id: "writer" },                        // inherits github, weather
      { id: "docs", skills: ["docs-search"] }, // replaces defaults
      { id: "locked-down", skills: [] },       // no skills
    ],
  },
}

Token Impact of Skills

When โ‰ฅ1 skill is eligible, OpenClaw injects a compact XML list into the system prompt.

Formula (characters):

total = 195 + ฮฃ (97 + len(name_escaped) + len(description_escaped) + len(location_escaped))

Rough estimate: ~4 chars/token โ†’ 97 chars โ‰ˆ 24 tokens per skill plus field lengths.


11. Multi-Agent Routing

Multi-agent routing lets you run multiple isolated agents (separate workspaces + auth + sessions) in one Gateway, with deterministic inbound routing via bindings.

What Is an Agent?

An agent is a fully scoped “brain” with:

Auth profiles are per-agent. Never reuse agentDir across agents.

Bindings โ€” How Messages Pick an Agent

Bindings are deterministic and most-specific wins:

  1. peer match (exact DM/group/channel id)
  2. parentPeer match (thread inheritance)
  3. guildId + roles (Discord role routing)
  4. guildId (Discord)
  5. teamId (Slack)
  6. accountId match for a channel
  7. Channel-level match (accountId: "*")
  8. Fallback to default agent (agents.list[].default, else first entry, default: main)

Example: Two Telegram Bots, Two Agents

{
  agents: {
    list: [
      { id: "main", workspace: "~/.openclaw/workspace-main" },
      { id: "linus", workspace: "~/.openclaw/workspace-linus", model: "openrouter/z-ai/glm-5.1" },
    ],
  },
  bindings: [
    { agentId: "main", match: { channel: "telegram", accountId: "default" } },
    { agentId: "linus", match: { channel: "telegram", accountId: "linus" } },
  ],
  channels: {
    telegram: {
      accounts: {
        default: {
          botToken: "",
          dmPolicy: "allowlist",
          allowFrom: [""],
        },
        linus: {
          botToken: "",
          dmPolicy: "allowlist",
          allowFrom: [""],
        },
      },
    },
  },
}

Each bot has its own botToken and dmPolicy. Both restrict DMs to your Telegram user ID.

Example: WhatsApp Daily Chat + Telegram Deep Work

Route WhatsApp to a fast everyday agent and Telegram to a deeper-thinking agent:

{
  agents: {
    list: [
      {
        id: "chat",
        model: "anthropic/claude-sonnet-4-6",
      },
      {
        id: "opus",
        model: "anthropic/claude-opus-4-6",
      },
    ],
  },
  bindings: [
    { agentId: "chat", match: { channel: "whatsapp" } },
    { agentId: "opus", match: { channel: "telegram" } },
  ],
}

Example: Route One DM to a Different Agent

Keep WhatsApp on the fast agent, but route one specific DM to opus:

{
  bindings: [
    {
      agentId: "opus",
      match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551234567" } },
    },
    { agentId: "chat", match: { channel: "whatsapp" } },
  ],
}

Peer bindings always win โ€” keep them above channel-wide rules.


12. Security Best Practices

Authorized Senders

Your Telegram bots already restrict access to you via dmPolicy: "allowlist" and allowFrom: [""]. No changes needed.

If you add bots to Telegram groups, group access is controlled separately by groupPolicy (default: allowlist with no groupAllowFrom), so group messages are also blocked by default.

Workspace Security

.DS_Store
.env
**/*.key
**/*.pem
**/secrets*

Control UI Security

The Control UI is an admin surface (chat, config, exec approvals). Do not expose it publicly.

Sandbox

For untrusted inputs or risky tools, enable sandboxing:

{
  agents: {
    defaults: {
      sandbox: {
        mode: "all",       // always sandbox
        scope: "agent",    // one container per agent
        docker: {
          setupCommand: "apt-get update && apt-get install -y git curl",
        },
      },
    },
  },
}

Note: setupCommand runs once on container creation. The binary must also exist inside the container for skills to work there.

Exec Approvals

For elevated commands (exec host=gateway), review and edit your allowlists regularly:

openclaw exec approvals list

In the Control UI, use the Exec Approvals panel to manage gateway and node allowlists.


Quick Reference

Essential CLI Commands

openclaw gateway                    # Start the gateway
openclaw gateway --tailscale serve  # Start with Tailscale Serve
openclaw dashboard                  # Open the Control UI
openclaw status --usage             # Check token usage
openclaw models list                # List configured models
openclaw models scan                # Scan OpenRouter free models
openclaw cron list                  # List cron jobs
openclaw cron add --name "..." ...  # Add a cron job
openclaw devices list               # List paired devices
openclaw agents list --bindings     # List agents with routing
openclaw memory status              # Check memory index status
openclaw memory search "query"      # Search memory from CLI
openclaw skills install <slug>      # Install a skill
openclaw subagents list             # (in chat: /subagents list)
openclaw sessions cleanup --dry-run # Preview session maintenance
openclaw doctor                     # Run diagnostics

Essential Chat Commands

/status              # Session status card with tokens and cost
/usage full          # Per-message usage footer
/compact             # Force compaction
/model               # Switch model for this session
/new                 # Start a fresh session
/new <model>         # Fresh session + model switch
/stop                # Stop current reply
/subagents spawn ... # Spawn a background agent
/dreaming status     # Check dreaming status
/dreaming on|off     # Enable/disable dreaming
/focus <id>          # Focus on a thread-bound sub-agent

Key Config Paths

~/.openclaw/openclaw.json                              # Main config
~/.openclaw/agents/<agentId>/agent/auth-profiles.json   # Auth profiles
~/.openclaw/agents/<agentId>/sessions/                  # Session store
~/.openclaw/cron/jobs.json                              # Cron jobs
~/.openclaw/openclaw/workspace/                         # Default workspace
~/.openclaw/workspace-linus/                            # Linus workspace

This guide covers the core concepts. The official docs at https://docs.openclaw.ai/ are the definitive reference for edge cases and advanced configuration.