Discord Bot Setup: Application, Intents, and Guild Workspace

Set up a Discord bot for OpenClaw: create the application, enable privileged intents, invite the bot to your server, pair it, and configure a guild workspace. Written for server admins and operators.

Read this when

  • Setting up a Discord bot for OpenClaw for the first time
  • Adding a Discord server to the guild allowlist

This page covers all the steps for getting a Discord bot operational: building the application, enabling intents, inviting it to a server, pairing it, and setting up a guild workspace.

Quick setup

Build a Discord application that includes a bot, invite that bot to your server, then pair it with OpenClaw. A private server is preferable; if you don't have one, create it first (Create My Own > For me and my friends).

Create a Discord application and bot

Head to the Discord Developer Portal, hit New Application, and give it a name (for instance "OpenClaw").

Select Bot from the sidebar, then set the Username field to whatever your agent is called.

Enable privileged intents

While still on the Bot page, turn on the following under Privileged Gateway Intents:

  • Message Content Intent (needed for ordinary guild messages)
  • Server Members Intent (suggested; needed for role allowlists, matching names to IDs, and channel-audience access groups)
  • Presence Intent (not required; used only for presence updates)

Copy your bot token

From the Bot page, select Reset Token and copy the resulting token.

Note

The label is misleading: this is how your first token gets generated, and nothing is actually being "reset."

Generate an invite URL and add the bot to your server

Pick OAuth2 in the sidebar. Under the OAuth2 URL Generator, turn on these scopes:

  • bot
  • applications.commands

In the Bot Permissions section that then appears, enable at minimum:

General Permissions

  • View Channels

Text Permissions

  • Send Messages
  • Read Message History
  • Embed Links
  • Attach Files
  • Add Reactions (optional)

Those permissions form the baseline for ordinary text channels. Should the bot need to post in threads, including forum or media channel workflows that start or continue a thread, turn on Send Messages in Threads as well.

Copy the URL that was generated, open it in a browser, pick your server, then click Continue. The bot should now show up in your server.

Enable Developer Mode and collect your IDs

Turn on Developer Mode inside the Discord app so IDs become copyable:

  1. User Settings (gear icon) → Developer → switch Developer Mode on (mobile: App Settings → Advanced)
  2. Right-click your server icon → Copy Server ID
  3. Right-click your own avatar → Copy User ID

Hold on to the Server ID and User ID alongside your bot token; the next step needs all three.

Allow DMs from server members

Discord has to allow the bot to DM you before pairing can succeed. Right-click your server icon → Privacy Settings → switch Direct Messages on.

Leave this enabled if you plan to use Discord DMs with OpenClaw. Should guild channels be your only use case, it can be turned off once pairing is done.

Set your bot token securely (do not send it in chat)

The bot token must be kept secret. Before you message your agent, set it on the machine where OpenClaw runs:

export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
cat > discord.patch.json5 <<'JSON5'
{
  channels: {
    discord: {
      enabled: true,
      token: { source: "env", provider: "default", id: "DISCORD_BOT_TOKEN" },
    },
  },
}
JSON5
openclaw config patch --file ./discord.patch.json5 --dry-run
openclaw config patch --file ./discord.patch.json5
openclaw gateway

When OpenClaw is already running as a background service, restart it through the OpenClaw Mac app, or stop and start the openclaw gateway run process. For managed service installs, run openclaw gateway install from a shell where DISCORD_BOT_TOKEN is set, or store the variable in ~/.openclaw/.env so that after a restart the service can resolve the env SecretRef. Should Discord's startup application lookup block or rate-limit your host, supply the application/client ID from the Developer Portal so startup can skip that REST call: channels.discord.applicationId for the default account, or channels.discord.accounts.<accountId>.applicationId per bot.

Configure OpenClaw and pair

Ask your agent

Talk to your OpenClaw agent on a channel you already have (Telegram, for example) and give it the instruction. When Discord is your first channel, use the CLI / config tab instead.

"I already set my Discord bot token in config. Please finish Discord setup with User ID <user_id> and Server ID <server_id>."

CLI / config

File-based config:

{
  channels: {
    discord: {
      enabled: true,
      token: {
        source: "env",
        provider: "default",
        id: "DISCORD_BOT_TOKEN",
      },
    },
  },
}

Env fallback for the default account:

DISCORD_BOT_TOKEN=...

