OpenClaw Integration Guide

Technology: openclaw · Category: ai · Last reviewed: 2026-08-23

Source: https://tech-stack.codeamanilabs.org/guide/openclaw

Insight:

OpenClaw is a self-hosted agent gateway, not an SDK — one long-lived daemon on your own box that fronts 30+ messaging channels, 50+ model providers, and a file-based skill system, all driven by the openclaw CLI. The trade-off is ownership for ops: you get a WhatsApp/Telegram-native agent with no per-seat SaaS bill, but you run the daemon, hold the keys, and inherit the blast radius of an agent that can exec. For codeAmani it is the fastest way to put a Claude-backed brain behind a WhatsApp number — ideal for internal ops and prototyping the Kenya builds, with the Meta Cloud API still the answer for customer-facing production traffic.

 ██████╗ ██████╗ ███████╗███╗   ██╗ ██████╗██╗      █████╗ ██╗    ██╗
██╔═══██╗██╔══██╗██╔════╝████╗  ██║██╔════╝██║     ██╔══██╗██║    ██║
██║   ██║██████╔╝█████╗  ██╔██╗ ██║██║     ██║     ███████║██║ █╗ ██║
██║   ██║██╔═══╝ ██╔══╝  ██║╚██╗██║██║     ██║     ██╔══██║██║███╗██║
╚██████╔╝██║     ███████╗██║ ╚████║╚██████╗███████╗██║  ██║╚███╔███╔╝
 ╚═════╝ ╚═╝     ╚══════╝╚═╝  ╚═══╝ ╚═════╝╚══════╝╚═╝  ╚═╝ ╚══╝╚══╝

OpenClaw Integration Guide

Focus: Running a self-hosted OpenClaw Gateway as a personal/ops AI agent that lives inside WhatsApp, Telegram, Slack and friends — install, config, agents, skills, MCP, and how to harden it before it leaves loopback.

Overview

OpenClaw (MIT, github.com/openclaw/openclaw, developed in the open by the non-profit OpenClaw Foundation — openclaw.org) is "a personal AI assistant that runs on your devices and meets you in the channels you already use." It is not a library you import — there is no import { OpenClaw }. It is a daemon plus a CLI: you install the openclaw npm package globally, run an onboarding wizard, and end up with a long-lived Gateway process on 127.0.0.1:18789 that owns your messaging connections, your model providers, your agent sessions, and your tool policy.

The design point that makes it different from an agent framework: the messaging platform is the UI. There is no app to build. You DM a WhatsApp or Telegram number, the Gateway routes that message to an agent, the agent runs tools in a workspace directory on your machine, and the reply comes back down the same channel. A browser Control UI (openclaw dashboard) exists for administration, not as the primary surface.

OpenClaw Agent SDK / framework Managed bot platform
Shape Daemon + CLI you self-host Library you compile into an app Hosted SaaS
UI Existing messaging apps You build it Vendor's console
Model Bring your own key, 50+ providers Whatever you wire Vendor's models
Secrets Your disk (~/.openclaw/) Your env Vendor holds them
Ops burden Yours (process, updates, auth) Yours (deploy) None
Multi-tenant No — single-operator by design Yes, if you build it Yes
flowchart LR
  subgraph CH["Channels"]
    W["WhatsApp"]
    T["Telegram"]
    S["Slack / Discord / Signal"]
  end
  subgraph HOST["Your host — one Gateway daemon"]
    G["Gateway<br/>127.0.0.1:18789<br/>WebSocket + HTTP"]
    A["Agents<br/>agents.entries.*<br/>workspace + skills"]
    TP["Tool policy<br/>tools.allow / tools.deny"]
  end
  subgraph CP["Control plane"]
    C["openclaw CLI"]
    U["Control UI<br/>openclaw dashboard"]
    N["Nodes<br/>macOS / iOS / Android"]
  end
  P["Model providers<br/>anthropic/ · openai/ · ollama/"]
  M["MCP servers<br/>stdio · HTTP · SSE"]

  W --> G
  T --> G
  S --> G
  C --> G
  U --> G
  N --> G
  G --> A
  A --> TP
  TP --> M
  A --> P

