Skip to content

Discord Integration

Connect your herdctl agents to Discord, allowing users to interact with AI agents through chat messages and slash commands. Each agent appears as a distinct bot with its own identity, presence, and configuration.

herdctl uses a per-agent bot architecture where each Discord-enabled agent has its own Discord Application and bot token. This design provides several benefits:

Distinct Identities

Each agent appears as a separate bot with its own name, avatar, and presence status

Independent Configuration

Different agents can monitor different channels with different response modes

Scalable Architecture

Add new agents without affecting existing bot configurations

Clear User Experience

Users always know which agent they’re talking to by the bot’s identity

Discord Server
├── #support
│ └── @SupportBot responds to mentions (support-agent)
├── #dev-chat
│ └── @CoderBot responds to all messages (coder-agent)
└── DMs
└── @SupportBot auto-responds (support-agent)

Each agent connects to Discord with its own bot account. When a user messages or mentions the bot, herdctl triggers a Claude session to respond.

ModeBehaviorBest For
mentionResponds only when @mentionedShared channels where multiple bots exist
autoResponds to all messagesDedicated support channels, DMs

herdctl supports two different Discord integrations:

IntegrationTypePurposeConfiguration
ChatTwo-wayInteractive conversationschat.discord
Notification HooksOne-wayJob completion alertshooks.after_run

The chat integration documented on this page enables interactive, two-way conversations:

  • Bot responds to user messages and mentions
  • Maintains conversation context
  • Users can ask questions and get responses
  • Configured in the chat.discord section of agent config

Notification hooks send one-way alerts when jobs complete:

  • Post job results to a channel
  • Conditional notifications (e.g., only when a price drops)
  • No user interaction—just announcements
  • Configured in the hooks.after_run section

Example notification hook:

hooks:
after_run:
- type: discord
channel_id: "${DISCORD_CHANNEL_ID}"
bot_token_env: DISCORD_BOT_TOKEN
when: "metadata.shouldNotify"

Before setting up Discord integration, ensure you have:

  • A Discord account
  • Administrator or Manage Server permissions on the target Discord server
  • Access to the Discord Developer Portal
  • herdctl installed and configured
  • Your agent configuration file ready
  1. Open the Discord Developer Portal

    Navigate to https://discord.com/developers/applications and sign in with your Discord account.

  2. Create a New Application

    Click the New Application button in the top-right corner.

    Enter a name for your application. This name appears in OAuth authorization screens but not as the bot’s display name.

  3. Navigate to the Bot Section

    In the left sidebar, click Bot.

  4. Configure the Bot Username

    Click Edit next to the bot’s username. This is the name users will see in Discord.

    Example names:

    • Support Bot for a customer support agent
    • Code Assistant for a development agent
    • Marketing Bot for a content agent
  5. Set the Bot Avatar (Optional)

    Click on the bot’s avatar to upload a custom image. This helps users identify the bot.

  6. Copy the Bot Token

    Click Reset Token to generate a new token (or Copy if one exists).

  7. Save the Token Securely

    Add the token to your environment:

    Terminal window
    # Add to your shell profile or .env file
    export SUPPORT_DISCORD_TOKEN="your-bot-token-here"

herdctl requires these Privileged Gateway Intents to function properly:

  1. In your Discord Application, go to Bot settings

  2. Scroll down to Privileged Gateway Intents

  3. Enable the following intents:

    IntentRequiredPurpose
    Message Content IntentYesRead message text to respond to users
    Server Members IntentNoNot required for basic functionality
    Presence IntentNoNot required for basic functionality
  4. Click Save Changes

When inviting the bot, herdctl needs these permissions:

PermissionPurpose
Send MessagesReply to user messages
Read Message HistoryBuild conversation context
Use Slash CommandsHandle /help, /reset, /status commands
View ChannelsSee channels the bot has access to

