> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moldable.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Discord

> Configure the Discord channel adapter.

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

```json theme={null}
{
  "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`:

```json theme={null}
{
  "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).

```json theme={null}
{
  "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](/core/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.
