Messaging gateway

Hermes Agent on Discord

Hermes Agent runs on Discord as a bot through its messaging gateway. You create a Discord application and bot, turn on the Message Content Intent, invite the bot with the bot and applications.commands scopes, give Hermes the bot token plus your numeric Discord user ID (hermes gateway setup), and keep hermes gateway running.

Once connected, Hermes answers every message in a DM, but in server channels only when you @mention it — and each mention opens a new thread by default. With no allowlist configured it stays online but answers no one, and it goes offline whenever the gateway stops.

Checked against official Nous Research sources on September 26, 2026 (Hermes Agent v0.21.5).

How Hermes behaves on Discord

Defaults from the official Discord docs — most “the bot is ignoring me” reports are one of these rows:

WhereDefault behaviorChange it with
DMReplies to every message; no mention needed. Each DM is its own session.—
Server channelReplies only when @mentioned, then moves the conversation into a new threadDISCORD_REQUIRE_MENTION, DISCORD_AUTO_THREAD
Free-response channelReplies to every message, inline (no thread)DISCORD_FREE_RESPONSE_CHANNELS
Thread Hermes is already inKeeps replying without a new mentionDISCORD_THREAD_REQUIRE_MENTION
Forum channelEvery send from Hermes creates a new forum postNo setting — forums only accept posts
Message @mentioning someone elseStays silent (server channels only)DISCORD_IGNORE_NO_MENTION
Messages from other botsIgnoredDISCORD_ALLOW_BOTS
Several people in one channelEach person gets a separate conversationgroup_sessions_per_user in config.yaml

What you need before setup

  • A working Hermes install with a model connected — confirm a plain chat works first (setup guide).
  • A Discord account and a server where you have Manage Server (needed to invite a bot).
  • Discord Developer Mode on (User Settings → Advanced) so you can copy numeric IDs.
  • A machine that stays on while you want the bot to answer — your laptop works for testing; see the gateway section.

Step 1: Create the Discord bot

  1. In the Discord Developer Portal, click New Application and name it. Note the Application ID.
  2. Open Bot. Leave Require OAuth2 Code Grant off. Public Bot on lets you use Discord's generated invite link; off means you must build the invite URL by hand (Step 2).
  3. Under Privileged Gateway Intents, turn on the intents below and click Save Changes.
  4. Under Token, click Reset Token and copy it — Discord shows it once. Anyone with it controls the bot.
IntentDoes Hermes need it?What breaks without it
Message ContentAlways — Hermes requests it on every connectDiscord refuses the connection with PrivilegedIntentsRequired, so the bot never comes online
Server MembersOnly if you allowlist by role (DISCORD_ALLOWED_ROLES) or by username instead of numeric IDRole and username allowlists can't be resolved
PresenceNoNothing
Sources disagree: The official setup steps call Server Members Intent “required”, while the same page's troubleshooting section — and the Discord adapter source — request it only for role or username allowlists. Turning it on anyway is harmless for a personal bot; bots in 100+ servers need Discord's verification to use privileged intents.

Step 2: Invite the bot to your server

Use the Installation tab (Guild Install, scopes bot + applications.commands) or build the URL yourself. The applications.commands scope is what lets Hermes register its slash commands.

Manual invite URL (recommended permissions)
text
https://discord.com/oauth2/authorize?client_id=YOUR_APP_ID&scope=bot+applications.commands&permissions=274878286912
Permission setIntegerIncludes
Minimal117760View Channels, Send Messages, Read Message History, Attach Files
Recommended274878286912Minimal plus Embed Links, Send Messages in Threads, Add Reactions

Hermes auto-creates threads and adds 👀/✅/❌ reactions by default, so the recommended set matches the default behavior. The bot shows as offline in the member list until the gateway starts.

Step 3: Connect Discord to Hermes

Run the guided setup and choose Discord, or write the values yourself. The web dashboard's Channels page has the same per-platform form. Unlike Telegram, the official docs describe no QR shortcut for Discord — you create the bot in the Developer Portal.

Configure and start
bash
$hermes gateway setup # choose Discord, paste the token and your user ID
$
# …or add to ~/.hermes/.env
$DISCORD_BOT_TOKEN=your-bot-token
$DISCORD_ALLOWED_USERS=284102345871466496
$
$hermes gateway # start in the foreground to test

Send the bot a DM, then @mention it in a channel it can see. The 👀 reaction means the message was accepted and is being processed. Once that works, install the gateway as a service (hermes gateway install) so it survives logout and reboots. Settings in .env override the matching keys under discord: in ~/.hermes/config.yaml.

Which ID goes where