The combined permission integer is: 2147551232

  1. In your Discord Application, go to OAuth2 > URL Generator

  2. Under Scopes, select:

    • bot
    • applications.commands
  3. Under Bot Permissions, select:

    • Send Messages
    • Read Message History
    • Use Slash Commands
    • View Channels

    Or use permission integer: 2147551232

  4. Copy the generated URL at the bottom of the page

  5. Open the URL in your browser

  6. Select the server where you want to add the bot

  7. Click Authorize

  8. Complete the CAPTCHA if prompted

The bot will now appear in your server’s member list (offline until you start herdctl).

Configure Discord in your agent’s YAML file under the chat.discord section:

name: support-agent
description: "Customer support agent"
chat:
discord:
bot_token_env: SUPPORT_DISCORD_TOKEN
guilds:
- id: "123456789012345678"
channels:
- id: "987654321098765432"
name: "#support"
mode: mention
chat:
discord:
# Environment variable containing the bot token (required)
bot_token_env: SUPPORT_DISCORD_TOKEN
# Session expiry in hours (default: 24)
session_expiry_hours: 24
# Log level: minimal, standard, verbose (default: standard)
log_level: standard
# Optional: slash command registration mode
# global = available everywhere (slower to propagate)
# guild = faster updates for one guild (recommended for local dev)
command_registration:
scope: global # global | guild
# guild_id: "123456789012345678" # required when scope: guild
# Output configuration - control what SDK messages appear in Discord
output:
tool_results: true # Show tool result embeds (default: true)
tool_result_max_length: 900 # Max chars in tool output (default: 900, max: 1000)
system_status: true # Show system status embeds (default: true)
result_summary: true # Show completion summary embed (default: true)
errors: true # Show error embeds (default: true)
typing_indicator: true # Show typing indicator while processing (default: true)
acknowledge_emoji: "👀" # Emoji reaction on receipt (default: "👀", empty to disable)
assistant_messages: answers # Which assistant turns to send: "answers" or "all" (default: answers)
progress_indicator: true # Show progress embed with tool names (default: true)
# Bot presence/activity (optional)
presence:
activity_type: watching # playing, watching, listening, competing
activity_message: "for support requests"
# Voice message transcription (optional)
voice:
enabled: true # Enable voice message transcription (default: false)
provider: openai # Transcription provider (default: openai)
api_key_env: OPENAI_API_KEY # Environment variable with API key (default: OPENAI_API_KEY)
model: whisper-1 # Whisper model to use (default: whisper-1)
language: en # Language hint for accuracy (ISO 639-1, optional)
# File attachments (optional)
attachments:
enabled: true # Enable file attachment processing (default: false)
max_file_size_mb: 10 # Maximum file size in MB (default: 10)
max_files_per_message: 5 # Maximum files per message (default: 5)
allowed_types: # Allowed MIME types (default: image/*, pdf, text/*)
- "image/*"
- "application/pdf"
- "text/*"
download_dir: ".discord-attachments" # Directory for downloaded files (default: .discord-attachments)
cleanup_after_processing: true # Delete files after processing (default: true)
# Skill discovery (optional, recommended in containerized deployments)
skills:
- name: "security-audit"
description: "Run a comprehensive security audit"
- name: "docs-update"
description: "Update documentation"
# Guild (server) configurations
guilds:
- id: "123456789012345678" # Discord server ID
# Default channel mode for unlisted channels (optional)
# When set, bot responds to @mentions (or all messages if "auto") in any channel
default_channel_mode: mention # mention or auto (optional)
channels:
- id: "987654321098765432" # Channel ID
name: "#support" # For documentation (optional)
mode: mention # mention or auto
context_messages: 10 # Messages to include as context
- id: "111222333444555666"
name: "#general"
mode: auto
context_messages: 5
# DM settings for this guild's members (optional)
dm:
enabled: true
mode: auto
allowlist: ["user-id-1", "user-id-2"] # Only these users (optional)
blocklist: ["spam-user-id"] # Block specific users (optional)
# Global DM settings (applies to all DMs)
dm:
enabled: true
mode: auto
FieldTypeDefaultDescription
bot_token_envstringRequired. Environment variable name containing the bot token
session_expiry_hoursnumber24Hours before a conversation session expires
log_levelstringstandardLogging verbosity: minimal, standard, verbose
command_registrationobject{ scope: global }Slash command registration mode (global or guild)
presenceobjectBot presence/activity configuration
guildsarrayList of Discord servers to operate in
dmobjectGlobal DM configuration
voiceobjectVoice message transcription configuration
attachmentsobjectFile attachment handling configuration
skillsarrayExplicit skill list for /skills and /skill commands
FieldTypeDescription
activity_typestringActivity type: playing, watching, listening, competing
activity_messagestringActivity text shown in the bot’s status
FieldTypeDefaultDescription
scopestringglobalglobal registers app commands globally; guild registers to one guild for faster propagation
guild_idstringRequired when scope: guild; target guild for registration
FieldTypeDescription
idstringRequired. Discord server (guild) ID
channelsarrayChannels to monitor in this guild
default_channel_modestringDefault mode for channels not explicitly listed. When set, bot responds to @mentions (or all messages if auto) in any channel in this guild
dmobjectDM settings for members of this guild
FieldTypeDefaultDescription
idstringRequired. Discord channel ID
namestringHuman-readable name (for documentation)
modestringmentionResponse mode: mention or auto
context_messagesnumber10Number of recent messages to include as context
FieldTypeDefaultDescription
enabledbooleantrueAllow direct messages
modestringautoResponse mode for DMs
allowliststring[]Only allow DMs from these user IDs
blockliststring[]Block DMs from these user IDs

