Skip to main content
This enables you to use Discord to securely connect with your local computer via the gateway. The Discord adapter uses Discord’s Gateway API for inbound events and Discord REST API for outbound messages and typing indicators. It supports DMs, guild channels, and thread-aware replies.

Requirements

  • A Discord bot token.
  • The bot invited to your server with message and channel permissions.
  • Message Content intent enabled in the Discord Developer Portal for non-mention guild content.

Basic configuration

{
  "channels": {
    "discord": {
      "enabled": true,
      "bot_token_ref": "vault:secret:discord-bot-token",
      "allow_from": [],
      "groups": [],
      "require_mention": true,
      "reply_to_mode": "first",
      "auto_thread": false,
      "include_thread_starter": true,
      "native_commands": false,
      "native_command_allow": [],
      "actions_enabled": false,
      "action_allow": []
    }
  }
}

Reply and thread behavior

  • reply_to_mode: controls Discord message reference behavior (off, first, all).
  • In existing thread contexts, Discord replies stay anchored to the triggering thread message even when reply_to_mode is off (thread-planning parity behavior).
  • auto_thread: if enabled, Discord can create a thread from the triggering message and send replies there.
  • Auto-thread title generation strips Discord mention tokens (<@...>, <@!...>, <@&...>, <#...>) before sanitization.
  • include_thread_starter: if enabled, inbound thread messages include the thread starter text as context; lookup follows forum/media vs standard-thread channel targeting with fallback probing, and falls back to starter embed description when body content is empty.
  • Thread session routing inherits parent channel context while maintaining thread isolation via a thread-specific session suffix.
  • native_commands: if enabled, the adapter deploys baseline Discord slash commands (/ask, /new, /reset, /compact, /workspace, /approve, /deny) and maps them into the gateway command flow.
  • native_command_allow: optional allowlist of native command names to deploy (empty = deploy all baseline commands).
  • Native slash autocomplete baseline supports /workspace name, /approve mode, /approve id, and /deny id. Approval id autocomplete now prefers recent pending ids observed from Discord approval buttons in the same channel/thread scope.
  • For /approve, if id is provided without a mode, Discord replies with an ephemeral mode-picker button menu (Once, Session, Always) and dispatches the selected mode through component interaction. Picker buttons are bound to the invoking user.
  • Native interaction callbacks handle Discord’s structured Unknown interaction expiry responses gracefully so delayed slash/component follow-ups do not spam warning logs.
  • actions_enabled: enables Discord action execution through channel action requests.
  • action_allow: optional allowlist of Discord action keys (empty = allow all enabled actions). Supported keys: reaction_add, reaction_remove, reaction_list, reaction_clear_own, message_info, messages_read, messages_search, message_edit, message_delete, pin_add, pin_remove, pins_list, thread_create, threads_list, thread_info, thread_archive, thread_unarchive, moderation_timeout, moderation_kick, moderation_ban, guild_info, guild_channels, guild_roles, emoji_list, emoji_upload, sticker_upload, events_list, events_create, voice_status, channel_create, channel_edit, channel_delete, channel_move, channel_permission_set, channel_permission_remove, category_create, category_edit, category_delete, role_add, role_remove, member_info, channel_info, presence_set.
  • Message admin actions: message:info:<message_id>, messages:read[:<limit>[|<before>[|<after>[|<around>]]]] (single-cursor), messages:search:<guild_id>:<query>[|<limit>[|<channel_ids_csv>[|<author_ids_csv>]]], and message:edit:<message_id>:<content> (OpenClaw-aligned baseline).
  • Reaction admin action: reactions:list:<message_id>[|<limit>] (or reaction:list:...) to inspect emoji counts and up to limit reacting users per emoji.
  • Reaction cleanup action: reactions:clear-own:<message_id> (or reaction:clear-own:...) to remove this bot’s own reactions from all emoji on a message.
  • Thread admin actions: thread:create:<message_id>:<name>[|<auto_archive_minutes>] and route-less thread:create-channel:<name>[|<auto_archive_minutes>[|<content>]] (forum/media channels use starter content when provided).
  • Thread list actions: threads:list (active threads for current channel), threads:list:<channel_id> (active threads for channel), threads:list:<channel_id>|archived[|<before>[|<limit>]] (archived public threads), and threads:list:guild:<guild_id> (guild active threads).
  • member_info supports both member:info:<user_id> and guild-scoped member:info:<guild_id>:<user_id> action formats. In guild contexts, the action includes richer guild member fields (nick, role ids, resolved role names, join time, timeout) when available, plus best-effort cached presence status/activity/client-surface details (presence_status, presence_activities, presence_clients) and cache freshness (presence_cached_at, presence_age_seconds) when Discord emits presence updates.
  • presence:set action baseline is supported for bot status updates via gateway heartbeats. Format: presence:set[:<status>[:<activity_type>[:<activity_name>[:<activity_state>[:<activity_url>]]]]] where status is one of online|dnd|idle|invisible and activity type is playing|streaming|listening|watching|custom|competing (or 0..5).
When native_commands is disabled, the adapter clears global application commands for the bot on startup (management baseline parity). You can also override thread behavior and policy surface per channel via group_rules:
{
  "channels": {
    "discord": {
      "group_rules": {
        "123456789012345678": {
          "adapter": "openai",
          "agent_id": "ops",
          "workspace_id": "ops-workspace",
          "skills": ["incident-response", "runbooks"],
          "tool_policy": "Prefer read-only inspection tools first; ask for approval before writes.",
          "allow_exec_approvals": false,
          "allow_file_approvals": false,
          "allow_connector_approvals": true,
          "actions_enabled": true,
          "action_allow": ["reaction_add", "thread_create"],
          "native_command_allow": ["ask", "workspace", "approve", "deny"],
          "auto_thread": true,
          "include_thread_starter": true,
          "allow_bots": false,
          "system_prompt": "Keep replies concise and ops-focused in this channel."
        }
      }
    }
  }
}
For Discord, groups and group_rules keys can be:
  • the channel ID (123456789012345678)
  • the channel name (ops-alerts)
  • a normalized slug from the channel name (ops-alerts)
When a human-friendly key is used, the adapter resolves it at runtime and still sends outbound messages to the underlying Discord channel ID. Set group_rules.<key>.allow_bots=true only when you explicitly want to process messages from other bots in that channel. The gateway always ignores messages authored by its own bot user. Set group_rules.<key>.agent_id to route that Discord channel to a specific configured agent. Set group_rules.<key>.adapter to override the AI adapter for that channel/thread route. Set group_rules.<key>.workspace_id to provide a default workspace for that channel/thread when the session has no explicit workspace set. Set group_rules.<key>.skills to provide channel-level skill guidance in system context (prioritized, deduplicated, and applied with thread-aware precedence). Set group_rules.<key>.tool_policy to inject channel-specific tool usage policy guidance into system context. Set group_rules.<key>.allow_exec_approvals, allow_file_approvals, and allow_connector_approvals to enforce channel-level approval gating in Discord group contexts (unset defaults to allowed). Deny actions remain available so users can safely reject pending requests even when allow-actions are blocked. Set group_rules.<key>.native_command_allow to further restrict which slash commands are accepted in that channel/thread scope (in addition to global native_command_allow). Set group_rules.<key>.actions_enabled=false to hard-disable Discord actions for that channel/thread scope. Set group_rules.<key>.action_allow to further restrict allowed Discord action keys in that channel/thread scope (in addition to global action_allow). Set group_rules.<key>.enabled=false to hard-disable inbound Discord processing, native interactions, and action dispatch for that channel/thread scope (thread rule takes precedence over parent rule when both exist). Set group_rules.<key>.require_mention to override mention gating per scope with thread-aware precedence. For thread sessions, a thread rule can relax or tighten mention requirements independently of the parent channel.

Multi-account baseline

Discord supports account-scoped adapters via channels.discord.accounts (mirrors OpenClaw’s account-id pattern).
{
  "channels": {
    "discord": {
      "enabled": true,
      "bot_token_ref": "vault:secret:discord-default-token",
      "accounts": {
        "ops": {
          "enabled": true,
          "bot_token_ref": "vault:secret:discord-ops-token"
        },
        "support": {
          "enabled": true,
          "bot_token_ref": "vault:secret:discord-support-token"
        }
      }
    }
  }
}
  • Base adapter channel key is discord.
  • Account adapters use discord/<account-id> (for routing, policy checks, and session keys).
  • Account configs inherit base Discord policy/settings and only override token material in this baseline.

Group mention gating

If require_mention is enabled, guild/group messages are processed only when the bot is explicitly mentioned. For bot-created auto-thread conversations, Discord thread replies are treated as mention-authorized (OpenClaw parity behavior) so users can continue naturally without re-mentioning on every message.

Pairing and allowlists

Discord uses the shared pairing and allowlist rules. See Security and pairing.

Security tips

  • Keep pairing.dm_policy=pairing unless you have a tightly controlled setup.
  • Prefer allow_from and group_allow_from for high-trust deployments.
  • Avoid adding the bot to untrusted public servers.