A terminal-style web interface for your Hermes agent. Chat, manage cron jobs, and monitor system health — all inside Telegram.
A single 75KB HTML file. No build step, no framework, no npm. Copy it and go.
Real-time SSE streaming with typing indicator, haptic feedback, and abort-on-cancel.
Live model name, token usage progress bar, and session duration — just like the Hermes CLI.
View, create, pause, and trigger scheduled jobs from a dedicated tab.
CPU, memory, disk gauges plus process list and quick actions.
Validates Telegram initData using their published public key. No bot token needed for verification.
CSS containment, visualViewport handling, GPU-composited scrolls. No jank on keyboard open.
Seven steps. No build tools, no frameworks, no surprises.
You need Hermes v0.8.0 or later.
pip install hermes-agent
Open @BotFather, send /newbot, pick a name and username. Save the bot token — it looks like 123456789:ABCdefGHIjklMNOpqrsTUVwxyz.
Open @userinfobot, send /start. It replies with your numeric ID. This is a number like 9876543210 — not your username.
One file. That's it.
mkdir -p ~/.hermes/miniapp cp index.html ~/.hermes/miniapp/index.html
Add these to ~/.hermes/.env:
TELEGRAM_BOT_TOKEN=your_bot_token_here TELEGRAM_OWNER_ID=your_numeric_user_id TELEGRAM_ALLOWED_USERS=your_numeric_user_id API_SERVER_KEY=$(python3 -c "import secrets; print(secrets.token_urlsafe(32))")
The Hermes gateway runs on port 8642. Telegram needs HTTPS to reach it.
# Quick test (URL changes on restart): cloudflared tunnel --url http://localhost:8642 # Production (stable URL): cloudflared tunnel create hermes cloudflared tunnel route dns hermes miniapp.yourdomain.com cloudflared tunnel run hermes
In @BotFather, send /setmenubutton, pick your bot, then send your URL: https://your-domain/miniapp/index.html
Users tap the menu button in the chat to launch the mini app.
Ed25519 signature validation — Telegram's official method. No bot token needed for verification.
initData payload using their Ed25519 private key.
initData to your server via the X-Telegram-Init-Data header on every API request.
TELEGRAM_OWNER_ID. Only you can access the API.
The mini app talks to the Hermes gateway API.
| Endpoint | Auth | Purpose |
|---|---|---|
GET /health | None | System health (CPU, memory, uptime) |
GET /api/model-info | Yes | Active model, provider, context length |
GET /api/session-usage | Yes | Cumulative token usage |
GET /api/jobs | Yes | List cron jobs |
POST /api/command | Yes | Execute a slash command |
POST /v1/chat/completions | Yes | Streaming chat (SSE) |
initData validation is failing. Check:
TELEGRAM_BOT_TOKEN set? It's needed to extract the bot ID for validation.curl https://api.telegram.org/bot<TOKEN>/getMeTELEGRAM_OWNER_ID your numeric ID? Not your username.The cron tab uses Bearer token fallback. Check that API_SERVER_KEY is set in your environment and matches what the mini app has stored. Try clearing the mini app's storage: Telegram → tap and hold the mini app → Clear storage.
initData is valid for 24 hours. If the app stays open overnight, close and reopen it to get fresh data.
Free cloudflared tunnel --url tunnels get random URLs each restart. Set up a named tunnel with your own domain for stability.
cryptography packageEd25519 validation requires the cryptography Python package. Install it with:
pip install cryptography
~/.hermes/miniapp/
Found a bug? Have an idea? PRs are welcome on GitHub.