Agents

Hermes

An assistant I message on Telegram. It answers from my notes, which it can read but never change, and keeps my to-dos and what I ask it to remember. It answers only me, has no shell, browser or web access, and runs under a monthly spending cap.

Category
DispatchTakes what comes in to me and decides who handles it.
Runtime
Hermes Agent in a container on my own server
Trigger
On demand, from a chat message
Adoption
TrialHow far an agent has made it into how I work, given as a ring, after the Technology Radar.Adopt Part of how I workTrial Runs for real, on probationAssess Being looked at or built, not running regularlyHold Stopped or paused
A folded-paper chat bubble labelled Telegram sends a message to Hermes, a running origami messenger with a winged helmet, drawn inside a dashed boundary, and gets a reply. From inside the boundary Hermes reaches three things: Notes, locked with a padlock, To-dos and Remember.

What it is for

Hermes is the assistant I message on Telegram. It answers from my notes, keeps the to-dos I give it on the go, and remembers what I ask it to. That is the whole job. It never sends, posts or changes anything on my behalf: when an answer should become a note, it hands me the text and I file it myself.

It exists because of a rule I set for my second brain early on: an agent never writes to the vault directly. Reading is the useful part, with answers grounded in my own notes, from my phone. Writing is where the damage would be.

Where it runs

It runs on a small Linux server I rent, in one container, as an unprivileged user, built from a pinned release of Hermes Agent by Nous Research. Nothing on that server listens to the internet. Hermes reaches out to Telegram; Telegram never reaches in, so there is no open port and the server needs no public name.

My notes get there one way. A second container keeps a download-only mirror of my Obsidian vault, and that mirror is mounted into Hermes read-only. Hermes can read my notes and nothing else, and it cannot change them. It has no shell, no browser and no web access. The model is Claude Opus 5.5, called through an API key with a monthly cap.

How Hermes is wired Telegram messages reach two profiles in one container on my server: Hermes reads a one-way mirror of my notes and keeps its own to-dos, and Hermes coder starts a Claude Code session through an approval gate, which ends as a draft pull request on GitHub. OUTSIDE MY SERVER HERMES CONTAINER OUTSIDE READ READ · WRITE APPROVAL Telegram no open port AGENT Hermes answers, remembers PROFILE Hermes coder dispatches only MCP Session starts sessions Notes read-only mirror To-dos and memory SESSION Claude Code its own user Obsidian download only GitHub draft pull request
Solid lines are calls. The heavy line is the one path that starts a coding session, and it passes through an approval gate. The dashed line is the one-way mirror of my notes.

How a message travels

I write or dictate a message in Telegram. Hermes answers only me; a message from anyone else goes unanswered. The message goes to the model. When the model wants a note, it reads it, and nothing outside the notes. The text comes back as context, the model answers, and the reply goes to Telegram. Two gates sit on that path: who may talk, and what may be read.

Hermes coder and the MCP layer

Hermes coder is a second profile of the same deployment, with its own bot. It dispatches; it never codes. Its only tool is a small MCP server of my own that starts and stops coding sessions. It cannot read my notes, and the two bots never answer each other, so nothing that reads my notes can start code work.

When I ask it for a change, it writes a brief in my words and asks for a session. The MCP server then asks me, through Telegram buttons, whether to go ahead. Anything but an explicit yes is a no, including silence, and that check lives in the server’s code, not in a prompt. On yes, Claude Code starts under a separate user, in one of a few allowed repositories, and I get a link. The session shows up in the Claude app, where I watch and steer it from my phone. It ends as a draft pull request that I review and merge. Hermes never merges, pushes or reviews.

Why I stay sceptical

Hermes is a piece of software I have to run and maintain, with access to my notes and my phone. I do not trust it blindly. I am a bit paranoid about security, and I think that is the right default for an agent: a prompt injection in a note, an email or a web page can make an agent act. So every barrier above is something I test by calling the tools directly, not by asking the model to refuse. The model refusing proves nothing.

Honestly, I am sceptical. The barriers stop mistakes, not a determined attacker, and some of the trade-offs I accepted I would rather not have. The specifics stay in my private notes. That is why Hermes sits in Trial: it runs for real, on probation, and every new capability comes one step at a time, read-only first, with my approval in the loop.