Intro#
This guide covers how to install and configure OpenClaw - a self-hosted AI agent gateway that connects LLMs to your tools via MCP and to your chat apps via Matrix.
If you want to know why I set this up and how I use it day to day, check out the blog post:
This page is the technical “how to get it running” part.
Prerequisites#
Before you start, you will need:
- A Linux machine (I run Ubuntu, kernel 6.8.0) - a dedicated VM is recommended
- Node.js
- A Matrix homeserver - for the communication layer. See my Matrix Synapse setup guide if you do not have one yet
- An LLM API key - I use GLM-5.1 and GLM-5 Turbo via Z.AI (OpenAI-compatible API), but OpenClaw supports multiple providers
- MCP servers (optional but that is the whole point) - see my MCP explainer
Installation#
Setting up the gateway#
I run OpenClaw as a systemd user service. First, install OpenClaw:
# Install OpenClaw globally
npm install -g openclaw
# Or clone and build from source
git clone https://github.com/openclaw/openclaw.git
cd openclaw
npm install && npm run build
Creating the systemd service#
Create a systemd user service so OpenClaw starts automatically and restarts on failure:
mkdir -p ~/.config/systemd/user
Create the service file at ~/.config/systemd/user/openclaw.service:
[Unit]
Description=OpenClaw AI Agent Gateway
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/openclaw start
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=default.target
Then enable and start it:
systemctl --user daemon-reload
systemctl --user enable openclaw
systemctl --user start openclaw
Check the status:
systemctl --user status openclaw
Logs go to /tmp/openclaw/ by default. You can also follow them with:
journalctl --user -u openclaw -f
Gateway configuration#
The main config file lives at ~/.openclaw/config.yaml (or wherever you point OpenClaw). Here is the general structure:
Network binding#
By default OpenClaw binds to localhost. To make it accessible on your LAN:
gateway:
bind: "0.0.0.0:18789"
allowedOrigins:
- "claw.kohnkenet.de:18789"
- "chat.kohnkenet.de"
The dashboard will be available at http://<your-ip>:18789/.
Authentication#
OpenClaw uses token-based authentication. Store your token as a secret (more on that below) and reference it in the config:
auth:
type: token
token:
$secretRef: "gateway_token"
Secrets management#
Do not put plaintext secrets in your config files. OpenClaw supports referencing secrets from an external file.
Create ~/.openclaw/secrets.json:
{
"gateway_token": "your-secure-random-token-here",
"zai_api_key": "your-z-ai-api-key",
"brave_api_key": "your-brave-search-api-key",
"matrix_claw_password": "...",
"matrix_dave_password": "...",
"matrix_remy_password": "..."
}
Lock it down:
chmod 600 ~/.openclaw/secrets.json
Then reference secrets in your config using $secretRef:
providers:
zai:
apiKey:
$secretRef: "zai_api_key"
Setting up agents#
Each agent gets its own configuration block with a system prompt, workspace, and Matrix identity.
Agent configuration#
agents:
- name: claw
matrix:
userId: "@claw:your-domain.de"
password:
$secretRef: "matrix_claw_password"
homeserver: "https://matrix.your-domain.de"
workspace: "~/.openclaw/workspace"
systemPrompt: |
You are claw, a general-purpose assistant.
Help with task management, workspace operations, cron jobs, and general questions.
- name: dave
matrix:
userId: "@dave:your-domain.de"
password:
$secretRef: "matrix_dave_password"
homeserver: "https://matrix.your-domain.de"
workspace: "~/.openclaw/workspace-dave"
systemPrompt: |
You are dave, a vegan travel assistant.
Focus on restaurant discovery, trip planning, accommodation search,
travel logistics, and neighborhood tips.
Give quality-over-budget recommendations. Be honest about bad vegan scenes.
Do not preach - just help.
- name: remy
matrix:
userId: "@remy:your-domain.de"
password:
$secretRef: "matrix_remy_password"
homeserver: "https://matrix.your-domain.de"
workspace: "~/.openclaw/workspace-remy"
systemPrompt: |
You are remy, a vegan recipe assistant (named after the rat from Ratatouille).
Find recipes from the web - never invent them, always link to sources.
Build shopping lists via Bring!, help with meal planning.
Use metric units. Handle ingredient substitutions.
Only vegan recipes - flag non-vegan ingredients from sources and suggest swaps.
Each agent gets its own workspace directory so their files and memory do not collide.
AGENTS.md and SOUL.md#
Every agent workspace has two key files that define how the agent behaves. OpenClaw injects both into the system prompt at the start of every session — no restart needed when you edit them.
AGENTS.md — the operating manual. Defines the agent’s role, which tools to use, how to use memory, and any rules to follow. Be specific — the more precise your instructions, the less the agent hallucinates.
Create ~/.openclaw/workspace-dave/AGENTS.md:
# AGENTS.md - Dave
## Role
Dave is a vegan travel assistant. Restaurant discovery, trip planning, accommodation search, travel logistics.
## Memory
- Daily notes: `memory/YYYY-MM-DD.md`
- Long-term: `MEMORY.md`
- Track user preferences: travel style, budget comfort zone, dietary restrictions.
## Tools
- Use **Brave Search** for current travel info, restaurant reviews, neighborhood guides.
- Use **Trek** tools for trip management: create trips, add places, manage itineraries.
- Use **Airbnb** and **Booking.com** tools for accommodation search.
- Use **Reddit** tools for real traveler recommendations.
## Rules
- Always suggest vegan-friendly restaurants and neighborhoods.
- Be honest about destinations with a bad vegan food scene.
- Quality over budget. Do not recommend the cheapest option if it is bad.
SOUL.md — the personality. Defines the agent’s voice, tone, boundaries, and behavioral quirks. Keep it concise. Short beats long, sharp beats vague.
Create ~/.openclaw/workspace-dave/SOUL.md:
# SOUL.md
## Identity
Name: Dave
Role: Vegan travel assistant — restaurant discovery, trip planning, accommodation search
## Voice
- Relaxed and knowledgeable, like a well-traveled friend.
- Direct about what is worth your time and what is a tourist trap.
- Concise. Give me the good stuff, skip the filler.
## Behavior
- When asked about a destination, lead with the vegan food scene.
- Suggest neighborhoods to stay in based on restaurant density.
- Always mention seasonal considerations.
- If a destination has a weak vegan scene, say so upfront.
- Do not preach about veganism. Just help.
## Boundaries
- Stay in the travel domain. Not a general assistant.
- Do not invent restaurants or attractions. Use search tools to verify everything.
- If unsure about a restaurant being vegan-friendly, say so and suggest verifying.
The workspace also supports other files like USER.md (who the user is), TOOLS.md (local tool conventions), and IDENTITY.md (name and emoji). See the OpenClaw workspace docs for the full list.
[!TIP] The SOUL.md docs have great advice on writing personality files. The short version: keep
AGENTS.mdfor operating rules,SOUL.mdfor voice and style. Do not dump your security policy or a life story into SOUL.md.
Matrix account setup#
Before the agents can connect to Matrix, you need to create accounts for them on your Synapse server:
# Create each agent account on your Matrix server
docker exec -it synapse register_new_matrix_user -c /data/homeserver.yaml http://localhost:8008
Create three accounts for your agents. Store the passwords in your secrets.json.
Matrix channel configuration#
The Matrix plugin controls how agents handle DMs and group rooms:
plugins:
matrix:
enabled: true
e2ee: true
dm:
policy: allowlist
allow:
- "@your-user:your-domain.de"
group:
policy: open
autoJoin: true
sessions:
scope: per-room
dmScope: per-channel-peer
allowBots: true
Key settings:
- E2EE: End-to-end encryption on all agent accounts
- DM allowlist: Only specific users can DM the agents directly
- Group policy open: Agents auto-join when invited to group rooms (good for shared planning)
- allowBots: Agents can talk to each other via Matrix
LLM provider configuration#
OpenClaw supports multiple LLM providers. I use Z.AI with an OpenAI-compatible API:
providers:
zai:
type: openai-compatible
baseUrl: "https://api.z.ai/v1"
apiKey:
$secretRef: "zai_api_key"
models:
- name: glm-5.1
contextWindow: 202000
maxOutput: 131000
reasoning: true
- name: glm-5-turbo
contextWindow: 202000
maxOutput: 131000
reasoning: true
Connecting MCP servers#
This is where the agents get their tools. MCP servers are configured per-gateway and available to all agents.
Trek (self-hosted, OAuth)#
mcpServers:
- name: trek
transport:
type: http
url: "https://travel.kohnkenet.de/mcp"
auth:
type: oauth
clientId:
$secretRef: "trek_oauth_client_id"
clientSecret:
$secretRef: "trek_oauth_client_secret"
Bring! (local MCP server)#
- name: bring
transport:
type: stdio
command: "node"
args: ["/home/user/mcp/bring-mcp/index.js"]
Remote MCP servers via mcp-remote#
For services that use the RapidAPI-style MCP remotes:
- name: airbnb
transport:
type: stdio
command: "npx"
args: ["-y", "@openbnb/mcp-server-airbnb"]
- name: booking
transport:
type: stdio
command: "npx"
args: ["-y", "mcp-remote", "https://rapidapi.com/booking-endpoint"]
- name: reddit
transport:
type: stdio
command: "npx"
args: ["-y", "mcp-remote", "https://rapidapi.com/reddit-endpoint"]
Enabling plugins and skills#
Plugins#
plugins:
braveSearch:
enabled: true
apiKey:
$secretRef: "brave_api_key"
zai:
enabled: true
matrix:
enabled: true
Skills#
Skills can be toggled on or off. Here are the ones I have enabled:
skills:
goplaces:
enabled: true
apiKey:
$secretRef: "google_places_api_key"
coding-agent:
enabled: true
nano-pdf:
enabled: true
openhue:
enabled: true
bridgeIp: "192.168.1.x"
apiKey:
$secretRef: "hue_api_key"
About 30 more skills are available but disabled by default (Discord, Slack, Notion, Obsidian, Spotify, Trello, WhatsApp, Apple Notes, 1Password, etc.). Toggle them on as needed.
Security hardening#
A few things worth doing on a production setup:
Node deny-list#
Block sensitive capabilities on connected nodes:
nodes:
denyList:
- camera
- screenRecording
- contacts
- calendar
- sms
File permissions#
# Secrets file should be locked down
chmod 600 ~/.openclaw/secrets.json
# Workspace directories should be user-only
chmod 700 ~/.openclaw/workspace
chmod 700 ~/.openclaw/workspace-dave
chmod 700 ~/.openclaw/workspace-remy
Dedicated VM#
I run OpenClaw on a dedicated VM. This isolates the agent’s exec tool from the rest of my infrastructure. The agents can run shell commands, so giving them their own sandbox is a good idea.
[!WARNING] OpenClaw agents with the
exectool can run arbitrary shell commands on your server. Use a dedicated VM or container, and be thoughtful about what you let them do. The self-restart loop I mention in the blog post is a funny example, but it could have been worse.
Useful commands#
# Start the gateway
systemctl --user start openclaw
# Stop the gateway
systemctl --user stop openclaw
# Restart (the agents will feel this one)
systemctl --user restart openclaw
# Check status
systemctl --user status openclaw
# Follow logs
journalctl --user -u openclaw -f
# Check if the dashboard is responding
curl http://localhost:18789/health
What to do with it#
Now that you have an AI agent gateway running, here are some things you can build:
Wrapping up#
That is the full setup. One gateway, three agents, MCP servers for tools, Matrix for communication, all running on a dedicated VM that you control.
The building blocks that led up to this:
Happy self-hosting.