Control which SDK messages are surfaced in Discord. When your agent uses tools (Bash, Read, Write, etc.) or the SDK emits system/error messages, these settings determine what appears in the channel.

FieldTypeDefaultDescription
output.tool_resultsbooleantrueShow tool result embeds when the agent uses tools
output.tool_result_max_lengthnumber900Maximum characters shown in tool output (max: 1000)
output.system_statusbooleantrueShow system status embeds (e.g., “Compacting context…”)
output.result_summarybooleantrueShow a summary embed when the agent finishes (duration, cost, tokens)
output.errorsbooleantrueShow error embeds when the SDK reports errors
output.typing_indicatorbooleantrueShow typing indicator while processing. Set to false on long-running jobs to prevent Discord timeout errors
output.acknowledge_emojistring"👀"Emoji reaction added when message is received. Removed automatically after response is sent. Set to empty string to disable
output.assistant_messagesstring"answers"Which assistant turns to send to Discord: "answers" (only text responses) or "all" (includes tool_use blocks)
output.progress_indicatorbooleantrueShow a “Working…” embed that updates in real-time with tool names as the agent works

All output types appear as compact Discord embeds with color coding:

Message TypeEmbed ColorExample Content
Tool result (success)Blurple🔧 Bash> git status with output preview
Tool result (error)Red🔧 Bash — command output with error
System statusGray⚙️ System — “Compacting context…”
Result summaryGreen/Red✅ Task Complete — duration, turns, cost, token usage
ErrorRed❌ Error — error description

Tool result embeds include the tool name with an emoji, the input summary (command, file path, or search pattern), execution duration, output length, and a truncated preview of the output in a code block.

Minimal output (text responses only):

chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
output:
tool_results: false
system_status: false
errors: false

Full visibility (all message types):

chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
output:
tool_results: true
tool_result_max_length: 500
system_status: true
result_summary: true
errors: true

herdctl can automatically transcribe voice messages sent in Discord text channels using OpenAI’s Whisper API. When enabled, users can send voice recordings and the agent receives the transcribed text as the prompt.

  1. User sends a voice message in a Discord channel
  2. herdctl downloads the audio file
  3. Audio is transcribed via OpenAI Whisper API
  4. Transcription text is used as the agent’s prompt
  5. Bot sends a grey embed showing the transcription
  6. Agent responds based on the transcribed text
