Running a local AI assistant that responds to your WhatsApp messages — using models that run entirely on your own machine, with no cloud API costs — sounds complex. It’s not, but there are enough sharp edges to make the first setup painful if you don’t know what to expect.
This is a full account of how I set this up on Ubuntu, every error I encountered, and exactly how to fix each one.
What Are These Tools?
Ollama is a runtime for running large language models (LLMs) locally. It manages model downloads, serves a local REST API on http://localhost:11434, and handles GPU/CPU inference. Think of it as Docker for LLMs.
OpenClaw is a multi-channel AI gateway. It connects your local LLM (via Ollama) to communication channels like WhatsApp, runs agents, handles scheduling, and exposes a local control dashboard. You message it on WhatsApp, it thinks using your local model, and replies — all without any data leaving your machine.
Prerequisites
- Ubuntu 22.04+ (this guide uses Ubuntu with kernel 6.x)
- Node.js 20+ (
node --version) - npm with a global prefix configured (
npm config get prefix) - At least 8 GB RAM (16 GB+ recommended for 8B models)
- No GPU required — both tools run fine on CPU
Step 1 — Install Ollama
Ollama provides a one-line install script:
curl -fsSL https://ollama.com/install.sh | sh
This installs the ollama binary to /usr/local/bin, creates a systemd service, and starts it automatically.
Verify it is running:
systemctl status ollama
ollama --version
The service listens on 127.0.0.1:11434 by default. Test it:
curl http://localhost:11434/api/version
You should see {"version":"0.x.x"}.
Pull Your First Model
ollama pull qwen3:8b
qwen3:8b is 5.2 GB and is currently the best model for this stack on CPU — it supports tool calling (required by OpenClaw) and has a 40k token context window. More on model selection below.
List installed models:
ollama list
Step 2 — Install OpenClaw
OpenClaw is distributed as an npm package:
npm install -g openclaw
If npm complains about permissions, make sure your global prefix is set to a user-writable directory:
npm config set prefix ~/.npm-global
export PATH="$HOME/.npm-global/bin:$PATH"
Add that PATH export to your ~/.bashrc so it persists.
Verify the install:
openclaw --version
Step 3 — Run Onboarding
OpenClaw has an interactive setup wizard:
openclaw onboard
This walks you through:
- Gateway mode — choose
localfor a personal machine - Model provider — select Ollama, point it to
http://127.0.0.1:11434/v1 - Model selection — pick
qwen3:8b - Channel setup — WhatsApp, Telegram, Discord, etc.
- Gateway install — installs a systemd user service
At the end of onboarding, OpenClaw installs a systemd user service and starts the gateway.
Step 4 — Link WhatsApp
During onboarding (or afterwards with openclaw channels login), you will see a QR code in the terminal. Scan it from WhatsApp on your phone:
WhatsApp → Settings → Linked Devices → Link a Device
Once linked, the channel status will show:
WhatsApp │ ON │ OK │ linked · +91XXXXXXXXXX
Your WhatsApp number is now connected to your local AI agent.
Step 5 — Install the Gateway as a Service
openclaw gateway install
systemctl --user enable openclaw-gateway.service
systemctl --user start openclaw-gateway.service
The gateway runs on ws://127.0.0.1:18789 and the control dashboard at http://127.0.0.1:18789/.
Check status:
openclaw status
Headaches I Hit — and How to Fix Them
1. Wrong service name on systemctl restart
Error:
Failed to start openclaw.service: Unit openclaw.service not found.
Why it happens: The actual systemd unit is named openclaw-gateway.service, not openclaw.service.
Fix:
systemctl --user restart openclaw-gateway.service
To find the correct service name at any time:
systemctl --user list-units | grep claw
2. Gateway shows “unreachable” after updating OpenClaw
Symptom: openclaw status shows the gateway as unreachable (timeout) but systemctl status openclaw-gateway.service shows it as active and running.
Why it happens: When you update OpenClaw with npm update -g openclaw, the new binary is on disk but the old version is still running in memory. The service file also still references the old version number.
Fix: Reinstall the service file with the new version, then restart:
openclaw gateway install --force
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service
3. Model context window too small
Error in logs:
⚠️ Agent failed before reply: Model context window too small (8192 tokens). Minimum is 16000.
Why it happens: Some models have small context windows. gemma2:2b has only 8192 tokens — below OpenClaw’s minimum of 16,000.
Affected models:
gemma2:2b— 8192 tokens (too small)
Models that work:
qwen3:8b— 40,960 tokens ✓deepseek-r1:1.5b— 131,072 tokens ✓ (but see issue #4)
Fix: Switch to a model with sufficient context:
openclaw config set agents.defaults.model.primary ollama/qwen3:8b
systemctl --user restart openclaw-gateway.service
4. Model does not support tools
Error:
Ollama API error 400: {"error":"registry.ollama.ai/library/deepseek-r1:1.5b does not support tools"}
Why it happens: OpenClaw uses tool calling (function calling) so the agent can take actions. Not all models support this. deepseek-r1:1.5b and gemma2:2b do not support tool calling.
Check if a model supports tools:
curl -s http://localhost:11434/api/show -d '{"name":"qwen3:8b"}' | grep -i tools
If the template contains <tools> XML tags, it supports tool calling.
Models tested:
| Model | Tool Support | Context | Notes |
|---|---|---|---|
qwen3:8b | ✓ Yes | 40k | Best overall choice |
gemma2:2b | ✗ No | 8k | Too small, no tools |
deepseek-r1:1.5b | ✗ No | 131k | Great context, no tools |
qwen2.5-coder:32b | ✓ Yes | Large | Heavy, needs strong hardware |
Fix: Use qwen3:8b.
5. Credentials directory has wrong permissions
Shown in security audit:
CRITICAL Credentials dir is writable by others
/home/neel/.openclaw/credentials mode=775
Fix: chmod 700 /home/neel/.openclaw/credentials
Fix:
chmod 700 ~/.openclaw/credentials
6. Security critical — small model without sandboxing
Shown in security audit:
CRITICAL Small models require sandboxing and web tools disabled
Why it happens: Small models are more susceptible to prompt injection. OpenClaw flags this when a small model is active with web browsing tools enabled.
Fix (without Docker): Disable web tools:
openclaw config set tools.deny '["group:web","browser"]'
systemctl --user restart openclaw-gateway.service
If you want full sandboxing (recommended for production), install Docker and set:
openclaw config set agents.defaults.sandbox.mode all
7. Gateway probe shows “missing scope: operator.read”
Symptom: openclaw status shows unreachable (missing scope: operator.read) even though the gateway is running fine and WhatsApp is connected.
Why it happens: This is a cosmetic issue in v2026.3.13. The openclaw status probe connects via WebSocket and uses the legacy shared token from gateway.auth.token. The new version expects scoped tokens for this connection. The gateway itself is fully functional — this only affects the CLI status probe display.
Workaround: Use openclaw gateway probe to verify actual connectivity:
openclaw gateway probe
This will confirm Reachable: yes and RPC: ok. The WhatsApp channel status in openclaw status is the reliable health indicator.
Choosing the Right Model
With no dedicated GPU, you are running inference on CPU. Here is a practical breakdown of the models and their suitability:
| Model | Size | Tool Support | Context | CPU Speed | Verdict |
|---|---|---|---|---|---|
qwen3:8b | 5.2 GB | ✓ | 40k | Moderate | Best choice |
gemma2:2b | 1.6 GB | ✗ | 8k | Fast | Unusable (no tools) |
deepseek-r1:1.5b | 1.1 GB | ✗ | 131k | Very fast | Unusable (no tools) |
qwen3:4b | ~2.6 GB | ✓ | 32k | Fast | Good lighter option |
opencoder:latest | 4.7 GB | ✗ | — | Moderate | Code only, no tools |
qwen2.5-coder:32b | 19 GB | ✓ | Large | Very slow | Impractical on CPU |
Recommendation: Use qwen3:8b for the best balance of quality, tool support, and context length on CPU. If responses are too slow, pull qwen3:4b — same architecture, half the size, still supports tools.
Basic Usage
Once the gateway is running and WhatsApp is linked, message your own number on WhatsApp. The agent will respond using your local model.
Check status at any time:
openclaw status
View live logs:
openclaw logs --follow
Open the control dashboard:
openclaw dashboard
# Opens http://127.0.0.1:18789/ in your browser
# Paste your gateway token when prompted
Send a test message directly:
openclaw agent --message "What is 2 + 2?" --deliver
Maintenance
Adding a New Model
Step 1 — Pull the model:
ollama pull qwen3:4b
Step 2 — Auto-detect it in OpenClaw:
openclaw models scan --provider ollama
Step 3 — Set as default (optional):
openclaw config set agents.defaults.model.primary ollama/qwen3:4b
Step 4 — Restart the gateway:
systemctl --user restart openclaw-gateway.service
Updating OpenClaw
npm update -g openclaw
openclaw gateway install --force
systemctl --user daemon-reload
systemctl --user restart openclaw-gateway.service
Always run gateway install --force after an update — this regenerates the systemd service file with the new version number.
Updating Ollama
curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl restart ollama
The install script handles updates in place.
Checking Health
# Full system status
openclaw status
# Gateway connectivity
openclaw gateway probe
# Security audit
openclaw security audit
# Doctor (checks config, sandbox, channels)
openclaw doctor
Restarting Everything
sudo systemctl restart ollama
systemctl --user restart openclaw-gateway.service
Keeping the Stack Secure
A few habits that matter:
- Keep credentials private. The
~/.openclaw/credentialsdirectory should always be700. - Use the allowlist. The
channels.whatsapp.allowFromsetting restricts who can message your agent. Keep it to your own number unless you have a specific reason to expand it. - Disable web tools with small models. If you switch to a smaller model, disable
group:webandbrowserto reduce prompt injection risk. - Update regularly. OpenClaw releases frequently. Run
openclaw statusand check the Update row.
Summary
| Component | Version | Status |
|---|---|---|
| Ollama | 0.17.5+ | systemd service, auto-start |
| OpenClaw | 2026.3.13+ | user systemd service, auto-start |
| Model | qwen3:8b | 40k context, tool support |
| Channel | linked, personal number | |
| Dashboard | http://127.0.0.1:18789/ | local only |
The whole stack runs offline, on your hardware, with no subscription. Responses are slower than cloud APIs on CPU — expect 5–30 seconds depending on message length and model — but everything stays private and costs nothing after the initial setup.