Skill: fcsouza/openclaw-genie (version 1.2.0)

--- name: openclaw-genie version: 1.2.0 description: >- Use when the user asks about OpenClaw — installation, configuration, agents, channels, memory, tools, hooks, skills, deployment, Docker, multi-agent, OAuth, gateway, CLI, browser, exec, PDF, voice, secrets, sandboxing, sessions, cron, webhooks, heartbeat, sub-agents, nodes, companion devices, canvas, camera, or messaging platform integration. --- # OpenClaw Genie OpenClaw is a self-hosted personal AI agent gateway (MIT license, open source). It connects LLM agents to 22+ messaging platforms natively (WhatsApp, Telegram, Discord, Slack, Signal, iMessage, MS Teams, Matrix, and more) with 50+ integrations (Gmail, GitHub, Obsidian, Spotify, and more) through a single Gateway process. All data stays local. --- ## Quick Start ```bash # One-liner install (macOS/Linux, requires Node 22+) curl -fsSL https://openclaw.ai/install.sh | bash # Or via npm npm install -g openclaw@latest # Interactive setup — gateway, workspace, channels, skills openclaw onboard --install-daemon # Verify openclaw status openclaw gateway status ``` Web Control UI: `http://127.0.0.1:18789/` --- ## Core Architecture ``` Channels (WhatsApp, Discord, Telegram, Slack, Signal, …) ↓ Gateway ← WebSocket control plane (port 18789), single source of truth ↓ Agents ← isolated workspaces, sessions, memory, tools ↓ Tools ← exec, browser, skills, hooks, messaging, sub-agents ↓ Nodes ← companion devices (macOS/iOS/Android): camera, canvas, screen ``` - **Gateway**: Multiplexed port (WebSocket + HTTP + Control UI). Hot-reloads config. - **Agents**: Fully isolated — own workspace, session store, memory, auth profiles, sandbox. - **Channels**: 22+ native adapters run simultaneously. Deterministic routing: replies return to origin. - **Nodes**: Paired companion devices that expose `canvas.*`, `camera.*`, `screen.*`, `device.*`, `notifications.*` via `node.invoke`. - **Sessions**: Key format `agent:<agentId>:<channel>:<scope>:<chatId>`. DM scopes: `main`, `per-peer`, `per-channel-peer`, `per-account-channel-peer`. --- ## Agent Configuration Workspace files in `~/.openclaw/workspace/` (default agent) or `~/.openclaw/workspace-<agentId>/`: | File | Purpose | |------|---------| | `SOUL.md` | Agent personality and system prompt | | `IDENTITY.md` | Name, emoji, avatar | | `USER.md` | User profile information | | `MEMORY.md` | Curated long-term memory | | `memory/YYYY-MM-DD.md` | Daily append-only session logs | | `TOOLS.md` | Tool usage guidance | | `BOOTSTRAP.md` | One-time init tasks (deleted after first run) | | `HEARTBEAT.md` | Periodic check-in instructions | Bootstrap injection: IDENTITY → SOUL → USER → MEMORY → daily log → skills → session. Limits: 20,000 chars/file, 150,000 chars total (configurable). Multi-agent config uses `agents.list[]` and `bindings[]` in openclaw.json (see `references/multi-agent.md`). --- ## Configuration — openclaw.json Location: `~/.openclaw/openclaw.json` (JSON5 — comments and trailing commas OK). ```jsonc { "models": { // primary, fallbacks, aliases, image model "primary": "anthropic/claude-sonnet-4-5", "fallbacks": ["openai/gpt-4o"] }, "channels": { }, // discord, telegram, whatsapp, slack, signal, … "agents": { }, // list, defaults, bindings, broadcast, subagents "tools": { }, // profiles, allow/deny, loop detection, exec config "skills": { }, // entries, load dirs, install manager "browser": { }, // profiles, SSRF policy, executable path "sandbox": { }, // mode (off/non-main/all), scope, Docker hardening "gateway": { }, // port, auth, discovery, binding "automation": { }, // cron, webhooks, heartbeat "hooks": { }, // internal hooks config "session": { }, // dmScope, resets, sendPolicy, maintenance "auth": { } // OAuth profiles, key rotation, order } ``` - **Env vars**: `~/.openclaw/.env`, `${VAR}` substitution in config strings. - **`$include`**: Nested file inclusion (up to 10 levels). - **Hot reload**: `hybrid` mode (default) — safe changes hot-apply, critical ones auto-restart. Debounce 300ms. - **Strict validation**: Unknown keys prevent Gateway startup. For full reference, read `references/configuration.md`. --- ## Channels Quick Reference | Channel | Setup | Notes | |---------|-------|-------| | Discord | `openclaw channels add discord` | Bot API + Gateway; servers, DMs, threads, slash commands, voice | | Telegram | `openclaw channels add telegram` | grammY; groups, forums, inline buttons, webhook mode | | WhatsApp | `openclaw channels add whatsapp` | Baileys; QR pairing, media, polls | | Slack | `openclaw channels add slack` | Bolt SDK; socket or HTTP mode, native streaming | | Signal | `openclaw channels add signal` | signal-cli; privacy-focused, auto-daemon | | iMessage | `openclaw channels add bluebubbles` | BlueBubbles; reactions, edits, groups | | Google Chat | `openclaw channels add googlechat` | HTTP webhook app | | IRC | `openclaw channels add irc` | NickServ, channels + DMs | | MS Teams | `openclaw plugins install @openclaw/msteams` | Adaptive Cards, polls | | Matrix | `openclaw plugins install @openclaw/matrix` | E2EE, threads, rooms | | Mattermost | `openclaw plugins install @openclaw/mattermost` | Self-hosted | | Nextcloud Talk | `openclaw plugins install @openclaw/nextcloud-talk` | Self-hosted | | WebChat | Built-in web UI | Browser-based access at gateway URL | **Access control**: DM policy (`pairing`/`allowlist`/`open`/`disabled`), group policy, mention gating. Multi-account per channel supported. For per-channel details, read `references/channels.md`. --- ## Memory System - **Daily logs**: `memory/YYYY-MM-DD.md` — today + yesterday loaded at session start - **Long-term**: `MEMORY.md` — curated facts, decisions, preferences (private sessions only) - **Tools**: `memory_search` (vector recall, ~400-token chunks) and `memory_get` (file reads) - **Hybrid search**: BM25 (exact tokens) + vector (semantic) with configurable weights - **Post-processing**: MMR deduplication (lambda 0.7) + temporal decay (30-day half-life) - **Providers**: auto-selects local → OpenAI → Gemini → Voyage → Mistral - **QMD backend**: Optional local-first sidecar (BM25 + vectors + reranking) - **Auto flush**: Silent agentic turn before context compaction preserves important memories For full memory config, read `references/memory.md`. --- ## Tools Overview | Tool | Purpose | |------|---------| | `exec` | Shell commands (sandbox/gateway/node hosts) | | `process` | Background process management | | `browser` | Chromium automation (navigate, click, type, screenshot) | | `web_search` | Brave Search API queries | | `web_fetch` | URL → markdown extraction | | `memory_search` | Semantic vector search over memory | | `memory_get` | Direct memory file reads | | `message` | Cross-channel messaging (send, react, thread, pin, poll) | | `sessions_spawn` | Sub-agent runs (one-shot or persistent, up to depth 5) | | `canvas` | Node Canvas UI (HTML display on connected devices) | | `nodes` | Paired device control: camera snap/clip, screen record, notifications, canvas A2UI | | `pdf` | Native PDF analysis (up to 10 PDFs, Anthropic/Google native mode, extraction fallback) | **Access control**: Profiles (`minimal`, `coding`, `messaging`, `full`), allow/deny lists, tool groups (`group:fs`, `group:runtime`, `group:sessions`, `group:web`, `group:ui`, `group:automation`). **Default profile** (since v2026.3.2): onboarding defaults to `messaging` (not `coding`). For full tools, skills, and hooks reference, read `references/tools.md`. --- ## Hooks & Automation **Hooks** — event-driven TypeScript handlers in `<workspace>/hooks/`: | Event | Trigger | |-------|---------| | `command:new/reset/stop` | Session lifecycle | | `agent:bootstrap` | Pre-injection (can mutate bootstrap files) | | `gateway:startup` | After channels load | | `message:received/sent` | Message lifecycle | | `tool_result_persist` | Synchronous tool result transform | **Automation** — built into Gateway: - **Cron**: Scheduled jobs (cron expressions, intervals, one-shot). Isolated or main-session. - **Webhooks**: `/hooks/wake` (system events), `/hooks/agent` (isolated turns), custom mapped endpoints. - **Heartbeat**: Periodic check-ins (default 30min), batches multiple checks per turn. **Voice** — macOS/iOS wake word + talk mode overlay; continuous voice on Android with ElevenLabs or system TTS; OpenAI-compatible STT endpoint (`messages.tts.openai.baseUrl`). --- ## Deployment Options ```bash # Local service (default) openclaw gateway install && openclaw gateway start # One-liner Docker ./docker-setup.sh # Manual Docker docker build -t openclaw:local -f Dockerfile . docker compose up -d openclaw-gateway ``` **Cloud**: Fly.io, Railway, Render, GCP, Hetzner, Cloudflare Workers, Ansible. **Sandbox**: Docker isolation for untrusted sessions. Modes: `off`, `non-main`, `all`. Scopes: `session`, `agent`, `shared`. **Remote access**: Tailscale/VPN preferred, SSH tunnel fallback. For full deployment guide, read `references/deployment.md`. --- ## CLI Essentials | Command | Purpose | |---------|---------| | `openclaw onboard` | Interactive first-time setup | | `openclaw gateway start/stop/status` | Service management | | `openclaw channels add/list/status/login` | Channel management | | `openclaw models list/set/auth/scan` | Model config + auth | | `openclaw skills list/info/check` | Skill management | | `openclaw hooks list/enable/disable/install` | Hook management | | `openclaw agent --message "..."` | Single agent turn | | `openclaw agents list/add/delete` | Multi-agent management | | `openclaw sessions` | List/manage sessions | | `openclaw browser` | Browser control (50+ subcommands) | | `openclaw cron list/add/run` | Scheduled jobs | | `openclaw nodes status` | List paired companion nodes | | `openclaw devices list/approve` | Manage device pairing requests | | `openclaw config get/set/unset/validate` | Config helpers (`validate` checks file before startup) | | `openclaw doctor [--fix]` | Health checks + auto-repair | | `openclaw security audit [--deep]` | Security audit | | `openclaw logs [--follow]` | Tail gateway logs | | `openclaw memory search "query"` | Vector search | | `openclaw dns setup` | CoreDNS + Tailscale discovery | | `openclaw tui` | Terminal UI | **Global flags**: `--dev`, `--profile <name>`, `--json`, `--no-color` --- ## When to Read Reference Files | If you need… | Read | |--------------|------| | Full openclaw.json, model providers, env vars, auth, OAuth | `references/configuration.md` | | Per-channel setup, routing, access control, streaming, multi-account | `references/channels.md` | | Memory files, vector search, QMD, embeddings, hybrid search | `references/memory.md` | | Exec, browser, skills, hooks, tool access, sub-agents, nodes | `references/tools.md` | | Docker, cloud deploy, sandboxing, native install, security | `references/deployment.md` | | Multi-agent config, bindings, broadcast, sub-agents, workspaces | `references/multi-agent.md` |

