Complete guide to setting up, configuring, and running OpenAB with Discord.
- Go to the Discord Developer Portal
- Click New Application
- Give it a name (e.g.
AgentBroker) and click Create
- In your application, go to the Bot tab (left sidebar)
- Scroll down to Privileged Gateway Intents
- Enable Message Content Intent
- Enable Server Members Intent (recommended)
- Click Save Changes
- Still on the Bot tab, click Reset Token
- Copy the token — you'll need this for
DISCORD_BOT_TOKEN - Keep this token secret. If it leaks, reset it immediately
- Go to OAuth2 → URL Generator (left sidebar)
- Under Scopes, check
bot - Under Bot Permissions, check:
- Send Messages
- Send Messages in Threads
- Create Public Threads
- Read Message History
- Add Reactions
- Manage Messages
- Copy the generated URL at the bottom
- Open the URL from step 4 in your browser
- Select the server you want to add the bot to
- Click Authorize
- In Discord, go to User Settings → Advanced → enable Developer Mode
- Right-click the channel where you want the bot to respond
- Click Copy Channel ID
- Use this ID in
allowed_channelsin your config
- Make sure Developer Mode is enabled (see step 6)
- Right-click your own username (in a message or the member list)
- Click Copy User ID
- Use this ID in
allowed_usersto restrict who can interact with the bot
📖 Full config options with defaults: docs/config-reference.md
[discord]
bot_token = "${DISCORD_BOT_TOKEN}"
allowed_channels = ["123456789"] # channel ID allowlist (empty = all)
allowed_users = ["987654321"] # user ID allowlist (empty = all)
allow_bot_messages = "off" # off | mentions | all
allow_user_messages = "involved" # involved | mentions
trusted_bot_ids = [] # bot user IDs allowed through (empty = any)allowed_channels |
allowed_users |
Result |
|---|---|---|
| empty | empty | All users, all channels (default) |
| set | empty | Only these channels, all users |
| empty | set | All channels, only these users |
| set | set | AND — must be in allowed channel AND allowed user |
- Empty
allowed_users(default) = no user filtering - Denied users get a 🚫 reaction and no reply
Controls whether the bot processes messages from other Discord bots.
| Value | Behavior | Loop risk |
|---|---|---|
"off" (default) |
Ignore all bot messages | None |
"mentions" |
Only process bot messages that @mention this bot | Very low |
"all" |
Process all bot messages (capped at 10 consecutive) | Mitigated by turn cap |
The bot's own messages are always ignored regardless of this setting.
Controls whether the bot requires @mention in threads.
| Value | Behavior |
|---|---|
"involved" (default) |
Respond in threads the bot owns or has participated in without @mention. Main channel always requires @mention. |
"mentions" |
Always require @mention, even in the bot's own threads. |
"multibot-mentions" |
Same as involved in single-bot threads. In threads where other bots have also posted, requires @mention — prevents all bots from responding to every message. |
| Scenario | involved |
mentions |
multibot-mentions |
|---|---|---|---|
| Main channel (no @mention) | ❌ | ❌ | ❌ |
| Main channel (with @mention) | ✅ | ✅ | ✅ |
| Single-bot thread (no @mention) | ✅ | ❌ | ✅ |
| Single-bot thread (with @mention) | ✅ | ✅ | ✅ |
| Multi-bot thread (no @mention) | ✅ | ❌ | ❌ |
| Multi-bot thread (with @mention) | ✅ | ✅ | ✅ |
involved— Single-bot setup, or you want all bots to respond freely in shared threads.mentions— Strict control. Every message must explicitly @mention the bot. Best for high-traffic channels where accidental triggers are a concern.multibot-mentions— Multi-bot setup. Natural conversation in single-bot threads, explicit @mention control in multi-bot threads. Recommended for most multi-bot deployments.
When allow_bot_messages is "mentions" or "all", you can restrict which bots are allowed through:
trusted_bot_ids = ["123456789012345678"] # only this bot's messages pass throughEmpty (default) = any bot can pass through (subject to the mode check).
Role IDs that trigger the bot, same as a direct @mention. This enables users to invoke multiple bots simultaneously with a single role mention (e.g. @AllBots review this).
allowed_role_ids = ["123456789012345678"] # @mention this role = trigger the botEmpty (default) = role mentions do not trigger the bot.
Setup:
- Create a Discord role (e.g.
BotsorAllAgents) - Assign the role to all bots you want to trigger together
- Add the role's ID to each bot's
allowed_role_ids - Users type
@RoleName <prompt>to trigger all bots at once
Note: If multiple bots share the same role, all will respond simultaneously. Use
multibot-mentionsmode if you want bots to require explicit @mention when other bots are already in the thread.
When allow_user_messages = "multibot-mentions" is set alongside allowed_role_ids:
| Action | Result |
|---|---|
@Role review this in a channel |
All bots trigger (role mention = explicit mention) |
| Follow-up in the thread without @mention | Only the thread owner responds (multibot gate kicks in) |
@Role follow up in the thread |
All bots respond again |
This gives the best of both worlds: one role mention to summon all bots, but subsequent messages in the thread don't cause all bots to pile on.
The bot responds to:
- Direct @mention (
@BotUser) — always works - Role mention (
@RoleName) — only if the role ID is inallowed_role_ids - Thread reply — depends on
allow_user_messagesmode (no @mention needed ininvolvedmode)
✅ @AgentBroker hello ← user mention, bot responds
✅ @AllBots hello ← role mention, bot responds (if role in allowed_role_ids)
❌ @SomeOtherRole hello ← role not in allowed_role_ids, bot ignores
The triggering role mention is stripped from the prompt sent to the agent (same as the bot's own user mention).
When a user mentions another user (e.g. @SomeUser) in a message to the bot, the raw Discord mention <@UID> is preserved in the prompt sent to the LLM. This means:
- The LLM can copy
<@UID>into its reply to produce a clickable Discord mention - The bot's own mention is stripped (so the bot doesn't see itself being triggered)
- Triggering role mentions (in
allowed_role_ids) are stripped - Other role mentions are replaced with
@(role)placeholder
To help the LLM know who each UID refers to, provide a UID→name mapping via system prompt or context entry (see Multi-Bot Setup below).
When you @mention the bot in a channel, it creates a thread from your message and responds there. After that:
involvedmode (default): just type in the thread — no @mention neededmentionsmode: @mention required for every message, even in threads
Each thread gets its own agent session. Sessions are cleaned up after session_ttl_hours (default: 24h).
OpenAB processes Discord file attachments and converts them into content blocks for the agent. Supported types (checked in order):
| Type | Detection | Agent receives |
|---|---|---|
| Audio | MIME audio/* |
Transcribed text via STT (if enabled) |
| Text files | Extension list (.txt, .md, .json, etc.) |
File content inlined (up to 5 files, 1 MB total) |
| Images | MIME image/* or image extensions |
Base64-encoded image block |
| Video | MIME video/* or extensions (.mp4, .mov, .webm, .mkv, .m4v, .avi) |
Text block with filename, content type, size, and Discord CDN URL |
Unsupported attachment types are silently ignored.
Video files are not downloaded or transcoded. The agent receives metadata and the
Discord CDN URL so it can fetch or inspect the file using tools like ffprobe.
[Video attachment]
filename: demo.mp4
content_type: video/mp4
size_bytes: 8421376
url: https://cdn.discordapp.com/attachments/.../demo.mp4
No configuration is needed — video forwarding is always enabled.
OpenAB uses edit-streaming on Discord — the bot sends a placeholder message and updates it every 1.5 seconds as tokens arrive, giving a live typing effect.
Streaming is decided per-thread, not globally:
| Thread state | Streaming |
|---|---|
| Single bot + human | ✅ ON — live edit updates |
| 2+ bots in thread | ❌ OFF — send-once to avoid edit interference |
When a second bot posts in a thread, streaming automatically switches off for that thread. This prevents multiple bots from editing placeholder messages simultaneously, which causes visual glitches on Discord.
No configuration needed — this is automatic based on multibot detection.
Multiple bots can share the same Discord channel. Each bot only responds to its own @mentions.
helm install openab openab/openab \
--set agents.kiro.discord.botToken="$BOT_A_TOKEN" \
--set-string 'agents.kiro.discord.allowedChannels[0]=CHANNEL_ID' \
--set agents.dealer.discord.botToken="$BOT_B_TOKEN" \
--set-string 'agents.dealer.discord.allowedChannels[0]=CHANNEL_ID' \
--set agents.dealer.discord.enabled=true \
--set agents.dealer.command=kiro-cli \
--set 'agents.dealer.args={acp,--trust-all-tools}'- One thread per message: when you @mention both bots in a single message, only the first bot creates a thread. The second bot's thread creation fails and the message is dropped. Workaround: @mention each bot in separate messages.
- Thread ownership: a bot only responds in threads it owns or has participated in (
involvedmode). To have Bot B respond in Bot A's thread, usementionsmode and explicitly @mention Bot B.
In multi-bot channels, use multibot-mentions to get the best of both worlds:
[discord]
allow_user_messages = "multibot-mentions"- Single-bot threads: natural conversation, no @mention needed (same as
involved) - Multi-bot threads: requires @mention so only the addressed bot responds
To enable bots to collaborate (e.g. code review → deploy handoff):
# Bot that receives bot messages
[discord]
allow_bot_messages = "mentions"To prevent runaway bot-to-bot loops, OpenAB enforces two layers of protection:
- Soft limit (
max_bot_turns, default: 100) — total bot messages in a thread without human intervention. When reached, the bot sends a one-time warning and stops responding. A human message in the thread resets the counter. - Hard limit (1000, not configurable) — cap on consecutive bot messages in
allow_bot_messages = "all"mode. When reached, bot-to-bot conversation stops until a human replies.
Both limits count all bot messages in the thread, including the bot's own replies. In a two-bot ping-pong with max_bot_turns = 100, each bot sends ~50 messages before the limit triggers.
Warning messages are sent exactly once (on the exact threshold hit) to prevent warnings from ping-ponging between bots.
[discord]
max_bot_turns = 200 # default is 100Since user mentions are preserved as raw <@UID>, bots need a UID→name mapping to know who is who. Add an ice-breaking greeting to each bot's system prompt or context entry:
We have 3 participants in this room:
MY_NICIKNAME <@MY_NAME>
BOT1_NICKNAME <@BOT1>
BOT2_NICKNAME <@BOT2>
Always use <@UID> format to mention someone in your messages.
This lets each bot build the mapping in its own context from the start and correctly mention others using <@UID>.
See multi-agent.md for detailed examples.
helm install openab openab/openab \
--set agents.kiro.discord.botToken="$DISCORD_BOT_TOKEN" \
--set-string 'agents.kiro.discord.allowedChannels[0]=YOUR_CHANNEL_ID' \
--set agents.kiro.discord.allowBotMessages=off \
--set agents.kiro.discord.allowUserMessages=involved \
--set-string 'agents.kiro.discord.allowedRoleIds[0]=YOUR_ROLE_ID'--set-string for channel/user/role IDs to avoid float64 precision loss.
- Check channel ID — make sure it's in
allowed_channels - Check permissions — bot needs Send Messages, Create Public Threads, Read Message History in the channel
- Check intents — Message Content Intent must be enabled in Developer Portal
- Check @mention type — use user mention or a role in
allowed_role_ids - Check if in a thread — with
mentionsmode, @mention is required even in threads
Discord Gateway may throttle event delivery after rapid reconnects. Use scale 0 → wait 5s → scale 1 instead of rollout restart:
kubectl scale deployment/openab-kiro --replicas=0 && sleep 5 && kubectl scale deployment/openab-kiro --replicas=1See #455 for details.
Discord only allows one thread per message. If another bot already created a thread on the same message, this error appears. The message is dropped. This is a known limitation for multi-bot setups (#457).
The bot token is wrong or expired. Reset it in the Developer Portal and redeploy.
The agent CLI isn't authenticated. For kiro-cli:
kubectl exec -it deployment/openab-kiro -- kiro-cli login --use-device-flow
kubectl rollout restart deployment/openab-kiro