Official Documentation

Resource URL
Getting started https://docs.openclaw.ai/start/getting-started
Install (all methods) https://docs.openclaw.ai/install
Architecture (Gateway, nodes, frames) https://docs.openclaw.ai/concepts/architecture
Gateway config & security https://docs.openclaw.ai/gateway
Agent config (agents.*, bindings) https://docs.openclaw.ai/gateway/config-agents
Channels index https://docs.openclaw.ai/channels
WhatsApp channel https://docs.openclaw.ai/channels/whatsapp
Model providers (50+) https://docs.openclaw.ai/providers
Anthropic provider https://docs.openclaw.ai/providers/anthropic
Skills (SKILL.md) https://docs.openclaw.ai/tools/skills
Tools & tool policy https://docs.openclaw.ai/tools
MCP servers https://docs.openclaw.ai/tools/mcp
CLI reference https://docs.openclaw.ai/cli
ClawHub (plugin/skill registry) https://clawhub.ai
Repository https://github.com/openclaw/openclaw

Install

Requirements: Node 22.22.3+, 24.15+, or 25.9+ (Node 26 recommended), plus an API key from at least one model provider.

The one-liner installers handle Node and the daemon for you:

# macOS / Linux / WSL2
curl -fsSL --proto '=https' --tlsv1.2 https://openclaw.ai/install.sh | bash
# Windows (PowerShell)
iwr -useb https://openclaw.ai/install.ps1 | iex

If you manage Node yourself, install the npm package globally. npm 12+ blocks unapproved lifecycle scripts, so the --allow-scripts flag is required (this is the exact form the docs ship):

npm install -g openclaw@latest --allow-scripts openclaw
openclaw onboard --install-daemon
# pnpm
pnpm add -g --allow-build=openclaw openclaw@latest && openclaw onboard --install-daemon

# bun
bun add -g --trust openclaw@latest && openclaw onboard --install-daemon

Verify:

openclaw --version
openclaw doctor           # config + environment diagnostics
openclaw gateway status   # should report listening on 18789
openclaw dashboard        # opens the Control UI in a browser

Releases are date-versioned (2026.7.1-2 style) and ship on four dist-tags: latest, extended-stable, beta, alpha. Pin extended-stable on anything you don't want moving under you.


Configuration

State lives in $HOME/.openclaw/; the config file is JSON5 (comments and trailing commas allowed) and is normally ~/.openclaw/openclaw.json. Override the path with OPENCLAW_CONFIG_PATH (keep it a real file — OpenClaw rewrites config atomically, so a symlinked openclaw.json gets its target replaced). You can edit it directly: the Gateway watches the file and hot-reloads changes, and it refuses to start on a config that fails validation. Still, prefer the CLI so a typo is caught up front rather than at reload:

openclaw config file            # print the resolved config path
openclaw config get agents.defaults.model
openclaw config set agents.defaults.model.primary "anthropic/claude-opus-5"
openclaw config validate
openclaw config schema          # full JSON Schema

Model providers

Models are addressed as "provider/model". Provider credentials live under env.vars in the config (or in the process environment):

{
  env: {
    vars: {
      ANTHROPIC_API_KEY: "sk-ant-...", // resolved from your secret manager, not committed
    },
  },
  agents: {
    defaults: {
      model: {
        primary: "anthropic/claude-opus-5",
        fallbacks: ["anthropic/claude-sonnet-5"],
      },
      utilityModel: "anthropic/claude-fable-5", // cheap model for routing/summarisation
      thinkingDefault: "low",
    },
  },
}
openclaw onboard --anthropic-api-key "$ANTHROPIC_API_KEY"
openclaw models list --provider anthropic

The "provider/model" shape and the Claude ids used here are verified against docs/providers/anthropic.md in the tree, which documents anthropic/claude-opus-5, anthropic/claude-sonnet-5, anthropic/claude-fable-5, anthropic/claude-mythos-5, and dated builds such as anthropic/claude-opus-4-8. (Anthropic can also be driven through an existing Claude Code CLI login on the same host instead of an API key; for a long-lived Gateway, prefer a dedicated ANTHROPIC_API_KEY.)

