Broad drift audit against origin/main (b52b63396).
Reference pages (most user-visible drift):
- slash-commands: add /busy, /curator, /footer, /indicator, /redraw, /steer
that were missing; drop non-existent /terminal-setup; fix /q footnote
(resolves to /queue, not /quit); extend CLI-only list with all 24
CLI-only commands in the registry
- cli-commands: add dedicated sections for hermes curator / fallback /
hooks (new subcommands not previously documented); remove stale
hermes honcho standalone section (the plugin registers dynamically
via hermes memory); list curator/fallback/hooks in top-level table;
fix completion to include fish
- toolsets-reference: document the real 52-toolset count; split browser
vs browser-cdp; add discord / discord_admin / spotify / yuanbao;
correct hermes-cli tool count from 36 to 38; fix misleading claim
that hermes-homeassistant adds tools (it's identical to hermes-cli)
- tools-reference: bump tool count 55 -> 68; add 7 Spotify, 5 Yuanbao,
2 Discord toolsets; move browser_cdp/browser_dialog to their own
browser-cdp toolset section
- environment-variables: add 40+ user-facing HERMES_* vars that were
undocumented (--yolo, --accept-hooks, --ignore-*, inference model
override, agent/stream/checkpoint timeouts, OAuth trace, per-platform
batch tuning for Telegram/Discord/Matrix/Feishu/WeCom, cron knobs,
gateway restart/connect timeouts); dedupe the Cron Scheduler section;
replace stale QQ_SANDBOX with QQ_PORTAL_HOST
User-guide (top level):
- cli.md: compression preserves last 20 turns, not 4 (protect_last_n: 20)
- configuration.md: display.platforms is the canonical per-platform
override key; tool_progress_overrides is deprecated and auto-migrated
- profiles.md: model.default is the config key, not model.model
- sessions.md: CLI/TUI session IDs use 6-char hex, gateway uses 8
- checkpoints-and-rollback.md: destructive-command list now matches
_DESTRUCTIVE_PATTERNS (adds rmdir, cp, install, dd)
- docker.md: the container runs as non-root hermes (UID 10000) via
gosu; fix install command (uv pip); add missing --insecure on the
dashboard compose example (required for non-loopback bind)
- security.md: systemctl danger pattern also matches 'restart'
- index.md: built-in tool count 47 -> 68
- integrations/index.md: 6 STT providers, 8 memory providers
- integrations/providers.md: drop fictional dashscope/qwen aliases
Features:
- overview.md: 9 image models (not 8), 9 TTS providers (not 5),
8 memory providers (Supermemory was missing)
- tool-gateway.md: 9 image models
- tools.md: extend common-toolsets list with search / messaging /
spotify / discord / debugging / safe
- fallback-providers.md: add 6 real providers from PROVIDER_REGISTRY
(lmstudio, kimi-coding-cn, stepfun, alibaba-coding-plan,
tencent-tokenhub, azure-foundry)
- plugins.md: Available Hooks table now includes on_session_finalize,
on_session_reset, subagent_stop
- built-in-plugins.md: add the 7 bundled plugins the page didn't
mention (spotify, google_meet, three image_gen providers, two
dashboard examples)
- web-dashboard.md: add --insecure and --tui flags
- cron.md: hermes cron create takes positional schedule/prompt, not
flags
Messaging:
- telegram.md: TELEGRAM_WEBHOOK_SECRET is now REQUIRED when
TELEGRAM_WEBHOOK_URL is set (gateway refuses to start without it
per GHSA-3vpc-7q5r-276h). Biggest user-visible drift in the batch.
- discord.md: HERMES_DISCORD_TEXT_BATCH_SPLIT_DELAY_SECONDS default
is 2.0, not 0.1
- dingtalk.md: document DINGTALK_REQUIRE_MENTION /
FREE_RESPONSE_CHATS / MENTION_PATTERNS / HOME_CHANNEL /
ALLOW_ALL_USERS that the adapter supports
- bluebubbles.md: drop fictional BLUEBUBBLES_SEND_READ_RECEIPTS env
var; the setting lives in platforms.bluebubbles.extra only
- qqbot.md: drop dead QQ_SANDBOX; add real QQ_PORTAL_HOST and
QQ_GROUP_ALLOWED_USERS
- wecom-callback.md: replace 'hermes gateway start' (service-only)
with 'hermes gateway' for first-time setup
Developer-guide:
- architecture.md: refresh tool/toolset counts (61/52), terminal
backend count (7), line counts for run_agent.py (~13.7k), cli.py
(~11.5k), main.py (~10.4k), setup.py (~3.5k), gateway/run.py
(~12.2k), mcp_tool.py (~3.1k); add yuanbao adapter, bump platform
adapter count 18 -> 20
- agent-loop.md: run_agent.py line count 10.7k -> 13.7k
- tools-runtime.md: add vercel_sandbox backend
- adding-tools.md: remove stale 'Discovery import added to
model_tools.py' checklist item (registry auto-discovery)
- adding-platform-adapters.md: mark send_typing / get_chat_info as
concrete base methods; only connect/disconnect/send are abstract
- acp-internals.md: ACP sessions now persist to SessionDB
(~/.hermes/state.db); acp.run_agent call uses
use_unstable_protocol=True
- cron-internals.md: gateway runs scheduler in a dedicated background
thread via _start_cron_ticker, not on a maintenance cycle; locking
is cross-process via fcntl.flock (Unix) / msvcrt.locking (Windows)
- gateway-internals.md: gateway/run.py ~12k lines
- provider-runtime.md: cron DOES support fallback (run_job reads
fallback_providers from config)
- session-storage.md: SCHEMA_VERSION = 11 (not 9); add migrations
10 and 11 (trigram FTS, inline-mode FTS5 re-index); add
api_call_count column to Sessions DDL; document messages_fts_trigram
and state_meta in the architecture tree
- context-compression-and-caching.md: remove the obsolete 'context
pressure warnings' section (warnings were removed for causing
models to give up early)
- context-engine-plugin.md: compress() signature now includes
focus_topic param
- extending-the-cli.md: _build_tui_layout_children signature now
includes model_picker_widget; add to default layout
Also fixed three pre-existing broken links/anchors the build warned
about (docker.md -> api-server.md, yuanbao.md -> cron-jobs.md and
tips#background-tasks, nix-setup.md -> #container-aware-cli).
Regenerated per-skill pages via website/scripts/generate-skill-docs.py
so catalog tables and sidebar are consistent with current SKILL.md
frontmatter.
docusaurus build: clean, no broken links or anchors.
16 KiB
| sidebar_position | title | description |
|---|---|---|
| 15 | Web Dashboard | Browser-based dashboard for managing configuration, API keys, sessions, logs, analytics, cron jobs, and skills |
Web Dashboard
The web dashboard is a browser-based UI for managing your Hermes Agent installation. Instead of editing YAML files or running CLI commands, you can configure settings, manage API keys, and monitor sessions from a clean web interface.
Quick Start
hermes dashboard
This starts a local web server and opens http://127.0.0.1:9119 in your browser. The dashboard runs entirely on your machine — no data leaves localhost.
Options
| Flag | Default | Description |
|---|---|---|
--port |
9119 |
Port to run the web server on |
--host |
127.0.0.1 |
Bind address |
--no-open |
— | Don't auto-open the browser |
--insecure |
off | Allow binding to non-localhost hosts (DANGEROUS — exposes API keys on the network; pair with a firewall and strong auth) |
--tui |
off | Expose the in-browser Chat tab (embedded hermes --tui via PTY/WebSocket). Alternatively set HERMES_DASHBOARD_TUI=1. |
# Custom port
hermes dashboard --port 8080
# Bind to all interfaces (use with caution on shared networks)
hermes dashboard --host 0.0.0.0
# Start without opening browser
hermes dashboard --no-open
Prerequisites
The default hermes-agent install does not ship the HTTP stack or PTY helper — those are optional extras. The web dashboard needs FastAPI and Uvicorn (web extra). The Chat tab also needs ptyprocess to spawn the embedded TUI behind a pseudo-terminal (pty extra on POSIX). Install both with:
pip install 'hermes-agent[web,pty]'
The web extra pulls in FastAPI/Uvicorn; pty pulls in ptyprocess (POSIX) or pywinpty (native Windows — note that the embedded TUI itself still requires WSL). pip install hermes-agent[all] includes both extras and is the easiest path if you also want messaging/voice/etc.
When you run hermes dashboard without the dependencies, it will tell you what to install. If the frontend hasn't been built yet and npm is available, it builds automatically on first launch.
Pages
Status
The landing page shows a live overview of your installation:
- Agent version and release date
- Gateway status — running/stopped, PID, connected platforms and their state
- Active sessions — count of sessions active in the last 5 minutes
- Recent sessions — list of the 20 most recent sessions with model, message count, token usage, and a preview of the conversation
The status page auto-refreshes every 5 seconds.
Chat
The Chat tab embeds the full Hermes TUI (the same interface you get from hermes --tui) directly in the browser. Everything you can do in the terminal TUI — slash commands, model picker, tool-call cards, markdown streaming, clarify/sudo/approval prompts, skin theming — works identically here, because the dashboard is running the real TUI binary and rendering its ANSI output through xterm.js with its WebGL renderer for pixel-perfect cell layout.
How it works:
/api/ptyopens a WebSocket authenticated with the dashboard's session token- The server spawns
hermes --tuibehind a POSIX pseudo-terminal - Keystrokes travel to the PTY; ANSI output streams back to the browser
- xterm.js's WebGL renderer paints each cell to an integer-pixel grid; mouse tracking (SGR 1006), wide characters (Unicode 11), and box-drawing glyphs all render natively
- Resizing the browser window resizes the TUI via the
@xterm/addon-fitaddon
Resume an existing session: from the Sessions tab, click the play icon (▶) next to any session. That jumps to /chat?resume=<id> and launches the TUI with --resume, loading the full history.
Prerequisites:
- Node.js (same requirement as
hermes --tui; the TUI bundle is built on first launch) ptyprocess— installed by theptyextra (pip install 'hermes-agent[web,pty]', or[all]covers both)- POSIX kernel (Linux, macOS, or WSL). Native Windows Python is not supported — use WSL.
Close the browser tab and the PTY is reaped cleanly on the server. Re-opening spawns a fresh session.
Config
A form-based editor for config.yaml. All 150+ configuration fields are auto-discovered from DEFAULT_CONFIG and organized into tabbed categories:
- model — default model, provider, base URL, reasoning settings
- terminal — backend (local/docker/ssh/modal), timeout, shell preferences
- display — skin, tool progress, resume display, spinner settings
- agent — max iterations, gateway timeout, service tier
- delegation — subagent limits, reasoning effort
- memory — provider selection, context injection settings
- approvals — dangerous command approval mode (ask/yolo/deny)
- And more — every section of config.yaml has corresponding form fields
Fields with known valid values (terminal backend, skin, approval mode, etc.) render as dropdowns. Booleans render as toggles. Everything else is a text input.
Actions:
- Save — writes changes to
config.yamlimmediately - Reset to defaults — reverts all fields to their default values (doesn't save until you click Save)
- Export — downloads the current config as JSON
- Import — uploads a JSON config file to replace the current values
:::tip
Config changes take effect on the next agent session or gateway restart. The web dashboard edits the same config.yaml file that hermes config set and the gateway read from.
:::
API Keys
Manage the .env file where API keys and credentials are stored. Keys are grouped by category:
- LLM Providers — OpenRouter, Anthropic, OpenAI, DeepSeek, etc.
- Tool API Keys — Browserbase, Firecrawl, Tavily, ElevenLabs, etc.
- Messaging Platforms — Telegram, Discord, Slack bot tokens, etc.
- Agent Settings — non-secret env vars like
API_SERVER_ENABLED
Each key shows:
- Whether it's currently set (with a redacted preview of the value)
- A description of what it's for
- A link to the provider's signup/key page
- An input field to set or update the value
- A delete button to remove it
Advanced/rarely-used keys are hidden by default behind a toggle.
Sessions
Browse and inspect all agent sessions. Each row shows the session title, source platform icon (CLI, Telegram, Discord, Slack, cron), model name, message count, tool call count, and how long ago it was active. Live sessions are marked with a pulsing badge.
- Search — full-text search across all message content using FTS5. Results show highlighted snippets and auto-scroll to the first matching message when expanded.
- Expand — click a session to load its full message history. Messages are color-coded by role (user, assistant, system, tool) and rendered as Markdown with syntax highlighting.
- Tool calls — assistant messages with tool calls show collapsible blocks with the function name and JSON arguments.
- Delete — remove a session and its message history with the trash icon.
Logs
View agent, gateway, and error log files with filtering and live tailing.
- File — switch between
agent,errors, andgatewaylog files - Level — filter by log level: ALL, DEBUG, INFO, WARNING, or ERROR
- Component — filter by source component: all, gateway, agent, tools, cli, or cron
- Lines — choose how many lines to display (50, 100, 200, or 500)
- Auto-refresh — toggle live tailing that polls for new log lines every 5 seconds
- Color-coded — log lines are colored by severity (red for errors, yellow for warnings, dim for debug)
Analytics
Usage and cost analytics computed from session history. Select a time period (7, 30, or 90 days) to see:
- Summary cards — total tokens (input/output), cache hit percentage, total estimated or actual cost, and total session count with daily average
- Daily token chart — stacked bar chart showing input and output token usage per day, with hover tooltips showing breakdowns and cost
- Daily breakdown table — date, session count, input tokens, output tokens, cache hit rate, and cost for each day
- Per-model breakdown — table showing each model used, its session count, token usage, and estimated cost
Cron
Create and manage scheduled cron jobs that run agent prompts on a recurring schedule.
- Create — fill in a name (optional), prompt, cron expression (e.g.
0 9 * * *), and delivery target (local, Telegram, Discord, Slack, or email) - Job list — each job shows its name, prompt preview, schedule expression, state badge (enabled/paused/error), delivery target, last run time, and next run time
- Pause / Resume — toggle a job between active and paused states
- Trigger now — immediately execute a job outside its normal schedule
- Delete — permanently remove a cron job
Skills
Browse, search, and toggle skills and toolsets. Skills are loaded from ~/.hermes/skills/ and grouped by category.
- Search — filter skills and toolsets by name, description, or category
- Category filter — click category pills to narrow the list (e.g. MLOps, MCP, Red Teaming, AI)
- Toggle — enable or disable individual skills with a switch. Changes take effect on the next session.
- Toolsets — a separate section shows built-in toolsets (file operations, web browsing, etc.) with their active/inactive status, setup requirements, and list of included tools
:::warning Security
The web dashboard reads and writes your .env file, which contains API keys and secrets. It binds to 127.0.0.1 by default — only accessible from your local machine. If you bind to 0.0.0.0, anyone on your network can view and modify your credentials. The dashboard has no authentication of its own.
:::
/reload Slash Command
The dashboard PR also adds a /reload slash command to the interactive CLI. After changing API keys via the web dashboard (or by editing .env directly), use /reload in an active CLI session to pick up the changes without restarting:
You → /reload
Reloaded .env (3 var(s) updated)
This re-reads ~/.hermes/.env into the running process's environment. Useful when you've added a new provider key via the dashboard and want to use it immediately.
REST API
The web dashboard exposes a REST API that the frontend consumes. You can also call these endpoints directly for automation:
GET /api/status
Returns agent version, gateway status, platform states, and active session count.
GET /api/sessions
Returns the 20 most recent sessions with metadata (model, token counts, timestamps, preview).
GET /api/config
Returns the current config.yaml contents as JSON.
GET /api/config/defaults
Returns the default configuration values.
GET /api/config/schema
Returns a schema describing every config field — type, description, category, and select options where applicable. The frontend uses this to render the correct input widget for each field.
PUT /api/config
Saves a new configuration. Body: {"config": {...}}.
GET /api/env
Returns all known environment variables with their set/unset status, redacted values, descriptions, and categories.
PUT /api/env
Sets an environment variable. Body: {"key": "VAR_NAME", "value": "secret"}.
DELETE /api/env
Removes an environment variable. Body: {"key": "VAR_NAME"}.
GET /api/sessions/{session_id}
Returns metadata for a single session.
GET /api/sessions/{session_id}/messages
Returns the full message history for a session, including tool calls and timestamps.
GET /api/sessions/search
Full-text search across message content. Query parameter: q. Returns matching session IDs with highlighted snippets.
DELETE /api/sessions/{session_id}
Deletes a session and its message history.
GET /api/logs
Returns log lines. Query parameters: file (agent/errors/gateway), lines (count), level, component.
GET /api/analytics/usage
Returns token usage, cost, and session analytics. Query parameter: days (default 30). Response includes daily breakdowns and per-model aggregates.
GET /api/cron/jobs
Returns all configured cron jobs with their state, schedule, and run history.
POST /api/cron/jobs
Creates a new cron job. Body: {"prompt": "...", "schedule": "0 9 * * *", "name": "...", "deliver": "local"}.
POST /api/cron/jobs/{job_id}/pause
Pauses a cron job.
POST /api/cron/jobs/{job_id}/resume
Resumes a paused cron job.
POST /api/cron/jobs/{job_id}/trigger
Immediately triggers a cron job outside its schedule.
DELETE /api/cron/jobs/{job_id}
Deletes a cron job.
GET /api/skills
Returns all skills with their name, description, category, and enabled status.
PUT /api/skills/toggle
Enables or disables a skill. Body: {"name": "skill-name", "enabled": true}.
GET /api/tools/toolsets
Returns all toolsets with their label, description, tools list, and active/configured status.
CORS
The web server restricts CORS to localhost origins only:
http://localhost:9119/http://127.0.0.1:9119(production)http://localhost:3000/http://127.0.0.1:3000http://localhost:5173/http://127.0.0.1:5173(Vite dev server)
If you run the server on a custom port, that origin is added automatically.
Development
If you're contributing to the web dashboard frontend:
# Terminal 1: start the backend API
hermes dashboard --no-open
# Terminal 2: start the Vite dev server with HMR
cd web/
npm install
npm run dev
The Vite dev server at http://localhost:5173 proxies /api requests to the FastAPI backend at http://127.0.0.1:9119.
The frontend is built with React 19, TypeScript, Tailwind CSS v4, and shadcn/ui-style components. Production builds output to hermes_cli/web_dist/ which the FastAPI server serves as a static SPA.
Automatic Build on Update
When you run hermes update, the web frontend is automatically rebuilt if npm is available. This keeps the dashboard in sync with code updates. If npm isn't installed, the update skips the frontend build and hermes dashboard will build it on first launch.
Themes & plugins
The dashboard ships with six built-in themes and can be extended with user-defined themes, plugin tabs, and backend API routes — all drop-in, no repo clone needed.
Switch themes live from the header bar — click the palette icon next to the language switcher. Selection persists to config.yaml under dashboard.theme and is restored on page load.
Built-in themes:
| Theme | Character |
|---|---|
Hermes Teal (default) |
Dark teal + cream, system fonts, comfortable spacing |
Midnight (midnight) |
Deep blue-violet, Inter + JetBrains Mono |
Ember (ember) |
Warm crimson + bronze, Spectral serif + IBM Plex Mono |
Mono (mono) |
Grayscale, IBM Plex, compact |
Cyberpunk (cyberpunk) |
Neon green on black, Share Tech Mono |
Rosé (rose) |
Pink + ivory, Fraunces serif, spacious |
To build your own theme, add a plugin tab, inject into shell slots, or expose plugin-specific REST endpoints, see Extending the Dashboard — the complete guide covers:
- Theme YAML schema — palette, typography, layout, assets, componentStyles, colorOverrides, customCSS
- Layout variants —
standard,cockpit,tiled - Plugin manifest, SDK, shell slots, page-scoped slots (inject widgets into built-in pages without overriding them), backend FastAPI routes
- A full combined theme-plus-plugin walkthrough (Strike Freedom cockpit demo)
- Discovery, reload, and troubleshooting