Configure and manage Discord channel routing for OpenClaw agents. Use when asked to set up Discord for an agent, add a Discord bot, manage guilds/channels/allowlists, or route a Discord bot to an existing agent.
Scripts in this skill write to ~/.openclaw/openclaw.json, which is outside the agent sandbox boundary.
mode: "non-main" (default): main sessions are not sandboxed — no action needed.mode: "all": enable elevated exec (tools.elevated.enabled: true) and run /elevated on before executing.This skill provides the complete workflow for configuring an OpenClaw agent in a multi-agent workspace to receive messages from a Discord bot, and for managing the ongoing configuration of Discord accounts, guilds, channels, and allowlists.
For full Discord channel documentation, see: https://github.com/openclaw/openclaw/blob/main/docs/channels/discord.md
Run the interactive setup:
{baseDir}/scripts/setup-discord-agent.sh
This will:
openclaw.jsonConfigure an existing Discord bot account to respond in an additional server:
{baseDir}/scripts/setup-discord-guild.sh
Or with arguments:
{baseDir}/scripts/setup-discord-guild.sh --agent <agent-id> --account <account-id> --guild <server-id>
After running, restart the gateway:
openclaw gateway restart
Use manage-discord.sh to view and modify Discord configuration after initial setup:
{baseDir}/scripts/manage-discord.sh <command> [options]
{baseDir}/scripts/manage-discord.sh list
Output shows accounts, their SecretRef token types (never values), bound agents, guilds, user/role allowlists, channel restrictions, and mention settings.
# Show allowlists for all guilds on an account
{baseDir}/scripts/manage-discord.sh allowlist show --account dev
# Show for a specific guild
{baseDir}/scripts/manage-discord.sh allowlist show --account dev --guild 123456789012345678
# Add a user to a guild's allowlist
{baseDir}/scripts/manage-discord.sh allowlist add --guild 123456789012345678 --user 987654321098765432
# Add a role to a guild's allowlist
{baseDir}/scripts/manage-discord.sh allowlist add --guild 123456789012345678 --role 111111111111111111
# Remove a user
{baseDir}/scripts/manage-discord.sh allowlist remove --guild 123456789012345678 --user 987654321098765432
When only one Discord account exists, --account is auto-detected.
# Add a guild with mention required and user allowlist
{baseDir}/scripts/manage-discord.sh guild add --guild 123456789012345678 --require-mention true --users "987654321098765432"
# Add a guild where bot responds to all messages
{baseDir}/scripts/manage-discord.sh guild add --guild 123456789012345678 --require-mention false
# Remove a guild
{baseDir}/scripts/manage-discord.sh guild remove --guild 123456789012345678
By default, a bot responds in all channels of an allowlisted guild. To restrict:
# Allow bot only in specific channels
{baseDir}/scripts/manage-discord.sh channel add --guild 123456789012345678 --channel 111111111111111111
{baseDir}/scripts/manage-discord.sh channel add --guild 123456789012345678 --channel 222222222222222222 --require-mention false
# List channels for a guild
{baseDir}/scripts/manage-discord.sh channel list --guild 123456789012345678
# Remove a channel restriction
{baseDir}/scripts/manage-discord.sh channel remove --guild 123456789012345678 --channel 111111111111111111
When channels is configured on a guild, only listed channels are allowed.
# Require @mention in a guild
{baseDir}/scripts/manage-discord.sh mention on --guild 123456789012345678
# Allow bot to respond without @mention
{baseDir}/scripts/manage-discord.sh mention off --guild 123456789012345678
# Override for a specific channel
{baseDir}/scripts/manage-discord.sh mention off --guild 123456789012345678 --channel 111111111111111111
bot, applications.commandsSave your bot token, server ID, and user ID — you'll need all three.
Bot tokens are never stored as plaintext in openclaw.json. They are stored via the active secrets provider and referenced by a SecretRef object.
The setup script handles this automatically. For manual setup:
# For env provider (default): store in ~/.openclaw/.env
echo 'export DISCORD_BOT_TOKEN_DEV="your-token"' >> ~/.openclaw/.env
chmod 600 ~/.openclaw/.env
# Write the SecretRef to config
openclaw config set channels.discord.accounts.dev.token \
--ref-provider default --ref-source env --ref-id DISCORD_BOT_TOKEN_DEV
# Validate
openclaw secrets audit --check
For other providers (file, exec/vault), see Secrets Management.
The resulting config uses SecretRef for the token:
"channels": {
"discord": {
"enabled": true,
"accounts": {
"dev": {
"enabled": true,
"token": {
"source": "env",
"provider": "default",
"id": "DISCORD_BOT_TOKEN_DEV"
},
"guilds": {
"YOUR_SERVER_ID": {
"requireMention": true,
"users": ["YOUR_USER_ID"]
}
}
}
}
}
}
Add a binding:
"bindings": [
{
"agentId": "dev",
"match": {
"channel": "discord",
"accountId": "dev"
}
}
]
openclaw secrets audit --check
openclaw gateway restart
| Field | Required | Description |
|---|---|---|
enabled | No (default: true) | Enable/disable this account |
token | Yes | SecretRef to bot token: { source: "env", provider: "default", id: "ENV_VAR" } |
guilds | No | Map of server IDs to guild config |
guilds.<id>.requireMention | No (default: true) | Bot must be @mentioned to respond in channels |
guilds.<id>.users | No | Array of Discord user IDs allowed to trigger the bot |
guilds.<id>.roles | No | Array of Discord role IDs allowed to trigger the bot |
guilds.<id>.channels | No | Map of channel IDs; if set, only listed channels are allowed |
guilds.<id>.ignoreOtherMentions | No | Drop messages that mention another user/role but not the bot |
| Field | Required | Description |
|---|---|---|
agentId | Yes | Target agent |
match.channel | Yes | Channel type: discord |
match.accountId | Yes | Discord account ID |
| Field | Required | Description |
|---|---|---|
session.idleMinutes | No (default: 10080) | How long a session can be idle before expiring, in minutes. e.g. 30, 720 (12h), 10080 (7d). Applies globally to all channels. |
Restrict the bot to specific channels within a server:
"guilds": {
"YOUR_SERVER_ID": {
"requireMention": true,
"channels": {
"CHANNEL_ID_1": { "allow": true },
"CHANNEL_ID_2": { "allow": true, "requireMention": false }
}
}
}
If channels is set, only listed channels are allowed. If omitted, all channels in the guild are allowed.
Route Discord guild members to different agents by role:
"bindings": [
{
"agentId": "opus",
"match": {
"channel": "discord",
"guildId": "YOUR_SERVER_ID",
"roles": ["ROLE_ID"]
}
},
{
"agentId": "sonnet",
"match": {
"channel": "discord",
"guildId": "YOUR_SERVER_ID"
}
}
]
openclaw.jsonopenclaw secrets audit --check verifies no plaintext residues remainBot doesn't respond:
openclaw secrets audit --check)guildsBot ignores channel messages but responds to DMs:
requireMention: true (default) — @mention the bot, or set to falseguilds allowlistchannels allowlist configured but the channel is not listedMessages going to wrong agent:
accountId in binding matches Discord accountroles