OpenClaw's provider directory covers 50+ backends — Anthropic, OpenAI, Google, Mistral, Cohere, Bedrock, Groq, Together AI, DeepSeek, Perplexity, plus local runtimes (Ollama, LM Studio, vLLM, llama.cpp, SGLang). Per codeAmani's AI routing policy, keep primary on Anthropic Claude and reserve cheaper tiers for utilityModel.

Agents

Agents are config objects, not code. agents.defaults sets the inherited baseline; agents.entries.<id> overrides per agent; bindings route channels to agents.

{
  agents: {
    ownership: "explicit", // required once you run more than one agent
    defaults: {
      workspace: "~/.openclaw/workspace",
      model: { primary: "anthropic/claude-opus-5" },
      skills: ["duka-inventory"],
      heartbeat: { every: "30m" },
    },
    entries: {
      ops: {
        name: "Ops Agent",
        workspace: "~/.openclaw/workspace-ops",
        model: "anthropic/claude-opus-5",
        identity: { name: "Amani", emoji: "🕊️" },
      },
      support: {
        workspace: "~/.openclaw/workspace-support",
        model: { primary: "anthropic/claude-sonnet-5", fallbacks: [] },
        skills: ["docs-search"],
      },
    },
  },
  bindings: [
    { agentId: "ops", match: { channel: "whatsapp", accountId: "internal" } },
    { agentId: "support", match: { channel: "telegram" } },
  ],
}

Binding resolution is deterministic and narrows outward: peer → guild/team → account → channel-wide fallback. With ownership: "explicit" there is no default agent — an unbound channel simply has nowhere to route.

openclaw agents list
openclaw agents add
openclaw agents bind          # attach an agent to a channel/account

Channels

Telegram, Reef, and WebChat are bundled. Everything else — WhatsApp, Slack, Discord, Signal, iMessage, Matrix, Microsoft Teams, Google Chat, LINE, SMS, IRC, Twitch and more — is an official plugin installed on demand.

openclaw plugins install clawhub:@openclaw/whatsapp
openclaw channels add --channel whatsapp     # interactive; installs the plugin if missing
openclaw channels login --channel whatsapp   # QR pairing
openclaw channels list

WhatsApp

Set the access policy before you log in, or the first stranger to message the number becomes a conversation:

{
  channels: {
    whatsapp: {
      dmPolicy: "pairing",              // unknown senders need owner approval
      allowFrom: ["+254712345678"],
      groupPolicy: "allowlist",
      groupAllowFrom: ["+254712345678"],
      textChunkLimit: 4000,             // default; lower it for 2G/3G users
      sendReadReceipts: true,
      replyToMode: "first",             // off | first | all | batched
    },
  },
}
dmPolicy Effect
pairing Unknown senders raise an approval request (expires after 1h, max 3 pending)
allowlist Only numbers in allowFrom get through
open Everyone — requires an explicit allowFrom: ["*"]
disabled No DMs at all

Approve a pending pairing from the Control UI (Settings → Channels → DM access requests) or the CLI:

openclaw pairing approve whatsapp <CODE>

Session credentials land in ~/.openclaw/credentials/whatsapp/<accountId>/creds.json — treat that directory as a secret. Multi-account setups live under channels.whatsapp.accounts.<id>, which is how one Gateway serves a personal and a business number with different agents bound to each.

Read this before shipping (settled against the source): the WhatsApp channel links a WhatsApp account via QR pairing over WhatsApp Web, not the Meta WhatsApp Business Cloud API and not Twilio. This is not inference — extensions/whatsapp depends on baileys (the WhatsApp-Web multi-device library), its login path is QR-only (login-qr-*, onQr), and the docs state it plainly: "production-ready via WhatsApp Web (Baileys). The gateway owns the linked session(s); there is no separate Twilio WhatsApp channel." Perfect for an internal ops number or a prototype; the wrong tool for customer-facing volume on a business number — see codeAmani notes.


Skills

Skills are the extension unit for agent behaviour, and they are just files: a directory containing a SKILL.md with YAML frontmatter plus a markdown body, following the AgentSkills spec.