For scripted or remote setup, write the same JSON5 block with openclaw config patch --file ./discord.patch.json5 --dry-run, then rerun without --dry-run. Plaintext token strings are also accepted, and SecretRef values work for channels.discord.token across env/file/exec/store providers. See Secrets Management.

When running multiple Discord bots, store each bot token and application ID under its own account. Accounts inherit a top-level channels.discord.applicationId, so set it there only if every account shares the same application ID.

{
  channels: {
    discord: {
      enabled: true,
      accounts: {
        personal: {
          token: { source: "env", provider: "default", id: "DISCORD_PERSONAL_TOKEN" },
          applicationId: "111111111111111111",
        },
        work: {
          token: { source: "env", provider: "default", id: "DISCORD_WORK_TOKEN" },
          applicationId: "222222222222222222",
        },
      },
    },
  },
}

Approve first DM pairing

With the gateway running, send a DM to your bot in Discord. A pairing code comes back in the reply.

Ask your agent

Pass the pairing code to your agent on the channel you already use:

"Approve this Discord pairing code: <CODE>"

CLI

openclaw pairing list discord
openclaw pairing approve discord <CODE>

Pairing codes are valid for 1 hour. Once approved, talk to your agent in a Discord DM.

Where Discord will not grant Message Content Intent, OpenClaw can still work in DMs and in guild channels where users @mention the bot explicitly. Set channels.discord.intents.messageContent: false so the Gateway does not request that unavailable privileged intent, and keep requireMention: true enabled on every configured guild channel. In this mode Discord leaves out user-authored content from other guild messages.

Note

Token resolution depends on the account. Config token values take precedence over the env fallback, and DISCORD_BOT_TOKEN applies only to the default account. When two enabled Discord accounts resolve to the same bot token, OpenClaw runs just one gateway monitor for that token: a config-sourced token beats the env fallback; if neither applies, the first enabled account wins and the duplicate is reported disabled with reason duplicate bot token. For advanced outbound calls (message tool/channel actions), an explicit per-call token applies to that call. This covers send and read/check-style actions (read/search/fetch/thread/pins/permissions). Account policy/retry settings are still taken from the selected account in the active runtime snapshot.

After DMs are working, you can convert your server into a full workspace where every channel gets a separate agent session with its own context. This is recommended for private servers shared only by you and your bot.

Add your server to the guild allowlist

With this in place, your agent can reply in any channel on your server, not only in DMs.

Ask your agent

"Add my Discord Server ID <server_id> to the guild allowlist"

Config

{
  channels: {
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: true,
          users: ["YOUR_USER_ID"],
        },
      },
    },
  },
}

Allow responses without @mention

By default the agent answers in guild channels only when @mentioned. On a private server, having it respond to every message is usually what you want.

In guild channels, normal replies are posted automatically by default. For shared always-on rooms, opt into messages.groupChat.visibleReplies: "message_tool" so the agent can lurk and post only when it judges a channel reply worthwhile. Latest-generation, tool-reliable models such as GPT-6 Astra suit this best. Ambient room events stay silent unless the tool sends. The full lurk-mode config is described in Ambient room events.

Should Discord display typing and the logs report token usage yet no message gets posted, verify whether the turn was set up as an ambient room event or opted into message-tool visible replies.

Session-busy notices follow this reply policy too. For ambient events and message-tool replies, the failure and the suppressed notice are recorded by Discord in Gateway logs without anything being posted to the room.

Ask your agent

"Allow my agent to respond on this server without having to be @mentioned"

Config

Set requireMention: false in your guild config:

{
  channels: {
    discord: {
      guilds: {
        YOUR_SERVER_ID: {
          requireMention: false,
        },
      },
    },
  },
}

To make message-tool sends mandatory for visible group/channel replies, set messages.groupChat.visibleReplies: "message_tool".

Plan for memory in guild channels

Long-term memory (MEMORY.md) auto-loads only in DM sessions; guild channels do not load it.

Ask your agent

"When I ask questions in Discord channels, use memory_search or memory_get if you need long-term context from MEMORY.md."

Manual

For shared context across every channel, place stable instructions in AGENTS.md or USER.md (injected into every session). Long-term notes belong in MEMORY.md, reached on demand through memory tools.

At this point, create channels and begin chatting. The agent can see the channel name, and every channel is an isolated session, so configure #coding, #home, #research, or whatever suits your workflow.

1,521 words · updated Oct 26, 2026