OpenClaw Masterclass: Self-Hosting, Omnichannel Setup & Autonomous Tool Loops
What You Will Master in This Tutorial
- Deploy OpenClaw locally on macOS, Linux, and Windows using native CLI daemons.
- Integrate omnichannel bot gateways for Telegram, Discord, and Slack.
- Configure Docker and process sandboxes to isolate autonomous shell execution.
- Mount external tools and APIs via Model Context Protocol (MCP) servers.
1. What is OpenClaw and Why is it Dominating 2026?
OpenClaw is an open-source personal autonomous agent framework that crossed 389k GitHub stars. Unlike cloud-locked assistants, OpenClaw runs directly on developer hardware, maintaining continuous background daemons that interact across messaging platforms and execute system-level operations.
# Global installation and daemon init
npm install -g openclaw@latest
# Configure local LLM backend (DeepSeek R1 via Ollama)
openclaw config set provider.type "ollama"
openclaw config set provider.model "deepseek-r1:14b"
openclaw config set provider.baseUrl "http://localhost:11434"
# Start the OpenClaw system daemon
openclaw daemon start
2. Omnichannel Bot Gateways: Telegram & Discord
OpenClaw provides drop-in connectors for messaging protocols. By connecting your personal bot token, you can message your development workstation from your phone to trigger deployments, run code tests, or summarize production logs.
# Link Telegram Bot
openclaw channel add telegram \
--token "$TELEGRAM_BOT_TOKEN" \
--allowed-users "123456789"
# Test agent response via command line
openclaw exec "Clone repo https://github.com/myorg/api and run pytest in Docker sandbox"
3. Tool Execution & Docker Sandboxing
Autonomous agents must never run arbitrary code directly on your host machine without safeguards. OpenClaw routes all bash commands, git mutations, and browser automations through ephemeral Docker containers.
# openclaw.config.json (Sandbox Definition)
{
"sandbox": {
"type": "docker",
"image": "python:3.12-slim-bookworm",
"cpuLimit": 2.0,
"memoryLimit": "4GB",
"network": "bridge",
"volumes": [
"/workspace:/app:rw"
]
},
"tools": [
"bash_exec",
"fs_read",
"fs_write",
"mcp_brave_search"
]
}
Knowledge Check: Test Your Understanding
4. Step by step: schedule a daily briefing agent
You have a running daemon (section 1), a Telegram gateway (section 2), and a Docker sandbox (section 3). The natural capstone is a job the agent runs without you: a morning briefing, researched in the sandbox and delivered to your phone. You will assemble it from the same commands this guide already taught — no new machinery.
Step 1: scope the job’s tools in the config
The briefing needs web search and file writes for its notes, but not the run of your filesystem. Tighten the sandbox definition from section 3 into a job-specific allowlist — the tools array is the agent’s permissions, and a scheduled job should hold the fewest you can give it:
# openclaw.config.json (briefing job profile)
{
"sandbox": {
"type": "docker",
"image": "python:3.12-slim-bookworm",
"cpuLimit": 2.0,
"memoryLimit": "4GB",
"network": "bridge",
"volumes": [ "/workspace/briefings:/app:rw" ]
},
"tools": [ "bash_exec", "fs_read", "fs_write", "mcp_brave_search" ]
}
Step 2: test the briefing prompt interactively
Never schedule a prompt you have not watched succeed once. Run it through openclaw exec exactly as the cron job will, and read the output critically — this is the same exec path section 2 used to test the Telegram gateway:
# Sanity check: the agent reports its sandbox and tool list
openclaw exec "Reply with the sandbox image you are running in and the tools you can use"
# The briefing task itself
openclaw exec "Search the web for the five most important AI developer-tool releases of the last 24 hours. For each: name, what changed, and the source link. Save the briefing as briefing.md in /app and print it."
Step 3: put it on the host scheduler
OpenClaw’s daemon is always on, but the trigger can be the scheduler your operating system already has. A crontab line that calls openclaw exec at 07:00 keeps the setup honest — one command, logged to a file you can audit:
# crontab -e -> run the briefing every day at 07:00
0 7 * * * openclaw exec "Run the morning briefing task and save it as briefing.md in /app" >> ~/openclaw-briefing.log 2>&1
5. A complete worked example
At 07:00 the cron line fires. The daemon hands the task to the agent, which plans two tool calls: mcp_brave_search for the last day’s releases, then fs_write to save briefing.md inside the sandbox, where the volume mount makes it appear in /workspace/briefings on the host. Because you linked Telegram in section 2 with your chat ID in --allowed-users, the same agent can deliver the result to your phone — message the bot "send me today’s briefing" and it reads the file back with fs_read and replies in the channel. The pieces compose because each layer does one job: cron triggers, the daemon reasons, the sandbox executes, the gateway delivers. By 07:05 you are reading five sourced release notes with your coffee, and the log file holds a complete audit trail of what ran.
The artifact: what briefing.md actually contains
Because the job saves a file instead of only chatting, every run leaves an inspectable artifact in /workspace/briefings on the host. This is the shape the exec prompt from step 2 produces — five items, each with its source, in a format you can scan in under a minute:
# Morning briefing - AI developer tools (last 24 hours)
1. [Tool name] - [what changed, one line] - [source link]
2. [Tool name] - [what changed, one line] - [source link]
3. [Tool name] - [what changed, one line] - [source link]
4. [Tool name] - [what changed, one line] - [source link]
5. [Tool name] - [what changed, one line] - [source link]
Generated by the OpenClaw briefing job; sources via mcp_brave_search.
Keep the format boring on purpose. A stable artifact shape is what lets you diff Monday against Tuesday, pipe the file into other tools, or have the same agent read yesterday’s briefing back over Telegram — the composability that makes a scheduled agent more useful than a scheduled script.
Check the run afterwards
A scheduled agent earns trust the same way a cron job does: by being auditable the morning after. Two commands tell you whether the 07:00 run happened, what it did, and whether the artifact exists — check these before changing any configuration:
# The audit trail the crontab line appends to on every run
tail -n 50 ~/openclaw-briefing.log
# The artifact itself, on the host side of the sandbox volume mount
ls -la /workspace/briefings/
If the log shows the run and the file is fresh, the system worked and any problem lives in the content, not the machinery. If the log is empty, the trigger never fired; if the log is full but the file is missing, the sandbox volume mount is where to look — that ordering saves an hour of debugging the wrong layer.
6. Troubleshooting
- The agent answers in the CLI but never on Telegram. The gateway is rejecting your messages: the chat ID in --allowed-users does not match the account you are messaging from, or the channel was added before the token changed. Re-run the channel add command from section 2 with the current BotFather token, then test with openclaw exec before blaming the model.
- openclaw exec hangs and eventually times out. The reasoning backend is unreachable. Section 1 pointed the provider at Ollama on http://localhost:11434 — if Ollama is not running, nothing downstream can work. Start Ollama, confirm the model name matches what openclaw config set provider.model recorded, and retry the sanity-check exec.
- Tools fail with network errors inside the sandbox. The sandbox definition controls this: "network": "bridge" (section 3) gives the container outbound access, while "none" isolates it completely. A config copied from a security example often ships with networking off — check the value before debugging the search tool.
- The agent says a tool is unavailable. The tool is not in the tools array of openclaw.config.json. The array is an allowlist, not a catalog: bash_exec, fs_read, fs_write, and mcp_brave_search exist for the agent only because section 3 declared them. Add the missing name, restart the daemon, and re-run the sanity check.