| name | openclaw-bot-review-dashboard |
| description | A lightweight web dashboard for monitoring OpenClaw agents, models, sessions, and health status in real-time without a database |
| triggers | ["how do I monitor my OpenClaw bots","set up OpenClaw dashboard","view OpenClaw agent status","monitor OpenClaw model usage and tokens","check OpenClaw session health","deploy OpenClaw monitoring dashboard","configure OpenClaw bot review interface","track OpenClaw agent performance"] |
OpenClaw Bot Review Dashboard
Skill by ara.so — Hermes Skills collection.
What It Does
OpenClaw Bot Review Dashboard is a Next.js-based web interface that provides real-time monitoring for OpenClaw agents across multiple platforms (Feishu, Discord, etc.). It reads directly from ~/.openclaw/openclaw.json and local session files to display:
- Bot/agent status with model bindings and platform health
- Model configurations with context windows and capabilities
- Session management with token usage tracking
- Statistics and trends (token consumption, response times)
- Skill inventory (built-in, extension, custom)
- Alert rules with notification support
- Gateway health monitoring with auto-polling
- Pixel-art office visualization of agents
No database required — all data is derived from OpenClaw's local configuration.
Installation
Standard Setup
git clone https://github.com/xmanrui/OpenClaw-bot-review.git
cd OpenClaw-bot-review
npm install
npm run start
The dashboard will be available at http://localhost:3000.
Production Build
npm run build
npm run start
Docker Deployment
docker build -t openclaw-dashboard .
docker run -d --name openclaw-dashboard \
-p 3000:3000 \
-v $HOME/.openclaw:/root/.openclaw:ro \
openclaw-dashboard
docker run -d --name openclaw-dashboard \
-p 3000:3000 \
-e OPENCLAW_HOME=/opt/openclaw \
-v /path/to/openclaw:/opt/openclaw:ro \
openclaw-dashboard
Requirements
- Node.js: 18+ required
- OpenClaw: Must be installed with config at
~/.openclaw/openclaw.json
- Platforms: Works with Feishu, Discord, and other OpenClaw-supported platforms
Configuration
Environment Variables
export OPENCLAW_HOME=/opt/openclaw
export PORT=3000
OPENCLAW_HOME=/opt/openclaw npm run start
Directory Structure
The dashboard expects the following OpenClaw directory structure:
~/.openclaw/
├── openclaw.json # Main configuration file
├── sessions/ # Session data per agent
│ ├── agent1/
│ │ ├── session1.json
│ │ └── session2.json
│ └── agent2/
└── skills/ # Installed skills
OpenClaw Configuration
The dashboard reads from openclaw.json:
{
"agents": [
{
"name": "my-agent",
"emoji": "🤖",
"model": "gpt-4",
"platforms": {
"feishu": {
"app_id": "${FEISHU_APP_ID}",
"app_secret": "${FEISHU_APP_SECRET}"
}
}
}
],
"models": {
"gpt-4": {
"provider": "openai",
"api_key": "${OPENAI_API_KEY}",
"context_window": 8192,
"max_output": 4096
}
Key Features and Usage
Bot Dashboard
View all agents at a glance:
Model Management
Monitor all configured models:
Session Monitoring
Track active sessions per agent:
Auto-Refresh Configuration
Theme and Language
API Routes
The dashboard includes Next.js API routes for reading OpenClaw data:
Get All Bots
import type { NextApiRequest, NextApiResponse } from 'next';
import { readOpenClawConfig } from '@/lib/openclaw';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const config = await readOpenClawConfig();
const bots = config.agents.map(agent => ({
name: agent.name,
emoji: agent.emoji,
model: agent.model,
platforms: Object.keys(agent.platforms || {}),
sessionCount: getSessionCount(agent.name),
}));
res.status().({ bots });
} (error) {
res.().({ : });
}
}
Get Models
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const config = await readOpenClawConfig();
const models = Object.entries(config.models).map(([name, model]) => ({
name,
provider: model.provider,
contextWindow: model.context_window,
maxOutput: model.max_output,
reasoning: model.reasoning_support || false,
}));
res.status(200).json({ models });
}
Test Platform Connection
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { platform, agentName } = req.query;
try {
const result = await testPlatformConnection(
platform as string,
agentName as string
);
res.status(200).json({ success: result.success, message: result.message });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
}
Gateway Health Check
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const config = await readOpenClawConfig();
if (!config.gateway?.enabled) {
return res.status(200).json({ healthy: false, reason: 'disabled' });
}
try {
const port = config.gateway.port || 8080;
const response = await fetch(`http://localhost:${port}/health`);
const healthy = response.ok;
res.status(200).json({ healthy, port });
} catch (error) {
res.status(200).json({ healthy: false, reason: 'unreachable' });
}
}
Common Patterns
Reading OpenClaw Config
import fs from 'fs/promises';
import path from 'path';
import os from 'os';
export interface OpenClawConfig {
agents: Agent[];
models: Record<string, Model>;
gateway?: Gateway;
}
export async function readOpenClawConfig(): Promise<OpenClawConfig> {
const openclawHome = process.env.OPENCLAW_HOME ||
path.join(os.homedir(), '.openclaw');
const configPath = path.join(openclawHome, 'openclaw.json');
try {
const content = await fs.readFile(configPath, 'utf-8');
return JSON.parse(content);
} catch (error) {
throw new Error(`Failed to read OpenClaw config: ${error.message}`);
}
}
Reading Session Data
export async function getAgentSessions(agentName: string) {
const openclawHome = process.env.OPENCLAW_HOME ||
path.join(os.homedir(), '.openclaw');
const sessionsDir = path.join(openclawHome, 'sessions', agentName);
try {
const files = await fs.readdir(sessionsDir);
const sessions = await Promise.all(
files
.filter(f => f.endsWith('.json'))
.map(async file => {
const content = await fs.readFile(
path.join(sessionsDir, file),
'utf-8'
);
return JSON.parse(content);
})
);
return sessions;
} catch (error) {
return [];
}
}
Testing Platform Connection
export async function testPlatformConnection(
platform: string,
agentName: string
): Promise<{ success: boolean; message: string }> {
const config = await readOpenClawConfig();
const agent = config.agents.find(a => a.name === agentName);
if (!agent) {
return { success: false, message: 'Agent not found' };
}
const platformConfig = agent.platforms?.[platform];
if (!platformConfig) {
return { success: false, message: `${platform} not configured` };
}
if (platform === 'feishu') {
try {
const response = await fetch('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', {
method: 'POST',
headers: { 'Content-Type': },
: .({
: process.[platformConfig.] || platformConfig.,
: process.[platformConfig.] || platformConfig.,
}),
});
data = response.();
{
: data. === ,
: data. === ? : data.,
};
} (error) {
{ : , : error. };
}
}
{ : , : };
}
Component Example: Bot Card
import { useState } from 'react';
interface BotCardProps {
bot: {
name: string;
emoji: string;
model: string;
platforms: string[];
sessionCount: number;
};
}
export default function BotCard({ bot }: BotCardProps) {
const [isTestingPlatform, setIsTestingPlatform] = useState(false);
const testPlatform = async (platform: string) => {
setIsTestingPlatform(true);
try {
const res = await fetch(
`/api/test/platform?platform=${platform}&agentName=${bot.name}`
);
const data = await res.json();
alert(data.message);
} finally {
setIsTestingPlatform(false);
}
};
return (
{bot.emoji}
{bot.name}
Model: {bot.model}
Sessions: {bot.sessionCount}
{bot.platforms.map(platform => (
testPlatform(platform)}
disabled={isTestingPlatform}
className="px-2 py-1 text-xs bg-blue-500 text-white rounded hover:bg-blue-600 disabled:opacity-50"
>
Test {platform}
))}
);
}
Troubleshooting
Dashboard Not Loading Bots
Problem: Dashboard shows no bots or "Config not found" error.
Solution:
ls -la ~/.openclaw/openclaw.json
chmod 644 ~/.openclaw/openclaw.json
export OPENCLAW_HOME=/path/to/openclaw
npm run start
Gateway Health Shows Unhealthy
Problem: Gateway indicator shows red or unreachable.
Solution:
cat ~/.openclaw/openclaw.json | grep -A 3 gateway
netstat -an | grep 8080
tail -f ~/.openclaw/logs/gateway.log
Platform Test Fails
Problem: Clicking "Test Feishu" or "Test Discord" returns error.
Solution:
echo $FEISHU_APP_ID
echo $FEISHU_APP_SECRET
cat ~/.openclaw/openclaw.json | grep -A 5 feishu
Sessions Not Showing
Problem: Session count shows 0 or sessions page is empty.
Solution:
ls -la ~/.openclaw/sessions/
ls ~/.openclaw/sessions/my-agent/
cat ~/.openclaw/sessions/my-agent/session1.json | jq .
Docker Container Can't Read Config
Problem: Docker container shows "Config not found" error.
Solution:
docker run -d --name openclaw-dashboard \
-p 3000:3000 \
-v $HOME/.openclaw:/root/.openclaw:ro \
openclaw-dashboard
docker run -d --name openclaw-dashboard \
-p 3000:3000 \
-e OPENCLAW_HOME=/data/openclaw \
-v /opt/openclaw:/data/openclaw:ro \
openclaw-dashboard
docker logs openclaw-dashboard
Auto-Refresh Not Working
Problem: Dashboard doesn't update automatically.
Solution:
localStorage.getItem('dashboardRefreshInterval')
localStorage.removeItem('dashboardRefreshInterval')
Build Fails
Problem: npm run build errors.
Solution:
rm -rf node_modules package-lock.json
npm install
node --version
npm run type-check
npm run build -- --debug
Additional Resources