---
name: mpesa-reconcile
description: Reconcile M-Pesa C2B callbacks against open orders and flag mismatches.
---

# M-Pesa reconciliation

When asked to reconcile payments:
1. Read `orders.csv` from the workspace.
2. Match on `CheckoutRequestID`, never on amount alone.
3. Report unmatched rows as a table; never auto-refund.

Discovery walks up to 6 levels deep inside configured roots, and the name in frontmatter wins over the directory name. When the same name appears twice, the highest-priority source wins:

Priority Source
1 Workspace skills — <workspace>/skills
2 Project agent skills — <workspace>/.agents/skills
3 Personal agent skills — ~/.agents/skills
4 Managed/local skills — <state-dir>/skills
5 Bundled skills (shipped with OpenClaw)
6 Extra directories + plugin skills
openclaw skills install @owner/slug              # from ClawHub
openclaw skills install git:owner/repo@ref       # from a git ref
openclaw skills install ./path/to/skill --as mpesa-reconcile
openclaw skills install @owner/slug --global     # visible to every agent
openclaw skills verify @owner/slug               # trust check before install
openclaw skills update --all

At run time OpenClaw resolves eligible skills against gating rules and allowlists, injects skills.entries.<name>.env variables, and compiles a snapshot into the system prompt as XML. Skills surface as slash commands (/mpesa-reconcile) and as $mpesa-reconcile references inside a prompt; set disable-model-invocation: true in frontmatter to make a skill user-only.


Tools and tool policy

Agents get a broad built-in toolset — exec, process, terminal, code_execution; read/write/edit/apply_patch; web_search, x_search, web_fetch, browser; view_image, image_generate, tts; sessions_*, subagents, agents_wait, goal; cron and heartbeat_respond for background work; ask_user, message, screen.

Policy is enforced before the model call — a denied tool's schema is never sent for that turn, so the model cannot even attempt it:

{
  agents: {
    entries: {
      support: {
        tools: {
          deny: ["exec", "terminal", "process", "code_execution"],
        },
      },
    },
  },
}

That deny-list is the single most important config line for any agent reachable from a public channel.

MCP servers

MCP servers plug in as first-class tool sources under mcp.servers, over stdio, streamable HTTP, or SSE:

openclaw mcp add
openclaw mcp login <name>            # OAuth for protected servers
openclaw mcp doctor <name> --probe   # reachability + capability probe
openclaw mcp status --verbose

Their tools flow through the same tool-profile and policy controls, and can be narrowed with toolFilter.include / toolFilter.exclude.


Gateway operations & security

One Gateway per host, one multiplexed port for WebSocket control, HTTP APIs, and the Control UI (the node/device bridge listens separately on 18790, and channel plugins that need an inbound webhook — e.g. MS Teams on 3978 — open their own).

openclaw gateway start
openclaw gateway status
openclaw gateway restart
openclaw logs
openclaw health

Port resolves --port → OPENCLAW_GATEWAY_PORT → gateway.port → 18789. Bind resolves CLI override → gateway.bind → loopback (containers default to auto, i.e. 0.0.0.0, unless Tailscale serve/funnel is active, which forces loopback).

Authentication is mandatory by default, and OpenClaw refuses to bind a non-loopback interface without it:

{
  gateway: {
    bind: "loopback",
    auth: { token: "..." },            // or auth.password
    controlUi: {
      allowedOrigins: ["https://claw.internal.example"], // required for remote browsers
    },
  },
}

Equivalent env vars: OPENCLAW_GATEWAY_TOKEN, OPENCLAW_GATEWAY_PASSWORD. For a reverse proxy that terminates auth itself, set gateway.auth.mode: "trusted-proxy".

For remote access the docs push Tailscale/VPN first, SSH tunnel second — and an SSH tunnel does not bypass gateway auth; clients still send the token:

ssh -N -L 18789:127.0.0.1:18789 user@gateway-host

