← Back to the blog

My OpenClaw setup

Series: How I built a second brain · part 2

I left the details of OpenClaw from my TechEd talk for the blog. Here they are. I go through my configuration piece by piece, and then four things I only learned about OpenClaw once it was running, because you won't find them in the documentation.

How OpenClaw is built

OpenClaw is an open-source runtime for AI agents. It has two parts, and the difference matters more than it seems:

  • The gateway is a long-running process. It holds the agents' sessions, the connections to the models and the channels you talk to the agents through. Mine runs as a systemd service on an NVIDIA DGX Spark workstation, around the clock.
  • The CLI (openclaw agent …) is only a client. It sends a task to the gateway and waits for the answer. The actual work runs in the gateway.

Everything else is one file: ~/.openclaw/openclaw.json.

Models: Ollama on the same machine, and Claude where I choose it

My configuration has two model providers. Ollama on the same machine, with seven registered local models (Gemma 4, several sizes of Qwen including qwen3-coder-next, and others), and models from Anthropic.

Two settings for the local models are worth copying:

  1. Set the context window explicitly (num_ctx on each model). Ollama's default context is small, and an agent that reads files uses it up fast. My models have 64,000 to 256,000 tokens.
  2. Be generous with timeouts. A local 35B model is not a cloud API: a single step can take minutes. I give the model 10 minutes to respond and the agent 29 minutes for a whole "turn".

But the default model for all agents is Claude Opus, run through the claude-cli runtime with a high thinking level. An agent has to name a local model in its own settings.

This needs saying openly, because at the TechEd conference I said that "no data leaves the machine". For my personal system I deliberately chose Claude, a cloud model. It answers much better, and I know I am giving up some privacy for it: whatever I write to it goes to Anthropic's servers. The agents that work on their own with public data still run only on local models. So that sentence from the conference holds for specific agents, not for the machine. Decide where this line is before you start.

Agents: nine defined, five in use

In OpenClaw an agent is three things: a workspace folder, its own state directory and a model. My configuration has nine, but these five are the main ones:

  • A personal assistant (main) on Claude.
  • Four autonomous agents on Qwen, which collect data around the clock for the Transparence project, a map of influence in the Czech Republic built from public sources. Nobody talks to them; their runs are started by a scheduler and a work queue.

Sandbox: limits in the config, not in the prompt

An agent that works on its own needs limits that don't live in the prompt. OpenClaw has a sandbox for this, and I turn it on fully for all four autonomous agents:

  • Each agent in its own Docker container (sandbox.mode: all, scope: agent).
  • All Linux capabilities dropped (capDrop: ALL), a limit of 512 processes and 8 GB of memory.
  • The repository mounted read-write, but its .git folder read-only. The agent can change files but cannot write anything to the history. Commits are made by code outside the container, after it has checked what changed.
  • Denied tool groups (tools.deny): sending messages, UI, media, device control and starting other agents. An autonomous agent has nobody to write to and cannot call in a helper.

And one less obvious trick: in the env block I give git a different committer identity. Every command the agent runs inherits it, so if an agent did manage to commit after all, you can see it at a glance and undo it. This did not come from caution: the agents really did it in June.

Channels and the gateway: who may talk to the agents

  • The main bot on Telegram in pairing mode: an unknown sender has to be paired before the bot answers. Groups only from an allowlist.
  • WhatsApp only from one number, mine.

Whoever gets through gets their own session, separate in each channel (session.dmScope: per-channel-peer), so different people's conversations don't mix.

The gateway listens only on localhost and requires a token. The control panel allows a single address, and that one is on my private Tailscale network. And for nodes (devices paired with the gateway, typically a phone or a Mac with the OpenClaw app) I have denied the commands an agent should not be able to run even by accident: taking photos with the camera, recording the screen, sending SMS, and adding contacts, calendar events or reminders.

Skills: turn off more than you turn on

In OpenClaw a skill is a Markdown guide to using some tool. I have turned off forty built-in ones I don't need: Slack, Notion, Spotify, 1Password, Apple Notes and others. Every skill that is on is an ability the agent has, even when it doesn't need it.

For Google Workspace I have a set of skills for mail, calendar, documents and spreadsheets. They take a completely different route from the nodes: through Google, directly from the Spark. The ban on adding calendar events on the nodes does not reach them. And since a skill is just text, for the skill that writes to the calendar the only safeguard is a line with a warning. A safeguard the model can read and overlook is not a safeguard. The real limit has to be somewhere else: in the denied tool groups and the sandbox, which the model cannot get around.

Four things I learned in production

1. When a timeout expires, the work doesn't stop. The CLI is only a client; the model runs in the gateway. When I killed the CLI on a timeout, generation in the gateway carried on and kept the GPU busy. The next run then got less compute, timed out too, and so on: on 22 June, for four hours straight, every run ended at the limit and produced nothing. ollama stop didn't help (it waits for the request to finish), and OpenClaw has no command to cancel a running turn. The only thing that reliably stops generation is closing the connection the request came from. So after a timeout I restart the gateway.

2. The sandbox doesn't see what the shell sees. In the sandbox the file-reading tool is locked to the agent's workspace folder and cannot see the mounted repository, even though shell commands can. The agents tried paths like ../, and in three days I counted 734 failed reads. The fix: before each run, copy the documents the agent needs to read into its workspace folder.

3. Without their own session ID, runs pile up. When openclaw agent doesn't get a --session-id, OpenClaw adds the turn to the agent's long-lived main session. Every later run then inherits the full transcript of all the earlier ones: tasks, tool calls and their outputs. The context grows until it hits the model's window and forces compaction mid-task, every run reprocesses the whole accumulated history (the main reason runs were slow), and the context of one task leaks into the next. So every automated run gets a new session ID. Memory that matters belongs in files.

4. Back up, but watch what you back up. OpenClaw has built-in openclaw backup create and openclaw backup verify. I run them every week and keep the archives outside the repository, because they contain credentials. I found two things out along the way: OpenClaw itself never deletes old session transcripts, so before a backup I delete the ones nobody has touched for 60 days. And in July one agent copied a 1.9 GB copy of git into its workspace folder, which made the weekly backup four times bigger. I only noticed after five days.

Why my second brain doesn't run on it

Part one was about my wiki. I considered moving it to OpenClaw several times and each time ended up at the same problem.

When OpenClaw calls Claude through claude-cli, it turns off the project rules file (CLAUDE.md), hooks and skills. And that file is my whole wiki: what must never be overwritten, how times are recorded, how much an advisor may read. An agent that can't see it is a clever stranger with access to my files. So in July I built my AI advisors on Claude Code running directly in the wiki folder. In August, when they were meant to start working unsupervised, that reason held even more. That is what the next parts are about.

So OpenClaw does what it is good at: it handles the channels, the personal assistant and the autonomous agents on local models, on one machine, behind one gateway.

How to start

  1. Decide which agent may send data out, and write it into the config. The default model applies to every agent that doesn't have its own.
  2. Set num_ctx and the timeouts before you start wondering why your local agent forgets and crashes.
  3. An autonomous agent gets a sandbox, denied tool groups and a read-only .git.
  4. Lock down the channels straight away: pairing, an allowlist of numbers, the gateway only on localhost.
  5. Keep in mind that the CLI is not the one doing the work. A timeout on the client doesn't stop the model in the gateway.
  6. Back up with openclaw backup and prune old session transcripts.

Next time: six AI advisors and how I talk to them through Claude Code.

← Back to the blog Get in touch