A beautiful, zero-dependency command center for OpenClaw AI agents.
When you run OpenClaw seriously β multiple agents, dozens of cron jobs, sub-agents spawning sub-agents, several Telegram groups and Whatsapp, Slack, and Discord channels, 10+ models, multiple agents and sub-agents β information gets scattered fast.
The problem: there was no single place to answer the obvious questions:
- Is my gateway actually running right now?
- How much have I spent today, and which model is burning the most?
- Which cron jobs ran, which failed, and when does the next one fire?
- What sessions are active and how much context are they consuming?
- Are my sub-agents doing useful work or spinning in circles?
- What's the cost trend over the last 7 days β am I accelerating?
The only way to answer these was digging through log files, running CLI commands, and mentally stitching together a picture from 5 different sources. That friction adds up.
The solution: a single local page that collects everything in one place β gateway health, costs, cron status, active sessions, sub-agent runs, model usage, git log β refreshed automatically, no login, no cloud, no external dependencies. Open a browser tab, get the full picture in seconds.
It's not trying to replace the OpenClaw CLI or Telegram interface. It's the at-a-glance overview layer that tells you whether everything is healthy and where your money and compute are going β so you can make decisions without hunting for data.
- π Top Metrics Bar β Live CPU, RAM, swap, disk + OpenClaw version + gateway β always on, colour-coded by configurable thresholds (see Top Metrics Bar)
- π Header Bar β Bot name, online/offline status, auto-refresh countdown, theme picker
β οΈ Alerts Banner β Smart alerts for high costs, failed crons, high context usage, gateway offline- π System Health β Gateway status, PID, uptime, memory, compaction mode, active session count
- π° Cost Cards β Today's cost, all-time cost, projected monthly, cost breakdown donut chart
- β° Cron Jobs β All scheduled jobs with status, schedule, last/next run, duration, model
- π‘ Active Sessions β Recent sessions with model, type badges (DM/group/cron/subagent), context %, tokens
- π Token Usage & Cost β Per-model breakdown with 7d/30d/all-time tabs, usage bars, totals
- π€ Sub-Agent Activity β Sub-agent runs with cost, duration, status + token breakdown (7d/30d tabs)
- π Charts & Trends β Cost trend line, model cost breakdown bars, sub-agent activity β all pure SVG, 7d/30d toggle
- π§© Bottom Row β Available models grid, skills list, git log
- π¬ AI Chat β Ask questions about your dashboard in natural language, powered by your OpenClaw gateway
- π On-Demand Refresh β
server.pyrefreshes data when you open the dashboard (no stale data) - β±οΈ Auto-Refresh β Page auto-refreshes every 60 seconds with countdown timer
- π¨ 6 Built-in Themes β 3 dark (Midnight, Nord, Catppuccin Mocha) + 3 light (GitHub, Solarized, Catppuccin Latte), switchable from the UI
- ποΈ Glass Morphism UI β Subtle transparency and hover effects
- π± Responsive β Adapts to desktop, tablet, and mobile
- π Local Only β Runs on localhost, no external dependencies
- π‘οΈ Rate Limiting β 10 req/min per-IP on
/api/chat(Go + Python, 429 + Retry-After) - β±οΈ HTTP Timeouts β Read 30s / Write 90s / Idle 120s (Go server)
- π§ Cross-Platform β macOS and Linux
- β‘ Zero Dependencies β Pure HTML/CSS/JS frontend, Python stdlib backend, or single Go binary
- π Top Metrics Bar β Always-on CPU/RAM/swap/disk + gateway status, per-metric thresholds, macOS + Linux
- π¬ AI Chat β Natural language queries about costs, sessions, crons, and config via OpenClaw gateway
- π― Accurate Model Display β 5-level resolution chain ensures every session/sub-agent shows its real model, not the default
- π Runtime Observability β
/api/systemnow includes live gateway runtime state (liveness, readiness, failing deps, uptime, PID, memory) sourced from/healthz,/readyz, andopenclaw status --json - π‘ Gateway Readiness Alerts β Alert banner shows
π‘ Gateway not ready: discord(or any failing dep) and auto-clears on recovery; distinct from offline/online state - β‘ Gateway Runtime + Config Cards β System Settings split into two panels: Gateway Runtime (live probes) and Gateway Config (static config snapshot)
Two server options β choose what fits your environment:
| Go Binary | Python Server | |
|---|---|---|
| Install | Download one file | Clone repo + Python 3 |
| Runtime deps | None | Python 3.6+ |
| Throughput | ~2,019 req/s | 1,745 req/s |
| Deploy size | 9.5 MB (arm64), 10 MB (amd64) | ~81 MB (Python framework) |
| Best for | Production, headless, containers | Quick setup, customization |
Go now ships as the same release artifact family as
v2026.3.8and continues to include runtime-observability features. For reproducible numbers, see the latest entry in BENCHMARK.md (Go vs Python,/api/system, 20k requests @ 200 concurrency).
Download a single pre-built binary β no runtime dependencies needed.
Note: latest release assets are versioned as
openclaw-dashboard-<platform>-<arch>, while thelatest/download/...links below always point to the current release.
# macOS (Apple Silicon)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-darwin-arm64 -o openclaw-dashboard
chmod +x openclaw-dashboard
./openclaw-dashboard --port 8080
# macOS (Intel)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-darwin-amd64 -o openclaw-dashboard
chmod +x openclaw-dashboard
./openclaw-dashboard --port 8080
# Linux (x86_64)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-linux-amd64 -o openclaw-dashboard
chmod +x openclaw-dashboard
./openclaw-dashboard --port 8080
# Linux (ARM64 / Raspberry Pi)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-linux-arm64 -o openclaw-dashboard
chmod +x openclaw-dashboard
./openclaw-dashboard --port 8080Verify download integrity:
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/checksums-sha256.txt -o checksums-sha256.txt
shasum -a 256 -c checksums-sha256.txtNote: Place
config.json,themes.json, andrefresh.shin the same directory as the binary for full functionality.
# One-line install
curl -fsSL https://raw.githubusercontent.com/mudrii/openclaw-dashboard/main/install.sh | bashThis will:
- Install to
~/.openclaw/dashboard - Create a default config
- Run initial data refresh
- Start
server.pyas a system service - Open http://127.0.0.1:8080
# Clone the repo
git clone https://github.com/mudrii/openclaw-dashboard.git ~/.openclaw/dashboard
cd ~/.openclaw/dashboard
# Create your config
cp examples/config.minimal.json config.json
nano config.json # Set your bot name
# Start the server (refreshes data on-demand)
python3 server.py &
# Or bind to LAN for access from other devices
python3 server.py --bind 0.0.0.0 &
# Open in browser
open http://127.0.0.1:8080 # macOS
xdg-open http://127.0.0.1:8080 # Linuxgit clone https://github.com/mudrii/openclaw-dashboard.git
cd openclaw-dashboard
go build -ldflags="-s -w" -o openclaw-dashboard .
./openclaw-dashboard --port 8080# Go binary (default β 30MB image, recommended)
docker build -t openclaw-dashboard .
docker run -p 8080:8080 -v ~/.openclaw:/home/dashboard/.openclaw openclaw-dashboard
# Python server (alternative β 180MB image)
docker build --target python -t openclaw-dashboard:python .
docker run -p 8080:8080 -v ~/.openclaw:/home/dashboard/.openclaw openclaw-dashboard:python# Go binary (default)
nix run github:mudrii/openclaw-dashboard
# Python server
nix run github:mudrii/openclaw-dashboard#python-server
# Dev shell (Go + Python + tools)
nix develop github:mudrii/openclaw-dashboardClick the π¨ button in the header to switch themes instantly β no reload or server restart needed. Choice persists via localStorage.
| Theme | Type | Vibe |
|---|---|---|
| π Midnight | Dark | Original glass morphism (default) |
| ποΈ Nord | Dark | Arctic blue, calm, great for long sessions |
| πΈ Catppuccin Mocha | Dark | Warm pastels, easy on eyes |
| βοΈ GitHub Light | Light | Clean, professional, high readability |
| π Solarized Light | Light | Scientifically optimized contrast |
| π» Catppuccin Latte | Light | Soft pastels |
Add your own themes by editing themes.json. Each theme defines 19 CSS color variables:
{
"my-theme": {
"name": "My Theme",
"type": "dark",
"icon": "π―",
"colors": {
"bg": "#1a1a2e",
"surface": "rgba(255,255,255,0.03)",
"surfaceHover": "rgba(255,255,255,0.045)",
"border": "rgba(255,255,255,0.06)",
"accent": "#e94560",
"accent2": "#0f3460",
"green": "#4ade80",
"yellow": "#facc15",
"red": "#f87171",
"orange": "#fb923c",
"purple": "#a78bfa",
"text": "#e5e5e5",
"textStrong": "#ffffff",
"muted": "#737373",
"dim": "#525252",
"darker": "#404040",
"tableBg": "rgba(255,255,255,0.025)",
"tableHover": "rgba(255,255,255,0.05)",
"scrollThumb": "rgba(255,255,255,0.1)"
}
}
}server.py / openclaw-dashboard (Go) β HTTP server (choose one)
βββ index.html β Single-page dashboard (fetches /api/refresh, /api/chat)
βββ themes.json β Theme definitions (user-editable)
βββ refresh.sh β Data collection script (called by server)
βββ data.json β Generated data (auto-refreshed)
Two server implementations, same API:
Python (server.py) |
Go (openclaw-dashboard) |
|
|---|---|---|
Serves index.html |
From disk | Embedded in binary (//go:embed) |
/api/refresh |
Blocking (waits for refresh.sh) |
Stale-while-revalidate (instant response) |
/api/chat |
Reads data.json per request |
Mtime-cached data.json (dual raw+parsed cache) |
/api/system |
system_metrics.py β TTL cache, stale-serving |
SystemService β parallel collectors, RWMutex cache |
| Static files | Allowlisted (themes.json, data.json, index.html) |
Allowlisted only (themes.json) |
| Rate limiting | 10 req/min per-IP on /api/chat |
10 req/min per-IP on /api/chat |
| HTTP timeouts | N/A (stdlib defaults) | Read 30s / Write 90s / Idle 120s |
| Pre-warm | None | Runs refresh.sh at startup |
| Shutdown | Clean thread exit | Graceful (drains requests, 5s timeout) |
| Gateway limit | 1MB response cap | 1MB response cap |
| Tests | pytest (122 tests) |
go test -race (87 tests) |
When you open the dashboard, index.html calls /api/refresh. The server runs refresh.sh (with 30s debounce) to collect fresh data from your OpenClaw installation, then returns the JSON. No cron jobs needed.
The /api/chat endpoint accepts {"question": "...", "history": [...]} and forwards a stateless request to the OpenClaw gateway's OpenAI-compatible /v1/chat/completions endpoint, with a system prompt built from live data.json.
The entire frontend lives in a single <script> tag inside index.html β zero dependencies, no build step. The JS is organized into 7 plain objects:
βββββββββββββββββββββββββββββββββββββββββββββββ
β App.init() β
β (wires everything, starts timer) β
βββββββββ¬βββββββββββββββ¬βββββββββββββββ¬ββββββββ
β β β
ββββββΌβββββ βββββββΌββββββ ββββββΌββββββ
β State βββββ DataLayer β β Theme β
β (truth) β β (fetch) β β (colors) β
ββββββ¬βββββ βββββββββββββ ββββββββββββ
β
ββββββΌβββββββββββββ
β DirtyChecker β
β (what changed?) β
ββββββ¬βββββββββββββ
β
ββββββΌβββββ ββββββββββ
βRenderer β β Chat β
β (DOM) β β (AI) β
βββββββββββ ββββββββββ
| Module | Responsibility |
|---|---|
| State | Single source of truth β holds data, prev, tabs, countdown. Produces immutable deep-frozen snapshots for each render cycle. |
| DataLayer | Stateless fetch with _reqId counter for out-of-order protection. Returns parsed JSON or null. |
| DirtyChecker | Computes 13 boolean dirty flags by comparing current snapshot against State.prev. Uses stableSnapshot() to strip volatile timestamps from crons/sessions. |
| Renderer | Pure DOM side-effects. Receives frozen snapshot + pre-computed flags, dispatches to 14 section renderers. Owns the agent hierarchy tree, recent-finished buffer, and all chart SVG rendering. |
| Theme | Self-contained theme engine β loads themes.json, applies CSS variables, persists choice to localStorage. |
| Chat | AI chat panel β manages history, sends stateless requests to /api/chat. |
| App | Wiring layer β init() starts theme + timer + first fetch; renderNow() captures snapshot β computes flags β schedules render via requestAnimationFrame; commitPrev(snap) runs inside rAF to prevent fetch/paint races. |
All inline onclick handlers route through window.OCUI β a thin namespace that calls State.setTab() / App.renderNow(). No bare globals remain outside the module objects and top-level utilities ($, esc, safeColor, relTime).
See ARCHITECTURE.md for the full specification.
Edit config.json:
{
"bot": {
"name": "My Bot",
"emoji": "π€"
},
"theme": {
"preset": "nord"
},
"refresh": {
"intervalSeconds": 30
},
"server": {
"port": 8080,
"host": "127.0.0.1"
},
"ai": {
"enabled": true,
"gatewayPort": 18789,
"model": "your-model-id",
"maxHistory": 6,
"dotenvPath": "~/.openclaw/.env"
},
"system": {
"enabled": true,
"pollSeconds": 10,
"diskPath": "/",
"cpu": { "warn": 80, "critical": 95 },
"ram": { "warn": 75, "critical": 90 },
"swap": { "warn": 80, "critical": 95 },
"disk": { "warn": 85, "critical": 95 }
}
}| Key | Default | Description |
|---|---|---|
bot.name |
"OpenClaw Dashboard" |
Dashboard title |
bot.emoji |
"π¦" |
Avatar emoji |
theme.preset |
"midnight" |
Default theme (midnight, nord, catppuccin-mocha, github-light, solarized-light, catppuccin-latte) |
timezone |
"UTC" |
IANA timezone for all time calculations (requires Python 3.9+) |
refresh.intervalSeconds |
30 |
Debounce interval for refresh |
alerts.dailyCostHigh |
50 |
Daily cost threshold for high alert ($) |
alerts.dailyCostWarn |
20 |
Daily cost threshold for warning alert ($) |
alerts.contextPct |
80 |
Context usage % threshold for alerts |
alerts.memoryMb |
640 |
Gateway memory threshold (MB) for alerts |
server.port |
8080 |
Server port (also --port / -p flag or DASHBOARD_PORT env) |
server.host |
"127.0.0.1" |
Server bind address (also --bind / -b flag or DASHBOARD_BIND env) |
ai.enabled |
true |
Enable/disable the AI chat panel and /api/chat endpoint |
ai.gatewayPort |
18789 |
Port of your OpenClaw gateway |
ai.model |
"" |
Model to use for chat β any model ID registered in your OpenClaw gateway |
ai.maxHistory |
6 |
Number of previous messages to include for context |
ai.dotenvPath |
"~/.openclaw/.env" |
Path to .env file containing OPENCLAW_GATEWAY_TOKEN |
system.enabled |
true |
Enable/disable the top metrics bar and /api/system endpoint |
system.pollSeconds |
10 |
How often the browser polls /api/system (seconds, 2β60) |
system.metricsTtlSeconds |
10 |
Server-side metrics cache TTL (seconds) |
system.versionsTtlSeconds |
300 |
Version/gateway probe cache TTL (seconds) |
system.gatewayTimeoutMs |
1500 |
Timeout for gateway liveness probe (ms) |
system.diskPath |
"/" |
Filesystem path to report disk usage for |
system.warnPercent |
70 |
Global warn threshold (% used) β overridden by per-metric values |
system.criticalPercent |
85 |
Global critical threshold (% used) β overridden by per-metric values |
system.cpu.warn |
80 |
CPU warn threshold (%) |
system.cpu.critical |
95 |
CPU critical threshold (%) |
system.ram.warn |
80 |
RAM warn threshold (%) |
system.ram.critical |
95 |
RAM critical threshold (%) |
system.swap.warn |
80 |
Swap warn threshold (%) |
system.swap.critical |
95 |
Swap critical threshold (%) |
system.disk.warn |
80 |
Disk warn threshold (%) |
system.disk.critical |
95 |
Disk critical threshold (%) |
The top bar shows live host metrics β always visible above the alerts banner.
Metrics displayed:
| Pill | What it shows |
|---|---|
| CPU | Usage % (current delta, not boot average) |
| RAM | Used / Total GB |
| Swap | Usage % |
| Disk | Used / Total GB (used %) |
| OpenClaw | Installed version |
| GW | Gateway status (online / offline) |
Colour coding:
- π’ Green β below warn threshold
- π‘ Yellow β above warn, below critical
- π΄ Red β above critical threshold
- β« Grey β collection error / N/A
Per-metric config example (config.json):
"system": {
"enabled": true,
"pollSeconds": 10,
"diskPath": "/",
"cpu": { "warn": 80, "critical": 95 },
"ram": { "warn": 75, "critical": 90 },
"swap": { "warn": 60, "critical": 80 },
"disk": { "warn": 85, "critical": 95 }
}Platform support:
- macOS β CPU via
top -l 2(current delta), RAM viavm_stat, Swap viasysctl vm.swapusage, Disk viastatfs - Linux β CPU via
/proc/stat(200ms dual-sample including steal field), RAM+Swap via/proc/meminfo(single read, shared), Disk viastatfs
API endpoint: GET /api/system β returns JSON with all metrics, thresholds, version info, and the openclaw runtime block. Includes stale-serving semantics (returns cached data immediately while refreshing in background).
openclaw block in /api/system β provides live gateway runtime state beyond what refresh.sh collects:
| Field | Description |
|---|---|
openclaw.gateway.live |
true when /healthz returns 200 |
openclaw.gateway.ready |
true when /readyz indicates all deps ready |
openclaw.gateway.uptimeMs |
Process uptime in milliseconds (from /healthz) |
openclaw.gateway.failing |
Array of failing dependency names from /readyz |
openclaw.gateway.healthEndpointOk |
Whether /healthz endpoint responded |
openclaw.gateway.readyEndpointOk |
Whether /readyz endpoint responded |
openclaw.status.currentVersion |
Installed OpenClaw version |
openclaw.status.latestVersion |
Latest published version (from npm) |
openclaw.status.connectLatencyMs |
Gateway connection latency (ms) |
openclaw.freshness.gateway |
RFC3339 timestamp of last successful gateway probe |
openclaw.freshness.status |
RFC3339 timestamp of last successful status probe |
The chat panel requires:
- Your OpenClaw gateway running with the
chatCompletionsendpoint enabled:"gateway": { "http": { "endpoints": { "chatCompletions": { "enabled": true } } } }
OPENCLAW_GATEWAY_TOKENset in your.envfile (defaults to~/.openclaw/.env)
The chat is stateless β each question is sent directly to the gateway with a system prompt built from live data.json. No agent memory or tools bleed in.
See docs/CONFIGURATION.md for full details.
Full dashboard view β all sections at a glance:
Real-time bot status, gateway uptime, memory usage, active session count, today's cost, all-time spend, projected monthly cost, and a per-model cost breakdown donut chart. Smart alert banners surface high costs, failed crons, and context overflows automatically.
Three always-visible SVG charts with 7d/30d toggle: cost trend over time, per-model cost breakdown bars, and sub-agent activity volume. No external chart libraries β pure inline SVG.
All scheduled jobs with status badges (active/idle/error), schedule expression, last run time, next run, duration, and the model used. At-a-glance view of your automation health.
Live sessions with model, type badges (DM / group / subagent), context usage %, and token count. Above the session list: a visual agent hierarchy tree showing parent β sub-agent β sub-sub-agent relationships with live/idle status and trigger labels β updated every refresh.
Per-model token and cost breakdown with 7d / 30d / all-time tabs. Includes input tokens, output tokens, cache reads, and total cost per model β sortable at a glance.
All sub-agent runs with cost, duration, status, and token breakdown. Separate 7d/30d tabs. Useful for tracking which tasks spawn the most agents and where spend is concentrated.
Quick reference panel showing all configured models, active skills, and the last 5 git commits from your OpenClaw workspace β so you always know what's deployed.
Full agent setup at a glance: model routing chain (primary β fallbacks), sub-agent routing by purpose (General / Dev+Coding / Work), agent details table with per-agent fallbacks, agent bindings with resolved group names, runtime config (compaction, memory flush), and subagent limits (max depth, max children/agent).
./uninstall.shOr manually:
# macOS
launchctl unload ~/Library/LaunchAgents/com.openclaw.dashboard.plist
rm -rf ~/.openclaw/dashboard
# Linux
systemctl --user stop openclaw-dashboard
rm -rf ~/.openclaw/dashboardGo binary (Option A):
- Pre-built binary β no runtime dependencies
refresh.sh+bash(for data collection)- OpenClaw β Installed at
~/.openclaw(docs) - macOS 10.15+ or Linux (Ubuntu 18.04+, Debian 10+, ARM64)
Python server (Option B):
- Python 3.6+ β Backend server and data collection
- OpenClaw β Installed at
~/.openclaw(docs) - macOS 10.15+ or Linux (Ubuntu 18.04+, Debian 10+)
Both options:
- Modern web browser
See CONTRIBUTING.md for guidelines.
MIT License β see LICENSE
Made with π¦ for the OpenClaw community