FieldTypeDefaultDescription
voice.enabledbooleanfalseEnable voice message transcription
voice.providerstring"openai"Transcription provider (currently only openai supported)
voice.api_key_envstring"OPENAI_API_KEY"Environment variable containing the OpenAI API key
voice.modelstring"whisper-1"Whisper model to use for transcription
voice.languagestringLanguage hint for better accuracy (ISO 639-1 code like "en", "es", "fr")
chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
voice:
enabled: true
provider: openai
api_key_env: OPENAI_API_KEY
model: whisper-1
language: en # Improves accuracy for English
  1. Get an OpenAI API key

    Sign up at platform.openai.com and create an API key with access to the Whisper API.

  2. Add the API key to your environment

    Terminal window
    export OPENAI_API_KEY="sk-..."
  3. Enable voice in your agent config

    chat:
    discord:
    bot_token_env: DISCORD_BOT_TOKEN
    voice:
    enabled: true
  4. Start herdctl

    Terminal window
    herdctl start
  5. Test with a voice message

    In Discord, hold the microphone button to record a voice message and send it in a channel where the bot is active.

herdctl can process file attachments (images, PDFs, text files) uploaded by users alongside their messages. When enabled, agents can view and analyze files, and agents can also send files back to users.

User uploads to agent:

  1. User sends a message with file attachments (images, PDFs, code files, etc.)
  2. herdctl downloads and categorizes the files
  3. Text files are inlined directly in the prompt
  4. Images and PDFs are saved to the agent’s working directory
  5. Agent receives file metadata and can use the Read tool to access saved files

Agent sends to user:

  1. Agent uploads a file via MCP upload_file operation
  2. herdctl buffers the file in memory
  3. File is automatically attached to the next Discord message (the agent’s answer)
