---
title: 'Hermes Flightplan #1: The Ultimate Zero to Always-On Telegram AI Agent'
summary: >-
  A complete, copy-paste path to a Hermes Agent you message from your phone over
  Telegram — one that keeps running after you close the laptop and comes back on
  its own after a crash or reboot. Written from two real builds: a cheap Hetzner
  VPS and a Mac Mini M4. One route, with the box only changing two things: the
  install command and the layer that keeps the gateway alive. Verified against
  Hermes Agent v0.16.0.
author: witcheer
authorUrl: 'https://x.com/witcheer'
category: Guides
difficulty: Intermediate
readingTime: 14
date: '2026-06-23'
tags:
  - telegram
  - gateway
  - vps
  - mac-mini
  - systemd
  - launchd
  - always-on
  - tmux
  - ssh-hardening
  - nous-portal
  - watchdog
  - goals
  - flightplan
integrations:
  - Hermes Agent
  - Telegram
  - Nous Portal
  - Hetzner
  - systemd
  - launchd
---

Want an AI agent you can message from your phone — one that keeps running after you close the laptop and comes back on its own after a reboot? Hermes Agent does this: it runs as a gateway you talk to over Telegram, and once you wire it up right, it restarts itself after a crash or a power cut.

I built the same setup on two boxes — a cheap cloud VPS and the Mac Mini on my desk — so I could write the whole path down with nothing skipped. It is **one route**. The box only changes what you type in two places: the install command, and the part that keeps the gateway alive. Everything in between is identical.

Everything below ran on my own hardware:

- **Linux path:** a Hetzner CX23 (x86, 2 vCPU, 4GB RAM, 40GB disk) on Ubuntu 24.04.4 LTS
- **Mac path:** a Mac Mini M4 on macOS 15

Both ran Hermes Agent **v0.16.0**.

## What you will have at the end

- Hermes Agent installed, running as a normal user, not root
- A Telegram bot you message from your phone, locked to your account only
- The gateway running as a managed service, so it comes back after a crash or a reboot
- On the VPS: a hardened box — key-only SSH, no root login, a firewall

## Pick your box

A **VPS** is the cheapest way in. Any x86 box with 4GB RAM and about 20GB of free disk runs this; mine is a Hetzner CX23 at **$7.79/month** (Hetzner US pricing, 2026-06-18). Rent it, and it is always on by definition.

A **Mac you already own** is the other option. Any Apple silicon Mac that stays powered works, and the running cost is zero beyond the model. The trade is that the durability layer is fiddlier on macOS, which I cover at the end.

You need an SSH key on your own machine (`ssh-keygen -t ed25519` if you do not have one), a Telegram account, and a model for the agent. This guide points at **Nous Portal**, which is OAuth, so there is no API key to keep in a file. Hermes needs a model with at least **64k context**.

## Step 1: Get the box ready

### On a VPS

Create the server at your provider: Ubuntu 24.04, an **x86** instance (not Arm — see the cost note), and paste your SSH public key at create time.

A fresh public box needs a few minutes of hardening before you put an agent on it. The `secure-box.sh` in the recipe does it in one pass: an apt upgrade, a 2GB swapfile, a non-root sudo user with your key, key-only SSH with root login off, and a firewall that allows only SSH. Edit the two variables at the top, copy it over, run it as root:

```bash
scp secure-box.sh root@<your-vps-ip>:
ssh root@<your-vps-ip> 'bash secure-box.sh'
```

This Ubuntu image shipped with `PasswordAuthentication` set to `yes`, even though I created the box with an SSH key. The script turns it off. **Before you close the root session**, open a second terminal and confirm the new user logs in, so a mistake cannot lock you out:

```bash
ssh hermes@<your-vps-ip>
```

From here you are `hermes`, not `root`.

### On a Mac

No hardening pass. It is your machine on your own network, not a public box. Install Homebrew if you do not have it (the installer uses it on the next step) and you are ready.

## Step 2: Install Hermes

The install is one command, the same on both boxes, run as your normal user:

