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 β
GET /api/refreshserves cacheddata.jsonimmediately and triggers a debounced background refresh when needed - β±οΈ 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(429 + Retry-After) - β±οΈ HTTP Timeouts β Read 30s / Write 90s / Idle 120s
- π§ Cross-Platform β macOS and Linux
- β‘ Zero Dependencies β Pure HTML/CSS/JS frontend, single Go binary backend
- π 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/systemincludes 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 - β‘ Gateway Runtime + Config Cards β System Settings split into two panels: Gateway Runtime (live probes) and Gateway Config (static config snapshot)
brew install mudrii/tap/openclaw-dashboardThe Homebrew formula installs the binary and seeds a writable runtime directory at
~/.openclaw/dashboard on first run.
Homebrew upgrades preserve existing config.json and runtime themes.json, and
refresh the package-managed VERSION file automatically so openclaw-dashboard --version stays in sync with the installed formula.
Then run:
openclaw-dashboard --refresh # generate data.json
openclaw-dashboard # start server on http://localhost:8080Download a release tarball β includes the binary plus runtime assets.
# macOS (Apple Silicon)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-darwin-arm64.tar.gz | tar xz
./openclaw-dashboard --port 8080
# macOS (Intel)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-darwin-amd64.tar.gz | tar xz
./openclaw-dashboard --port 8080
# Linux (x86_64)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-linux-amd64.tar.gz | tar xz
./openclaw-dashboard --port 8080
# Linux (ARM64 / Raspberry Pi)
curl -L https://github.com/mudrii/openclaw-dashboard/releases/latest/download/openclaw-dashboard-linux-arm64.tar.gz | tar xz
./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.txtcurl -fsSL https://raw.githubusercontent.com/mudrii/openclaw-dashboard/main/install.sh | bashThis will:
- Install to
~/.openclaw/dashboard - Download the latest release archive for your platform
- Create a default config
- Run initial data refresh
- Attempt to install and start the dashboard as a background service
- Print the local dashboard URL
brew upgrade mudrii/tap/openclaw-dashboardAfter upgrading, verify the installed release with:
openclaw-dashboard --versionThe binary has built-in service management β no shell scripts needed:
# Install and start as a system service (launchd on macOS, systemd on Linux)
openclaw-dashboard install
# With custom port and bind address
openclaw-dashboard install --port 9090 --bind 0.0.0.0
# Check status
openclaw-dashboard status
# Stop / start / restart
openclaw-dashboard stop
openclaw-dashboard start
openclaw-dashboard restart
# Remove the service (config and data are preserved)
openclaw-dashboard uninstallAll commands are also available under the service namespace:
openclaw-dashboard service install
openclaw-dashboard service status
openclaw-dashboard service uninstallHomebrew users should use the built-in service commands above. The current tap
does not define a brew services formula service.
git clone https://github.com/mudrii/openclaw-dashboard.git
cd openclaw-dashboard
make build
./openclaw-dashboard --port 8080docker build -t openclaw-dashboard .
docker run -p 8080:8080 -v ~/.openclaw:/home/dashboard/.openclaw openclaw-dashboard# Run directly
nix run github:mudrii/openclaw-dashboard
# Dev shell (Go + 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 in your runtime directory. Default themes
ship from assets/runtime/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)"
}
}
}cmd/openclaw-dashboard/ CLI entrypoint
internal/appconfig/ config loading
internal/appruntime/ runtime-dir resolution
internal/appchat/ chat prompt + gateway client
internal/apprefresh/ data collector
internal/appserver/ HTTP server
internal/appsystem/ metrics and runtime probes
web/index.html embedded frontend
assets/runtime/ runtime defaults
data.json generated dashboard data
Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Serves embedded web/index.html with theme/version injection |
/api/refresh |
GET | Stale-while-revalidate data.json (instant response, background refresh) |
/api/chat |
POST | AI chat via OpenClaw gateway (10 req/min rate limit) |
/api/system |
GET | Live host metrics (CPU/RAM/Swap/Disk) + gateway status |
/api/logs |
GET | Merged tail view of configured dashboard log sources |
/api/errors |
GET | Aggregated warning/error signatures for the dashboard error feed |
| Feature | Details |
|---|---|
| Serves frontend | Embedded from web/index.html (//go:embed) |
/api/refresh |
Stale-while-revalidate (instant response) |
/api/chat |
Mtime-cached data.json (dual raw+parsed cache) |
/api/system |
SystemService β parallel collectors, RWMutex cache |
| Static files | Allowlisted only (themes.json, optional favicons) |
| Rate limiting | 10 req/min per-IP on /api/chat |
| HTTP timeouts | Read 30s / Write 90s / Idle 120s |
| Pre-warm | Runs --refresh at startup |
| Shutdown | Graceful (drains requests, 5s timeout) |
| Gateway limit | 1MB response cap |
| Tests | go test -race |
When you open the dashboard, the embedded frontend calls /api/refresh. The server returns the current data.json immediately, and if the refresh debounce window has expired it starts a background refresh to rebuild the file from your OpenClaw installation. If data.json does not exist yet, the handler waits briefly for the first refresh before returning. No cron jobs are required.
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 web/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 in your dashboard runtime directory. In a source checkout this
is usually the repo root. For install.sh installs it is
${OPENCLAW_HOME:-~/.openclaw}/dashboard/config.json; with Homebrew it is
~/.openclaw/dashboard/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 |
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 |
5000 |
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 the refresh collector gathers:
| 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).
openclaw-dashboard uninstallThis stops the service, removes the LaunchAgent (macOS) or systemd unit (Linux), and preserves all config and data at ~/.openclaw/dashboard.
To also remove all data:
openclaw-dashboard uninstall
rm -rf ~/.openclaw/dashboardOr using the uninstall script to remove the runtime directory as well:
./uninstall.sh- Pre-built Go binary β no runtime dependencies
bash(only needed if using the optionalrefresh.shwrapper script, not required for the binary itself)- OpenClaw β Installed at
~/.openclaw(docs) - macOS 10.15+ or Linux (Ubuntu 18.04+, Debian 10+, ARM64)
- Modern web browser
See CONTRIBUTING.md for guidelines.
MIT License β see LICENSE
Made with π¦ for the OpenClaw community









