Hermes Agent is an open source artificial intelligence agent developed by Nous Research. Unlike a simple chat interface, it can use tools, run commands, keep a memory, schedule tasks and reply from platforms such as Telegram or Discord. Installed on a VPS, it stays available around the clock, even when your personal computer is switched off.
This flexibility comes with more risk than a regular chatbot. An agent that can run commands should not run as root, accept messages from the whole Internet or keep its API keys in a world-readable file. This guide therefore describes an installation designed for a server, with a dedicated Linux account, a script reviewed before execution, a systemd service, restricted access, backups and an update procedure.
This guide was checked on September 17, 2026 on Debian and Ubuntu. Hermes Agent moves quickly. Always preview an update and read the official release notes before applying it to a production instance.
This guide covers the Hermes Agent project by Nous Research, released under the MIT license. Do not confuse it with other products named Hermes.
What you will set up
Once the installation is complete, you will have the following architecture.
- Hermes Agent runs under an unprivileged Linux user named
hermes. - Configuration files, sessions and secrets stay in
/home/hermes/.hermes/. - The AI model is provided by the service you choose, or by a compatible endpoint you run yourself.
- The Hermes gateway runs as a systemd user service and restarts at boot.
- Only the Telegram, Discord or other accounts you have authorized can talk to the agent.
- No Hermes administration port is publicly exposed by default.
Hermes Agent is free and open source, but using a model provider may be billed. The project does not ship a large language model able to run comfortably on a small VPS. Usage costs and request processing therefore depend on the provider you choose.
Prerequisites and VPS sizing
The official installation documentation supports Linux and mainly requires Git, curl and xz-utils. The installer then takes care of its Python environment, Node.js and the other required components.
To follow this guide, you will need the following.
- A recent VPS running Debian or Ubuntu, for example an OuiHeberg Linux VPS.
- An administration account with
sudo. - SSH access with a key.
- Working outbound HTTPS and DNS resolution.
- An API key or a subscription with the model provider of your choice.
- Optionally a Telegram, Discord or other supported platform token.
Hermes does not publish a universal hardware minimum, because needs change with the tools you enable. The values below are operating recommendations, not official requirements.
| Use case | vCPU | Memory | Storage | Note |
|---|---|---|---|---|
| CLI and gateway with a remote model | 2 | 4 GB | 25 GB NVMe | Reasonable baseline for personal use |
| Browsing, audio or several sessions | 4 | 8 GB | 50 GB NVMe | More headroom for Chromium and concurrent processing |
| Locally run model | Variable | Variable | Variable | Depends entirely on the model, often with a dedicated GPU |
A small VPS is enough when model inference is offloaded to an API. It may fall short if the agent launches a browser, processes large files or runs several tasks at once. Keep an eye on memory, disk space and processes after a few days of real use.
Our Hermes Agent VPS page lists the plans suited to this use. It recommends the Linux VPS 04G and its 4 GB of RAM as a starting point.
Before installing an autonomous agent, also apply the server security basics (updates, key-based SSH, firewall, backups and logging). Our Linux VPS security checklist covers these prerequisites in detail.
1. Update the system
Log in to the VPS with your administration account, then update the package index and the installed packages.
sudo apt update
sudo apt upgrade
Then install the prerequisites listed by the project.
sudo apt install ca-certificates curl git xz-utils
Check that the commands are available.
git --version
curl --version
xz --version
If a kernel or major system component update requires a reboot, do it before going further. This way you will not troubleshoot Hermes while the server is still using old libraries.
2. Create a dedicated Linux account
Do not install Hermes in /root and do not run its gateway as the superuser. The official production checklist explicitly recommends a non-root account.
Create a user named hermes.
sudo adduser --disabled-password --gecos "" hermes
Do not add it to the sudo group. Do not add it to the docker group either without weighing the consequences, because direct access to the Docker socket usually grants privileges equivalent to root on the host.
To manage this account over SSH, install only the public key you want. If the ~/.ssh/authorized_keys file of your current account holds the key that should also access the hermes account, you can copy it like this.
sudo install -d -m 0700 -o hermes -g hermes /home/hermes/.ssh
sudo install -m 0600 -o hermes -g hermes \
~/.ssh/authorized_keys /home/hermes/.ssh/authorized_keys
Check the permissions.
sudo ls -ld /home/hermes /home/hermes/.ssh
sudo ls -l /home/hermes/.ssh/authorized_keys
Next, enable lingering so user services keep running after logout. This lets the Hermes systemd service start at boot without an open SSH session.
sudo loginctl enable-linger hermes
Check the result.
loginctl show-user hermes -p Linger
The expected output is Linger=yes.
Now open a new SSH connection directly with this account.
ssh hermes@VPS_IP_ADDRESS
Unless stated otherwise, all the following commands run from this session and without sudo.
3. Download and review the official installer
Hermes publishes a quick install command.
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
It is convenient, but it pipes the downloaded content straight into the interpreter. On a server, it is better to separate download from execution so you can read the script and keep the exact fingerprint of the file you used.
Download the installer from the official domain.
curl --proto '=https' --tlsv1.2 -fsSLo /tmp/hermes-install.sh \
https://hermes-agent.nousresearch.com/install.sh
Display its SHA-256 fingerprint and read its content.
sha256sum /tmp/hermes-install.sh
less /tmp/hermes-install.sh
The fingerprint identifies the file you reviewed and documents your deployment. On its own, it is not a publisher signature. At the very least, check that the script really comes from the official domain, that it contains no unexpected destination and that the installation paths match the documentation.
Minimal installation for a VPS without a browser
If the agent does not need to drive Chromium or use the visual control features, reduce the installed software surface.
bash /tmp/hermes-install.sh --skip-browser --skip-computer-use
This option suits a bot that mostly relies on a remote model, APIs and text-based tools. The skipped components can be added later.
Installation with browser automation
To use the local browsing tools, simply run the script without these options.
bash /tmp/hermes-install.sh
Installing the Chromium system libraries requires administrator privileges. Since the hermes account deliberately has no sudo, the installer sets up what it can in the user space and then prints the exact command an administrator must run. Run it from your administration account. The official documentation also mentions sudo npx playwright install-deps chromium for Debian and Ubuntu, but it is better to use the command printed by the version actually installed.
The installer normally puts things in the following locations.
| Item | Per-user location |
|---|---|
| Project code | ~/.hermes/hermes-agent/ |
hermes command | ~/.local/bin/hermes |
| Configuration and data | ~/.hermes/ |
This mode keeps the installation inside /home/hermes. An installation launched with sudo would use a different layout and, above all, could place the secrets in /root/.hermes, which is what we avoid here.
4. Check the installation
Reload the shell environment.
source ~/.bashrc
Then check the command path, the version and the overall status.
command -v hermes
hermes --version
hermes doctor
The first result should normally point to /home/hermes/.local/bin/hermes. The hermes doctor command checks the environment, the configuration and the dependencies, among other things.
If hermes still cannot be found, add the user directory to the PATH, then reload the shell.
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Do not run the source file ~/.hermes/hermes-agent/hermes directly with the system Python. The documentation warns that this bypasses the virtual environment and can cause missing module errors.
5. Configure the model provider
Hermes orchestrates a model, but the VPS does not provide the inference service. Start the selection wizard.
hermes model
You can also use the global wizard.
hermes setup
The project supports several providers and custom endpoints. Choose based on your needs for privacy, cost, data location and tool compatibility. With an external provider, the requests sent to the model leave your VPS. The official FAQ states that Hermes collects no telemetry and keeps conversations, memory and skills locally, but calls are still sent to the provider you configure.
Enter the keys in the interactive wizard. Avoid putting a secret directly in a command, because it could remain in the shell history, in the logs of an automation tool or in the process list.
Then protect any sensitive files that were created.
chmod 700 ~/.hermes
find ~/.hermes -maxdepth 1 -type f \
\( -name '.env' -o -name 'auth.json' \) \
-exec chmod 600 {} +
Secrets belong to the hermes account and must never be copied into a Git repository. For business use, the secrets documentation also explains how to load them from external managers such as 1Password or Bitwarden Secrets Manager.
Finally, test a simple request.
hermes chat -q "Reply only with: installation operational"
If the call fails, check the key, the model name, the provider account credits, the server date and HTTPS connectivity before going further.
6. Understand the stored data
The ~/.hermes/ directory is the first thing to protect and back up. Depending on the features you use, it contains the following files in particular.
| Path | Role | Sensitivity |
|---|---|---|
config.yaml | Non-secret configuration of the agent and its tools | Medium |
.env | API keys, tokens and secret settings | Critical |
auth.json | Authentication data | Critical |
state.db | Persistent state of the gateway and sessions | High |
SOUL.md | Agent instructions and identity | Medium |
memories/ | Memory kept by the agent | High |
sessions/ | Session history and context | High |
skills/ | Added skills | Variable |
cron/ | Scheduled tasks | High |
logs/ | Operating logs | Variable |
A file without an API key is not public for all that. Conversations, memories and logs can contain business data, internal paths or document fragments. Restrict access to the hermes account and encrypt off-server backups.
7. Harden the configuration before running 24/7
Open the built-in configuration editor.
hermes config edit
The following settings make a cautious policy explicit.
approvals:
mode: smart
timeout: 300
cron_mode: deny
single_query_mode: deny
unattended_mode: deny
security:
allow_private_urls: false
Then validate the configuration.
hermes config check
The smart mode analyzes commands considered dangerous and asks for confirmation when a human decision is needed. The off mode, also presented as --yolo mode, removes these prompts. It is not suitable for an agent exposed through messaging on a VPS.
The three deny values prevent a scheduled task, a single query or an API call with no operator present from automatically approving a dangerous command. The allow_private_urls: false setting, which is the default, keeps protection against requests to private ranges, loopback and cloud metadata addresses. Only enable it if access to the internal network is essential and you accept this change of trust boundary.
These mechanisms reduce risk, but they do not turn local execution into a sandbox. A malicious prompt, a compromised tool or a model mistake can still modify every file the hermes user can access.
Isolate commands in a container
For a production gateway allowed to run code, the documentation recommends an isolated backend, Docker in particular.
terminal:
backend: docker
docker_forward_env: []
container_cpu: 1
container_memory: 2048
container_disk: 10240
container_persistent: false
These limits are an example to adapt to the memory and storage of your VPS. An empty docker_forward_env list avoids passing the server variables to the commands run inside the container.
This option assumes a properly hardened Docker installation. It must not lead you to blindly give the hermes account unrestricted access to the Docker socket. To understand the permission model, see Install Docker on a Linux VPS and our Docker Compose on a Linux VPS guide. In a sensitive environment, the SSH backend to a separate worker machine isolates the gateway and the messaging secrets even better from the commands produced by the model.
8. Connect Telegram, Discord or another messaging platform
Hermes offers a single gateway for several platforms. Start its wizard.
hermes gateway setup
The wizard asks for the credentials of each platform, for example the token of a Telegram or Discord bot. Create a dedicated bot, grant only the permissions it needs and do not reuse a token already used by another application.
Restrict who can use the agent
A valid bot token is not enough. You also need to decide who can send instructions to the agent. Hermes rejects unknown users as long as no allowlist is defined and global access is not enabled. Keep this closed-by-default behavior.
Two methods are available.
- Use code-based pairing, then approve only the expected request.
- Explicitly declare the authorized IDs for each platform.
To list pending pairings, use the following command.
hermes pairing list
To approve a Telegram code received through the expected channel, pass it like this.
hermes pairing approve telegram RECEIVED_CODE
If you prefer an explicit list, add only the IDs you need to ~/.hermes/.env.
TELEGRAM_ALLOWED_USERS=123456789
DISCORD_ALLOWED_USERS=111222333444555666
Do not set GATEWAY_ALLOW_ALL_USERS=true in production. This option would let any user who can reach the bot query the agent, spend your model budget and potentially trigger its tools.
After editing .env, check its permissions again.
chmod 600 ~/.hermes/.env
9. Install the gateway as a systemd service
Install the user service provided by Hermes.
hermes gateway install
hermes gateway start
hermes gateway status
Since loginctl enable-linger hermes was run earlier, the service keeps running after the SSH session closes and restarts with the VPS. Check that it is enabled.
systemctl --user is-enabled hermes-gateway
systemctl --user is-active hermes-gateway
Look at the latest log entries.
journalctl --user -u hermes-gateway -n 100 --no-pager
To follow events live, add the -f option.
journalctl --user -u hermes-gateway -f
The documentation also offers a system service installed with sudo hermes gateway install --system. On a single-user VPS, the user service with lingering is usually simpler and clearly keeps the unprivileged identity. Do not install a user unit and a system unit for the same profile at the same time, or you will run two competing gateways.
Add an optional watchdog
Systemd can restart the gateway if its event loop hangs. Add this setting to ~/.hermes/config.yaml.
gateway:
systemd_watchdog_seconds: 120
Then regenerate the unit and restart it.
hermes gateway install --force
hermes gateway stop
hermes gateway start
hermes gateway status
This watchdog detects a stuck process. It does not replace monitoring of connectivity with Telegram, Discord or the model provider.
10. Do you need to open a firewall port?
For a regular Telegram or Discord bot, the gateway opens the outbound connections it needs by itself. You normally have no Hermes port to publish on the Internet. The firewall can therefore keep allowing only the services you want, SSH in particular and any web services you already manage.
Do not open a port just because it appears in a Docker example or in API documentation. Server and dashboard interfaces widen the attack surface. If you need a web interface, follow these rules.
- Bind it to
127.0.0.1rather than0.0.0.0. - Reach it through an SSH tunnel or a VPN.
- Or put it behind an HTTPS reverse proxy with strong authentication.
- Never treat a secret port number as access control.
A local SSH tunnel follows this principle.
ssh -L 9119:127.0.0.1:9119 hermes@VPS_IP_ADDRESS
This command does not start the dashboard. It only makes a service already bound to loopback reachable from your local machine. If you publish an application through Nginx or Apache, also protect the transport with TLS by following our Certbot and Let's Encrypt on a VPS guide.
11. Back up Hermes without forgetting the secrets
A VPS backup is useful, but an application-level export also makes it easier to restore on another machine. Hermes provides a dedicated command.
hermes backup
According to the official migration procedure, this command creates a hermes-backup-<timestamp>.zip archive in the home directory containing all of ~/.hermes/, including the configuration, API keys, memories, sessions, skills and profiles.
This archive is therefore a critical secret. Once it is created, follow these steps.
- Check that it exists and that its size makes sense.
- Test its integrity with
unzip -t. - Transfer it to storage outside the VPS.
- Encrypt it at rest.
- Apply a retention policy.
- Delete the local copy when you no longer need it.
Here is an example check.
ls -lh ~/hermes-backup-*.zip
unzip -t ~/hermes-backup-YYYY-MM-DD_HH-MM-SS.zip
Replace the name with the one actually generated. Do not use a wildcard in a restore command if several archives are present.
Restoring is done on an existing Hermes installation.
hermes import ~/hermes-backup-YYYY-MM-DD_HH-MM-SS.zip
hermes setup
hermes doctor
Test this procedure regularly on a temporary VPS or an isolated environment. An untested backup is only an assumption.
hermes profile export is not the same as hermes backup. A profile export deliberately leaves out credentials, while the full backup includes them. The first is for sharing a sanitized profile, the second for recovering after an incident.
12. Update Hermes cleanly
Hermes moves quickly. Still, avoid blind automatic updates on a gateway that runs tools. First preview availability and the plan.
hermes update --check
hermes update --plan
The first command checks whether an update exists without changing files or restarting the gateway. The second takes stock of the installation and the services that would be affected.
For an important deployment, request a full backup before the update.
hermes update --backup
The update documentation explains that this operation updates the code and dependencies, handles configuration migrations and restarts the detected gateways. Logs are kept in ~/.hermes/logs/update.log, with detailed receipts in ~/.hermes/logs/update_receipts/.
Then check the state of the installation.
cd ~/.hermes/hermes-agent
git status --short
hermes doctor
hermes --version
hermes gateway status
Empty output from git status --short means the working tree has no local changes. If files show up although you never changed the code, review them before any other update.
To force a full backup on every update, add this setting.
updates:
pre_update_backup: full
Still keep an external copy. An archive left only on the VPS protects neither against losing the server nor against a compromised account.
13. Monitor and troubleshoot the installation
Keep this short diagnostic sequence at hand.
hermes doctor
hermes config check
hermes gateway status
journalctl --user -u hermes-gateway -n 200 --no-pager
df -h
free -h
It covers most incidents, whether an invalid configuration, a stopped service, a platform error, a full disk or a lack of memory.
The hermes command cannot be found
Reload ~/.bashrc and check the path.
source ~/.bashrc
printf '%s\n' "$PATH"
ls -l ~/.local/bin/hermes
The gateway stops after the SSH session ends
Check lingering from the administrator account.
loginctl show-user hermes -p Linger
Enable it again if needed.
sudo loginctl enable-linger hermes
The bot replies to the wrong people or to nobody
Check the user lists and pairings.
hermes pairing list
grep -E '^(TELEGRAM|DISCORD|GATEWAY).*ALLOWED_USERS' ~/.hermes/.env
Here the grep command only shows the authorized IDs, not the token lines. Still review your terminal before pasting its output into a support ticket.
The configuration no longer matches after an update
Use the built-in validation and migration tools.
hermes config check
hermes config migrate
Read the proposed changes before accepting them, then run hermes doctor again.
The model call fails
Common causes are an invalid key, an unauthorized model, an exhausted balance, a wrong endpoint or a DNS problem. Test resolution and HTTPS without displaying the key.
getent hosts hermes-agent.nousresearch.com
curl -I https://hermes-agent.nousresearch.com/
Then reconfigure the provider with hermes model rather than editing a secret blindly.
The browser does not start
Run hermes doctor and use the system dependency command printed by the installer. Chromium libraries must be installed by an administrator, while the browser and its profile stay tied to the hermes account. Do not give sudo to the service account just to fix this problem.
14. Checklist before going to production
Before letting the agent run permanently, confirm each point.
- Hermes runs with the unprivileged
hermesuser, never withroot. - The
hermesaccount belongs neither to thesudogroup nor, without a reason, to thedockergroup. - The installation script was downloaded from the official domain and reviewed before execution.
hermes doctorreports no error you do not understand.- The
.envandauth.jsonfiles are restricted to their owner. - Messaging accounts are controlled by pairing or an explicit list.
GATEWAY_ALLOW_ALL_USERSis not enabled.- The approval mode is not set to
off. - Unattended tasks reject dangerous commands.
- Private URLs stay blocked unless there is a documented need.
- No dashboard or API port is exposed directly to the Internet.
- Full backups are encrypted, stored off-site and tested.
- Updates are previewed, backed up and validated.
- Logs, disk space and memory are monitored.
Conclusion
Installing Hermes Agent on a VPS is not just about running a curl | bash one-liner. The real work is defining a lasting trust boundary, with a dedicated Linux user, limited messaging access, protected secrets, isolated commands, no needless public port and restorable backups.
The recommended path is deliberately minimal. Start without a browser or public interface, validate that the model works from the command line, then add one integration at a time. This approach makes troubleshooting easier and avoids granting permissions before you actually need them.