```bash
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
source ~/.bashrc
hermes --version
```

The installer detects your OS and pulls its own toolchain (uv, Python 3.11, Node.js 22, ripgrep, ffmpeg, a Playwright Chromium for browser tools) into `~/.hermes`, so it never touches your system Python. On my Hetzner box it landed Hermes Agent v0.16.0 on Python 3.11.15.

This is the heavy step. On the VPS it took the disk from 1.2GB used to 7.8GB — about **6.6GB**, most of it the browser engine and Node. Plan for 20GB free and stop worrying. Run over a plain SSH command with no terminal, the installer prints `Setup wizard skipped (no terminal available)`, which is fine — the setup is the next step.

On a Mac the same command runs, with one wrinkle: **install Homebrew first**. With Homebrew present, the installer pulls git and its dependencies without a prompt. Without it, it falls back to Apple's Command Line Tools, which can open a macOS dialog you have to click — and a dialog is no good over SSH (this is in the installer's macOS branch). After that it is the same flow as above.

## Step 3: Point it at a model

```bash
hermes setup --portal
```

This is OAuth against Nous Portal: it prints a URL and a code, you approve it in the browser, and now the box talks to a model with **no API key sitting in a file**. Nous Portal has a free tier, and I ran the whole thing on a free model. If you would rather bring your own provider, run `hermes model` and pick one; the key then lives in `~/.hermes/.env`.

## Step 4: Talk to it

### Talk to it on a VPS

The moment your SSH drops, a foreground session dies with it. **tmux** keeps the session alive: start inside tmux, detach, and it keeps running.

```bash
sudo apt-get install -y tmux
tmux new -s hermes        # then, inside:  hermes
```

Detach with `Ctrl-b` then `d`, and reconnect later from anywhere:

```bash
ssh hermes@<your-vps-ip>
tmux attach -t hermes
```

First boot of the interactive agent takes a moment. Mine spent about 30 seconds loading the model and skills before the prompt appeared. Once it is up, the slash commands work.

`/goal` is the one worth showing: it sets a standing goal the agent works on across turns, with a judge model checking after each turn whether it is done.

```bash
/goal check this box total RAM and free disk using shell tools, then report both on one line and mark the goal done
```

Mine ran the shell command itself and came back with `VPS total RAM: 3.7Gi, free disk space: 28G` in about 15 seconds. That is the agent using its own tools.

Keep two ideas apart: **tmux holds an interactive session open across a dropped SSH connection, but not across a reboot.** For an unattended gateway that survives a restart, you want a managed service, which is step 6.

### Talk to it on a Mac

You are sitting at the machine, so you can run `hermes` in a terminal. tmux still helps if you SSH in from your laptop, but it is optional here.

## Step 5: The Telegram gateway

This part is identical on both boxes. Create a bot: message **@BotFather** on Telegram, send `/newbot`, and copy the token. Get your numeric user id from **@userinfobot**. Then configure the gateway:

```bash
hermes gateway setup
```

Pick Telegram, paste the token, and set the allowed users to your numeric id so **only you** can talk to it. The token lands in `~/.hermes/.env`, the rest in `~/.hermes/gateway.json`.

Setup only writes config. It does not start anything, so the bot stays silent — and that catches people out: nothing is polling Telegram yet. Start it in the foreground once to check it connects:

```bash
hermes gateway run
```

You want to see, in the log:

```bash
gateway.run: Connecting to telegram...
[Telegram] Connected to Telegram (polling mode)
gateway.run: ✓ telegram connected
```

**Polling mode** means the gateway reaches out to Telegram; nothing connects in to your box, which is why the firewall needs no inbound port beyond SSH. Message your bot; it should answer. Then stop the foreground gateway with `Ctrl-C`, because you cannot have two things polling the same token at once, and the next step runs it as a service.

## Step 6: Make it survive a reboot

This is the one place the two boxes diverge.

### On a VPS: systemd

