OpenClaw Discord Integration: Run Your AI Agent in Discord Servers
Discord is where developer communities live. It's where your team coordinates, where your users ask questions, and where a lot of real async work actually happens. If your AI agent can't show up there, it's missing a huge chunk of the action.
OpenClaw's Discord integration is genuinely first-class. It connects your agent as a native Discord bot — not a webhook that pastes text, but a full participant that reads history, responds in threads, handles slash commands, maintains per-channel sessions, and can even join voice channels. This guide walks through the full setup: from creating a bot in the Discord Developer Portal to advanced patterns like guild workspaces, role-based routing, and thread-bound sub-agents.
What you get with Discord + OpenClaw
Before diving into setup, here's the scope of what's actually supported:
- DMs — Direct messages to your bot, with pairing-based access control
- Guild channels — Your bot responds in server channels, with per-channel session isolation
- Forum channels — Threaded forum posts, with auto-thread creation
- Slash commands — Native
/model,/config,/focus, and more - Voice channels — Real-time voice conversations with your agent (with TTS and STT)
- Thread-bound sub-agents — Spawn a coding agent and bind it to a thread so follow-ups stay in context
- Live streaming — Watch replies arrive token-by-token (partial or block mode)
- Reactions and components — Ack reactions while processing, button-based approvals
That's not a marketing list — each of those is a real OpenClaw feature with config knobs. Let's build this step by step.
Step 1: Create a Discord bot
Go to the Discord Developer Portal and click New Application. Name it something like "OpenClaw" or whatever you call your agent.
Inside the app, click Bot in the sidebar. Set the username to match your agent's identity. Then scroll down to Privileged Gateway Intents and enable:
- Message Content Intent — required; without this, your bot can't read message text
- Server Members Intent — recommended; needed for user ID resolution and role-based allowlists
Next, click Reset Token (it's generating your first token, not resetting anything). Copy it — you'll need it shortly.
Step 2: Set up OAuth permissions and invite the bot
Click OAuth2 in the sidebar. Under OAuth2 URL Generator, check:
botapplications.commands
In the Bot Permissions section that appears, enable:
- View Channels
- Send Messages
- Read Message History
- Embed Links
- Attach Files
- Add Reactions (optional, for ack reactions)
Copy the generated URL, paste it in your browser, select your server, and click Continue. Your bot is now in the server.
Step 3: Collect your IDs
Enable Developer Mode in Discord: User Settings → Advanced → Developer Mode. Then:
- Right-click your server icon → Copy Server ID
- Right-click your own avatar → Copy User ID
You now have three things: bot token, server ID, user ID. Keep them safe. The token is a secret — treat it like a password.
Step 4: Configure OpenClaw
Set your bot token securely before starting the gateway. Do this on the machine running OpenClaw — not in a chat message:
{codeBlock0} Or if you prefer file-based config, add this to your openclaw.json:
{codeBlock1} OpenClaw also reads DISCORD_BOT_TOKEN from environment as a fallback for the default account.
Step 5: Pair your Discord DM
Once the gateway is running, DM your bot in Discord. It will reply with a pairing code. Approve it:
{codeBlock8} Or if you're already on another channel (like Telegram or Slack), send the code to your agent there: "Approve this Discord pairing code: XXXX"
Pairing codes expire after 1 hour. Once approved, Discord DMs are live.
Step 6: Set up your guild workspace
DMs are good for personal use. For a real workspace, you want your agent operating in server channels. The simplest setup for a private server:
{codeBlock2} This adds your server to the allowlist, sets requireMention: false so the agent responds to every message (not just @mentions), and restricts to your user ID only. Good baseline for a private server that's just you and your bot.
For a more controlled setup with multiple channels and roles:
{codeBlock3} The channels block inside a guild lets you control access per-channel. Channels not listed are denied. This is how I run my own setup — coding channel has full access, random is blocked entirely.
Session isolation per channel
One of the more useful things about the Discord integration: each guild channel gets its own isolated session. That means your #coding channel has different context than #research or #home. The agent knows which channel it's in from the session key.
Session key format: agent:<agentId>:discord:channel:<channelId>
DMs, by default, share the main agent session (agent:main:main). You can adjust this with session.dmScope if you need DMs to be isolated too.
One thing to be aware of: long-term memory (MEMORY.md) does not auto-load in guild channel sessions. It only loads in the main DM session. If you need long-term context in channels, either put stable instructions in AGENTS.md (which is injected everywhere), or explicitly call memory_search when needed.
Tuning the experience
A few config tweaks that make a real difference in day-to-day use:
{codeBlock4} - streaming: "partial" — watch replies stream in token-by-token, like watching someone type
- replyToMode: "first" — agent threads its reply to the triggering message (keeps channels clean)
- historyLimit: 30 — how many messages of channel history the agent reads for context (default 20)
You can also set a custom presence so your bot has a status in the member list:
{codeBlock5} Activity type 4 is "Custom" — the activity text shows as a status. Types 0-5 cover Playing, Streaming, Listening, Watching, Custom, and Competing. OpenClaw also supports autoPresence which maps gateway health to Discord status automatically: healthy → online, degraded → idle, unavailable → dnd.
Thread-bound sub-agents
This is where Discord + OpenClaw gets genuinely powerful. You can spawn a sub-agent (say, a coding agent working on a feature) and bind it to a Discord thread. Every follow-up message in that thread routes to the same agent session — with full context continuity.
{codeBlock7} With this config, running sessions_spawn(thread: true) from within a Discord session automatically creates a new thread and binds it. The /focus, /unfocus, and /agents slash commands let you manage these bindings interactively.
Bindings expire after idleHours of inactivity (default 24). You can set a hard max with maxAgeHours.
Voice channels
OpenClaw can join Discord voice channels for real-time conversation. Your agent listens, transcribes, responds, and speaks back using TTS:
{codeBlock6} Requirements: native commands must be enabled, and the bot needs Connect + Speak permissions in the voice channel. Use /vc join, /vc leave, and /vc status slash commands to control sessions.
Voice transcript ownership follows the Discord allowlist — speakers not in your allowlist can't trigger owner-only tools. Smart isolation.
Slash commands
Native slash commands are enabled by default on Discord. The built-in catalog includes:
/model— switch the agent's model with an interactive picker/config set|unset— modify OpenClaw config from Discord/focus— bind the current thread to a sub-agent session/unfocus— release thread binding/agents— show active runs and binding state/session idle|max-age— inspect or update thread binding timeouts/vc join|leave|status— control voice channel sessions
Commands run in isolated command sessions but carry a CommandTargetSessionKey that links back to the conversation session — so slash commands have full context of the channel they're used in.
Note: Discord shows slash commands to all users, but execution enforces your OpenClaw allowlists. Unauthorized users get an ephemeral "not authorized" reply.
Access control deep dive
OpenClaw's Discord security model has two layers: DM policy and guild policy.
DM policy (channels.discord.dmPolicy):
pairing(default) — unknown users get a pairing flowallowlist— only listed user IDs can DMopen— anyone can DM (requires explicit allowFrom: ["*"])disabled— DMs turned off entirely
Guild policy (channels.discord.groupPolicy):
allowlist(default when Discord is configured) — only listed guilds can trigger the agentopen— any server the bot is indisabled— guild messages off
Within allowlisted guilds, you can restrict by users (user IDs) and roles (role IDs). If either list is set, a sender matches if they appear in either list — not both. Use numeric IDs; name matching is disabled by default and flagged by openclaw security audit.
You can also route different Discord users to different agents by role. The bindings[] array at the top level supports role-based routing:
{`{
"bindings": [
{
"agentId": "opus",
"match": {
"channel": "discord",
"guildId": "123456789012345678",
"roles": ["111111111111111111"]
}
},
{
"agentId": "sonnet",
"match": {
"channel": "discord",
"guildId": "123456789012345678"
}
}
]
}`} Admins get the Opus agent. Everyone else gets Sonnet. One bot, tiered access.
Troubleshooting
The most common issues and their fixes:
Bot sees no guild messages — Message Content Intent is not enabled. Go back to the Developer Portal, Bot page, and enable it. Restart the gateway.
Guild messages blocked unexpectedly — Check groupPolicy. If it's allowlist, your server ID must be in channels.discord.guilds. If you have a channels block in the guild config, only listed channels are allowed.
Agent not responding even without @mention — requireMention must be set in the guild or channel entry, not at the top level. Check your nesting.
Handlers timing out or duplicate replies — Tune the listener timeout and worker timeout:
{`{
"channels": {
"discord": {
"accounts": {
"default": {
"eventQueue": { "listenerTimeout": 120000 },
"inboundWorker": { "runTimeoutMs": 1800000 }
}
}
}
}
}`} For anything else, these three commands are your first stop:
{codeBlock9} Real-world patterns
A few setups that work well in practice:
Personal command center — Private server, just you and your bot. requireMention: false, full memory access via DM. Create channels for different contexts: #coding, #research, #ops. Each gets isolated session history. This is how I run my day.
Team AI assistant — Shared server, requireMention: true, allowlist limited to team members. Agent responds when @mentioned. Bind a sub-agent to a thread for long-running tasks like PR reviews or multi-step research.
Community bot with tiered access — Public or semi-public server, role-based routing. Patrons get a more capable model. Moderators get access to admin tools. Everyone else gets a standard assistant. One bot, multiple personas based on Discord roles.
Voice-first meeting bot — Agent auto-joins a voice channel during scheduled standups. Takes notes, answers questions, summarizes action items. All hands-free.
Quick security checklist
- Store bot token in environment variable (
DISCORD_BOT_TOKEN), not in chat - Use numeric user IDs and role IDs in allowlists — not names
- Start with
groupPolicy: "allowlist"and add guilds explicitly - Grant least-privilege bot permissions — avoid Administrator
- Run
openclaw security auditperiodically to catch name-matching risks
The bigger picture
Discord isn't just a chat app — it's async infrastructure. Guild channels are persistent, searchable, thread-able workspaces. When your AI agent lives in Discord, it becomes part of that infrastructure: answering questions in #support, running tasks from #ops, spinning up coding agents in threads, joining voice for standups.
That's the shift OpenClaw enables. Not a chatbot you paste queries into. An agent that participates in the same spaces you work in, with the same access controls and audit trails.
Setup takes about 15 minutes. The compound value takes a week to fully appreciate.
Want the complete guide? Get The OpenClaw Playbook — $9.99