AI / GenAI  /  OpenClaw

🦞 OpenClaw Guide 3 of 4 14 guides · updated 2026

Running your own self-hosted AI assistant — install, gateway architecture, messaging channels, skills, scheduling, and the security work that makes it safe to leave running.

How OpenClaw Works: Gateway, Sessions, Agents and Nodes

Most people configure OpenClaw by trial and error. They change a setting, send a test message, see what happens, change something else. It works, eventually, but it produces a setup nobody understands — including the person who built it.

There’s a faster path, and it’s about twenty minutes of reading. Once you can trace what happens between “I sent a WhatsApp message” and “a command ran on my machine,” almost every configuration question answers itself. You stop guessing which key to change because you know which box in the pipeline is misbehaving.

This page is that trace.


The Four Layers

OpenClaw has four architectural layers, and nearly every concept you’ll meet belongs to exactly one of them.

4 · Agents & nodes

Agent

model · prompt · workspace

Tools

Companion nodes

voice · camera · screen

3 · Gateway

Routing & access policy

Session manager

Tool policy

Scheduler: cron · heartbeat · hooks

2 · Channels

WhatsApp

Telegram

Slack / Discord / Teams

iMessage / Signal / Matrix

1 · Control interfaces

CLI

Web Control UI

TUI

Control interfaces are how you administer the system — CLI, the browser Control UI, the terminal UI. They talk to the Gateway; they are not the Gateway.

Channels are adapters that translate between a messaging platform’s API and OpenClaw’s internal message format. WhatsApp and Slack have nothing in common at the protocol level; by the time a message reaches the Gateway, that difference is gone.

The Gateway is the control plane. Routing, access policy, sessions, tool permissions, scheduling. This is where the interesting decisions live.

Agents and nodes do the work: an agent is a model plus a prompt plus a workspace plus a tool set; nodes are device-local extensions that add capabilities like voice or camera.

Hold onto the distinction between the Gateway and the agent. Beginners collapse them into “the bot.” They’re separate, and the security model depends entirely on the separation: the Gateway is the part that says no, and it says no before the model ever sees the message.


Following a Message End to End

Here’s the actual sequence when you text your assistant “check if the staging site is up.”

Phone (WhatsApp)
① Channel adapter normalise to internal message
│ sender id, chat id, body, attachments
② Access policy is this sender allowed?
│ dmPolicy / allowFrom / pairing
│ ── rejected? stop here, model never invoked
③ Mention gating group chat? was the bot addressed?
│ requireMention / implicitMentions
④ Session resolution which conversation does this belong to?
│ dmScope → session key → history
⑤ Agent selection which agent handles this route?
│ model, system prompt, workspace, tools
⑥ Model invocation prompt + history + memory + tool schemas
⑦ Tool loop model requests a tool
│ ├─ tool policy: allowed?
│ ├─ needs approval? ask the operator
│ ├─ sandboxed? run in container
│ └─ result returns to model ──┐
│ │
│ ◄───────────── repeat until done ───────────┘
⑧ Reply back through the channel adapter
│ to the same thread
Phone

Steps ② and ③ are your security perimeter, and they happen before any tokens are spent. That ordering is deliberate and it’s worth internalising: a blocked sender costs you nothing and reaches nothing. This is why access control is cheap and why there’s no excuse for leaving it loose.

Step ⑦ is where the loop lives. The model doesn’t produce an answer in one shot — it asks for a tool, gets a result, reasons about it, maybe asks for another. A single “is staging up” might be three round trips. That’s normal, and it’s also why an agent turn costs meaningfully more than a chat message.


The Gateway in Detail

The Gateway is a long-lived local process that multiplexes WebSocket and HTTP on one port — 18789 by default. Everything else connects to it.

What it owns

Channel connections. It maintains live sessions with every enabled platform: a WebSocket to Slack, a long poll to Telegram, a linked-device session for WhatsApp. When a channel drops, the Gateway reconnects it.

Access policy. Every inbound message is evaluated against dmPolicy, allowFrom, groupPolicy, and mention rules before anything downstream happens.