FieldTypeDefaultDescription
attachments.enabledbooleanfalseEnable file attachment processing
attachments.max_file_size_mbnumber10Maximum file size in megabytes
attachments.max_files_per_messagenumber5Maximum number of files per message
attachments.allowed_typesarray["image/*", "application/pdf", "text/*"]Allowed MIME type patterns (supports wildcards)
attachments.download_dirstring".discord-attachments"Directory for downloaded files (relative to agent’s working_directory)
attachments.cleanup_after_processingbooleantrueDelete downloaded files after agent run completes
chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
attachments:
enabled: true
max_file_size_mb: 10
max_files_per_message: 5
allowed_types:
- "image/*" # PNG, JPG, GIF, etc.
- "application/pdf"
- "text/*" # .txt, .md, .json, .yaml, etc.
- "text/x-python" # Specific MIME type for .py files
download_dir: ".discord-attachments"
cleanup_after_processing: true
CategoryMIME PatternExamplesProcessing
Imagesimage/*PNG, JPG, GIF, WebPSaved to download directory, accessible via Read tool
PDFsapplication/pdfPDF documentsSaved to download directory, accessible via Read tool
Texttext/*.txt, .md, .json, .yaml, .py, .jsContent inlined directly in prompt

When running in Docker, herdctl automatically translates file paths:

  • Files are saved to the download directory inside the container
  • Paths in prompts reference the container filesystem
  • Cleanup happens inside the container after the run
chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
attachments:
enabled: true
allowed_types: ["image/*"]

User sends:

Check this screenshot for errors
[screenshot.png]

Agent receives prompt with file metadata:

Check this screenshot for errors
Files attached:
- screenshot.png (image/png, 245 KB)
Path: /agent-working-dir/.discord-attachments/screenshot.png

Agent can then use the Read tool to view the image.

herdctl can discover and expose skills via the /skills and /skill slash commands. By default, skills are discovered from the filesystem, but you can override this with an explicit list.

Skills are discovered from these directories (in order):

  1. .claude/skills/ (recommended location)
  2. .codex/skills/ (legacy location)
  3. skills/ (alternative location)

Each skill is a subdirectory containing a skill.json or skill.yaml file with metadata.

Override filesystem discovery by providing an explicit skills array:

chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
skills:
- name: "security-audit"
description: "Run a comprehensive security audit"
- name: "docs-update"
description: "Update documentation with latest changes"
- name: "review-pr"
description: "Review a GitHub pull request"
ScenarioRecommendation
Containerized deploymentUse explicit skills list (filesystem may not be available)
Disable skill discoverySet skills: [] to disable /skills and /skill commands
Curated skill listList only the skills you want exposed in Discord
DevelopmentOmit skills field to auto-discover from filesystem

To disable skill commands entirely:

chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
skills: [] # Empty array disables skill discovery

herdctl uses environment variables for Discord tokens to keep secrets out of configuration files.

Use a consistent naming pattern for your bot tokens:

Terminal window
# Pattern: {AGENT_NAME}_DISCORD_TOKEN
export SUPPORT_DISCORD_TOKEN="your-support-bot-token"
export CODER_DISCORD_TOKEN="your-coder-bot-token"
export MARKETING_DISCORD_TOKEN="your-marketing-bot-token"

Add to ~/.bashrc, ~/.zshrc, or equivalent:

Terminal window
export SUPPORT_DISCORD_TOKEN="your-token-here"

Then reload:

Terminal window
source ~/.bashrc # or ~/.zshrc

In your agent YAML, reference the environment variable name (not the value):

chat:
discord:
bot_token_env: SUPPORT_DISCORD_TOKEN # The variable NAME

herdctl reads the token from process.env.SUPPORT_DISCORD_TOKEN at runtime.

Discord IDs are unique 17-19 digit numbers. You’ll need IDs for servers (guilds), channels, and users.

  1. Open Discord (desktop or web app)

  2. Go to User Settings (gear icon near your username)

  3. Navigate to App Settings > Advanced

  4. Enable Developer Mode

With Developer Mode enabled, right-click on any server, channel, or user to see a Copy ID option:

ItemHow to Copy
Server IDRight-click the server icon in the sidebar > Copy Server ID
Channel IDRight-click the channel name > Copy Channel ID
User IDRight-click a user’s name > Copy User ID
Message IDRight-click a message > Copy Message ID
guilds:
- id: "1234567890123456789" # Server ID (18 digits)
channels:
- id: "9876543210987654321" # Channel ID (19 digits)
Terminal window
herdctl start

Look for connection messages in the logs:

[support-agent] Connecting to Discord...
[support-agent] Connected to Discord: SupportBot#1234
[support-agent] Slash commands registered successfully

The bot should appear online in your Discord server with the configured presence:

SupportBot - Watching for support requests

In a channel configured with mode: mention:

You: @SupportBot How do I reset my password?
SupportBot: To reset your password, follow these steps...

In a channel configured with mode: auto:

You: How do I reset my password?
SupportBot: To reset your password, follow these steps...

herdctl automatically registers slash commands for every Discord-enabled agent:

CommandDescription
/helpShow available commands and usage
/pingQuick health check
/configShow runtime-relevant agent configuration
/toolsShow allowed/denied tools and MCP servers
/usageShow last run stats and cumulative session totals
/skillsList discovered skills for this agent
/skillTrigger a skill (with autocomplete)
/statusShow bot connection status and session info
/sessionShow current session and run state for this channel
/resetClear conversation context and start fresh
/newAlias for starting a fresh conversation
/stopStop the active run in this channel
/cancelAlias for /stop
/retryRetry the last prompt in this channel

Discord slash commands are not regular chat messages. Type / in the message box, then pick the command under your bot’s app name in Discord’s command picker. Discord sends this as an interaction event (not a normal message), which herdctl handles via the command manager.

Try them in any channel where the bot is active:

/status

Shows available commands and basic usage information:

/help

Example output:

🤖 Support Bot Commands
/help - Show this message
/usage - Show latest run usage
/skills - List discovered skills
/status - Show bot status and stats
/reset - Clear conversation context
Chat with me:
• @SupportBot your question - In channels
• Just type in DMs - Direct messages

Shows detailed connection status and statistics:

/status

Example output:

🟢 Support Bot Status
Connected: Yes
Uptime: 2h 34m
Session: Active (expires in 21h)
Stats:
• Messages received: 47
• Responses sent: 43
• Current channel: #support

Clears the conversation context for the current channel:

/reset

Example output:

✨ Conversation reset! Starting fresh.

Use /reset when:

  • The bot seems confused or stuck on a previous topic
  • You want to start a completely new conversation
  • The session has accumulated too much irrelevant context

If DMs are enabled, send a direct message to the bot:

You (DM): Hello!
SupportBot: Hello! How can I help you today?

You can have multiple agents (each with their own bot) in the same Discord server. This is useful for specialized agents:

agents/support-agent.yaml
name: support-agent
chat:
discord:
bot_token_env: SUPPORT_DISCORD_TOKEN
guilds:
- id: "123456789012345678"
channels:
- id: "support-channel-id"
name: "#support"
mode: mention
# agents/coder-agent.yaml
name: coder-agent
chat:
discord:
bot_token_env: CODER_DISCORD_TOKEN
guilds:
- id: "123456789012345678" # Same server
channels:
- id: "dev-channel-id"
name: "#dev-chat"
mode: auto

You can configure a bot to respond to @mentions in any channel in a guild, without explicitly listing each channel:

chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
guilds:
- id: "123456789012345678"
# Respond to @mentions in any channel (no explicit channel list needed)
default_channel_mode: mention
# Optionally, override mode for specific channels
channels:
- id: "987654321098765432"
name: "#support"
mode: auto # Auto mode in this specific channel

This is useful for:

  • Support bots that should be accessible everywhere via @mention
  • Bots that need to respond in channels created after deployment
  • Keeping auto mode in specific channels while allowing mentions elsewhere

How it works:

  • If a channel is explicitly listed in channels, that configuration takes precedence
  • If a channel is not listed, default_channel_mode applies
  • If default_channel_mode is not set, the bot ignores unlisted channels
  1. Use distinct bot names and avatars - Help users identify which bot they’re addressing

  2. Use mention mode in shared channels - Prevents bots from responding to each other or creating confusion

  3. Dedicate channels when possible - Assign specific channels to specific bots with auto mode

  4. Document bot purposes - Add channel topics explaining which bot handles what

ScenarioRecommendation
Two bots in same channelUse mode: mention for both
Bot in dedicated channelUse mode: auto
Support + Dev botsSeparate channels or mention mode

Discord chat integration maintains conversation context so your agent can have multi-turn conversations and “remember” what was discussed.

  • Scope: Sessions are per-channel (or per-DM conversation)
  • Identity: Session ID is based on channel ID
  • Expiry: Sessions expire after session_expiry_hours (default: 24 hours)
  • Persistence: Sessions survive bot restarts within the expiry window

When a user sends a message, the agent receives:

  1. The current message as the prompt
  2. Recent conversation history from the session
  3. The channel/user context

This allows natural conversations:

User: What's the current price of the Hyken chair?
Bot: The Hyken chair is currently $189 at Staples.
User: When did you last check?
Bot: I checked prices 2 hours ago at 10:30 AM.
User: Is that below my target?
Bot: Yes! Your target is $200, so $189 is $11 below target.

The bot remembers the chair and target price from earlier in the conversation.

chat:
discord:
bot_token_env: DISCORD_BOT_TOKEN
session_expiry_hours: 24 # Default: 24 hours

Choose expiry based on your use case:

Use CaseRecommended Expiry
Support bot24-48 hours
Quick Q&A1-4 hours
Long-running projects72+ hours
Stateless responses1 hour

Users can clear their session context using /reset:

/reset

This is useful when:

  • The bot is confused about context from earlier
  • Starting a completely new topic
  • Testing fresh conversation flows

Control how many recent messages are included as context:

guilds:
- id: "123456789012345678"
channels:
- id: "987654321098765432"
mode: mention
context_messages: 10 # Include last 10 messages

More context = better continuity but higher token usage.

ScenarioRecommended Mode
Shared channel with humansmention
Shared channel with other botsmention
Dedicated support channelauto
Direct messagesauto
High-traffic general channelmention

For multiple agents in the same server:

  1. Dedicated channels: Give each bot its own channel with auto mode

    #support → SupportBot (auto)
    #dev-help → CoderBot (auto)
  2. Shared channels: Use mention mode so users choose which bot to address

    #general → SupportBot (mention) + CoderBot (mention)

Open DMs (friendly bot):

dm:
enabled: true
mode: auto

Restricted DMs (team only):

dm:
enabled: true
mode: auto
allowlist:
- "user-id-1"
- "user-id-2"

No DMs (channel-only):

dm:
enabled: false

Block specific users:

dm:
enabled: true
mode: auto
blocklist:
- "spam-user-id"

Discord has rate limits on message sending. To avoid issues:

  1. Don’t use auto mode in high-traffic channels - Use mention mode instead
  2. Keep responses concise - Avoid very long multi-paragraph responses
  3. Reduce context_messages for busy channels - Lower token usage means faster responses

If you see rate limit warnings in logs, consider:

  • Switching busy channels to mention mode
  • Reducing session expiry to limit context size
  • Using shorter context_messages values

Cause: The environment variable specified in bot_token_env is not set or is empty.

Solution:

Terminal window
# Check if the variable is set
echo $SUPPORT_DISCORD_TOKEN
# Set it if missing
export SUPPORT_DISCORD_TOKEN="your-token-here"

Cause: Message Content Intent is not enabled in the Discord Developer Portal.

Solution:

  1. Go to Discord Developer Portal
  2. Select your application
  3. Go to Bot > Privileged Gateway Intents
  4. Enable Message Content Intent
  5. Save changes

”Missing Access” or “Missing Permissions”

Section titled “”Missing Access” or “Missing Permissions””

Cause: The bot lacks required permissions in the channel.

Solution:

  1. Check that the bot role has Send Messages, Read Message History permissions
  2. Check channel-specific permission overrides
  3. Re-invite the bot with correct permissions

Cause: herdctl isn’t running or connection failed.

Solution:

  1. Start herdctl: herdctl start
  2. Check logs for connection errors
  3. Verify token is valid (not expired or reset)

Cause: Various configuration issues.

Checklist:

  • Is the channel ID correct in the config?
  • Is the mode appropriate? (mention requires @mention)
  • Is Message Content Intent enabled?
  • Check logs for “messageIgnored” events

Cause: The bot token is incorrect or has been reset.

Solution:

  1. Go to Discord Developer Portal
  2. Navigate to your application’s Bot section
  3. Click Reset Token
  4. Update your environment variable with the new token

Enable verbose logging to troubleshoot issues:

chat:
discord:
bot_token_env: SUPPORT_DISCORD_TOKEN
log_level: verbose # Shows detailed debug information

Verbose logs include:

  • All received messages and whether they were processed
  • Connection state changes
  • Rate limit events
  • Channel configuration resolution

Use the /status slash command in Discord to check the bot’s connection status and statistics.

Discord rate limits are handled automatically by the connector. If you see frequent rate limit warnings:

  1. Reduce message frequency
  2. Avoid rapid-fire responses
  3. Consider using shorter context windows (context_messages)

Rate limit events are logged at the standard level:

[support-agent] Rate limited by Discord API: { route: '/channels/123/messages', timeToReset: 5000 }