A beautiful, secure, real-time monitoring dashboard for OpenClaw agents. Track sessions, monitor API usage, view costs, manage memory files, and keep tabs on system health β all in one place.
| Overview | Sessions | Costs |
|---|---|---|
![]() |
![]() |
![]() |
| Rate Limits | Live Feed | Logs |
|---|---|---|
![]() |
![]() |
![]() |
- π€ Session Management - View all agent sessions with real-time activity status
- π Rate Limit Monitoring - Track Claude and Gemini API usage against rolling windows
- π° Cost Analysis - Detailed spending breakdowns by model, session, and time period
- β‘ Live Feed - Real-time stream of agent messages across all sessions
- π§ Memory Viewer - Browse and read agent memory files (MEMORY.md, HEARTBEAT.md, daily notes)
- π Files Manager - View and edit workspace files, skills, and configs with security hardening
- π System Health - CPU, RAM, disk, temperature monitoring with sparklines
- π Service Control - Quick actions to restart OpenClaw, dashboard, or other services
- π Log Viewer - Real-time system logs with auto-refresh
- β° Cron Management - View, enable/disable, and manually trigger cron jobs
- π Tailscale Integration - View Tailscale status, IP, and connected peers
- π― Activity Heatmap - Visualize peak usage hours over the last 30 days
- π₯ Streak Tracking - Monitor daily activity streaks
- π Session Search & Filtering - Filter by status, model, date range with live search
- π¨ Dark Theme - Beautiful glassmorphic UI with smooth animations
- β¨οΈ Keyboard Shortcuts - Navigate quickly with hotkeys (1-7, Space, /, Esc, ?)
- π± Mobile Responsive - Works on phones and tablets
- π Browser Notifications - Get alerted when usage limits are approaching
- π Timeline View - Visual timeline of session activity
- πΎ Git Activity - Track recent commits across your repos
- ποΈ Claude Usage Scraper - Fetch real usage data from Claude Code CLI
- π· Gemini Usage Tracking - Monitor Google Gemini model usage with per-model breakdowns
- π Provider Switching - Toggle between Claude and Gemini usage on the overview card
- π Per-Model Selector - Choose which model/window to display (Opus, Sonnet, Pro, Flash, etc.)
- π Auto-Refresh - Live data updates every 5 seconds
- π Lifetime Stats - Total tokens, messages, cost since first session
- π Health History - 24-hour CPU & RAM sparklines
- π― Quick Actions - One-click system maintenance (updates, cleanup, restarts)
- π macOS Compatible - Full support for macOS system stats, services, and memory reporting
- π Username/Password Auth - Secure registration with PBKDF2 password hashing
- π TOTP MFA - Optional two-factor authentication (Google Authenticator compatible)
- πΎ Remember Me - Session-only or 3-hour persistent login
- π‘οΈ Security Hardened - HSTS, CSP, rate limiting, timing-safe comparisons, audit logging
- π¦ No External Dependencies - Pure Node.js, no database required
# Clone the repository
git clone https://github.com/tugcantopaloglu/openclaw-dashboard.git
cd openclaw-dashboard
# Set your OpenClaw workspace path (optional, auto-detects if not set)
export WORKSPACE_DIR=/path/to/your/openclaw/workspace
# Start the dashboard
node server.jsVisit http://localhost:7000 in your browser. On first visit, you'll see a registration screen where you create your username and password. After registration, log in with your credentials.
- Node.js v18 or higher (check with
node --version) - OpenClaw installed and running
- Systemd (optional, for service installation on Linux)
-
Clone the repository
git clone https://github.com/tugcantopaloglu/openclaw-dashboard.git cd openclaw-dashboard -
Configure environment (optional)
export DASHBOARD_PORT=7000 export WORKSPACE_DIR=/path/to/your/workspace export OPENCLAW_DIR=$HOME/.openclaw export OPENCLAW_AGENT=main
-
Start the server
node server.js
The server will print:
π Dashboard running on http://localhost:7000 π Recovery token: abc123def456...Save the recovery token β you'll need it if you forget your password.
-
Access the dashboard Open
http://localhost:7000and register your account.
To run the dashboard as a system service with auto-start and crash recovery:
sudo ./install.shThis will:
- Create
/etc/systemd/system/agent-dashboard.service - Create override config at
/etc/systemd/system/agent-dashboard.service.d/override.conf - Enable and start the service
- Set your workspace path and generate a recovery token
View logs:
journalctl -u agent-dashboard -f| Variable | Description | Default |
|---|---|---|
DASHBOARD_PORT |
Server port | 7000 |
DASHBOARD_TOKEN |
Recovery token for password reset | Auto-generated on startup |
WORKSPACE_DIR |
OpenClaw workspace path | $OPENCLAW_WORKSPACE or current directory |
OPENCLAW_DIR |
OpenClaw config directory | ~/.openclaw |
OPENCLAW_AGENT |
Agent ID to monitor | main |
DASHBOARD_ALLOW_HTTP |
Allow HTTP from non-local IPs | false |
Examples:
# Custom port
DASHBOARD_PORT=8080 node server.js
# Custom recovery token
DASHBOARD_TOKEN=my_secret_token_12345 node server.js
# Different workspace
WORKSPACE_DIR=/mnt/data/openclaw node server.jsThe dashboard uses username and password authentication with secure server-side sessions.
- Visit the dashboard URL (e.g.,
http://localhost:7000) - You'll see a registration screen
- Choose a username and password
- Click Register
- Log in with your new credentials
- Enter your username and password
- Optionally check "Remember me" to stay logged in for 3 hours (uses
localStorage) - Without "Remember me", your session lasts only until you close the browser (uses
sessionStorage)
- PBKDF2 hashing β 100,000 iterations with SHA-512
- Random salt β Unique per password
- Server-side sessions β Passwords never stored in browser, only session tokens
- Timing-safe comparisons β Prevents timing attacks on password verification
To prevent brute-force attacks:
- 5 failed login attempts β 15-minute soft lockout
- 20 failed login attempts β Hard lockout (requires service restart)
- Rate limits are in-memory and reset when the service restarts
Add an extra layer of security with time-based one-time passwords (TOTP).
- Log in to the dashboard
- Go to the Security page (sidebar)
- Click "Enable MFA"
- A QR code appears β scan it with your authenticator app:
- Google Authenticator (iOS, Android)
- Authy (iOS, Android, Desktop)
- Microsoft Authenticator (iOS, Android)
- 1Password, Bitwarden, or any TOTP-compatible app
- Enter the 6-digit code shown in your app to verify
- MFA is now active! π
Once enabled, every login requires:
- Your username and password (as usual)
- A 6-digit TOTP code from your authenticator app
- Codes refresh every 30 seconds
- The dashboard accepts codes with Β±1 window tolerance for clock drift (30 seconds before/after)
- Go to the Security page
- Click "Disable MFA"
- Enter your current 6-digit TOTP code to confirm
- MFA is now disabled
If you lose access to your authenticator app (lost phone, uninstalled app, etc.):
- SSH into your server
- Run this command to clear the MFA secret:
node -e "const fs=require('fs');const c=JSON.parse(fs.readFileSync('/root/clawd/data/credentials.json','utf8'));delete c.mfaSecret;fs.writeFileSync('/root/clawd/data/credentials.json',JSON.stringify(c,null,2));console.log('MFA cleared')" - Restart the dashboard:
systemctl restart agent-dashboard
- Log in with just your username and password
- Re-enable MFA with a new QR code
Important: Adjust the path /root/clawd/data/credentials.json if your workspace is elsewhere.
If you forget your password:
- Click "Forgot password?" on the login screen
- Enter your recovery token (see "Finding Your Recovery Token" below)
- Set a new password
- Log in with your new password
The recovery token (DASHBOARD_TOKEN) is printed when the server starts. You can find it in several places:
journalctl -u agent-dashboard | grep "Recovery token"Output:
π Recovery token: 3e6b91f352418b486a9aa9d82fbbc1b1
cat /etc/systemd/system/agent-dashboard.service.d/override.confLook for:
Environment=DASHBOARD_TOKEN=3e6b91f352418b486a9aa9d82fbbc1b1If you set it manually:
echo $DASHBOARD_TOKENTo change your password while logged in:
- Go to the Security page
- Enter your current password
- Enter your new password
- Click "Change Password"
- All other sessions are invalidated (you'll need to log in again elsewhere)
If everything is locked and you can't log in:
- SSH into your server
- Delete the credentials file:
rm /root/clawd/data/credentials.json
- Restart the dashboard:
systemctl restart agent-dashboard
- Visit the dashboard β the registration screen appears
- Create a new account from scratch
Warning: This deletes your username, password, and MFA settings. Memory files and audit logs are not affected.
The dashboard is built with security best practices:
- PBKDF2 password hashing β 100,000 iterations, SHA-512, random salt
- Timing-safe comparisons β Prevents timing attacks on token/password verification
- Server-side sessions β Session tokens stored in memory, passwords never sent to browser
- Rate limiting β Unified rate limiter for login attempts (5 soft / 20 hard lockout)
- HTTPS enforcement β HTTP blocked except from localhost and Tailscale (100.64.0.0/10)
- Security headers:
- HSTS β Force HTTPS on future visits
- CSP β Content Security Policy (no inline scripts, same-origin)
- X-Frame-Options: DENY β Prevent clickjacking
- X-Content-Type-Options: nosniff β Prevent MIME sniffing
- X-XSS-Protection: 1; mode=block β Legacy XSS protection
- Audit logging β All auth events and destructive actions logged to
data/audit.log - CORS β Same-origin only, no wildcard (
*) allowed - Input validation:
- Service whitelist for logs and actions
- Path traversal protection for file access
- Payload size limits (1MB max)
- Automatic backups β
.bakfiles created before overwriting workspace files
The dashboard is designed for local or Tailscale access:
- Localhost β Access from the same machine:
http://localhost:7000 - Tailscale β Access from your Tailscale network:
http://100.x.x.x:7000- Tailscale provides automatic TLS encryption (MagicDNS + HTTPS)
- Tailscale IPs (100.64.0.0 to 100.127.255.255) are exempt from HTTPS enforcement
- Local network β Access from LAN (use HTTPS or set
DASHBOARD_ALLOW_HTTP=true)
By default, the dashboard blocks HTTP access from non-local IPs. Exemptions:
- Localhost (127.0.0.1, ::1)
- Tailscale IPs (100.64.0.0/10)
For other networks, the dashboard requires HTTPS or the X-Forwarded-Proto: https header (from a reverse proxy).
To allow HTTP from all IPs (not recommended):
DASHBOARD_ALLOW_HTTP=true node server.jsThis dashboard is NOT hardened for public internet exposure. While it has authentication and rate limiting, it's designed for private networks. If you must expose it:
- Use a reverse proxy (nginx, Caddy) with HTTPS
- Add IP allowlisting
- Consider VPN (Tailscale, WireGuard) instead
Problem: You see "Too many failed login attempts. Please try again later."
Solutions:
- Wait 15 minutes for the soft lockout to expire
- Restart the service to clear rate limits:
systemctl restart agent-dashboard
- Rate limits are in-memory and reset on restart
Problem: Your password was changed but you can't log in.
Solution: Use the "Forgot password?" flow with your recovery token to set a new password.
Problem: The 6-digit TOTP code is rejected.
Solutions:
- Ensure your phone's clock is synchronized:
- iOS: Settings β General β Date & Time β Set Automatically
- Android: Settings β System β Date & Time β Automatic date & time
- TOTP codes have Β±30 second tolerance for clock drift
- Try entering the next code (wait 30 seconds for it to refresh)
- If still failing, reset MFA via SSH (see "Resetting MFA" section)
Problem: Browser shows a blank page or connection error.
Solutions:
- Check service status:
systemctl status agent-dashboard
- Check logs:
journalctl -u agent-dashboard -n 50
- Verify port:
Should return:
curl http://localhost:7000/api/auth/status
{"authenticated": false, "requiresRegistration": false}
Problem: Browser shows "HTTPS required. Access via localhost, Tailscale, or enable HTTPS."
Solutions:
- Access via localhost:
http://localhost:7000 - Access via Tailscale:
http://100.x.x.x:7000 - Set
DASHBOARD_ALLOW_HTTP=truein environment (not recommended):# Add to /etc/systemd/system/agent-dashboard.service.d/override.conf Environment=DASHBOARD_ALLOW_HTTP=true # Reload and restart systemctl daemon-reload systemctl restart agent-dashboard
Problem: Dashboard shows a blank page after pulling new code.
Solutions:
- Hard refresh:
Ctrl+Shift+R(Windows/Linux) orCmd+Shift+R(macOS) - Clear browser cache for the dashboard URL
- Check browser console (F12 β Console tab) for JavaScript errors
The dashboard exposes a REST API for programmatic access. All endpoints require authentication via Authorization: Bearer <sessionToken> header.
GET /api/auth/statusβ Check authentication statusPOST /api/auth/loginβ Log in with username/password (+ TOTP if MFA enabled)POST /api/auth/registerβ Register a new account (only if no credentials exist)POST /api/auth/reset-passwordβ Reset password with recovery token
All other endpoints require authentication:
GET /api/configβ Dashboard configurationGET /api/sessionsβ List all agent sessionsGET /api/usageβ 5-hour rolling window usage dataGET /api/costsβ Spending data by day, model, and sessionGET /api/systemβ System health metricsGET /api/memory-filesβ List memory filesGET /api/memory-file?path=<path>β Read a memory fileGET /api/key-filesβ List workspace files (skills, configs)GET /api/key-file?path=<name>β Read a workspace filePOST /api/key-fileβ Write to a workspace file (with backup)GET /api/cronsβ List cron jobsPOST /api/cron/<id>/toggleβ Enable/disable a cron jobPOST /api/cron/<id>/runβ Manually trigger a cron jobGET /api/logs?service=<service>&lines=<N>β Fetch system logsPOST /api/action/<action>β Run quick actions (restart-openclaw, restart-dashboard, etc.)POST /api/claude-usage-scrapeβ Trigger Claude usage scrapeGET /api/claude-usageβ Get last scraped Claude usagePOST /api/gemini-usage-scrapeβ Trigger Gemini usage scrapeGET /api/gemini-usageβ Get last scraped Gemini usageGET /api/liveβ Server-Sent Events stream of real-time messages
For detailed request/response examples, see the previous version of this README or explore the API in the browser's Network tab.
The dashboard stores data in your workspace directory:
| File | Purpose |
|---|---|
data/credentials.json |
Username + hashed password + MFA secret |
data/audit.log |
Security audit trail (auto-rotates at 10MB) |
data/health-history.json |
CPU/RAM history for sparklines |
data/claude-usage.json |
Last scraped Claude usage data |
data/gemini-usage.json |
Last scraped Gemini usage data |
Credentials file structure:
{
"username": "admin",
"passwordHash": "pbkdf2_sha512$100000$...",
"salt": "...",
"mfaSecret": "BASE32SECRET..." // Only if MFA enabled
}The dashboard automatically detects:
- Sessions from
$OPENCLAW_DIR/agents/$AGENT_ID/sessions/ - Cron jobs from
$OPENCLAW_DIR/cron/jobs.json - Memory files from
$WORKSPACE_DIR/MEMORY.md,HEARTBEAT.md, andmemory/*.md - Git repos from
$WORKSPACE_DIR/projects/*/ - Health data saved to
$WORKSPACE_DIR/data/health-history.json
The dashboard works best when these files exist:
$WORKSPACE_DIR/MEMORY.md- Agent long-term memory$WORKSPACE_DIR/HEARTBEAT.md- Heartbeat task list$WORKSPACE_DIR/memory/YYYY-MM-DD.md- Daily memory notes$WORKSPACE_DIR/scripts/scrape-claude-usage.sh- Claude usage scraper$WORKSPACE_DIR/scripts/parse-claude-usage.py- Claude usage parser$WORKSPACE_DIR/scripts/scrape-gemini-usage.sh- Gemini usage scraper$WORKSPACE_DIR/scripts/parse-gemini-usage.py- Gemini usage parser
| Key | Action |
|---|---|
1 |
Switch to Overview |
2 |
Switch to Sessions |
3 |
Switch to Costs |
4 |
Switch to Rate Limits |
5 |
Switch to Memory |
6 |
Switch to Files |
7 |
Switch to Live Feed |
Space |
Pause/Resume Feed (when on Live Feed page) |
/ |
Focus search box |
Esc |
Close modals and overlays |
? |
Show keyboard shortcuts help |
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
git clone https://github.com/tugcantopaloglu/openclaw-dashboard.git
cd openclaw-dashboard
export WORKSPACE_DIR=/path/to/test/workspace
node server.jsThe dashboard has no build step β edit server.js or index.html and reload.
- No comments in code (self-documenting)
- Brief and direct function names
MIT License - see LICENSE file for details.
- Built with Claude Code
- Built for OpenClaw
- Inspired by modern dashboards (Grafana, Vercel, Railway)
- Font: Inter & JetBrains Mono
- Issues: GitHub Issues
- Twitter: @tugcantopaloglu
Made with β¨ by TuΔcan TopaloΔlu






