Hermes Agent integrates with Matrix, the open, federated messaging protocol. Matrix lets you run your own homeserver or use a public one like matrix.org — either way, you keep control of your communications. The bot connects via the mautrix Python SDK, processes messages through the Hermes Agent pipeline (including tool use, memory, and reasoning), and responds in real time. It supports text, file attachments, images, audio, video, and optional end-to-end encryption (E2EE).
Hermes works with any Matrix homeserver — Synapse, Conduit, Dendrite, or matrix.org.
Before setup, here’s the part most people want to know: how Hermes behaves once it’s connected.
Hermes responds to every message. No @mention needed. Each DM has its own session. Set MATRIX_DM_MENTION_THREADS=true to start a thread when the bot is @mentioned in a DM.
Rooms
By default, Hermes requires an @mention to respond. Set MATRIX_REQUIRE_MENTION=false or add room IDs to MATRIX_FREE_RESPONSE_ROOMS for free-response rooms. Room invites are auto-accepted.
Threads
Hermes supports Matrix threads (MSC3440). If you reply in a thread, Hermes keeps the thread context isolated from the main room timeline. Threads where the bot has already participated do not require a mention.
Auto-threading
By default, Hermes auto-creates a thread for each message it responds to in a room. This keeps conversations isolated. Set MATRIX_AUTO_THREAD=false to disable.
Shared rooms with multiple users
By default, Hermes isolates session history per user inside the room. Two people talking in the same room do not share one transcript unless you explicitly disable that.
Tip
The bot automatically joins rooms when invited. Just invite the bot’s Matrix user to any room and it will join and start responding.
MATRIX_REACTIONS=true# default: true — emoji reactions during processing
Tip: Disabling reactionsMATRIX_REACTIONS=false turns off the processing-lifecycle emoji reactions (👀/✅/❌) the bot posts on inbound messages. Useful for rooms where reaction events are noisy or aren’t supported by all participating clients.
Note
If you are upgrading from a version that did not have MATRIX_REQUIRE_MENTION, the bot previously responded to all messages in rooms. To preserve that behavior, set MATRIX_REQUIRE_MENTION=false.
This guide walks you through the full setup process — from creating your bot account to sending your first message.
The response includes an access_token field — copy it.
Warning: Keep your access token safe
The access token gives full access to the bot’s Matrix account. Never share it publicly or commit it to Git. If compromised, revoke it by logging out all sessions for that user.
Instead of providing an access token, you can give Hermes the bot’s user ID and password. Hermes will log in automatically on startup. This is simpler but means the password is stored in your .env file.
The bot should connect to your homeserver and start syncing within a few seconds. Send it a message — either a DM or in a room it has joined — to test.
Tip
You can run hermes gateway in the background or as a systemd service for persistent operation. See the deployment docs for details.
If your Matrix account has cross-signing enabled (the default in Element), set the recovery key so the bot can self-sign its device on startup. Without this, other Matrix clients may refuse to share encryption sessions with the bot after a device key rotation.
Terminal window
MATRIX_RECOVERY_KEY=EsT...yourrecoverykeyhere
Where to find it: In Element, go to Settings → Security & Privacy → Encryption → your recovery key (also called the “Security Key”). This is the key you were asked to save when you first set up cross-signing.
On each startup, if MATRIX_RECOVERY_KEY is set, Hermes imports cross-signing keys from the homeserver’s secure secret storage and signs the current device. This is idempotent and safe to leave enabled permanently.
Warning: Deleting the crypto store
If you delete ~/.hermes/platforms/matrix/store/crypto.db, the bot loses its encryption identity. Simply restarting with the same device ID will not fully recover — the homeserver still holds one-time keys signed with the old identity key, and peers cannot establish new Olm sessions.
Hermes detects this condition on startup and refuses to enable E2EE, logging: device XXXX has stale one-time keys on the server signed with a previous identity key.
Easiest recovery: generate a new access token (which gets a fresh device ID with no stale key history). See the “Upgrading from a previous version with E2EE” section below. This is the most reliable path and avoids touching the homeserver database.
Manual recovery (advanced — keeps the same device ID):
Stop Synapse and delete the old device from its database:
Terminal window
sudosystemctlstopmatrix-synapse
sudosqlite3/var/lib/matrix-synapse/homeserver.db"
DELETE FROM e2e_device_keys_json WHERE device_id = 'DEVICE_ID' AND user_id = '@hermes:your-server';
DELETE FROM e2e_one_time_keys_json WHERE device_id = 'DEVICE_ID' AND user_id = '@hermes:your-server';
DELETE FROM e2e_fallback_keys_json WHERE device_id = 'DEVICE_ID' AND user_id = '@hermes:your-server';
DELETE FROM devices WHERE device_id = 'DEVICE_ID' AND user_id = '@hermes:your-server';
"
sudosystemctlstartmatrix-synapse
Or via the Synapse admin API (note the URL-encoded user ID):
Note: deleting a device via the admin API may also invalidate the associated access token. You may need to generate a new token afterward.
Delete the local crypto store and restart Hermes:
Terminal window
rm-f~/.hermes/platforms/matrix/store/crypto.db*
# restart hermes
Other Matrix clients (Element, matrix-commander) may cache the old device keys. After recovery, type /discardsession in Element to force a new encryption session with the bot.
Info
If mautrix[encryption] is not installed or libolm is missing, the bot falls back to a plain (unencrypted) client automatically. You’ll see a warning in the logs.
You can designate a “home room” where the bot sends proactive messages (such as cron job output, reminders, and notifications). There are two ways to set it:
Cause: The bot hasn’t joined the room, or MATRIX_ALLOWED_USERS doesn’t include your User ID.
Fix: Invite the bot to the room — it auto-joins on invite. Verify your User ID is in MATRIX_ALLOWED_USERS (use the full @user:server format). Restart the gateway.
”Failed to authenticate” / “whoami failed” on startup
Cause: The access token or homeserver URL is incorrect.
Fix: Verify MATRIX_HOMESERVER points to your homeserver (include https://, no trailing slash). Check that MATRIX_ACCESS_TOKEN is valid — try it with curl:
Tip
If you also manually deleted crypto.db, see the “Deleting the crypto store” warning in the E2EE section above — there are additional steps to clear stale one-time keys from the homeserver.
If you previously used Hermes with MATRIX_ENCRYPTION=true and are upgrading to
a version that uses the new SQLite-based crypto store, the bot’s encryption
identity has changed. Your Matrix client (Element) may cache the old device keys
and refuse to share encryption sessions with the bot.
Symptoms: The bot connects and shows “E2EE enabled” in the logs, but all
messages show “could not decrypt event” and the bot never responds.
What’s happening: The old encryption state (from the previous matrix-nio or
serialization-based mautrix backend) is incompatible with the new SQLite crypto
store. The bot creates a fresh encryption identity, but your Matrix client still
has the old keys cached and won’t share the room’s encryption session with a
device whose keys changed. This is a Matrix security feature — clients treat
changed identity keys for the same device as suspicious.
Fix (one-time migration):
Generate a new access token to get a fresh device ID. The simplest way:
Set your recovery key (if you use cross-signing — most Element users do). Add to ~/.hermes/.env:
Terminal window
MATRIX_RECOVERY_KEY=EsT...yourrecoverykeyhere
This lets the bot self-sign with cross-signing keys on startup, so Element trusts the new device immediately. Without this, Element may see the new device as unverified and refuse to share encryption sessions. Find your recovery key in Element under Settings → Security & Privacy → Encryption.
Force your Matrix client to rotate the encryption session. In Element,
open the DM room with the bot and type /discardsession. This forces Element
to create a new encryption session and share it with the bot’s new device.
Restart the gateway:
Terminal window
hermesgatewayrun
If MATRIX_RECOVERY_KEY is set, you should see Matrix: cross-signing verified via recovery key in the logs.
Send a new message. The bot should decrypt and respond normally.
Note
After migration, messages sent before the upgrade cannot be decrypted — the old
encryption keys are gone. This only affects the transition; new messages work
normally.
TipNew installations are not affected. This migration is only needed if you had
a working E2EE setup with a previous version of Hermes and are upgrading.
Why a new access token? Each Matrix access token is bound to a specific device
ID. Reusing the same device ID with new encryption keys causes other Matrix
clients to distrust the device (they see changed identity keys as a potential
security breach). A new access token gets a new device ID with no stale key
history, so other clients trust it immediately.
Matrix E2EE requires libolm, which doesn’t compile on macOS ARM64 (Apple Silicon). The hermes-agent[matrix] extra is gated to Linux only. If you’re on macOS, proxy mode lets you run E2EE in a Docker container on a Linux VM while the actual agent runs natively on macOS with full access to your local files, memory, and skills.
The Docker container only handles Matrix protocol + E2EE. When a message arrives, it decrypts it and forwards the text to the host via a standard HTTP request. The host runs the agent, calls tools, generates a response, and streams it back. The container encrypts and sends the response to Matrix. All sessions are unified — CLI, Matrix, Telegram, and any other platform share the same memory and conversation history.
Proxy mode is not limited to Matrix. Any platform adapter can use it — set GATEWAY_PROXY_URL on any gateway instance and it will forward to the remote agent instead of running one locally. This is useful for any deployment where the platform adapter needs to run in a different environment from the agent (network isolation, E2EE requirements, resource constraints).
Tip
Session continuity is maintained via the X-Hermes-Session-Id header. The host’s API server tracks sessions by this ID, so conversations persist across messages just like they would with a local agent.
NoteLimitations (v1): Tool progress messages from the remote agent are not relayed back — the user sees the streamed final response only, not individual tool calls. Dangerous command approval prompts are handled on the host side, not relayed to the Matrix user. These can be addressed in future updates.
Cause: Long-running tool executions can delay the sync loop, or the homeserver is slow.
Fix: The sync loop automatically retries every 5 seconds on error. Check the Hermes logs for sync-related warnings. If the bot consistently falls behind, ensure your homeserver has adequate resources.
Cause: The Hermes gateway isn’t running, or it failed to connect.
Fix: Check that hermes gateway is running. Look at the terminal output for error messages. Common issues: wrong homeserver URL, expired access token, homeserver unreachable.
Warning
Always set MATRIX_ALLOWED_USERS to restrict who can interact with the bot. Without it, the gateway denies all users by default as a safety measure. Only add User IDs of people you trust — authorized users have full access to the agent’s capabilities, including tool use and system access.
For more information on securing your Hermes Agent deployment, see the Security Guide.
Any homeserver: Works with Synapse, Conduit, Dendrite, matrix.org, or any spec-compliant Matrix homeserver. No specific homeserver software required.
Federation: If you’re on a federated homeserver, the bot can communicate with users from other servers — just add their full @user:server IDs to MATRIX_ALLOWED_USERS.
Auto-join: The bot automatically accepts room invites and joins. It starts responding immediately after joining.
Media support: Hermes can send and receive images, audio, video, and file attachments. Media is uploaded to your homeserver using the Matrix content repository API.
Native voice messages (MSC3245): The Matrix adapter automatically tags outgoing voice messages with the org.matrix.msc3245.voice flag. This means TTS responses and voice audio are rendered as native voice bubbles in Element and other clients that support MSC3245, rather than as generic audio file attachments. Incoming voice messages with the MSC3245 flag are also correctly identified and routed to speech-to-text transcription. No configuration is needed — this works automatically.