Session state. Which conversations exist, what history they hold, when they expire.

Tool policy. Which tools exist, which are permitted, which require approval, which run sandboxed. Critically, this is enforced at the Gateway — not by asking the model to behave. A model that has been talked into wanting to run rm -rf still can’t, if exec is denied.

The scheduler. Cron jobs, the heartbeat, and inbound webhooks all originate here.

Configuration. It watches ~/.openclaw/openclaw.json and hot-reloads changes. Most edits apply without downtime; some restart just their own subsystem — a channel, cron, the heartbeat, the health monitor — rather than the whole process.

Where it listens

gateway.bind is one of the two or three most consequential settings in the entire config:

ValueReachable fromAuth required
loopback (default)The host onlyNo
lanYour local networkYes
tailnetYour Tailscale networkYes
customWhatever you specifyYes

Default is loopback, and that’s the correct default. The Control UI can read your config, inspect session transcripts, and change agent behaviour — it is an administrative surface, and it should not be casually reachable. When you do need remote access, a tailnet almost always beats a LAN bind, and both beat port forwarding. That’s covered in Remote Access and Day-2 Operations.


Sessions: The Concept That Causes the Most Confusion

A session is one continuous conversation with history. The question that matters — and that people get wrong — is: when do two messages belong to the same session?

Get this wrong in one direction and your agent forgets what you just told it. Get it wrong in the other and your colleague’s DM lands in a context window containing your private conversation.

session.dmScope controls the answer. The important value:

{
session: {
dmScope: "per-channel-peer"
}
}

per-channel-peer means each sender on each channel gets their own isolated session. Your Telegram DMs are one conversation, your Slack DMs are another, and a colleague messaging you is a third that shares nothing with either.

The alternative — everything funnelling into one shared main session — is convenient when you’re the only user, because you can start a thought on your phone and continue it on desktop. It becomes a real problem the moment a second person can message the bot.

Rule of thumb: the instant anyone other than you can send a DM, per-channel-peer stops being a preference and becomes a requirement. It’s part of the documented hardened baseline for exactly this reason.

Sessions also expire. A conversation that’s been quiet for a long time gets retired, so context doesn’t grow without bound. Cron sessions have their own retention (cron.sessionRetention, e.g. "24h") because scheduled runs would otherwise accumulate forever.

Sessions versus memory

This distinction matters and the words sound similar.

When your assistant remembers your daughter’s name three weeks later, that’s memory, not session. When it remembers what you asked forty seconds ago, that’s session. They’re separate mechanisms with separate failure modes — expanded on in Memory and Workspace.


Agents

An agent is a named bundle of: a model, a system prompt/persona, a workspace directory, a tool allowlist, and optionally its own sandbox and heartbeat settings.

Config follows a two-bucket pattern that’s worth understanding because it saves enormous repetition:

{
agents: {
defaults: {
model: { primary: "anthropic/claude-sonnet-4-6" },
workspace: "~/openclaw-workspace",
heartbeat: { every: "4h" }
},
entries: {
research: {
model: { primary: "anthropic/claude-sonnet-4-6" },
tools: { allow: ["read", "web_fetch", "web_search"], deny: ["exec", "write"] }
},
ops: {
tools: { allow: ["read", "exec"] },
sandbox: { mode: "all" }
}
}
}
}

agents.defaults sets the baseline; agents.entries overrides per agent. Root-level keys (gateway, channels, session, cron) are infrastructure and cross-agent; anything under agents is per-agent behaviour.

Why multiple agents is a security tool, not a feature

This is the part worth pausing on. Multiple agents are usually presented as a personalisation feature — a formal one for work, a casual one for home. That framing undersells them badly.

The real value is capability separation. In the config above, the research agent can read files and fetch web pages but cannot execute anything or write to disk. Which means: if a malicious webpage it fetches contains injected instructions, the worst outcome is a wrong answer. The instruction to run a command has nowhere to land, because the agent holding the poisoned context has no exec tool.

Meanwhile ops can execute — but you only ever route trusted input to it.