Control-plane clients (CLI, Control UI, macOS app, automation) and nodes (macOS/iOS/Android/headless devices exposing camera.*, screen.record, location.get) all speak the same typed WebSocket protocol: a mandatory connect handshake, then {type:"req", id, method, params} → {type:"res", id, ok, payload|error} with events pushed as {type:"event", event, payload, seq?, stateVersion?}. Side-effecting methods (send, agent) accept idempotency keys — use them, because a reconnect that replays a send is a duplicate WhatsApp message to a customer.


Environment Variables

# Model provider (codeAmani primary — see AI routing policy)
ANTHROPIC_API_KEY=sk-ant-...

# Gateway auth — required for any non-loopback bind
OPENCLAW_GATEWAY_TOKEN=...
# or
OPENCLAW_GATEWAY_PASSWORD=...

# Optional
OPENCLAW_GATEWAY_PORT=18789
OPENCLAW_CONFIG_PATH=/etc/openclaw/openclaw.json
OPENCLAW_SERVICE_REPAIR_POLICY=...   # hand lifecycle to an external supervisor

Repository layout (grounding)

If you clone openclaw/openclaw to read the source, the monorepo is pnpm-workspace'd (packages: [., ui, packages/*, extensions/*, examples/*]) and the names in the docs don't map 1:1 to folders:

In the tree Is Note
extensions/ (~157 pkgs) Channels + model providers + tools What the docs and CLI call "plugins." Per the repo's own AGENTS.md: "Product/docs/UI/changelog wording: 'plugin/plugins'; extensions/ is internal." WhatsApp is extensions/whatsapp (pkg @openclaw/whatsapp), Anthropic is extensions/anthropic.
apps/ Companion clients android, ios, macos, linux, shared — the "nodes" that expose camera.*/screen.*/location.*.
config/ Repo tooling config lint/tsconfig/budgets — not runtime Gateway config (that lives at ~/.openclaw/openclaw.json).
deploy/ Deploy fragments just fly.private.toml; root also ships Dockerfile, docker-compose.yml, fly.toml, render.yaml.
docs/ The published docs Same paths as docs.openclaw.ai (e.g. docs/channels/whatsapp.md → /channels/whatsapp).
AGENTS.md Contributor policy CLAUDE.md is a symlink to it — edit AGENTS.md only.

The shipped docker-compose.yml starts the Gateway with --bind ${OPENCLAW_GATEWAY_BIND:-lan} and publishes 18789 (Gateway), 18790 (node/device bridge) and 3978 (MS Teams); it pins OPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATH/OPENCLAW_WORKSPACE_DIR under /home/node/.openclaw and expects OPENCLAW_GATEWAY_TOKEN — a containerised deploy is non-loopback by construction, so the token is mandatory.


codeAmani notes


Troubleshooting

Issue Fix
npm install -g openclaw skips setup / CLI missing npm 12+ blocks lifecycle scripts — reinstall with --allow-scripts openclaw (pnpm: --allow-build=openclaw, bun: --trust)
Refuses to start: "refusing to bind gateway … without auth" Non-loopback bind requires gateway.auth.token/.password or OPENCLAW_GATEWAY_TOKEN
Control UI blocked in a remote browser Add the origin to gateway.controlUi.allowedOrigins
Tunnel works but requests are rejected SSH tunnels do not bypass gateway auth — the client must still send the token
WhatsApp QR expires on a headless box Get the QR to your phone fast, or run openclaw channels login from a machine with a display and copy the credentials dir
Bot ignores an incoming DM dmPolicy: "pairing" is waiting on approval — openclaw pairing approve whatsapp <CODE> (expires after 1h, max 3 pending)
Messages arrive but no agent replies With agents.ownership: "explicit" there is no default agent — add a bindings entry for that channel/account
Skill installed but never used Check the name in SKILL.md frontmatter (it overrides the directory), the source precedence table, and whether disable-model-invocation: true is set
MCP tools missing from the agent openclaw mcp doctor <name> --probe, then check toolFilter.include/exclude and tools.allow/deny
Duplicate outbound messages after a reconnect Send send/agent requests with idempotency keys
Node version errors on install Needs Node 22.22.3+, 24.15+, or 25.9+ (26 recommended)

Official docs: