| name | openclaw-admin-vue |
| description | AI agent management platform built with Vue 3 for OpenClaw Gateway and Hermes Agent |
| triggers | ["set up openclaw admin dashboard","how do i configure the claw admin interface","install openclaw admin frontend","manage ai agents with openclaw","connect hermes agent to openclaw admin","deploy openclaw admin ui","configure openclaw gateway dashboard","troubleshoot openclaw admin connection"] |
OpenClaw Admin Vue Skill
Skill by ara.so — Hermes Skills collection.
OpenClaw Admin is a modern AI agent management platform built with Vue 3 that provides a comprehensive web interface for both OpenClaw Gateway and Hermes Agent. It enables visual management of AI agents, sessions, models, channels, skills, and includes a full-featured Web CLI terminal with session persistence.
What OpenClaw Admin Does
- Dual Gateway Support: Manages both OpenClaw Gateway and Hermes Agent from a single interface
- Web CLI Terminal: Real terminal emulation using xterm.js with session persistence and reconnection
- Multi-Agent Orchestration: Create and coordinate multiple AI agents for complex workflows
- Real-time Monitoring: System resources, session states, token usage, and event streams
- Channel Management: Configure QQ, Feishu, DingTalk, WeChat integrations
- Skill Management: Install, update, and configure agent skills/plugins
- Memory Management: Edit agent identity, personality (SOUL.md), and instructions
Installation
Prerequisites
node >= 18.0.0
npm >= 9.0.0
python >= 3.10
Setup Steps
git clone https://github.com/itq5/OpenClaw-Admin.git
cd OpenClaw-Admin
npm install
cp .env.example .env
vim .env
Environment Configuration
VITE_PORT=3001
VITE_OPENCLAW_WS_URL=ws://localhost:8081
VITE_OPENCLAW_HTTP_URL=http://localhost:8081
VITE_HERMES_API_URL=http://localhost:8642
VITE_HERMES_WEB_URL=http://localhost:9119
VITE_HERMES_API_KEY=
VITE_CLI_SESSION_DB=./cli-sessions.db
Development Mode
npm run dev
npm run dev:server
npm run dev:all
Production Build
npm run build
npm run start
Hermes Agent Integration
Install Hermes Agent
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
hermes setup
Configure Hermes Agent
hermes setup model
OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
vim ~/.hermes/.env
API_SERVER_ENABLED=true
GATEWAY_ALLOW_ALL_USERS=true
API_SERVER_KEY=${API_SERVER_KEY}
Start Hermes Gateway
hermes gateway install
hermes gateway start
hermes dashboard
curl http://localhost:8642/v1/health
curl http://localhost:9119/api/status
Key Features and API Usage
OpenClaw Gateway Module
Session Management API
import { sessionApi } from '@/api/openclaw/session'
const createSession = async () => {
const response = await sessionApi.createSession({
session_id: 'my-session',
agent_id: 'default',
metadata: {
user_id: 'user123',
channel: 'web'
}
})
return response.data
}
const listSessions = async () => {
const sessions = await sessionApi.listSessions({
agent_id: 'default',
active: true,
limit: 20
})
return sessions.data
}
await sessionApi.resetSession('session-id')
await sessionApi.deleteSession('session-id')
Model Management API
import { modelApi } from '@/api/openclaw/model'
const addModel = async () => {
await modelApi.addModel({
provider: 'openrouter',
api_key: process.env.OPENROUTER_API_KEY,
base_url: 'https://openrouter.ai/api/v1',
models: ['anthropic/claude-3.5-sonnet']
})
}
await modelApi.setDefaultModel('anthropic/claude-3.5-sonnet')
const probeResult = await modelApi.probeModel({
provider: 'openrouter',
model: 'anthropic/claude-3.5-sonnet',
api_key: process.env.OPENROUTER_API_KEY
})
Skill Management API
import { skillApi } from '@/api/openclaw/skill'
const skills = await skillApi.listSkills()
await skillApi.installSkill({
name: 'web-search',
version: 'latest'
})
await skillApi.updateSkill('web-search')
await skillApi.toggleSkillVisibility('web-search', true)
Cron Task API
import { cronApi } from '@/api/openclaw/cron'
const createTask = async () => {
await cronApi.createTask({
name: 'morning-report',
schedule_type: 'cron',
cron_expression: '0 9 * * *',
prompt: 'Generate daily summary report',
agent_id: 'default',
enabled: true
})
}
const tasks = await cronApi.listTasks()
await cronApi.triggerTask('task-id')
Hermes Agent Module
Chat API Integration
import { hermesApi } from '@/api/hermes'
const sendMessage = async (message: string) => {
const eventSource = hermesApi.chat.sendMessageStream({
message,
session_id: 'session-123',
model: 'anthropic/claude-sonnet-4',
stream: true
})
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data)
if (data.type === 'content') {
console.log('Chunk:', data.content)
} else if (data.type === 'tool_call') {
console.log('Tool invoked:', data.tool_name)
}
}
return eventSource
}
await hermesApi.chat.executeCommand('/skills enable web-search')
Session Management
import { hermesApi } from '@/api/hermes/session'
const sessions = await hermesApi.listSessions({
page: 1,
page_size: 20,
search: 'keyword'
})
const messages = await hermesApi.getSessionMessages('session-id')
await hermesApi.deleteSession('session-id')
Configuration Management
import { hermesApi } from '@/api/hermes/config'
const config = await hermesApi.getConfig()
await hermesApi.updateConfig({
model: 'anthropic/claude-sonnet-4',
provider: 'anthropic',
max_turns: 10,
temperature: 0.7
})
const envVars = await hermesApi.getEnvVars()
await hermesApi.setEnvVar('MY_API_KEY', process.env.MY_API_KEY)
Web CLI Terminal
Using the CLI Terminal UI
The CLI terminal provides a real terminal experience with full Hermes CLI support:
import CliTerminal from '@/components/hermes/cli/CliTerminal.vue'
<template>
<CliTerminal
:session-id="currentSessionId"
:auto-connect="true"
@session-created="handleSessionCreated"
/>
</template>
CLI Session API
import axios from 'axios'
const createCliSession = async () => {
const response = await axios.post('/api/cli/sessions', {
name: 'My CLI Session',
startup_params: {
model: 'anthropic/claude-sonnet-4',
provider: 'anthropic',
skills: ['web-search', 'code-execution'],
yolo: false,
verbose: true
}
})
return response.data.session_id
}
const sessions = await axios.get('/api/cli/sessions')
const reconnect = async (sessionId: string) => {
const response = await axios.post(`/api/cli/sessions/${sessionId}/connect`)
return response.data
}
await axios.post(, {
:
})
axios.(, {
: ,
:
})
axios.()
CLI Commands Available in Terminal
/skills
/skills enable web-search
/tools
/cron list
/config
/browser
/help
/new
/model claude-sonnet-4
/status
WebSocket Event Handling
import { useOpenClawStore } from '@/stores/openclaw'
const store = useOpenClawStore()
await store.connect()
store.on('session.message', (data) => {
console.log('New message:', data)
})
store.on('system.stats', (stats) => {
console.log('System stats:', stats)
})
store.sendCommand({
type: 'chat.send',
data: {
session_id: 'my-session',
message: 'Hello AI'
}
})
Configuration Patterns
Connecting to Multiple Gateways
export const useSettingsStore = defineStore('settings', {
state: () => ({
connections: {
openclaw: {
wsUrl: 'ws://localhost:8081',
httpUrl: 'http://localhost:8081',
enabled: true
},
hermes: {
apiUrl: 'http://localhost:8642',
webUrl: 'http://localhost:9119',
apiKey: '',
enabled: true
}
}
}),
actions: {
async testConnection(type: 'openclaw' | 'hermes') {
if (type === 'openclaw') {
const ws = new WebSocket(this.connections.openclaw.wsUrl)
return new Promise((resolve, reject) => {
ws.onopen = () => { ws.close(); resolve(true) }
ws.onerror = reject
})
} {
response = ()
response.
}
}
}
})
Slash Command Implementation
export class CommandProcessor {
private commands = {
'/new': () => this.newSession(),
'/model': (args: string) => this.switchModel(args),
'/skills': () => this.listSkills(),
'/status': () => this.showStatus(),
'/help': () => this.showHelp()
}
async process(input: string) {
const [command, ...args] = input.split(' ')
const handler = this.commands[command]
if (handler) {
return await handler(args.join(' '))
}
return null
}
private async switchModel(modelName: ) {
modelApi.(modelName)
}
}
Real-time Dashboard Updates
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useDashboardStore } from '@/stores/dashboard'
const store = useDashboardStore()
const stats = ref({})
let updateInterval: number
onMounted(() => {
store.loadStats()
updateInterval = setInterval(() => {
store.loadStats()
}, 5000)
store.on('stats.update', (data) => {
stats.value = data
})
})
onUnmounted(() => {
clearInterval(updateInterval)
})
</script>
Common Patterns
Agent Office Workflow
import { agentOfficeApi } from '@/api/openclaw/agent-office'
const createScenario = async () => {
const scenario = await agentOfficeApi.createScenario({
name: 'Code Review Team',
description: 'Collaborative code review workflow',
agents: [
{ id: 'reviewer-1', role: 'senior-reviewer' },
{ id: 'reviewer-2', role: 'security-expert' },
{ id: 'coordinator', role: 'team-lead' }
]
})
await agentOfficeApi.delegateTask(scenario.id, {
agent_id: 'coordinator',
task: 'Review pull request #123',
context: { pr_url: 'https://github.com/...' }
})
return scenario
}
Custom Skill Installation
const installCustomSkill = async () => {
await skillApi.installSkill({
name: 'my-custom-skill',
source: 'github',
repository: 'username/skill-repo',
branch: 'main',
path: 'skills/my-skill'
})
}
Memory/Identity Management
import { memoryApi } from '@/api/openclaw/memory'
const updateSoul = async () => {
await memoryApi.updateDocument('SOUL', `
# Agent Personality
You are a helpful coding assistant specialized in Vue.js and TypeScript.
## Guidelines
- Always provide type-safe examples
- Explain Vue 3 Composition API patterns
- Reference official documentation
`)
}
await memoryApi.updateDocument('AGENTS', `
# Agent Instructions
## Available Tools
- code_executor: Run code snippets
- web_search: Search the web
- file_manager: Manage files
`)
Troubleshooting
Connection Issues
const testOpenClaw = async () => {
try {
const ws = new WebSocket('ws://localhost:8081')
ws.onopen = () => console.log('✓ OpenClaw connected')
ws.onerror = (err) => console.error('✗ OpenClaw error:', err)
} catch (error) {
console.error('Cannot connect to OpenClaw:', error)
}
}
const testHermes = async () => {
try {
const health = await fetch('http://localhost:8642/v1/health')
const webUI = await fetch('http://localhost:9119/api/status')
console.log('API Server:', health.ok ? '✓' : '✗')
console.log('Web UI:', webUI. ? : )
} (error) {
.(, error)
}
}
CLI Terminal Not Starting
which python3
python3 --version
hermes --version
npm run dev:server
ls -la cli-sessions.db
ulimit -n
Session Persistence Issues
import Database from 'better-sqlite3'
const db = new Database('./cli-sessions.db')
const sessions = db.prepare('SELECT * FROM cli_sessions').all()
console.log('Active sessions:', sessions)
db.prepare('DELETE FROM cli_sessions WHERE last_activity < ?')
.run(Date.now() - 24 * 60 * 60 * 1000)
WebSocket Reconnection
class ResilientWebSocket {
private reconnectDelay = 1000
private maxDelay = 30000
connect() {
this.ws = new WebSocket(this.url)
this.ws.onerror = () => {
setTimeout(() => {
this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxDelay)
this.connect()
}, this.reconnectDelay)
}
this.ws.onopen = () => {
this.reconnectDelay = 1000
}
}
}
CORS Issues
app.use(cors({
origin: process.env.VITE_FRONTEND_URL || 'http://localhost:3001',
credentials: true
}))
Build Errors
rm -rf node_modules package-lock.json
npm install
node --version
npm run build -- --mode production --debug
npx tsc --noEmit
Model API Key Issues
hermes config show
hermes chat --model anthropic/claude-sonnet-4 "Hello"
echo $ANTHROPIC_API_KEY
vim ~/.hermes/.env
Production Deployment
npm run build
npm install -g pm2
pm2 start npm --name "openclaw-admin" -- start
pm2 logs openclaw-admin
pm2 monit
pm2 startup
pm2 save
Nginx Reverse Proxy
server {
listen 80;
server_name admin.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# WebSocket support
location /ws {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
Additional Resources