That is a genuine architectural boundary, enforced by the Gateway, not a hopeful sentence in a system prompt. Put the tools where the untrusted content isn’t. If you take one design idea from this page, take that one.


Channels

Channels normalise messaging platforms into one internal format. Beyond that, they carry per-platform policy — who may DM, which groups are permitted, when a mention is required.

Group chats deserve a specific note, because it’s where noisy failures happen. requireMention defaults to on: in a group, the agent stays quiet unless addressed. Without it, you have a bot responding to every message in a busy channel, burning tokens and goodwill simultaneously.

Mentions are also inferred, not just literal. implicitMentions treats replying to the bot’s message, quoting it, or being in an active thread with it as addressing it — because that’s how humans actually converse, and requiring @bot on every line reads as robotic.

Some channels also support multiple accounts under one config, letting you run, say, a personal Telegram bot and a separate alerting bot from a single Gateway. Full detail in Slack, Discord and Teams.


Tools

Tools are the agent’s hands: shell execution, file read/write, HTTP fetch, browser control, search, plus anything you add via MCP servers or plugins.

Three layers of control apply, in this order:

  1. Availability — is the tool loaded at all?
  2. Policytools.allow / tools.deny, and profiles like messaging that pre-select a narrow safe set. Tools can be denied individually or by group (group:fs, group:runtime, group:automation).
  3. Approvaltools.exec.ask: "always" means execution requests pause and wait for your explicit go-ahead.

The layering exists because the threat isn’t “the model is malicious.” It’s “the model is helpful, and someone else got instructions into its context.” A tool that isn’t loaded cannot be talked into running. See Tools and MCP.


Nodes and Companion Apps

Nodes are device-local extensions — a phone or a second computer that pairs with your Gateway and offers capabilities that machine uniquely has: microphone, camera, screen capture, a Canvas surface, device actions.

The pattern is: Gateway stays central, nodes attach at the edges. Your always-on Linux server can’t hear you; your phone can. Pair the phone as a node and voice becomes available without relocating the Gateway.

For most first setups you won’t need nodes at all. They matter when you want voice interaction or device-specific abilities.


The Scheduler

Three ways for things to happen without you typing:

Cron — jobs on a schedule. Each run is an agent turn, with its own session subject to cron.sessionRetention.

Heartbeat — a periodic wake-up where the agent gets a turn to think and act on its own initiative. This is what makes the assistant proactive rather than reactive, and it is also the single largest driver of ongoing cost. agents.defaults.heartbeat.every is a setting worth being conservative with.

Webhooks — an HTTP endpoint (hooks.path, protected by hooks.token) that lets external systems trigger the agent. CI finishes, monitoring fires, a form gets submitted — the agent wakes and handles it.

Detail in Cron, Heartbeat and Webhooks.


Putting It Together: Debugging With the Model

The payoff for all this is diagnostic speed. When something misbehaves, walk the pipeline in order and the answer usually falls out within one or two steps.

SymptomLayerFirst thing to check
No response at all to a DM② Access policyPending pairing request? allowFrom correct?
Silent in a group, fine in DM③ Mention gatingrequireMention — were you actually addressing it?
Forgets what you just said④ SessionsdmScope splitting one conversation across sessions
Mixes up two people’s context④ SessionsShared main session — switch to per-channel-peer
”I can’t do that” for a real tool⑦ Tool policytools.deny, or a restrictive profile
Nothing happens on scheduleSchedulerIs the daemon actually running? openclaw gateway status
Works in terminal, not from phone① Channel / GatewayChannel disconnected, or bind/auth issue

Two commands to reach for before anything else:

Terminal window
openclaw gateway status
Terminal window
openclaw doctor --fix

And the Control UI’s live session view shows messages arriving and tool calls firing in real time — which frequently makes the problem obvious in seconds rather than minutes of log archaeology.


Where to Go Next

You now have the mental model: Gateway decides, agent thinks, tools act, channels carry. Access control happens before inference; tool policy is enforced outside the model; sessions determine who shares context with whom.

Next: Understanding openclaw.json maps every concept here onto the actual config keys, section by section — including a hardened starting configuration you can copy.