This guide walks you through deploying Hermes Agent, an open-source self-hosted AI agent by Nous Research, on an ArkHost KVM VPS running Debian 13. Hermes runs as a persistent service, accessible via Telegram, with persistent memory and a self-improving skills system.
Hermes supports Discord, Slack, Signal, WhatsApp, Matrix, and other messaging platforms. This guide focuses on Telegram because it has the simplest bot setup and works well on mobile.
Prerequisites
- An ArkHost Linux VPS. The 1 CPU / 3 GB / 40 GB tier or higher for comfortable headroom. Hermes itself is lightweight; the heavy lifting happens at the model provider. If you also run local tools alongside it, consider a higher tier.
- Debian 13 (Trixie) installed at provisioning. Other distributions work but commands below assume Debian.
- SSH access as root, ideally restricted to a jumphost or trusted IP range.
- An OpenRouter account with a funded API key (or any other supported model provider).
- A Telegram account.
Server preparation
SSH into your fresh VPS and update the system:
apt update && apt upgrade -y
apt install -y curl git python3 python3-venv nano ufw fail2ban
Configure a basic firewall. Hermes makes outbound connections only and does not need inbound ports beyond SSH:
ufw default deny incoming
ufw default allow outgoing
ufw allow from YOUR_JUMPHOST_IP to any port 22 proto tcp
ufw enable
Replace YOUR_JUMPHOST_IP with the IP address of the system you SSH from. If you do not use a jumphost, allow port 22 from anywhere with ufw allow 22/tcp.
Enable fail2ban to harden SSH against brute-force attempts:
systemctl enable --now fail2ban
Install uv (Python package manager)
Hermes uses uv for dependency management. Install it:
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc
Verify the installation:
which uv
Install Hermes Agent
Run the official installer:
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
The installer downloads Hermes, sets up a virtual environment, and links the hermes command into /usr/local/bin. Verify:
which hermes
hermes --version
Configure model provider
Run the setup wizard:
hermes setup
When prompted:
- Provider: select OpenRouter (or your preferred provider).
- API key: paste your OpenRouter API key. Use a dedicated key for Hermes with a monthly spending cap. This limits exposure if a runaway tool loop drains credits.
- Default model: choose a model suited to agentic work. Strong open-weight options include
xiaomi/mimo-v2.5-proorz-ai/glm-5.1.
Create a Telegram bot
On your phone or desktop, open Telegram and message @BotFather:
- Send
/newbotand follow the prompts to choose a display name and username (must end inbot). - Copy the bot token BotFather returns. Treat it as a credential.
- Send
/setprivacy, select your bot, choose Enable. This restricts the bot to direct messages only. - Send
/setjoingroups, select your bot, choose Disable. This prevents the bot from being added to groups.
Get your numeric Telegram user ID by messaging @userinfobot. Copy the ID it returns.
Configure Telegram in Hermes
Edit the Hermes environment file:
nano ~/.hermes/.env
Add the following lines:
TELEGRAM_BOT_TOKEN=your-bot-token-here
TELEGRAM_ALLOWED_USERS=your-numeric-user-id
The TELEGRAM_ALLOWED_USERS setting ensures only your account can interact with the bot. Without it, anyone who finds the bot username can send messages and Hermes will respond, including running tools and reading files on the server.
Install as a service
Install the gateway as a systemd user service so it survives reboots and SSH logout:
hermes gateway install
loginctl enable-linger root
The linger flag is required. Without it, the user service stops when your SSH session ends and the bot goes offline. This is the single most common reason a working bot suddenly goes silent.
Start the service:
hermes gateway start
hermes gateway status
Status output should show active (running). If it shows inactive or failed, check logs with journalctl --user -u hermes-gateway -n 50.
Verify it works
Open Telegram and find your bot via t.me/your_bot_username. Send any message:
hello
Hermes should respond within 10 seconds. The first response may be slower due to cold start. Try a few tool-calling tasks to verify full functionality:
what is the load average on this server?check if arkhost.com is reachableremember that I prefer concise responses
The last command tests persistent memory. Ask the same question in a new session via /new to confirm the preference was retained.
Configuration tweaks
The default ~/.hermes/config.yaml has settings tuned for shared multi-user deployments. For a personal single-user setup, several changes are worth making.
Open the config file:
hermes config edit
Disable daily session reset. By default, Hermes resets sessions at 4 AM each day, which means you lose conversation context overnight. Find the session_reset block and change it to:
session_reset:
mode: none
Sessions now only reset when you explicitly run /new in Telegram.
Set a sensible default personality. The default personality is kawaii, which is an upstream choice that inserts playful expressions into responses. For a professional or technical setup, find the display block and change to one of the built-in personalities such as concise, technical, or helpful:
display:
personality: concise
Verify and tighten the Tirith scanner. Tirith is a Rust-based pre-execution security scanner that detects threats pattern-matching alone misses, including homograph URLs, pipe-to-interpreter patterns, ANSI terminal injection, and prompt injection in context files. Hermes auto-installs Tirith to ~/.hermes/bin/tirith on first use, but this directory is not on PATH by default. The startup banner may report Tirith as unavailable even when it is installed.
Verify the binary exists:
ls -la ~/.hermes/bin/tirith
If present, set the explicit path in config and tighten the fail-open setting so commands are blocked when Tirith cannot verify them:
security:
tirith_path: "/root/.hermes/bin/tirith"
tirith_fail_open: false
Important: Verify Tirith is working before enabling fail-closed. If the binary is missing or the path is wrong, fail-closed mode blocks every command Hermes tries to execute. Always run the ls check above first. Adjust the path if you run Hermes as a non-root user.
Enable hard stop on tool loops. By default, Hermes only warns when stuck in a tool-call loop. Enable hard stop to auto-abort genuinely stuck loops, which saves API credits and prevents runaway behavior:
tool_loop_guardrails:
warnings_enabled: true
hard_stop_enabled: true
Save and exit. Restart the gateway for changes to take effect:
hermes gateway restart
Launch the TUI briefly to confirm the startup banner no longer shows the Tirith unavailable warning:
hermes
Exit with /exit once verified.
Disable unused skills
Hermes ships with 80+ default skills. Many are not relevant to a typical user and add context bloat. Launch the interactive per-platform skill configuration UI:
hermes skills config
Use arrow keys to navigate, SPACE to toggle skills on or off, ENTER to confirm. Skills you can safely disable for a typical setup include:
godmodeandobliteratus: jailbreak and abliteration tools with no benign use case.pokemon-playerandminecraft-modpack-server: gaming integrations.spotify,openhue,heartmula,songsee,audiocraft-audio-generation: consumer media tools.baoyu-comicandbaoyu-infographic: Chinese-language content tools.manim-video,ascii-video,gif-search: media generation utilities.
Disabled skills remain installed and can be re-enabled at any time through the same UI. After saving, restart the gateway:
hermes gateway restart
Keep Hermes updated
Nous Research ships Hermes Agent frequently. The startup banner shows when your installation is behind upstream. To update:
hermes update
This pulls the latest code, updates dependencies, runs config migrations for new options, and restarts the gateway. The update command ignores SIGHUP, so closing the SSH session mid-install will not interrupt it. Output is mirrored to ~/.hermes/logs/update.log.
Common mistakes
Patterns we see most often when something goes wrong with a Hermes setup. Avoid these and most issues never happen.
- Adding features before verifying the basics. Configure cron jobs, MCP servers, or extra messaging platforms only after the core CLI and Telegram loop is responding correctly. Stacking complexity on a broken foundation makes troubleshooting twice as hard.
- Skipping the user allowlist. Without
TELEGRAM_ALLOWED_USERSset, anyone who discovers your bot username can chat with it. Hermes will obey them, including running tools and reading files. Set the allowlist before going live. - Forgetting
loginctl enable-linger. Without it, the gateway service dies when your SSH session ends. The bot looks fine while you're logged in and goes silent the moment you log out. - Sharing one OpenRouter key across all your tools. Use a dedicated key for Hermes with a monthly spending cap. A misbehaving tool loop can burn through credits in minutes. Cap it at $20 to start and raise based on actual usage.
- Pasting credentials in chat. API keys, passwords, and tokens belong in
.envfiles Hermes reads. Anything you paste in conversation may end up in persistent memory or session logs. - Enabling
tirith_fail_open: falsewithout verifying Tirith works. If Tirith is not installed correctly, fail-closed mode blocks every command. Always checkls ~/.hermes/bin/tirithbefore tightening this setting. - Giving Hermes SSH access to production servers. Hermes runs as root on its own VM. Adding SSH keys to other production servers means a single bad inference can cascade across your infrastructure. Keep Hermes isolated. If you need it to manage other hosts, create a dedicated non-root user with narrowly scoped sudo permissions on the target, not blanket root access.
- Not setting a spending cap on day one. An autonomous agent in a tool loop with no cap can spend hundreds of euros before you notice. Set the cap in your model provider's dashboard before your first message.
Troubleshooting
Bot does not respond: check the gateway logs:
journalctl --user -u hermes-gateway -f
Send a Telegram message and watch the live output. Common causes are an incorrect bot token, missing user ID in the allowlist, or OpenRouter API errors.
Service exits with status 75/TEMPFAIL: transient upstream failure (network blip, model provider hiccup). Systemd restarts the service automatically. Not a problem unless it repeats frequently.
High memory usage: Hermes accumulates state over long sessions. If memory peaks above 2 GB, restart the service:
hermes gateway restart
Spending hits the cap: review tool call patterns. A poorly-scoped autonomous task can burn credits quickly. The tool_loop_guardrails section in config.yaml controls when Hermes warns or stops on repeated tool failures.
Tirith warning at startup: verify the binary exists at ~/.hermes/bin/tirith and that tirith_path in config points to its absolute path. The default value "tirith" only resolves if the binary is on PATH.
Bot goes offline after SSH disconnect: loginctl enable-linger was not run. Re-enable it and restart the gateway service.
Use cases
With Hermes running on an ArkHost VPS, common workflows include:
- Ops automation. Ask Hermes to check disk usage, tail logs, verify SSL certificates, or confirm backup integrity, all from Telegram. Example:
check if the SSL cert on arkhost.com expires within 30 days. - Development assistance. Clone a repo to
/opt/projects/, ask Hermes to read the codebase, implement a feature on a branch, and push it for review. Example:add input validation to the registration form in /opt/projects/myapp, commit on a new branch. - Scheduled monitoring. Set up cron jobs that run without your input: daily server health reports, weekly disk usage summaries, certificate expiry checks, or external uptime monitoring. All results delivered to Telegram.
- Research and drafting. Ask Hermes to look up documentation, summarize articles, draft emails, or translate text. Example:
draft a reply to this email, keep it professional and concise. - Multi-step workflows. Describe a task in plain language and let Hermes break it down, execute the steps, and report back. Example:
set up a staging copy of the site at staging.arkhost.com with its own SSL cert.
Next steps
With Hermes running, useful next steps include:
- Pulling your project repos to
/opt/projects/so Hermes can read and modify them on dedicated branches. - Creating
AGENTS.mdfiles in each project to encode conventions Hermes will follow. - Adding scheduled tasks via
/cronfor daily summaries or recurring monitoring. - Configuring additional messaging gateways (Discord, Signal) via
hermes gateway setup.
For full documentation, see hermes-agent.nousresearch.com/docs.