With Developer Mode on, right-click a user, role, channel, or server and choose Copy ID. Every Hermes setting takes the numeric ID, never a name:

IDUsed inPurpose
Your user IDDISCORD_ALLOWED_USERSWho may talk to the bot (comma-separated)
Role IDDISCORD_ALLOWED_ROLESAnyone holding the role is allowed — also in DMs, via shared servers. OR-ed with the user list.
Channel IDDISCORD_ALLOWED_CHANNELS / DISCORD_IGNORED_CHANNELSOnly answer in these channels / never answer here, even when mentioned
Channel IDDISCORD_FREE_RESPONSE_CHANNELS / DISCORD_NO_THREAD_CHANNELSNo mention needed here / reply inline instead of threading
Channel IDDISCORD_HOME_CHANNELWhere scheduled-job output and notifications go; /sethome in a channel sets it
Application IDInvite URL onlyclient_id in the invite link
Server (guild) IDNot neededThe documented setup never asks for it

Hermes fails closed. Without DISCORD_ALLOWED_USERS, DISCORD_ALLOWED_ROLES, DISCORD_ALLOWED_CHANNELS, or an explicit allow-all flag, the bot connects and looks online but denies every message, and ~/.hermes/logs/gateway.log says No Discord access policy configured. The alternative to an allowlist is DM pairing: an unknown user who DMs the bot gets a one-time code, which you approve with hermes pairing approve discord <code> (codes expire after an hour). DISCORD_ALLOW_ALL_USERS=true opens the bot to everyone who can reach it — authorized users get the agent's full toolset, including the terminal.

Mentions: when Hermes replies in a server

For a message in a server channel, the rules apply in this order:

  1. Ignored channels win. A channel (or a thread under it) in DISCORD_IGNORED_CHANNELS is never answered.
  2. Allowed channels restrict. If DISCORD_ALLOWED_CHANNELS is set, other channels are ignored (DMs still work if the user is allowed).
  3. Mention required by default. DISCORD_REQUIRE_MENTION=true; set it to false to answer everything, or list individual free-response channels instead.
  4. Mentions of other people. A message that @mentions someone else but not the bot is skipped (DISCORD_IGNORE_NO_MENTION=true).

Because unmentioned messages aren't processed, Hermes backfills context when you do mention it: it reads the channel back to its own last reply (up to 50 messages) and adds that to your message. It skips this in DMs and free-response channels, where nothing was missed. Turn it off with DISCORD_HISTORY_BACKFILL=false.

Outgoing pings are restricted by default: Hermes cannot ping @everyone, @here, or roles even if the model writes them. Individual users and reply pings still work.

Threads and forum channels

ThreadsForum channels
How a conversation startsAn @mention in a text channel auto-creates a thread (DISCORD_AUTO_THREAD=true)Every message Hermes sends to a forum creates a new post
Follow-upsNo re-mention needed once Hermes is in the threadReply inside the post like any thread
SessionEach thread is its own session, separate from the parent channelEach post is its own thread
Naming—First line of the message (max 100 characters), or the attachment filename
Inherited settingsParent channel's free-response, ignore, per-channel prompt, and model overrideParent forum's per-channel prompt and model override
  • Free-response channels reply inline by default. Set discord.free_response_auto_thread: true to thread them too.
  • Several bots in one thread: set discord.thread_require_mention: true, otherwise every bot already in the thread answers every message.
  • Different model or persona per channel: platforms.discord.channel_overrides (model, provider, system prompt) and discord.channel_prompts; threads and forum posts fall back to their parent's entry.
  • A forum created after the gateway started is picked up on the next directory refresh or gateway restart.

Direct messages

DMs are the simplest mode: no mention, no auto-thread, and one session per DM that continues until you send /new or /reset — gateway conversations don't reset on inactivity. The user still has to be allowlisted, hold an allowed role in a server shared with the bot, or be paired. Slash commands, voice messages, and file uploads work the same as in channels.

The gateway: why the bot goes offline

The Discord bot is the Hermes gateway process. It connects out to Discord over Discord's Gateway WebSocket, so no inbound port or public URL is needed — but when hermes gateway stops (laptop asleep, terminal closed, crash), the bot shows offline and nothing answers. On a remote machine, the hermes serve or dashboard backend that Desktop connects to is a separate process from the gateway — start and keep the gateway running on its own.

  • Messages sent while offline are not answered by default. Opt in with discord.missed_message_backfill.enabled: true; it replays unanswered messages from listed channels (default: your free-response channels) from the last 6 hours, capped at 10 per reconnect.
  • Replies interrupted by a crash are redelivered on the next start from a delivery ledger; a possibly duplicated one is labeled “Recovered reply”.
  • Repeated Discord failures auto-pause the adapter (circuit breaker) and it stays paused until you run /platform resume discord.
  • For always-on use, run the gateway as a service on a machine that stays on — hosting options, VPS guide.
