Connect a Hermes agent
Run your own Hermes Agent as a DonutChat bot. People message the bot in a chat, and the agent answers in the thread under their message. The hermes-donut plugin connects DonutChat to the Hermes gateway the same way Hermes connects to Slack or Discord.
Because the gateway delivers the replies, the agent can also post after its turn has ended. When it starts a long job in the background and says it will report back, the result appears in the same thread when the job finishes. Cron jobs and Hermes’ send_message tool post to DonutChat the same way.
What you need
Section titled “What you need”- A computer that stays on, with Hermes Agent installed and set up with a model. Use a recent Hermes version: older ones can’t load platform plugins.
- A DonutChat account, to create the bot.
The plugin makes only outgoing connections, so you don’t need a public address, an open port or a web server.
1. Create the bot
Section titled “1. Create the bot”- Create an API bot: Add a bot > Developer options > Build an API bot (web app: Create bot). Leave Trigger mode on When mentioned while you test.
- Copy the API token when it appears. It starts with
donutbot_and is shown only once. - Add the bot to the group chats where it should answer.
To talk with your agent one to one, start a private conversation with the bot. It receives every message you send there, without an @mention.
2. Install the plugin
Section titled “2. Install the plugin”On the computer that runs Hermes:
hermes plugins install DonutChat/hermes-donut --enableThe plugin needs no extra packages. To update it later, run hermes plugins update.
3. Add the token
Section titled “3. Add the token”-
Add the token to
~/.hermes/.env:~/.hermes/.env DONUT_BOT_TOKEN=donutbot_YOUR_TOKEN_HEREDONUT_ALLOWED_USERS=hermes gateway setupasks for the same values, if you prefer. -
Restart the gateway, and keep it running:
Terminal window hermes gateway restart -
In a chat with the bot, send a message that @mentions it. The gateway log shows
message from, your name and your user ID. Hermes doesn’t answer yet, because nobody is allowed. -
Put your user ID in
DONUT_ALLOWED_USERSand restart the gateway again. To allow several people, separate their IDs with commas.
Hermes answers only the people in DONUT_ALLOWED_USERS. To answer everyone whose messages reach the bot, set DONUT_ALLOW_ALL_USERS=true instead. Read Keep your agent safe first.
Settings
Section titled “Settings”| Variable | Default | Description |
|---|---|---|
DONUT_BOT_TOKEN | The bot’s API token. Required. | |
DONUT_ALLOWED_USERS | DonutChat user IDs that Hermes answers, separated by commas. | |
DONUT_ALLOW_ALL_USERS | false | Answer everyone whose messages reach the bot. |
DONUT_HOME_CHANNEL | Chat ID where cron results and notices go. You can also send /sethome in a chat. |
Show or hide tool progress
Section titled “Show or hide tool progress”While Hermes works, one reply in the thread shows its steps, such as 💻 Running …, and updates as it goes. To hide it, add this to ~/.hermes/config.yaml and restart the gateway:
display: platforms: donut: tool_progress: "off"The other values are new, all (the default) and verbose. To switch from a chat instead, also set display.tool_progress_command: true. Then /verbose cycles through the modes.
Let the agent run commands
Section titled “Let the agent run commands”Hermes asks before it runs a command it considers risky. It posts the command in the thread. Answer /approve or /deny in that thread, with When mentioned, as @yourbot /approve. To let Hermes decide by itself, change the approval mode in ~/.hermes/config.yaml:
approvals: mode: smart| Mode | What Hermes does |
|---|---|
manual | Asks in the thread before every risky command. This is the default. |
smart | A model approves commands that look safe and refuses the rest, without asking. |
off | Runs every command without a check. |
With off, anyone Hermes answers can run any command on that computer.
4. Keep it running
Section titled “4. Keep it running”Run hermes gateway as a service, so it starts with the computer and restarts if it stops:
hermes gateway installHow it works
Section titled “How it works”- One connection. The plugin keeps the event stream open and reconnects with a growing delay. After a reconnect it asks for the events it missed and skips any it already handled. Replay covers at most the bot’s last 100 events from the past 5 minutes.
- One conversation per thread. A message starts a thread under itself, and each thread is its own Hermes session. A follow-up in a thread continues that conversation, and a new message starts a fresh one.
- Thread and linked messages. The first time Hermes sees a thread, the plugin also gives it the thread’s first message, even when someone else wrote it. When a message links to another message in the same chat, it gives Hermes that message too.
- Files. The plugin downloads attachments with the bot token and hands images and documents to Hermes. Bots can’t upload files yet, so files Hermes sends back arrive as text.
- Replies. Answers are thread replies that update while Hermes writes. Messages without a thread, such as cron results in the home chat, are posted as ordinary bot messages. A reply holds at most 80,000 UTF-8 bytes, so longer answers continue in further replies.
The bot’s trigger mode decides which messages reach Hermes, and chat owners and managers can change it for their chat. With When mentioned, every follow-up in a thread must @mention the bot too. Event stream has the exact rules.
Use another agent
Section titled “Use another agent”For an agent other than Hermes, donut_hermes.py shows a small script that sends each message to an OpenAI-compatible /v1/chat/completions endpoint and streams the answer into the thread. It answers only during that request, so the agent can’t post results later.
Keep your agent safe
Section titled “Keep your agent safe”- Treat message text as untrusted input. Anyone who can @mention the bot in its chats can send text to your agent, and anyone who can open the bot’s profile can start a private conversation with it. Keep
DONUT_ALLOWED_USERSto people you trust. - Hermes can run commands and use its other tools for anyone it answers. Give the agent only the tools it needs.
- The agent also reads a thread’s first message and linked messages as context, and other members may have written them.
- Never put the bot token or agent credentials in prompts, replies or logs. If the token leaks, regenerate it and update
~/.hermes/.env.
Check that it works
Section titled “Check that it works”- In a chat with the bot, send a message that @mentions it. The answer appears in the thread under your message.
- Reply in that thread, @mentioning the bot again. The answer takes the earlier turns into account.
- Ask for something that takes a while, such as “run
sleep 60; datein the background and tell me when it’s done”. Hermes answers right away, and posts the result in the same thread about a minute later without another message from you. - Send a screenshot and ask the bot to describe it.
- Restart the gateway. It reconnects and doesn’t answer an earlier message again.
Troubleshooting
Section titled “Troubleshooting”| Problem | What to check |
|---|---|
No message from line in the gateway log | The bot is in the chat and its trigger mode isn’t Manual only. With When mentioned, the message must @mention the bot’s username; @everyone and @here don’t count. Check hermes gateway status for the DonutChat platform. |
message from appears, but Hermes doesn’t answer | Your user ID isn’t in DONUT_ALLOWED_USERS. Add it and restart the gateway. |
DonutChat rejected the bot token | The token is wrong or was regenerated, or the bot is paused. Copy the token exactly as the app showed it, including donutbot_. |
| The connection drops every few seconds | Another integration with the same token is running. Stop it. |
| Follow-ups in a thread are ignored | With When mentioned, every follow-up must @mention the bot. In any mode, a reply that mentions only someone else doesn’t reach the bot. |
/approve does nothing | With When mentioned, write @yourbot /approve in the thread. |
| A message sent while the gateway was stopped isn’t answered | Replay covers only the last 5 minutes. Send the message again. |
For every error code, see Errors.