🤖HermesBlog
Hermes Messaging Platforms · Part 38/9/2026

Discord — AI in Your Server

Discord — AI in Your Server — easy-to-understand guide based on official docs

Discord: the polite guest

Discord — AI in Your Server

So you want to put Hermes Agent in your Discord server? Great choice. This guide walks you through the whole setup — from creating a bot on Discord’s Developer Portal to having your first conversation with your AI assistant.

But before we dive into the setup, let’s talk about the fun part: how Hermes actually behaves once it’s in your server.

How Hermes Behaves

Hermes isn’t just a dumb bot that replies to everything. It’s smart about when and where it responds. Here’s the breakdown:

Context Behavior
DMs Hermes replies to every message. No @mention needed. Each DM gets its own session.
Server channels By default, Hermes only responds when you @mention it. Otherwise, it stays quiet.
Free-response channels Want a channel where people can chat without tagging? Add it to DISCORD_FREE_RESPONSE_CHANNELS (or turn off mentions everywhere with DISCORD_REQUIRE_MENTION=false). Hermes answers inline, skipping auto-threading for a lightweight feel. Prefer a thread per top-level message instead? Set discord.free_response_auto_thread: true.
Threads Hermes replies in the same thread. Mention rules still apply unless the thread or its parent channel is free-response.
Shared channels By default, Hermes keeps each user’s session separate. Alice and Bob talking in #research get two independent conversations.
Messages mentioning others If a message @mentions other people but not Hermes, it stays silent (that’s DISCORD_IGNORE_NO_MENTION=true). Set it to false if you want it to respond to everything.

Pro tip: Want a normal bot-help channel where people can talk without tagging every time? Add that channel to DISCORD_FREE_RESPONSE_CHANNELS.

Hermes can also create isolated conversations with /thread and auto-threading — that needs the Create Public Threads permission (see the permissions table below).

The Gateway Model

Here’s what makes Hermes different from a simple webhook: every message goes through the full messaging gateway. That means each incoming message passes through:

  1. Authorization (via DISCORD_ALLOWED_USERS)
  2. Mention / free-response checks
  3. Session lookup
  4. Session transcript loading
  5. Full Hermes agent execution — tools, memory, slash commands
  6. Response delivery back to Discord

This matters in busy servers because behavior depends on both Discord routing and Hermes session policy.

Session Model: Who’s Talking to Whom?

By default, Hermes treats conversations like this:

  • Each DM gets its own session
  • Each server thread gets its own session namespace
  • Each user in a shared channel gets their own session inside that channel

So if Alice and Bob both talk to Hermes in #research, those are two separate conversations — even though they’re in the same visible channel.

This is controlled in config.yaml:

group_sessions_per_user: true

Set it to false if you want one shared conversation for the whole room:

group_sessions_per_user: false

Shared sessions can be great for collaborative rooms, but beware: users share context growth and token costs. One person’s long, tool-heavy task can bloat everyone else’s context, and one person’s in-flight run can interrupt another’s follow-up.

Interrupts and Concurrency

Hermes tracks running agents by session key.

With the default group_sessions_per_user: true:

  • Alice interrupting her own request only affects Alice’s session
  • Bob can keep chatting without inheriting Alice’s history or interrupting her run

With group_sessions_per_user: false:

  • The whole room shares one running-agent slot
  • Follow-up messages from different people can interrupt or queue behind each other

Gateway WebSocket Health

One important note: Discord REST and the Gateway WebSocket are separate transports. A successful REST response doesn’t prove the bot can still receive Gateway events. Hermes combines ready state, socket closure state, socket openness, heartbeat ACK age, heartbeat latency, and how long it’s been since the last parsed Gateway event to check health.

After a configured number of consecutive unhealthy samples, the adapter emits one retryable fatal event. A closed transport (socket_closed / client_closed) is a confirmed death and forces the reconnect on the first unhealthy sample; the threshold applies to soft signals only (stale heartbeat ACK, latency, event silence). The reconnect watcher creates a fresh adapter — no unbounded reconnect loops.

Configure the thresholds in config.yaml:

discord:
  websocket_liveness_interval_seconds: 15
  websocket_liveness_failure_threshold: 2
  websocket_heartbeat_ack_max_age_seconds: 60
  websocket_max_latency_seconds: 30
  websocket_event_max_silence_seconds: 14400

The old liveness_interval_seconds and liveness_failure_threshold names still work as compatibility aliases, but they no longer mean REST probing.