`hermes gateway install` registers the gateway as a systemd service so it restarts on crash and comes back after a reboot. On this version the installer asks two `[Y/n]` questions and there is no flag to skip them. Run it over a non-interactive SSH command — the natural thing when scripting a box — and it gets no answer, aborts, and installs nothing. Feed the answers in on stdin:

```bash
printf 'n\nY\n' | hermes gateway install
```

The two questions are "start the gateway now?" and "start automatically on login/boot?". The `n` then `Y` says: do not start it this second, but do enable it on boot. The installer also turns on user-session **lingering**, which is what lets a user service run before you have logged in. Confirm it, because this is what makes "survives reboot" true and not only "survives logout":

```bash
loginctl show-user $USER -p Linger     # want: Linger=yes
```

Start it and check it:

```bash
hermes gateway start
systemctl --user status hermes-gateway
```

You want `active (running)` and `NRestarts=0`. On my box the gateway used about 280MB and the whole machine sat at about 556MB — comfortable on 4GB.

Now the real test. Reboot and do not touch it:

```bash
sudo reboot
```

Mine came back in about 15 seconds, the gateway had started on its own, reconnected to Telegram, and answered the next message **with the conversation history from before the reboot intact**. That is the whole point.

### On a Mac: launchd and a watchdog

macOS uses launchd, not systemd, and there is a trap. On macOS 15 with Hermes v0.16.0, `hermes gateway start` can fail to register the launchd service and fall back — **without telling you** — to an unsupervised background process. You see this:

```bash
Bootstrap failed: 5: Input/output error
⚠ launchd cannot manage the gateway on this macOS version (launchctl exit 5)
✓ Started gateway as a background process instead
  It will NOT auto-start at login or auto-restart on crash.
```

If you had a working launchd job before, the command unloaded it, and the fallback runs fine until the first crash or reboot — then your agent is gone with nothing to tell you. Raw `launchctl` works where the CLI fails, including over SSH:

```bash
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.hermes.gateway.plist
launchctl print gui/$(id -u)/ai.hermes.gateway | grep state    # want: state = running
```

The plist starts the gateway at login but does not restart it on crash. A **cron watchdog** closes both gaps, and cron runs at boot with no login needed. The recipe ships `gateway-watchdog.sh`; it checks every 5 minutes whether the gateway process is alive and re-bootstraps it if not. Install it on a schedule:

```bash
(crontab -l 2>/dev/null; echo '*/5 * * * * $HOME/scripts/gateway-watchdog.sh >/dev/null 2>&1') | crontab -
```

I have watched this sequence recover a downgraded gateway on my own Mac Mini. Reboot it and confirm the gateway is back within five minutes without logging in.

## Verify your setup

- **The service is up:** `systemctl --user status hermes-gateway` on Linux (`active (running)`), or `launchctl print gui/$(id -u)/ai.hermes.gateway | grep state` on macOS (`state = running`)
- **Message your bot:** it answers you, and ignores anyone not in your allowed users
- **On Linux,** `loginctl show-user $USER -p Linger` reads `Linger=yes`
- **Reboot the box,** wait, message the bot again without logging back in: it answers

## Cost

On the VPS, the box is the only spend. Mine is a Hetzner CX23 at $0.012/hour, capped at **$7.79/month** (Hetzner US pricing, 2026-06-18; the EU CX22 is the same shape and cheaper).

On the Mac, it is a machine you already own — zero extra services. The model is free on Nous Portal's free tier in both cases.

Here, memory is not the limit: the gateway used about 280MB, the whole box about 556MB, so 1GB of RAM is plenty. **Disk is the real limit:** the install is about 6.6GB, so a 1GB or 10GB image is tight — give it 20GB. And use x86, it is the safe pick.

## Run it yourself, and what is next

Both boxes have a full recipe with the exact scripts, runnable as-is:

- The VPS path: `cheap-vps`
- The Mac path: `mac-mini-24-7`

You now have an always-on agent on Telegram that survives a reboot.

The next Flightplan builds on top of it: scheduled jobs that message you only when something matters, a git-synced workspace the agent reads and writes, and the draft-and-approve flow that keeps a human on every public action.