Check the gateway
bash
$hermes gateway status
$hermes gateway restart
$tail -n 50 ~/.hermes/logs/gateway.log

Several bots, profiles, and Bot Mode

One Hermes profile runs one gateway with one Discord bot token. To run several distinct bots, create a profile per bot, give each its own Discord application and token in that profile's .env, and start each profile's gateway. If two profiles use the same token, Hermes blocks the second gateway with an error naming the other profile. Cloning a profile never copies its Discord token or allowlists.

A Bot Mode bot in Hermes Desktop is a profile, so it can have its own Discord bot this way — but Bot Mode itself is a Desktop roster, not a Discord feature, and configuring one does not configure the other. If Hermes bots should answer each other in Discord, DISCORD_ALLOW_BOTS must be mentions or all, and a handoff needs a literal @mention; a loop guard drops bot messages in a channel after 20 in 5 minutes. Two gateways sharing one Discord application (for example staging and production) should set slash_commands: false on one of them so slash-command registration doesn't flap.

Voice, files, and slash commands

  • Slash commands: built-ins such as /model, /reset, and /sethome, plus one command per installed skill, up to Discord's 100-command limit; extra skills are skipped with a log warning.
  • Files in: any file type, up to 32 MiB per file by default (DISCORD_MAX_ATTACHMENT_BYTES). Small text files are read straight into the prompt.
  • Voice: incoming voice messages are transcribed; /voice tts adds spoken replies; /voice join brings Hermes into a voice channel.

Common problems

SymptomLikely causeFix
Bot is offlineGateway not running, or wrong tokenStart hermes gateway; re-check DISCORD_BOT_TOKEN after any token reset
Online, never repliesNo access policy configured (Hermes fails closed); the official docs also list Message Content IntentSet DISCORD_ALLOWED_USERS, enable the intent, hermes gateway restart
Won't connect: PrivilegedIntentsRequiredAn intent Hermes requests isn't enabled in the portalEnable Message Content (and Server Members for role/username allowlists); the log names the intent
Replies in DMs, silent in a channelNo @mention, channel ignored/not allowed, or no View Channel permissionMention the bot; check channel lists; grant View Channel + Read Message History
403 Forbidden in logsMissing permissionRe-invite with the recommended integer or fix the bot's role
Duplicate repliesTwo gateways answeringhermes gateway status on every machine; stop the extra one
People in one channel share contextgroup_sessions_per_user set to falseSet it back to true and restart

Open bugs affecting Discord right now

  • Files and audio from Hermes fail to send (“couldn't deliver the file attachment”; text still works) — #121938, opened September 24, 2026. The code path it describes is unchanged in the v0.21.5 release; a fix PR was open, not merged, on September 26, 2026.
  • Voice replies arrive but won't play — MP3 audio uploaded as a voice message (#123680).
  • Role-only access: messages work, slash commands are rejected and the user is offered a pairing code (#118958). Adding the user ID to DISCORD_ALLOWED_USERS avoids it.
  • Embed-only messages from other bots are invisible to replies and backfill (#45188).

Discord or Telegram?

Both run through the same gateway, and one gateway can serve both at once with shared memory and skills. The differences that change how you set Hermes up:

DiscordTelegram
Bot creationDeveloper Portal: application, intents, invite URLBotFather, or Create with QR in Desktop/dashboard
Group defaultAnswers only when @mentionedAnswers group messages it can see unless require_mention is set
What the bot can seeControlled by Message Content Intent + channel permissionsControlled by BotFather privacy mode or admin status
Conversation structureAuto-threads per mention; forum channelsGroup topics and private chat topics
Access controlUser IDs, role IDs, channel IDs, pairingUser IDs, chat IDs, pairing
ConnectionOutbound WebSocketLong polling, or optional webhook mode

Setting up Telegram instead? See Hermes Agent Telegram setup.

What we have not tested

Not tested by this site: HermesAgentAI.org has not run a Hermes Discord bot for this page. Setup steps, defaults, and behavior come from the official Hermes Discord, messaging, and profiles docs and the Discord adapter source on GitHub, checked September 26, 2026; the bug list comes from open GitHub issues. We make no claims about response speed, reliability, or uptime on Discord, or how it compares with Telegram in practice.

Primary sources

HermesAgentAI.org is an independent educational documentation resource and community guide. It is not affiliated with, sponsored by, or endorsed by Nous Research or FlyHermes. Hermes Agent is released under the MIT License by Nous Research.

Where to go next