Overview
Live snapshot · refreshed every 5sJobs running
Completed today
Failed today
Avg job duration
Jobs / hour — last 12h
Active connections
DB size on disk
Tokens used today
Jobs
Running, queued, and history — every job the bot has runCompleted vs failed — last 24h
Jobs by backend — today
Job queue & history
| ID | Type | Backend | Status | User | Started | Duration | Tokens |
|---|---|---|---|---|---|---|---|
| Loading… | |||||||
Connections & Telemetry
Every upstream the bot depends on, liveConnection health
Latency by backend — p50 / p95
Error rate — last 6h
Database
SQLite, WAL mode — every job and event logged locallyStorage
bot.db · WAL mode
Maintenance
VACUUM reclaims space after deletes/updates. Safe to run any time — it briefly locks writes.
Export data
Download a table's full contents as JSON or CSV.
Recent writes
Control Center
Every setting the bot exposes — changes apply via hot reload, no restartBackend router
Agent control
Under "Allowlist," set which instances each bot may target from its edit form in the Bots tab.
Feature toggles
Data retention
Automatically prunes old rows from the jobs, telemetry, connection-log, and Support Bot classification tables once a day — the tables that otherwise just grow forever. Never touches audit log, chat/session history, or config history, and never deletes a job that isn't finished yet regardless of age.
Appearance
Per-browser display preferences — saved on this device only, applied instantly, no server round trip.
Snapshots
A point-in-time copy of config + the database — take one before a risky change, restore it if the change turns out wrong. Creating one never stops the app; restoring briefly reopens the database connection, not a full restart.
| Snapshot | Label | Size |
|---|
Hot Reload
Applies an edit to BotServer's own bot/*.py to this already-running process — most files take effect on the very next call; Discord/Slack/Matrix code gets a brief reconnect; a documented set of core files (routing, the database connection, the dashboard itself) still need a full restart, reported here as "restart required" rather than silently skipped.
| When | Outcome | Detail |
|---|
Models — Claude
Models — Hermes Agent
Security — allowlisted users
| Telegram ID | Name |
|---|
Process controls
The Telegram bot also asks for confirmation on stop/restart when "Confirm destructive actions" is on.
TURN Server (WebRTC mesh relay)
Used by the Android app's WebRTC fallback for mesh APK transfers, when two devices can't reach each other directly (symmetric NAT, restrictive firewalls). BotServer never runs the relay itself — this only mints short-lived credentials for a real TURN server (coturn) you run separately with the same shared secret. See docs/turn-server-setup.md.
Environment
Where secrets (bot token, API key, dashboard token) are loaded from at startup. Changing this takes effect on the next bot restart.
Edit .env contents
Editing writes straight to the file above — this is the actual bot token, API key, etc. in plain text. A timestamped backup is made automatically before every save and every restore, so nothing is ever overwritten without one. Takes effect after the server process restarts.
Backups
Every save and restore snapshots the previous file — kept indefinitely, nothing here is auto-deleted.
| Backup | Saved | Size | |
|---|---|---|---|
| Unlock with the dashboard token to view. | |||
MCP servers
Servers Claude Desktop itself has configured — enable/disable each below.
Control this app over MCP
Registers this app's own control server (bot/mcp_server.py) with Claude Desktop as an MCP server named bot-server, so Claude Desktop (or Claude Code via claude mcp add) can check status, list jobs, flip backends, and start/stop/restart Claude Desktop itself — the same things this dashboard can do, but callable as MCP tools instead of clicks.
Resilience & Hot Reload
Atomic config swaps, drained in-flight work, automatic recoveryHealth checks
Reload state
Config change history
Live Logs
Streaming tail · filter by levelChat
The real conversation across every connected platform — read it live, and operate either side of itUnlock with the dashboard token to view.
Server Chat
A permanent channel between this server's own devices — the desktop app and every paired phone — for sending messages and files directly between them, no bot involvedSupport Bot
A local, dependency-free assistant for managing this server — plain English or slash commands, same engine the Android app's Support tab usesSessions
Every past conversation, grouped and browsable — pick one up where you left offLoading…
Bots
Run any number of independent bots at once — a Claude bot and a Hermes bot on the same platform, or several platforms each, all with fully separate chats and jobs. Changes here take effect on the next server restart.Add a bot
Advanced: per-bot backend overrides
{"web_search": {"backend": "custom_model", "backup": ["api"]}}. Leave as {} for none.Plugins
Local Python files that register extra agent tools and/or slash commands — trusted local code with the same privileges the app already has (not sandboxed, not fetched from a network). Enter the path to a plugin.py already on this machine's disk.
| Name | Description | Tools | Commands | Status |
|---|
Pending pairings
Someone messaged a bot from an unrecognized chat ID and got a one-time code — approve here to add them to that bot's allowed users.
| Bot | User | Code | Requested | Expires |
|---|
Configured bots
Schedules
Recurring prompts a bot runs on its own — the same store /cron, /loop, and /heartbeat already write to in chat, now visible and manageable here too.
| Chat | Kind | Prompt | Interval | Next run | |
|---|---|---|---|---|---|
| Select a bot above. | |||||
Backups
Every create/update/delete snapshots the full bot list first — kept indefinitely, nothing here is auto-deleted.
| Backup | Saved | Size | |
|---|---|---|---|
| Unlock with the dashboard token to view. | |||
Models
Add a provider's API key, then switch individual models on or off below — free models sorted first per provider. Wherever a model gets picked (this dashboard's Add-a-bot form, Telegram's /model, dispatch_native_swarm_goal's auto-pick-free logic), a disabled model is simply never offered.Providers
Named endpoints for the "custom_model"/"native_agent" backends — any OpenAI-compatible server (a local Ollama/LM Studio/vLLM/llama.cpp instance, OpenRouter, or real OpenAI). A bot instance points at one with a model of the form "<name>/<model_id>".
| Name | Base URL | API key |
|---|
Models
Kanban
One board per bot — cards a bot adds via /kanban show up here too, and vice versa.Swarms
Groups of bots working together on one prompt — fan out to several bots and merge the answers, have a leader pick the best one, relay drafts through a pipeline, decompose into subtasks, or build a fully custom step graph.Add a swarm
Configured swarms
| Name | Strategy | Enabled | |
|---|---|---|---|
| Unlock with the dashboard token to view. | |||
Hermes swarm tools — which Hermes agents can organize a swarm themselves
A Hermes-backed instance can always spawn its own sub-agents via its native delegate_task tool. Enabling swarm tools additionally registers this app's own MCP server into that instance's Hermes config, so its agent can reach OTHER bot instances too — ask_instance, run_swarm, dispatch_swarm_goal, and more, mid-turn. Takes effect on that instance's next message, not immediately.
| Instance | Backend | Hermes home | Swarm tools | |
|---|---|---|---|---|
| Unlock with the dashboard token to view. | ||||
Project context — shared markdown docs every agent can read/write
Small, named documents any registered instance (any backend) can read via read_project_context or write via write_project_context — the one place a swarm of workers and their manager keep something like a project-status update in sync, independent of any one instance's own conversation history. Capped at 8KB per doc, 50 docs total.
| Name | Size | Updated | By | |
|---|---|---|---|---|
| Unlock with the dashboard token to view. | ||||
Run a swarm
Run history
| Started | Prompt | Status | |
|---|---|---|---|
| No runs yet. | |||
Swarm budget — pre-dispatch cost ceiling for dispatch_swarm_goal
A worst-case ESTIMATE gate (max children × assumed tokens/child × the resolved model's known price) checked before a dispatch is ever sent — not a real spend tracker. A refused dispatch is logged below as swarm_dispatch_blocked and never touches Hermes.
Delegation activity — who asked whom to do what
Every cross-instance call — ask_instance, dispatch_swarm_goal, and an api-backend agent's own delegate_to_instance — logged here, newest first. A dispatch row can be expanded for its live tool-call status and post-hoc per-child breakdown.
| Time | Kind | Detail | |
|---|---|---|---|
| Unlock with the dashboard token to view. | |||
Training
Improve the Support Bot's recognition, and give any bot instance persistent custom instructions — separate from each other, and from any live conversationModel health — hybrid classifier self-monitoring
Every message the Support Bot classifies runs through two independent models — the deterministic TF-IDF centroid model and a trained neural network (MLP) — and the hybrid trusts whichever is right more often. This is that behavior, measured live over real traffic, not a static claim.
Classifications logged
Model agreement rate
Unknown rate
Avg TF-IDF confidence
Avg neural net confidence
Support Bot phrases
Add example phrasings for an intent the Support Bot misrecognized or missed entirely — retrains both the TF-IDF model and the neural network immediately, no restart. These are layered on top of the built-in baseline (training_data.py), never replacing it.
| Phrase | Intent | |
|---|---|---|
| No custom phrases added yet. | ||
Platforms (legacy)
Superseded by the Bots tab, which supports any number of bots per platform. Kept here read/write for transparency into the original single-bot .env fields this app started with — no longer read at startup, safe to ignore.Mobile
Pair the Android app with this server — each key is its own revocable device credential, never the master dashboard tokenGenerate a key
Leave all three blank to auto-fill this machine's own detected LAN/Tailscale/Funnel addresses. Each is an independent path to this server — the app tries them in order and switches automatically if one stops answering, so the phone stays connected from any network without you doing anything.
Shown once — this key can't be recovered after you leave this page. Copy it or scan the QR now.
Paired devices
"Send APK" queues the last APK built on the desktop app for that device — it downloads and prompts to install next time the Android app is opened (there's no way to push to a closed/backgrounded phone without Firebase configured).
| Label | Created | Last used | Status | |
|---|---|---|---|---|
| Loading… | ||||
Linked Servers
Other BotServer installations you run — each keeps its own database and Telegram bot, linked here so you can see and manage them from one place1. Generate a pairing token (for someone linking into THIS server)
One click — this server auto-detects its own reachable address and bakes it into the token, so whoever links in never needs to know or type it. Share the token — never your dashboard token — with them; it works once and expires in 10 minutes, so it's safe to send over chat.
Advanced: override the auto-detected address
2. Link a server (using ITS pairing token)
Just a name and a token — no address to look up. On the other server's own Linked Servers tab, have its admin generate a pairing token (step 1 above, done on their side) and paste it below. Your own dashboard token never leaves this machine — the pairing token is the only thing sent over the network, and it stops working the instant it's used.
Advanced: let it call you back too (auto-detected)
Linked servers
| Name | Address | Linked | Status | |
|---|---|---|---|---|
| Loading… | ||||