path: README.md
content: # OpenClaw Genie

A comprehensive agent skill for [OpenClaw](https://openclaw.ai) — the self-hosted AI agent gateway that connects LLM agents to 38+ messaging platforms.

## What It Covers

- Installation and quick start
- Full `openclaw.json` configuration reference
- Channel setup (Discord, Telegram, WhatsApp, Slack, Signal, iMessage, and more)
- Memory system (vector search, hybrid BM25+vector, QMD, local embeddings)
- Tools (exec, browser, skills, hooks, messaging, sub-agents)
- Deployment (Docker, Fly.io, Railway, Render, sandboxing, security)
- Multi-agent architecture (routing, broadcast, workspaces, session isolation)

## File Structure

```
openclaw-genie/
├── SKILL.md                          # Main skill (247 lines)
└── references/
    ├── configuration.md              # openclaw.json, model providers, auth, OAuth
    ├── channels.md                   # Per-channel setup, access control, streaming
    ├── memory.md                     # Vector search, QMD, hybrid, embeddings
    ├── tools.md                      # Exec, browser, skills system, hooks, sub-agents
    ├── deployment.md                 # Docker, cloud platforms, sandboxing, security
    └── multi-agent.md                # Bindings, broadcast, workspaces, sessions
```

## Installation

### Via [skills.sh](https://skills.sh) (recommended)

Works with 37+ agents — Claude Code, OpenClaw, Cursor, Copilot, Windsurf, and more:

```bash
npx skills add fcsouza/agent-skills --skill openclaw-genie
```

Install globally (available across all projects):

```bash
npx skills add fcsouza/agent-skills --skill openclaw-genie -g
```

### Via ClawHub (OpenClaw only)

```bash
clawhub install openclaw-genie
```

### Manual

Copy the `openclaw-genie/` folder to your agent's skills directory:

```bash
# OpenClaw (workspace skills, highest precedence)
cp -r openclaw-genie/ ~/.openclaw/workspace/skills/openclaw-genie/

# Claude Code
cp -r openclaw-genie/ .claude/skills/openclaw-genie/
```

## Usage

Once installed, the skill is automatically available. It triggers when you ask about any OpenClaw topic — installation, configuration, channels, memory, tools, hooks, deployment, or multi-agent setup.

Use `/openclaw-genie` as a slash command, or let the agent invoke it automatically based on context.

## Sources

- [OpenClaw Docs](https://docs.openclaw.ai)
- [OpenClaw GitHub](https://github.com/openclaw/openclaw) (229k stars, MIT license)
- [ClawHub Registry](https://clawhub.com)


path: references/channels.md
content: # OpenClaw Channels Reference

## Native Channels (9)

### Discord
```bash
openclaw config set channels.discord.token '"BOT_TOKEN"' --json
openclaw config set channels.discord.enabled true --json
```
- **Auth**: Bot token + Application ID. Enable Message Content Intent + Server Members Intent.
- **OAuth scopes**: `bot`, `applications.commands`. Permissions: View Channels, Send Messages, Read History, Embed Links, Attach Files.
- **Features**: Guilds, DMs, threads, forum channels, slash commands, voice, Components v2, interactive buttons, select menus, modals.
- **Streaming**: `off`, `partial`, `block`, `progress`. Preview streaming uses send+edit pattern.
- **Routing**: Role-based bindings via `bindings[].match.roles` (role IDs). Evaluate in sequence.
- **Config**: `historyLimit` (20), `dmHistoryLimit`, `replyToMode` (`off`/`first`/`all`), `textChunkLimit`, `status`, `activity`, `activityType` (0-5), `execApprovals.enabled` (button-based), `pluralkit.enabled`.
- **Persistent bindings** (v2026.3.7): Thread bindings survive gateway restarts; ACP management supported.

### Telegram
```bash
openclaw channels add --channel telegram --token "BOT_TOKEN"
# Or: openclaw config set channels.telegram.botToken '"TOKEN"'
```
- **Auth**: Token from @BotFather (`/newbot`). Env fallback: `TELEGRAM_BOT_TOKEN`.
- **Features**: Groups, forum topics, inline buttons, custom commands, webhook mode, reactions.
- **Webhook mode**: Set `webhookUrl` + `webhookSecret`. Default: long polling via grammY.
- **Streaming**: `partial` (default since v2026.3.2), `off`, `block`, `progress`. DM streaming uses `sendMessageDraft` for private previews.
- **Topic agent routing** (v2026.3.7): Individual forum topics can route to dedicated agents with isolated sessions.
- **Config**: `textChunkLimit` (4000), `chunkMode` (`length`/`newline`), `mediaMaxMb` (5), `linkPreview`, `reactionLevel` (`off`/`ack`/`minimal`/`extensive`), `historyLimit` (50), `dmHistoryLimit`.
- **Privacy**: Disable via BotFather `/setprivacy` for full group visibility. Remove/re-add bot after.
- **Network**: `proxy` (SOCKS/HTTP), `network.dnsResultOrder` (`ipv4first`/`verbatim`).

### WhatsApp
```bash
openclaw channels login --channel whatsapp
# Multi-account: openclaw channels login --channel whatsapp --account work
```
- **Auth**: QR code scan from phone. Credentials at `~/.openclaw/credentials/whatsapp/<accountId>/creds.json`.
- **Features**: Media (image, video, audio, documents, stickers), polls, groups, reactions.
- **Access**: E.164 format phone numbers. `allowFrom`, `groupAllowFrom`, `groups` (group allowlist).
- **Group behavior**: Two-layer: group membership allowlist → sender policy. Mention gating: explicit @mention, regex, reply-to-bot.
- **Config**: `textChunkLimit` (4000), `chunkMode`, `mediaMaxMb` (50), `sendReadReceipts`, `ackReaction`.
- **Note**: Requires Node runtime (Bun incompatible). More disk state than other channels.

### Slack
```bash
# Socket mode (recommended):
openclaw config set channels.slack.appToken '"xapp-..."' --json
openclaw config set channels.slack.botToken '"xoxb-..."' --json
# HTTP mode: also set signingSecret, webhookPath
```
- **Modes**: `socket` (default, needs `appToken` with `connections:write`) or `http` (needs `signingSecret`).
- **Scopes**: `chat:write`, `channels:history`, `channels:read`, `groups:history`, `im:history`, `app_mentions:read`, `assistant:write`, `reactions:read/write`, `files:read/write`, `commands`, + more.
- **Native streaming**: Uses `chat.startStream/appendStream/stopStream`. Requires "Agents and AI Apps" enabled + `assistant:write`.
- **Threading**: `thread.historyScope` (`thread`), `thread.inheritParent`, `thread.initialHistoryLimit` (20).
- **Config**: `textChunkLimit` (4000), `chunkMode` (`newline`), `mediaMaxMb` (20), `replyToMode`, slash commands (default off: `commands.native: true`).
- **Note**: `replyToMode="off"` disables ALL reply threading including explicit tags (differs from Telegram).

### Signal
```bash
openclaw channels add signal
# Requires signal-cli installed + registered phone number
```
- **Auth**: signal-cli via JSON-RPC + SSE. `autoStart: true` spawns daemon automatically.
- **Config**: `account` (E.164), `cliPath`, `httpHost`/`httpPort` (127.0.0.1:8080), `startupTimeoutMs` (120000).
- **Access**: Phone numbers or `uuid:<id>`. DM/group allowlists.
- **Features**: Reactions, read receipts, media, groups, typing indicators.

### BlueBubbles (iMessage)
```bash
openclaw channels add bluebubbles --http-url <url> --password <password>
```
- **Auth**: BlueBubbles server on macOS. `serverUrl` + `password`.
- **Features**: Reactions, edits, unsend, reply, group management, media, send effects.
- **Addressing**: `chat_guid:iMessage;-;+15555550123` (preferred), `chat_id:123`, handles.
- **Config**: `webhookPath` (`/bluebubbles-webhook`), `textChunkLimit`, `mediaMaxMb` (8), `mediaLocalRoots`.

### Google Chat, IRC
- **Google Chat**: HTTP webhook app. `openclaw channels add googlechat`.
- **IRC**: `host`, `port`, `tls`, `nick`, `channels[]`. NickServ support. Env vars: `IRC_HOST`, `IRC_PORT`, `IRC_NICK`, etc.

## Plugin Channels

```bash
openclaw plugins install @openclaw/matrix      # E2EE, threads, rooms
openclaw plugins install @openclaw/msteams     # Adaptive Cards, polls
openclaw plugins install @openclaw/<channel>   # mattermost, feishu, line, nostr, nextcloud-talk, twitch, zalo, synology-chat, etc.
```
Matrix supports encryption (`encryption: true`), auto-join, thread replies. MS Teams supports Adaptive Cards, polls stored locally. Nextcloud Talk and Mattermost support self-hosted deployments.

## Access Control (All Channels)

| Policy | Options | Default |
|--------|---------|---------|
| DM | `pairing`, `allowlist`, `open`, `disabled` | `pairing` |
| Group | `open`, `allowlist`, `disabled` | `allowlist` |
| Mention gating | `requireMention: true/false` | `true` for groups |

**Pairing**: 1-hour expiry, max 3 pending per channel. Approve via `openclaw pairing approve <channel> <code>`.
**Per-group overrides**: `requireMention`, `allowFrom`, `skills`, `systemPrompt`, `tools`, `toolsBySender`.
**Multi-account**: `channels.<channel>.accounts.<id>` with per-account overrides for policy, tokens, auth.

## Session Routing

- DMs → agent session per `dmScope` (`main`/`per-peer`/`per-channel-peer`/`per-account-channel-peer`)
- Groups → `agent:<id>:<channel>:group:<groupId>`
- Threads → `:thread:<threadTs>` (Slack/Discord) or `:topic:<topicId>` (Telegram forums)
- Deterministic: replies always return to originating channel
- Thread bindings: 24h TTL, configurable
- `session.identityLinks` maps cross-channel identities to single user


path: references/configuration.md
content: # OpenClaw Configuration Reference

## Config File

- Path: `~/.openclaw/openclaw.json` (JSON5 — comments, trailing commas).
- Override: `OPENCLAW_CONFIG_PATH` env var. Absent = safe defaults.
- Strict validation: unknown keys or malformed values prevent Gateway startup.
- `$include` directive: nested file inclusion up to 10 levels. Single file replaces, array deep-merges.

## Model Providers

Format: `provider/model-name`. Built-in aliases: `opus` → `anthropic/claude-opus-4-6`, `sonnet` → `anthropic/claude-sonnet-4-5`, `gpt` → `openai/gpt-5.2`, `gemini` → `google/gemini-3-pro-preview`.

| Provider | Env Var | Example |
|----------|---------|---------|
| Anthropic | `ANTHROPIC_API_KEY` | `anthropic/claude-sonnet-4-5` |
| OpenAI | `OPENAI_API_KEY` | `openai/gpt-4o` |
| Google | `GEMINI_API_KEY` / `GOOGLE_API_KEY` | `google/gemini-2.5-pro` |
| Mistral | `MISTRAL_API_KEY` | `mistral/mistral-large-latest` |
| OpenRouter | `OPENROUTER_API_KEY` | `openrouter/...` |
| Groq | `GROQ_API_KEY` | `groq/...` |
| xAI | `XAI_API_KEY` | `xai/grok-3` |
| Bedrock | AWS credentials | `bedrock/anthropic.claude-v2` |
| GitHub Copilot | `GH_TOKEN` / `GITHUB_TOKEN` | `github-copilot/...` |
| Ollama | Local, no key | `ollama/llama3` |

**Key rotation**: `OPENCLAW_LIVE_<PROVIDER>_KEY` > `<PROVIDER>_API_KEYS` (comma-separated) > `<PROVIDER>_API_KEY` > `<PROVIDER>_API_KEY_*` (numbered). Triggers on 429 errors only.

**Custom providers**:
```jsonc
{
  "models": {
    "providers": {
      "my-provider": {
        "baseUrl": "https://api.example.com/v1",
        "apiKey": "${CUSTOM_API_KEY}",
        "api": "openai-completions",  // or "anthropic-messages"
        "models": [{ "id": "model-id", "contextWindow": 128000 }]
      }
    }
  }
}
```

**Failover**: (1) Rotate auth profiles within provider. (2) Advance to fallback model. Exponential backoff: 1 → 5 → 25 → 60 min. Billing failures: 5h start, doubling, capped 24h.

## Full Config Structure

```jsonc
{
  "models": {
    "primary": "anthropic/claude-sonnet-4-5",
    "fallbacks": ["openai/gpt-4o"],
    "image": "openai/gpt-4o",
    "aliases": { "fast": "anthropic/claude-haiku-4-5-20251001" },
    "providers": {},             // custom provider definitions
    "mode": "merge"              // "merge" or "replace" for providers
  },
  "channels": {
    "discord": { "token": "", "dmPolicy": "pairing", "requireMention": true },
    "telegram": { "botToken": "", "dmPolicy": "pairing" },
    "whatsapp": { "dmPolicy": "pairing" },
    "slack": { "mode": "socket", "appToken": "", "botToken": "" }
  },
  "agents": {
    "list": [{ "id": "main", "default": true, "workspace": "~/.openclaw/workspace" }],
    "defaults": {
      "model": { "primary": "...", "fallbacks": [] },
      "compaction": { "memoryFlush": { "enabled": true, "softThresholdTokens": 4000 } },
      "memorySearch": { "enabled": true, "provider": "auto" },
      "subagents": { "maxSpawnDepth": 2, "maxConcurrent": 8 }
    }
  },
  "bindings": [],                // agent routing rules
  "broadcast": {},               // multi-agent broadcast groups
  "tools": {
    "profile": "coding",         // minimal | coding | messaging | full
    "allow": [], "deny": [],
    "byProvider": {},
    "exec": { "host": "sandbox", "security": "deny", "ask": "on-miss" },
    "loopDetection": { "warningThreshold": 3, "criticalThreshold": 5 },
    "agentToAgent": { "enabled": false }
  },
  "skills": {
    "entries": { "skill-name": { "enabled": true, "apiKey": "", "env": {} } },
    "load": { "extraDirs": [], "watch": true },
    "install": { "nodeManager": "npm" }
  },
  "browser": {
    "enabled": true, "defaultProfile": "openclaw",
    "ssrfPolicy": { "dangerouslyAllowPrivateNetwork": true },
    "evaluateEnabled": true, "profiles": {}
  },
  "sandbox": {
    "mode": "off",               // off | non-main | all
    "scope": "session",          // session | agent | shared
    "workspaceAccess": "none",   // none | ro | rw
    "docker": { "network": "none", "readOnlyRoot": false, "memory": "1g", "cpus": "1" }
  },
  "gateway": { "port": 18789, "auth": { "token": "" }, "discovery": {} },
  "session": {
    "dmScope": "main",           // main | per-peer | per-channel-peer | per-account-channel-peer
    "reset": { "daily": true, "hour": 4 },
    "identityLinks": {},
    "sendPolicy": { "rules": [], "default": "allow" }
  },
  "automation": { "heartbeat": {}, "cron": [], "webhooks": {} },
  "hooks": { "internal": { "enabled": true, "entries": {} } },
  "auth": { "profiles": {}, "order": {} }
}
```

## Environment Variables

| Variable | Purpose |
|----------|---------|
| `OPENCLAW_HOME` | Override `~/.openclaw` base directory |
| `OPENCLAW_STATE_DIR` | Override state storage location |
| `OPENCLAW_CONFIG_PATH` | Override config file path |
| `OPENCLAW_GATEWAY_PORT` | Override gateway port |

Env files: `~/.openclaw/.env`, workspace `.env`. Substitution: `${VAR_NAME}` in any config string (uppercase only, missing vars throw error).

## Auth & OAuth

**OAuth** (PKCE flow) for OpenAI Codex/ChatGPT. **Setup-token** for Anthropic subscriptions.

```bash
openclaw models auth login --provider openai     # OAuth flow
openclaw models auth setup-token --provider anthropic
openclaw models status                            # Check all auth
```

Storage: `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`. Auto-refresh under file lock.

```jsonc
{
  "auth": {
    "profiles": { "anthropic:work": { "provider": "anthropic", "mode": "api_key" } },
    "order": { "anthropic": ["anthropic:work", "anthropic:personal"] }
  }
}
```

## Profiles & Dev Mode

```bash
openclaw --profile work gateway start    # ~/.openclaw/profiles/work/
openclaw --dev agent                     # ~/.openclaw-dev/ (isolated)
```

## Hot Reload

Modes: `off`, `hot`, `restart`, `hybrid` (default). Most settings hot-apply (channels, models, tools, skills, hooks, cron, sessions). Gateway infrastructure (`gateway.*`, `discovery`) requires restart. Config RPC: `config.apply` (full replace) and `config.patch` (merge), rate-limited 3 req/60s.

## Secrets Management (SecretRef)

Store sensitive values outside config using a SecretRef instead of inline strings (64 credential targets supported).

```jsonc
{
  "channels": {
    "telegram": {
      "botToken": { "$secret": "TELEGRAM_BOT_TOKEN" }
    }
  },
  "gateway": {
    "auth": {
      "token": { "$secret": "GATEWAY_TOKEN" },
      "mode": "token"   // REQUIRED when both token and password are set (v2026.3.7+)
    }
  }
}
```

SecretRefs are resolved at runtime from env vars or a secrets backend. Run `openclaw secrets audit` to check coverage.

⚠️ **Breaking (v2026.3.7)**: If `gateway.auth` has both `token` and `password` configured (including via SecretRefs), `gateway.auth.mode` must now be explicitly set to `"token"` or `"password"` or the gateway will refuse to start.

## CLI Quick Reference

```bash
openclaw config get models.primary
openclaw config set models.primary '"anthropic/claude-opus-4-6"' --json
openclaw config unset channels.irc
openclaw config validate [--json]   # Validate config file before startup (v2026.3.2+)
openclaw models list [--all --provider anthropic]
openclaw models set anthropic/claude-opus-4-6
openclaw models scan            # Probe available models
openclaw models aliases list
openclaw models fallbacks add openai/gpt-4o
openclaw doctor [--fix --yes]   # Audit + auto-repair config
```


path: references/deployment.md
content: # OpenClaw Deployment Reference

## Installation Methods

### One-Liner (macOS/Linux)
```bash
curl -fsSL https://openclaw.ai/install.sh | bash
```

### npm (all platforms, requires Node 22+)
```bash
npm install -g openclaw@latest
openclaw onboard --install-daemon
```

### Git (hackable)
```bash
curl -fsSL https://openclaw.ai/install.sh | bash -s -- --install-method git
cd openclaw && pnpm install && pnpm run build
```

### Nix
```bash
nix-env -iA nixpkgs.openclaw
```

### macOS Companion App
Beta menubar application (macOS 14+, Universal Binary).

### Platform Notes
- **macOS**: npm, Nix, or Homebrew.
- **Linux**: npm, Nix, Docker, or Ansible.
- **Windows**: Node.js on WSL2 recommended. Native Windows has limited support.

## Local Service

### macOS (launchd)
```bash
openclaw gateway install     # Creates LaunchAgent ai.openclaw.gateway
openclaw gateway start/stop/restart/uninstall/status
```

### Linux (systemd user-level, recommended)
```bash
openclaw gateway install
sudo loginctl enable-linger $(whoami)  # Enable lingering
systemctl --user enable --now openclaw-gateway
```

### Linux (system-wide)
```bash
sudo openclaw gateway install --system
sudo systemctl enable --now openclaw-gateway
```

### Manual Foreground
```bash
openclaw gateway --port 18789 --verbose
```

## Docker

### Automated Setup
```bash
./docker-setup.sh  # Build, onboard, compose up, generate token
```

### Manual Setup
```bash
docker build -t openclaw:local -f Dockerfile .
docker compose run --rm openclaw-cli onboard
docker compose up -d openclaw-gateway
```

### docker-compose.yml
Two services: `openclaw-gateway` (ports 18789, 18790) and `openclaw-cli` (interactive).
Volumes: `~/.openclaw/` (config, sessions, auth), workspace directory.

### Dockerfile Details
- Base: `node:22-bookworm`. Runs as non-root `node` user (uid 1000).
- Optional Chromium: `--build-arg OPENCLAW_INSTALL_BROWSER=1` (+300MB).
- Default CMD: `node openclaw.mjs gateway --allow-unconfigured`.

### Environment Variables
| Variable | Purpose |
|----------|---------|
| `OPENCLAW_DOCKER_APT_PACKAGES` | Extra apt packages at build |
| `OPENCLAW_EXTRA_MOUNTS` | Bind mounts (`source:target[:options]`) |
| `OPENCLAW_HOME_VOLUME` | Named volume for `/home/node` |
| `PLAYWRIGHT_BROWSERS_PATH` | Browser cache location |
| API keys | `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, etc. |

### Channel Setup in Docker
```bash
docker compose run --rm openclaw-cli channels login                    # WhatsApp QR
docker compose run --rm openclaw-cli channels add --channel telegram --token "..."
docker compose run --rm openclaw-cli channels add --channel discord --token "..."
```

### Permissions
Container runs as uid 1000. Fix host: `sudo chown -R 1000:1000 ~/.openclaw`.

## Agent Sandboxing

Isolate agent execution in Docker containers for untrusted sessions.

```jsonc
{
  "sandbox": {
    "mode": "non-main",           // off | non-main | all
    "scope": "session",           // session | agent | shared
    "workspaceAccess": "none",    // none | ro | rw
    "docker": {
      "network": "none",
      "readOnlyRoot": false,
      "user": "1000:1000",
      "memory": "1g", "cpus": "1",
      "pidsLimit": 100,
      "seccompProfile": "", "apparmorProfile": "",
      "setupCommand": "apt-get update && apt-get install -y git"
    }
  }
}
```

**Sandbox images**: `sandbox-setup.sh` (bookworm-slim), `sandbox-common-setup.sh` (+ Node/Go/Rust), `sandbox-browser-setup.sh` (+ Chromium/noVNC). Corresponding Dockerfiles: `Dockerfile.sandbox`, `Dockerfile.sandbox-common`, `Dockerfile.sandbox-browser`.

**Default tool allow in sandbox**: exec, process, read, write, edit, sessions_list/history/send/spawn.
**Default tool deny in sandbox**: browser, canvas, nodes, cron, discord, gateway. Deny wins.

**Key rule**: If sandboxing is off and `host=sandbox` is requested, exec **fails closed** (won't silently run on gateway).

## Cloud Platforms

### Fly.io
```bash
fly apps create my-openclaw
fly volumes create openclaw_data --size 1 --region iad
fly secrets set OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)
fly secrets set ANTHROPIC_API_KEY=sk-ant-...
fly deploy
```
Config: `OPENCLAW_STATE_DIR=/data`, [REDACTED_SECRET], `node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan`. VM: `shared-cpu-2x`, 2048MB minimum.

### Railway
Required env: `SETUP_PASSWORD`, `PORT=8080`. Recommended: `OPENCLAW_STATE_DIR=/data/.openclaw`, `OPENCLAW_WORKSPACE_DIR=/data/workspace`. Volume at `/data`. Access setup wizard at `https://<domain>/setup`.

### Render
Deploy via `render.yaml`. Persistent disk for `~/.openclaw`.

### General Cloud Guidelines
- Always use persistent storage for `~/.openclaw` (sessions, memory, WhatsApp auth)
- API keys as secrets/env vars, never in config files
- Use Tailscale/VPN for secure access (preferred over public exposure)
- Consider `--bind lan` for non-loopback environments

## Remote Access

**Preferred**: Tailscale/VPN — gateway accessible at Tailscale IP:18789.
**Fallback**: SSH tunnel: `ssh -N -L 18789:127.0.0.1:18789 user@host`.
**DNS discovery**: `openclaw dns setup` (CoreDNS + Tailscale).

## Multiple Instances

```bash
OPENCLAW_HOME=~/.openclaw-2 openclaw gateway --port 18790
# Or named profiles:
openclaw --profile work gateway start
openclaw --profile personal gateway start
```
Each needs unique: port, config path, state directory.

## Security

- **`openclaw doctor`**: Audits file permissions (600 for config, 700 for directory).
- **`openclaw security audit [--deep --fix]`**: Checks inbound access, tool blast radius, network exposure, browser control, disk hygiene, policy drift.
- **Gateway auth**: `token`, `password`, or `trusted-proxy`. Fail-closed if not configured on non-loopback.
- **mDNS**: `discovery.mdns.mode: "off"` to disable Bonjour broadcast.
- **Ansible**: `openclaw-ansible` repo for automated hardened install with Tailscale, UFW, Docker isolation.


path: references/memory.md
content: # OpenClaw Memory System Reference

## File Structure

Memory lives as plain Markdown in the agent workspace (`~/.openclaw/workspace/`):

```
workspace/
├── MEMORY.md                    # Curated long-term memory (private sessions only)
└── memory/
    ├── 2025-01-15.md            # Daily append-only logs
    ├── 2025-01-16.md
    └── ...
```

- **`MEMORY.md`**: Durable facts, decisions, user preferences. Agent writes in private sessions.
- **`memory/YYYY-MM-DD.md`**: Day-to-day notes. Today + yesterday loaded at session start.
- Files are the source of truth — the model only "remembers" what persists to disk.
- Per-agent index: `~/.openclaw/memory/<agentId>.sqlite`

## Memory Tools

| Tool | Purpose | Returns on missing file |
|------|---------|------------------------|
| `memory_search` | Semantic vector recall (~400-token chunks, 80-token overlap) | `{ text: "", path }` |
| `memory_get` | Direct file/line-range reads (rejects paths outside memory dirs) | `{ text: "", path }` |

Search results include: snippet text (~700 char cap), file path, line range, score.

Writing: agent writes to `MEMORY.md` for durable facts, `memory/YYYY-MM-DD.md` for daily context.

## Vector Search Config

Location: `agents.defaults.memorySearch` in openclaw.json.

```jsonc
{
  "agents": {
    "defaults": {
      "memorySearch": {
        "enabled": true,
        "provider": "auto",           // auto | local | openai | gemini | voyage | mistral
        "extraPaths": [],             // index Markdown outside workspace
        "query": {
          "hybrid": {
            "vectorWeight": 0.7,
            "textWeight": 0.3,
            "mmr": { "enabled": true, "lambda": 0.7 },
            "temporalDecay": { "enabled": true, "halfLifeDays": 30 }
          }
        },
        "cache": { "enabled": true, "maxEntries": 50000 },
        "experimental": {
          "sessionMemory": false,     // index session transcripts
          "sources": ["memory"]       // ["memory", "sessions"]
        }
      }
    }
  }
}
```

**Provider auto-selection order**: local (if `modelPath` configured) → openai → gemini → voyage → mistral → disabled.

**Storage**: SQLite-backed embedding cache. Optional `sqlite-vec` extension for fast vector distance; falls back to JS cosine similarity. File-watch debouncing for auto-reindex.

## Hybrid Search

| Method | Strength | Use Case |
|--------|----------|----------|
| Vector | Semantic similarity | "machine running the gateway" matches "gateway host" |
| BM25 | Exact token matching | IDs, code symbols, error strings |

Merged: `finalScore = vectorWeight * vectorScore + textWeight * textScore`. Falls back to BM25-only if embeddings unavailable.

## Post-Processing

**MMR (Maximal Marginal Relevance)**: Reduces redundant snippets via Jaccard similarity. `lambda`: `1.0` = pure relevance, `0.0` = max diversity. Default: `0.7`.

**Temporal Decay**: `decayedScore = score * e^(-ln(2)/halfLifeDays * ageInDays)`. Default half-life: 30 days. **Evergreen files** (`MEMORY.md`, non-dated `memory/*.md`) never decay.

## Local Embeddings

```jsonc
{
  "memorySearch": {
    "provider": "local",
    "modelPath": "hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/..."
  }
}
```

Default model: ~600 MB GGUF, auto-downloaded on first load. Requires `pnpm approve-builds` for native build. Falls back to remote on failure if configured.

## QMD Backend

Local-first search sidecar combining BM25 + vectors + reranking:

```jsonc
{ "memory": { "backend": "qmd" } }
```

- Self-contained at `~/.openclaw/agents/<agentId>/qmd/`
- Auto-updates on boot + configurable interval (default 5min)
- Requires: QMD CLI, SQLite with extensions, Bun + `node-llama-cpp`
- macOS/Linux supported; Windows via WSL2
- Falls back to builtin SQLite on failure
- Config: `memory.qmd.*` (command, searchMode, refresh, limits, scope)

## Batch Indexing

For large corpora (OpenAI, Gemini, Voyage):
```jsonc
{ "memorySearch": { "remote": { "batch": { "enabled": true, "concurrency": 2 } } } }
```
Async processing via vendor batch APIs. Cheaper and faster than synchronous.

## Auto Memory Flush

Before context compaction, Gateway triggers a silent agentic turn:

```jsonc
{
  "compaction": {
    "memoryFlush": {
      "enabled": true,
      "softThresholdTokens": 4000,
      "reserveTokensFloor": 20000
    }
  }
}
```

Agent writes key context, responds `NO_REPLY` (invisible to user). One flush per compaction cycle. Skipped if workspace is `"ro"` or `"none"`.

## Session Memory (Experimental)

Index session transcripts alongside memory files:
```jsonc
{ "experimental": { "sessionMemory": true, "sources": ["memory", "sessions"] } }
```
Async indexing with delta thresholds (~100 KB, 50 messages).

## Citations

Optional source attribution in search results via `memory.citations` config.


path: references/multi-agent.md
content: # OpenClaw Multi-Agent Reference

## Overview

Single gateway hosts multiple isolated agents. Each agent has its own workspace, session store, memory, auth profiles, and optional sandbox. Default single-agent mode uses `agentId: "main"`.

## Agent Configuration (openclaw.json)

```jsonc
{
  "agents": {
    "list": [
      { "id": "home", "default": true, "workspace": "~/.openclaw/workspace-home" },
      { "id": "work", "workspace": "~/.openclaw/workspace-work",
        "model": { "primary": "openai/gpt-4o" },
        "tools": { "profile": "coding", "allow": ["browser*"], "deny": [] },
        "sandbox": { "mode": "all", "scope": "agent" }
      }
    ]
  }
}
```

### Agent Properties
| Property | Description |
|----------|-------------|
| `id` | Unique agent identifier |
| `default` | Default agent for unrouted messages |
| `workspace` | Isolated workspace directory |
| `model` | Primary model + fallbacks override |
| `tools` | Tool profile, allow/deny overrides |
| `sandbox` | Per-agent sandbox config |
| `identity` | Name, emoji, avatar |

Never reuse `agentDir` across agents (causes auth/session collisions).

## Per-Agent Workspaces

```
~/.openclaw/
├── workspace-home/              # "home" agent
│   ├── SOUL.md                  # Personality
│   ├── IDENTITY.md              # Name, emoji, avatar
│   ├── USER.md                  # User profile
│   ├── MEMORY.md                # Long-term memory
│   ├── TOOLS.md                 # Tool usage guidance
│   ├── BOOTSTRAP.md             # One-time init (deleted after)
│   ├── HEARTBEAT.md             # Periodic check-in instructions
│   ├── memory/                  # Daily logs
│   ├── skills/                  # Agent-specific skills
│   └── hooks/                   # Agent-specific hooks
├── workspace-work/              # "work" agent (same structure)
├── agents/home/                 # Agent state
│   ├── sessions/                # Session store + transcripts
│   └── agent/auth-profiles.json
└── agents/work/
```

- **Managed skills** (`~/.openclaw/skills/`) shared across all agents
- **Workspace skills/hooks** are per-agent (highest precedence)
- Each agent has independent memory, sessions, and vector indices

## Routing Rules (Bindings)

```jsonc
{
  "bindings": [
    { "agentId": "home", "match": { "channel": "whatsapp", "accountId": "personal" } },
    { "agentId": "work", "match": { "channel": "whatsapp", "accountId": "biz" } },
    { "agentId": "dev", "match": { "channel": "discord", "guildId": "123", "roles": ["456"] } },
    { "agentId": "support", "match": { "channel": "telegram", "peer": { "kind": "group", "id": "-100123" } } }
  ]
}
```

### Match Fields
`channel`, `accountId` (or `"*"`), `peer.kind` (`"direct"`/`"group"`), `peer.id`, `guildId`, `roles`, `teamId`. Multiple fields use AND.

### Priority (deterministic)
1. Exact peer match (channel + peer ID)
2. Parent peer match (thread inheritance)
3. Guild ID + roles (Discord)
4. Guild ID alone
5. Team ID (Slack)
6. Account ID (exact)
7. Channel-level (`accountId: "*"`)
8. Default agent fallback

First match in config order wins within the same tier.

## Broadcast Groups

Multiple agents process the same message. Currently **WhatsApp-only** (v2026.1.9+). Takes priority over bindings.

```jsonc
{
  "broadcast": {
    "strategy": "parallel",      // parallel | sequential
    "[REDACTED_SECRET]": ["assistant", "coder", "reviewer"],
    "+15551234567": ["agent1", "agent2"]
  }
}
```

**Parallel**: All agents respond independently. **Sequential**: Each sees previous agents' responses.

Each agent maintains completely isolated sessions, history, workspace, tools, and memory. Agents fail independently. No hard limit but 10+ may degrade performance.

## Sub-Agents

Background agent runs spawned from parent session. Isolated execution with immediate return.

```jsonc
{
  "agents": {
    "defaults": {
      "subagents": {
        "maxSpawnDepth": 2,          // 1-5, nesting depth
        "maxChildrenPerAgent": 5,    // 1-20
        "maxConcurrent": 8,
        "runTimeoutSeconds": 900,
        "archiveAfterMinutes": 60,
        "model": "anthropic/claude-haiku-4-5-20251001",
        "thinking": "low"
      }
    }
  }
}
```

- Session key: `agent:<agentId>:subagent:<uuid>`
- Depth-1: orchestrator tools. Depth-2+: leaf (no session tools).
- Default deny for sub-agents: `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`.
- Results announce back to requester chat.

**Slash commands**: `/subagents spawn|list|kill|log|info|send|steer`, `/focus <target>`, `/unfocus`, `/session ttl`.

## Agent-to-Agent Messaging

Disabled by default:
```jsonc
{
  "tools": {
    "agentToAgent": { "enabled": false, "allow": ["home", "work"] }
  }
}
```

## Session Isolation

### Session Key Format
- DMs: `agent:<agentId>:<mainKey>` (default: `agent:main:main`)
- Per-peer: `agent:<agentId>:dm:<peerId>`
- Per-channel-peer: `agent:<agentId>:<channel>:dm:<peerId>`
- Groups: `agent:<agentId>:<channel>:group:<groupId>`
- Threads: append `:thread:<threadTs>` (Slack/Discord) or `:topic:<topicId>` (Telegram)
- Sub-agents: `agent:<agentId>:subagent:<uuid>`
- Cron: `cron:<jobId>`
- Webhooks: `hook:<uuid>`

### DM Scope Options
| Scope | Behavior |
|-------|----------|
| `main` (default) | All DMs share one session |
| `per-peer` | Isolated by sender ID across channels |
| `per-channel-peer` | Isolated by channel + sender (recommended multi-user) |
| `per-account-channel-peer` | Isolated by account + channel + sender |

**Identity links**: Map cross-platform identities to one user:
```jsonc
{ "session": { "identityLinks": { "alice": ["telegram:123", "discord:456"] } } }
```

**Security**: Without per-peer scoping, different senders share conversation context (privacy leak). Use `per-channel-peer` or stricter in multi-user setups.

## Session Maintenance

Modes: `warn` (default) and `enforce`. Enforce: prune stale (30d), cap entries (500), archive transcripts, rotate (10MB), enforce disk budget.

Storage: `~/.openclaw/agents/<agentId>/sessions/sessions.json` + `<SessionId>.jsonl` transcripts.

## CLI

```bash
openclaw agents list [--json --bindings]
openclaw agents add <name> [--workspace]
openclaw agents delete <id> [--force]
openclaw agents set-identity [--agent --name --emoji --avatar]
openclaw agent --message "..." --agent <name>  # Single turn as specific agent
openclaw sessions [--agent <name> --json]
openclaw status --all --deep                    # Full system overview
```


path: references/tools.md
content: # OpenClaw Tools Reference

## Exec Tool

Runs shell commands with foreground/background execution.

| Parameter | Default | Description |
|-----------|---------|-------------|
| `command` | required | Shell command |
| `workdir` | current | Working directory |
| `env` | `{}` | Env var overrides (PATH/LD_*/DYLD_* rejected for host) |
| `yieldMs` | 10000 | Auto-background after delay (ms) |
| `background` | false | Immediately background |
| `timeout` | 1800 | Kill after (seconds) |
| `pty` | false | Pseudo-terminal for TTY tools |
| `host` | `sandbox` | `sandbox` / `gateway` / `node` |
| `security` | `deny` | `deny` / `allowlist` / `full` |
| `ask` | `on-miss` | `off` / `on-miss` / `always` |
| `elevated` | false | Request elevated permissions |

**Sandbox** (default): Isolated Docker. Fails closed if sandboxing is off. **Gateway**: Merges login-shell PATH. **Node**: Paired companion app.

**Security**: Allowlist uses resolved binary paths only. Safe bins (`/bin`, `/usr/bin`) bypass allowlisting. Approvals: `~/.openclaw/exec-approvals.json`. Shell: prefers `bash`/`sh` over `fish`.

**Process management** via `process` tool: `list`, `poll`, `log`, `write`, `kill`, `clear`, `remove`.

**Session overrides**: `/exec host=gateway security=allowlist ask=on-miss node=mac-1`

**apply_patch**: Experimental multi-file edit subtool. Enable under `tools.exec.applyPatch`. OpenAI/Codex models only.

## Browser Tool

Controls dedicated OpenClaw-managed Chromium. Auto-detect order: Chrome, Brave, Edge, Chromium.

**Profiles**: `openclaw` (managed, isolated), `chrome` (extension relay, default), `remote` (custom CDP URL). Config: `browser.defaultProfile`, `browser.profiles.<name>`.

**Core actions**: `navigate`, `click`, `double-click`, `type` (`--submit`), `press`, `hover`, `scrollintoview`, `drag`, `select`, `download`, `fill`, `dialog`, `upload`, `wait`, `evaluate`.

**Snapshots**: AI mode (numeric refs: `click 12`, requires Playwright) and Role mode (element refs: `click e12`, supports `--interactive`, `--compact`, `--depth`, `--labels`). Refs **not stable** across navigations.

**State**: Cookies, localStorage, sessionStorage, custom headers, HTTP auth, geolocation, media preferences, timezone, locale, device presets ("iPhone 14" style).

**Wait**: URL patterns, load states (`networkidle`), JS predicates, element selectors. Combinable.

**Security**: Loopback-only control. Disable `evaluateEnabled` to block arbitrary JS. SSRF policy (`dangerouslyAllowPrivateNetwork`, `hostnameAllowlist`). Treat CDP URLs/tokens as secrets.

**Remote/hosted**: `profiles.<name>.cdpUrl` for Browserless/external. Node browser proxy (auto-routes to paired nodes). Chrome extension relay: `openclaw browser extension install`.

**Sandbox**: Default sandboxed sessions use `target="sandbox"`. Override: `sandbox.browser.allowHostControl: true`.

## Skills System

Skills are Markdown files (`SKILL.md`) injected into agent system prompts. They are NOT executable code.

**SKILL.md format**:
```yaml
---
name: my-skill
description: When to trigger this skill
homepage: https://example.com           # optional
user-invocable: true                    # slash command (default: true)
disable-model-invocation: false         # exclude from prompt (default: false)
command-dispatch: tool                  # optional: bypass model for direct tool call
command-tool: tool-name                 # tool for dispatch mode
command-arg-mode: raw                   # forward unprocessed args
metadata: {"openclaw":{"os":["darwin"],"requires":{"bins":["node"]}}}
---
Skill body — injected into system prompt.
```

**Precedence** (high → low): workspace (`<workspace>/skills/`) → managed (`~/.openclaw/skills/`) → bundled (52 skills) → `skills.load.extraDirs`.

**Gating** via `metadata.openclaw`: `os` (darwin/linux/win32), `requires.bins`, `requires.anyBins`, `requires.env`, `requires.config`, `primaryEnv`, `always: true`.

**Config**:
```jsonc
{
  "skills": {
    "entries": { "skill-name": { "enabled": true, "apiKey": "sk-...", "env": {}, "config": {} } },
    "load": { "extraDirs": [], "watch": true, "watchDebounceMs": 250 },
    "install": { "nodeManager": "npm" }  // npm | pnpm | yarn | bun
  }
}
```

Env injection is per-agent-run only (not global). Token cost: ~195 chars base + ~97 per skill (~24 tokens each). Skills snapshot at session start; watcher auto-refreshes on changes.

**ClawHub**: `clawhub install <slug>`, `clawhub update --all`, `clawhub sync --all`. Browse: https://clawhub.com

**Installers**: `brew`, `node`, `go`, `uv`, `download`. Node respects `skills.install.nodeManager`.

## Hooks System

Event-driven TypeScript handlers running inside Gateway. Distinct from skills (prompt injection) and webhooks (external HTTP).

**HOOK.md format**:
```yaml
---
name: hook-id
description: "What it does"
metadata:
  openclaw:
    events: ["command:new", "message:received"]
    requires:
      bins: ["node"]
      env: ["MY_VAR"]
    emoji: "..."
    export: "default"
---
```

**Events**:

| Event | Trigger |
|-------|---------|
| `command:new` | New session started |
| `command:reset` | Session reset |
| `command:stop` | Session stopped |
| `agent:bootstrap` | Pre-injection (handlers can mutate bootstrap files) |
| `gateway:startup` | After channels load |
| `message:received` | Inbound message |
| `message:sent` | Outbound message |
| `tool_result_persist` | Synchronous tool result transformation |

**Handler** (`handler.ts`):
```typescript
const handler = async (event) => {
  if (event.type !== "command" || event.action !== "new") return;
  // event.messages.push("notification text");
  // event.context: { sessionEntry, workspaceDir, from, to, content }
};
export default handler;
```

**Discovery** (high → low): workspace (`<workspace>/hooks/`) → managed (`~/.openclaw/hooks/`) → bundled.

**Bundled hooks**: `session-memory` (saves context snapshots), `bootstrap-extra-files` (inject files via glob), `command-logger` (JSONL logging), `boot-md` (execute BOOT.md on startup).

**Hook packs**: npm packages with `"openclaw": { "hooks": [...] }`. Install: `openclaw hooks install <spec>`.

**CLI**: `openclaw hooks list [--eligible --verbose --json]`, `info`, `check`, `enable`, `disable`, `install`.

## Tool Access Control

**Profiles**: `minimal` (conversation only), `coding` (+ exec, fs, process), `messaging` (+ message, channel), `full` (all).

**Allow/deny**: Case-insensitive, wildcard support. `deny` wins over `allow`.
```jsonc
{ "tools": { "profile": "coding", "allow": ["browser*"], "deny": ["exec"], "byProvider": {} } }
```

**Groups**: `group:fs`, `group:runtime`, `group:sessions`, `group:web`, `group:ui`, `group:automation`.

**Default allow in sandbox**: exec, process, read, write, edit, sessions_list/history/send/spawn.
**Default deny in sandbox**: browser, canvas, nodes, cron, discord, gateway. Deny wins over allow.

**Loop detection**: `genericRepeat`, `knownPollNoProgress`, `pingPong`. Configurable warning/critical thresholds.

## PDF Tool

First-class native PDF analysis (added v2026.3.2).

| Parameter | Description |
|-----------|-------------|
| `pdf` | Single PDF path or URL |
| `pdfs` | Array of up to 10 PDFs |
| `prompt` | Analysis prompt (default: "Analyze this PDF document") |
| `pages` | Page filter range, e.g. `1-5` or `1,3,7-9` |
| `model` | Override model for this call |

**Supported references**: Local paths (`~` expanded), `file://`, `http://`, `https://`.

**Processing modes**:
- **Native** (Anthropic, Google): sends raw PDF bytes directly — page filtering not supported
- **Extraction fallback** (all other providers): extracts text (max 20 pages default); falls back to PNG render if fewer than 200 chars extracted

**Config**:
```jsonc
{
  "agents": {
    "defaults": {
      "pdfModel": "anthropic/claude-sonnet-4-5",  // preferred over imageModel
      "imageModel": "openai/gpt-4o"               // fallback
    }
  }
}
```

Defaults: max 10MB per PDF, max 20 pages. Output in `content[0].text` with metadata in `details`.

## Nodes (Companion Devices)

Paired macOS/iOS/Android/headless devices that connect to the Gateway as peripherals, exposing hardware surfaces.

**Pairing**:
```bash
openclaw devices list                    # List pending pairing requests
openclaw devices approve <requestId>     # Approve a device
openclaw nodes status                    # Show connected nodes
```

**Command surfaces** (via `node.invoke`):

| Surface | Actions |
|---------|---------|
| `canvas.*` | `present` (URL/HTML), `hide`, `navigate`, `eval` (JS), `snapshot` (PNG), A2UI push |
| `camera.*` | `snap` (JPG photo), `clip` (MP4 video, duration param) |
| `screen.*` | `record` (MP4, ≤60s, `--fps`, `--no-audio`) |
| `device.*` | `status`, `info`, `permissions`, `health` (Android) |
| `notifications.*` | `list`, `actions` (Android) |
| `system.*` | `run`, `which`, `notify`, exec approvals (macOS/headless) |
| `photos.*` | `latest` (Android) |
| `sms.*` | `send` (Android, requires telephony permission) |

**Remote node host** — route `system.run` calls to a separate machine:
```bash
openclaw node run --host <gateway-host> --port 18789 --display-name "Build Node"
```

**Key constraints**:
- Canvas/camera require foreground app on mobile
- Screen recordings capped at 60 seconds
- `exec` approvals required for `system.run` (stored in `~/.openclaw/exec-approvals.json`)
- Sandbox default: `browser` and `canvas` denied; `nodes` denied in sandboxed sessions

## Messaging & Sub-Agents

**`message` tool**: Unified cross-channel messaging. Actions: `send`, `react`, `edit`, `delete`, `pin`, `unpin`, `poll`, `thread-create`, `thread-reply`, `search`. Supports 9 channels.

**`sessions_spawn`**: Sub-agent runs. One-shot or persistent, thread-bound. Returns run ID immediately. Results announce back to requester.
- Nested spawning via `maxSpawnDepth` (1-5). Depth-1 = orchestrator, depth-2+ = leaf (no session tools).
- Config: `subagents.maxConcurrent` (8), `runTimeoutSeconds` (900), `model`, `thinking`.
- Slash commands: `/subagents spawn|list|kill|log|info|send|steer`, `/focus <target>`, `/unfocus`, `/session ttl`.
- Config: `subagents.maxChildrenPerAgent` (1-20, default 5), `maxConcurrent` (8), `runTimeoutSeconds` (900), `archiveAfterMinutes` (60).

**`canvas`**: HTML display on connected nodes (macOS/iOS/Android). Actions: `present`, `hide`, `navigate`, `eval`, `snapshot`.


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)