1. What is OpenClaw
OpenClaw is a self-hosted gateway that connects your chat apps to AI agents. One Gateway process serves WhatsApp, Telegram, Discord, iMessage, Signal, Slack, IRC, Google Chat, and more simultaneously. MIT licensed, open source.
Key Features
- Multi-channel — One Gateway, all your messaging apps
- Multi-model — Anthropic, OpenAI, Google, Ollama, OpenRouter
- Agent-native — Tool use, sessions, memory, multi-agent
- Self-hosted — Your hardware, your data, your rules
- Always-on — Runs as a daemon (systemd/launchd)
- Mobile nodes — Pair iOS/Android for camera, location, notifications
- Skills & plugins — Extend with ClawHub skills
Architecture
┌─────────────┐
│ Chat Apps │ WhatsApp, Telegram,
│ + Plugins │ Discord, iMessage, ...
└──────┬───────┘
│
┌──────▼───────┐
│ Gateway │ Single daemon process
│ (Node.js) │ Sessions, routing, tools
└──────┬───────┘
│
┌──────▼───────┐
│ AI Models │ Anthropic, OpenAI,
│ + Tools │ Google, Ollama, ...
└──────────────┘Requirements
Node 22+ • macOS, Linux, or Windows (WSL2 recommended) • An API key (Anthropic recommended) • 5 minutes to set up
2. Installation & Setup
Install
# Installer script (recommended — handles Node detection)
curl -fsSL https://openclaw.ai/install.sh | bash
# Windows (PowerShell)
iwr -useb https://openclaw.ai/install.ps1 | iex
# npm (if you already have Node 22+)
npm install -g openclaw@latest
# pnpm
pnpm add -g openclaw@latest
pnpm approve-builds -gFirst-Time Setup
# Interactive onboarding wizard (creates config + workspace)
openclaw onboard --install-daemon
# Or manual setup
openclaw configure # config wizard
openclaw setup # create workspace files
# Set your API key
export ANTHROPIC_API_KEY="sk-ant-..."
# Or store for daemon use:
echo 'ANTHROPIC_API_KEY=sk-ant-...' >> ~/.openclaw/.envGateway Daemon
# Start the gateway daemon
openclaw gateway start
# Check status
openclaw gateway status
# Stop / restart
openclaw gateway stop
openclaw gateway restart
# Run in foreground (debugging)
openclaw gateway --port 18789
# Health check
openclaw doctor
# Open the browser Control UI
openclaw dashboard
# → http://127.0.0.1:18789/3. Configuration (openclaw.json)
Config lives at ~/.openclaw/openclaw.json (JSON5 — comments and trailing commas allowed). The Gateway watches the file and hot-reloads changes.
Minimal Config
{
agent: { workspace: "~/.openclaw/workspace" },
channels: {
whatsapp: { allowFrom: ["+15555550123"] }
}
}Recommended Starter
{
identity: {
name: "Clawd",
theme: "helpful assistant",
emoji: "🦞"
},
agent: {
workspace: "~/.openclaw/workspace",
model: { primary: "anthropic/claude-sonnet-4-5" }
},
channels: {
whatsapp: {
allowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } }
},
telegram: {
enabled: true,
botToken: "123456:ABC-..."
}
},
// Heartbeat interval (periodic wake-ups)
agents: {
defaults: {
heartbeat: { every: "30m" }
}
}
}Config Editing
# Interactive wizard
openclaw configure
# CLI one-liners
openclaw config get agents.defaults.workspace
openclaw config set agents.defaults.heartbeat.every "2h"
openclaw config unset tools.web.search.apiKey
# Control UI (browser)
# Open http://127.0.0.1:18789 → Config tab4. Workspace Files
The workspace (~/.openclaw/workspace by default) contains Markdown files that define the agent's personality, memory, and behavior. All files are injected into the agent context at session start.
| File | Purpose | Loaded When |
|---|---|---|
| SOUL.md | Persona, tone, and boundaries | Every session |
| USER.md | Who the human is, how to address them | Every session |
| AGENTS.md | Operating instructions, behavior rules | Every session |
| IDENTITY.md | Agent name, vibe, emoji | Every session |
| TOOLS.md | User-maintained tool notes (cameras, SSH, etc.) | Every session |
| MEMORY.md | Curated long-term memory | Main session only (security) |
| HEARTBEAT.md | Periodic task checklist | On heartbeat |
| BOOTSTRAP.md | One-time first-run ritual (deleted after) | First session only |
| memory/YYYY-MM-DD.md | Daily logs (append-only) | Today + yesterday |
⚠️ Security: MEMORY.md
MEMORY.md is only loaded in the main (private) session — never in group chats or shared contexts. This prevents personal context from leaking to other users.
5. Channel Setup
Telegram
# 1. Create bot via @BotFather on Telegram
# → /newbot → get the token
# 2. Add to config
{
channels: {
telegram: {
enabled: true,
botToken: "123456789:AABBcc...",
dmPolicy: "pairing", // pairing | allowlist | open
groups: {
"*": { requireMention: true }
}
}
}
}
# 3. Webhook (optional, for production)
{
channels: {
telegram: {
webhookUrl: "https://your-domain.com/telegram",
webhookSecret: "random-secret-string"
}
}
}Discord
# 1. Create app at discord.com/developers
# 2. Add bot, enable Message Content + Server Members intents
# 3. Invite bot to your server
{
channels: {
discord: {
enabled: true,
token: "YOUR_BOT_TOKEN"
}
}
}
# Env fallback:
DISCORD_BOT_TOKEN=...# WhatsApp uses Baileys (Web API) — pair via QR code
openclaw channels login
{
channels: {
whatsapp: {
dmPolicy: "pairing",
allowFrom: ["+15555550123"],
groups: { "*": { requireMention: true } },
sendReadReceipts: true
}
}
}DM Policies
| Policy | Behavior |
|---|---|
| pairing (default) | Unknown senders get a one-time pairing code; owner approves |
| allowlist | Only senders in allowFrom (or paired allow store) |
| open | Allow all inbound DMs (requires allowFrom: ["*"]) |
| disabled | Ignore all inbound DMs |
6. Tools & Capabilities
| Tool | Purpose | Key Actions |
|---|---|---|
| exec | Run shell commands | command, workdir, env, background, pty |
| process | Manage background exec sessions | list, poll, log, write, kill |
| read | Read file contents | file_path, offset, limit |
| write | Create/overwrite files | file_path, content |
| edit | Precise file edits | file_path, old_string, new_string |
| web_search | Search the web (Brave API) | query, count, freshness |
| web_fetch | Fetch URL content as markdown | url, extractMode, maxChars |
| browser | Control a dedicated Chrome instance | open, snapshot, act, screenshot |
| image | Analyze images with vision models | image, prompt |
| tts | Text-to-speech | text, channel |
| cron | Schedule jobs | add, update, remove, list, run |
| message | Send messages to channels | send, edit, delete, react |
| nodes | Control paired devices | camera_snap, screen_record, notify |
| sessions_spawn | Spawn sub-agents | task, model, thinking |
| sessions_send | Cross-session messaging | target, message |
| memory_search | Semantic memory search | query |
Tool Policies (allow/deny)
{
// Deny specific tools globally
tools: { deny: ["browser"] },
// Or allow only specific tools
tools: { allow: ["read", "write", "exec", "web_search"] },
// Tool profiles (preset allowlists)
tools: { profile: "coding" },
// Profiles: "minimal" (session_status only),
// "coding" (fs, runtime, sessions, memory, image)
}7. Skills System
Skills are directories containing a SKILL.md file (YAML frontmatter + instructions) that teach the agent how to use tools. They follow the AgentSkills spec.
Skill Locations (precedence)
# Highest priority → lowest
1. <workspace>/skills/ # Per-agent, workspace-local
2. ~/.openclaw/skills/ # Shared across agents (managed/local)
3. Bundled skills # Shipped with OpenClaw install
# Extra skill folders (lowest priority)
{ skills: { load: { extraDirs: ["/path/to/shared-skills"] } } }Creating a Custom Skill
# 1. Create the directory
mkdir -p ~/.openclaw/workspace/skills/hello-world
# 2. Create SKILL.md
cat > ~/.openclaw/workspace/skills/hello-world/SKILL.md << 'EOF'
---
name: hello_world
description: A simple greeting skill.
---
# Hello World Skill
When the user asks for a greeting, respond with a warm,
personalized hello. Use the user's name from USER.md if available.
EOFClawHub (Public Registry)
# Search for skills
clawhub search "image generation"
# Install a skill
clawhub install nano-banana-pro
# Update all installed skills
clawhub update --all
# Sync (scan + publish updates)
clawhub sync --all
# Browse: https://clawhub.aiSkill Gating (conditional loading)
# In SKILL.md frontmatter — skill only loads when conditions met
---
name: nano-banana-pro
description: Generate images via Gemini
metadata: {"openclaw": {"requires": {
"bins": ["uv"],
"env": ["GEMINI_API_KEY"],
"config": ["browser.enabled"]
}}}
---8. Cron & Scheduling
The Gateway has a built-in scheduler for background jobs. Jobs persist across restarts under ~/.openclaw/cron/.
Schedule Types
| Kind | Use Case | Example |
|---|---|---|
| at | One-shot (deletes after success) | --at "2026-03-30T09:00:00Z" |
| every | Fixed interval (ms) | --every 3600000 (1 hour) |
| cron | 5-field cron expression | --cron "0 7 * * *" --tz "Europe/Zurich" |
CLI Examples
# One-shot reminder
openclaw cron add \
--name "Reminder" \
--at "2026-03-30T16:00:00Z" \
--session main \
--system-event "Reminder: check the deploy status" \
--wake now --delete-after-run
# Daily morning briefing (isolated session)
openclaw cron add \
--name "Morning brief" \
--cron "0 7 * * *" \
--tz "Europe/Zurich" \
--session isolated \
--message "Summarize overnight updates." \
--announce \
--channel telegram --to "123456789"
# List / run / delete
openclaw cron list
openclaw cron run <job-id>
openclaw cron remove <job-id>Payload Types
systemEvent (main session)
Enqueues event into the main session. Runs on next heartbeat or immediately (wakeMode: "now"). Best for tasks needing main-session context.
agentTurn (isolated session)
Runs a dedicated agent turn in cron:<jobId>. Fresh session each run. Can deliver results to a channel (announce) or stay internal (none).
9. Multi-Agent (Sessions)
Sub-Agents (sessions_spawn)
# The agent can spawn sub-agents for parallel/background work.
# Sub-agents run in isolated sessions and announce results back.
# Natural language (the agent handles the tool call):
"Spawn a sub-agent to research the latest Node.js release notes"
# Tool call shape:
{
"tool": "sessions_spawn",
"params": {
"task": "Research Node.js 22 release notes",
"model": "anthropic/claude-sonnet-4", // optional
"thinking": "low" // optional
}
}
# Returns: { status: "accepted", runId, childSessionKey }Cross-Session Messaging
# Send a message to another session
{
"tool": "sessions_send",
"params": {
"target": "agent:main:main",
"message": "Research complete — see findings below..."
}
}
# List active sessions
{
"tool": "sessions_list"
}Sub-Agent Configuration
{
agents: {
defaults: {
subagents: {
model: "minimax/MiniMax-M2.1", // cheaper model for sub-agents
thinking: "low",
maxConcurrent: 8,
autoArchiveMs: 3600000 // 60 minutes
}
}
}
}Session Key Structure
agent:main:main— Direct DM (main session)agent:main:telegram:group:-1001234— Telegram groupagent:main:discord:channel:123:thread:456— Discord threadagent:main:subagent:<uuid>— Sub-agent sessioncron:<jobId>— Isolated cron job
10. Nodes (Mobile/Remote)
Nodes are companion devices (iOS, Android, macOS, headless) that connect to the Gateway via WebSocket and expose commands like camera, screen capture, location, and notifications.
Pairing & Management
# List paired devices
openclaw devices list
# Check node status
openclaw nodes status
# Describe a specific node
openclaw nodes describe --node "iPhone"
# Approve/reject pending pairing requests
openclaw devices list --pending
openclaw devices approve <requestId>
openclaw devices reject <requestId>Node Commands (agent tool calls)
# Camera snapshot
{ "tool": "nodes", "params": {
"action": "camera_snap",
"node": "iPhone",
"facing": "back" // front | back | both
}}
# Screen recording
{ "tool": "nodes", "params": {
"action": "screen_record",
"node": "MacBook",
"durationMs": 5000
}}
# Get location
{ "tool": "nodes", "params": {
"action": "location_get",
"node": "iPhone",
"desiredAccuracy": "balanced" // coarse | balanced | precise
}}
# Send notification
{ "tool": "nodes", "params": {
"action": "notify",
"node": "iPhone",
"title": "Reminder",
"body": "Time to check the deploy"
}}Remote Node Host (exec on another machine)
# Start a node host on the remote machine
openclaw node run --host <gateway-host> --port 18789 \
--display-name "Build Node"
# Install as a service
openclaw node install --host <gateway-host> --port 18789 \
--display-name "Build Node"
# SSH tunnel for loopback-bound gateways
ssh -N -L 18790:127.0.0.1:18789 user@gateway-host
OPENCLAW_GATEWAY_TOKEN="<token>" \
openclaw node run --host 127.0.0.1 --port 1879011. Memory System
Memory is plain Markdown in the workspace. The model only "remembers" what gets written to disk. Vector search is available for semantic retrieval.
Memory Files
MEMORY.md (long-term)
Curated, distilled memory. Decisions, preferences, durable facts. Only loaded in the main private session (never in groups). Think of it as the agent's "long-term memory."
memory/YYYY-MM-DD.md (daily logs)
Append-only daily notes. Today + yesterday loaded at session start. Raw context: what happened, what was discussed, running notes.
Vector Memory Search
# CLI: check memory status and index
openclaw memory status
openclaw memory status --deep --index
openclaw memory index --verbose
# Search for relevant memories
openclaw memory search "release checklist"
# Agent tool call:
{ "tool": "memory_search", "params": { "query": "deployment process" } }
# Auto-recall: OpenClaw automatically searches memory
# before answering when relevant context might exist.Automatic Memory Flush
# When a session nears auto-compaction, OpenClaw triggers
# a silent turn to remind the model to save durable memories.
{
agents: {
defaults: {
compaction: {
reserveTokensFloor: 20000,
memoryFlush: {
enabled: true,
softThresholdTokens: 4000,
systemPrompt: "Session nearing compaction. Store durable memories now.",
prompt: "Write lasting notes to memory/YYYY-MM-DD.md; reply NO_REPLY if nothing."
}
}
}
}
}12. Advanced: Custom Agents & Workflows
Multi-Agent Architecture
{
agents: {
list: [
{
id: "main",
default: true,
workspace: "~/.openclaw/workspace",
model: { primary: "anthropic/claude-sonnet-4-5" },
subagents: { model: "minimax/MiniMax-M2.1" }
},
{
id: "researcher",
workspace: "~/.openclaw/workspace-researcher",
model: { primary: "anthropic/claude-sonnet-4" },
// Bind to specific channels/peers
bindings: [
{ peer: { kind: "discord", id: "channel:research-123" } }
]
},
{
id: "ops",
workspace: "~/.openclaw/workspace-ops",
model: { primary: "anthropic/claude-sonnet-4" },
tools: { allow: ["exec", "read", "web_fetch"] }
}
]
}
}Heartbeat-Driven Proactive Work
# HEARTBEAT.md — checked on each heartbeat interval
# The agent reads this file and acts on items
## Periodic Checks (rotate 2-4x daily)
- [ ] Check email inbox for urgent messages
- [ ] Review calendar for upcoming events (next 24h)
- [ ] Check weather if human might go out
- [ ] Review and update MEMORY.md with recent insights
## One-Time Tasks
- [ ] Finish the deployment docs draft
- [ ] Review PR #42 when CI passesBrowser Automation
# OpenClaw controls a dedicated Chrome profile (isolated from your browser)
# CLI
openclaw browser start
openclaw browser open https://example.com
openclaw browser snapshot
# Agent uses the browser tool:
{ "tool": "browser", "params": {
"action": "open",
"targetUrl": "https://news.ycombinator.com"
}}
{ "tool": "browser", "params": {
"action": "snapshot" // returns page structure
}}
{ "tool": "browser", "params": {
"action": "act",
"request": { "kind": "click", "ref": "e12" }
}}Production Tips
- ▸Use Claude Sonnet for daily tasks, Opus for complex reasoning
- ▸Set cheaper models for sub-agents to reduce costs
- ▸Use thinking levels:
offfor simple,low/mediumfor moderate,highfor complex - ▸Batch periodic checks into
HEARTBEAT.mdinstead of many cron jobs
- ▸Use
/compactwhen sessions feel stale - ▸Enable sandboxing for untrusted inputs
- ▸Use
openclaw doctorto diagnose issues - ▸Store API keys in
~/.openclaw/.envfor daemon access