Setting any knob to 0 disables the whole WebSocket liveness probe — except websocket_event_max_silence_seconds, which only opts out of the event-silence check while the others keep guarding. A socket can stay connected and keep ACKing heartbeats while delivering zero events, so this last check catches that silent state. The 4-hour default is generous on purpose: a quiet server can legitimately go hours without a single event.

Step 1: Create a Discord Application

  1. Go to the Discord Developer Portal and sign in.
  2. Click New Application in the top-right corner.
  3. Enter a name (e.g., “Hermes Agent”) and accept the Developer Terms of Service.
  4. Click Create.

You’ll land on the General Information page. Note the Application ID — you’ll need it later to build the invite URL.

Step 2: Create the Bot

  1. In the left sidebar, click Bot.
  2. Discord automatically creates a bot user. You can customize its username.
  3. Under Authorization Flow, set Public Bot to ON — required to use the Discord-provided invite link.

That’s the foundation. From here, you’ll grab your bot token, set your environment variables, and invite Hermes to your server. Once that’s done, you’re ready to start chatting with your AI assistant — whether in DMs, channels, or threads.

Step 3: Turn On Message Content Intent

This is the most critical step in the entire setup. Hermes always asks Discord for message content, so if Message Content Intent is off, Discord refuses the bot’s connection and the bot never comes online.

In the Developer Portal, go to your application → Bot → Privileged Gateway Intents and toggle Message Content Intent ON. Click Save Changes.

Without it, Discord rejects the connection; gateway.log shows “Discord rejected the connection because privileged Gateway Intents are not enabled”.

Step 4: Invite the Bot

Build your invite URL with your Application ID:

https://discord.com/oauth2/authorize?client_id=YOUR_APP_ID&scope=bot+applications.commands&permissions=309237763136

Pick the permission set that fits your needs:

Level Permissions value What it grants
Minimal 117760 View Channels, Send Messages, Embed Links, Attach Files, Read Message History
Recommended 309237763136 All of the above plus Create Public Threads, Send Messages in Threads, Add Reactions
Full (what hermes gateway setup prints) 309240908864 Recommended plus Connect and Speak (voice channels)

Existing installations do not gain newly requested permissions automatically. If you used an older Recommended URL, re-invite the bot with the URL above to grant Create Public Threads.

Steps 5–7: The Easy Way (Wizard)

:::tip[Shortcut: let the wizard do Steps 5–7] Create the application and copy the bot token (Steps 1–4), then run hermes gateway setup and pick Discord. Hermes checks the token with Discord, tells you if Message Content Intent is off (with a link straight to the toggle), prints a ready-made invite link for your server, and allowlists you as the bot’s owner — no Developer Mode needed. :::

Select Discord when prompted and paste your bot token. The wizard verifies it with Discord (a wrong or stale token is rejected before it is saved), checks the privileged intents, prints the invite link, and offers to allowlist the bot’s owner — you. Extra users can be added by user ID or username.

Access Control

Variable Required? Notes
DISCORD_ALLOWED_USERS Conditional Comma-separated Discord user IDs allowed to interact with the bot. Without this or DISCORD_ALLOWED_ROLES, the gateway denies all users unless DISCORD_ALLOW_ALL_USERS=true, GATEWAY_ALLOW_ALL_USERS=true, or DISCORD_ALLOWED_CHANNELS explicitly scopes guild access. Usernames also work: they are resolved to IDs when the bot connects (requires the Server Members Intent). Display names and server nicknames are never matched, because any member can set them.

Clarify Prompts

When Hermes asks a clarifying question with buttons, the buttons disable themselves once a choice is made so duplicate clicks don’t double-resolve the prompt. Configure the response timeout via agent.clarify_timeout in ~/.hermes/config.yaml (default 3600 seconds; 0 or less = unlimited). If you don’t respond within the timeout, the agent unblocks with "outcome": "timed_out" and adapts rather than hanging. Reply skip to skip a question.

Troubleshooting

Bot stays offline / privileged Gateway Intents error: The Message Content Intent is disabled. Go back to the Developer Portal, select your application → Bot → Privileged Gateway Intents, and make sure Message Content Intent is toggled ON. Click Save Changes.

Bot is online but ignores everyone: Usually Discord auth is failing closed because no access policy is configured. (A disabled Message Content Intent keeps the bot offline instead; see Step 3.)

/thread reports Discord error 50001 (Missing Access): Verify the bot’s effective permissions in the parent channel. It needs View Channel, Send Messages, Create Public Threads, and Send Messages in Threads. Check the parent category and channel-specific permission overrides as well: an explicit deny there can override permissions granted by the server role.

📖 Official Docs

This article is based on the official Hermes Agent documentation:Official docs › user-guide/messaging/discord