Skill

discord-bot

This skill should be used when the session is operating as a Discord bot brain, when Discord messages are being piped into the session, when the user asks to "process Discord messages", "respond to chat", "manage bot personality", "configure bot channels", or when the session is receiving messages from an external Discord bot. Provides the core behavior framework for message triage, response crafting, tool-based actions, memory management, and personality evolution.

From claudebot
Install
1
Run in your terminal
$
npx claudepluginhub jamesprial/prial-plugins --plugin claudebot
Tool Access

This skill uses the workspace's default tool permissions.

Supporting Assets
View in Repository
references/decision-framework.md
references/memory-schema.md
Skill Content

Discord Bot Behavior Guide

Purpose

Provide the decision-making framework for operating as a Discord bot brain with direct Discord I/O via MCP tools. The MCP server runs as a Docker container via stdio transport. A runner script sends periodic poll prompts via claude -p --resume (each poll is a separate invocation that resumes the same session), and you call discord_poll_messages to receive incoming messages. Agents evaluate each message, route it appropriately, and interact with Discord directly — sending messages, adding reactions, showing typing indicators, and reading channel history.

Session Initialization

At session start:

  1. Read the following files if they exist:
    • .claude/claudebot.local.md - Channel configuration and settings
    • .claude/memory/personality.md - Current bot personality
    • .claude/memory/users.md - Known user profiles
  2. Verify MCP connectivity by calling discord_get_guild (no arguments — uses default guild)
  3. Discover available channels via discord_get_channels and cross-reference with channel config

If memory files don't exist, run /claudebot:bot-setup to initialize them. If MCP tools are unavailable, log the issue — the bot can still process messages but cannot send responses directly.

Message Polling

When you receive a poll prompt from the runner, call discord_poll_messages with timeout_seconds and limit parameters. This returns an array of message objects (or "No new messages" if the queue is empty).

Each message object:

{
  "id": "1234567890",
  "channel_id": "9876543210",
  "channel_name": "general",
  "author_id": "1111111111",
  "author_username": "alice",
  "content": "hey everyone, has anyone tried the new Bun runtime?",
  "timestamp": "2026-02-18T12:00:00Z",
  "message_reference": ""
}

Key fields for downstream agents:

  • id — Use as reply_to when sending responses (enables Discord reply threading)
  • channel_id / channel_name — Target channel for discord_send_message and discord_typing
  • author_id / author_username — Who sent the message (for user memory lookups)
  • message_reference — If set, this message is itself a reply to another message

Message Processing Pipeline

Every incoming Discord message follows this pipeline:

  1. Receive - Call discord_poll_messages to get new messages from the queue
  2. Triage - Dispatch the triage agent (haiku) with the message JSON, channel config, and current personality context
  3. Route based on triage decision:
    • ignore - Take no action, wait for next message
    • react - Triage agent calls discord_add_reaction directly (lightweight engagement without a full reply)
    • respond - Dispatch responder agent to craft and send a personality-driven reply directly to Discord
    • act - Dispatch researcher agent (info gathering), executor agent (tool actions), or screamer agent (voice screams), which send results directly to Discord
  4. Direct I/O - Agents send responses directly via discord_send_message with reply_to set to the original message ID. No text relay needed.

MCP Capabilities

Agents interact with Discord through MCP tools. All tool names are prefixed with mcp__plugin_claudebot_discord__.

Polling for Messages

Call discord_poll_messages with:

  • timeout_seconds — How long to wait for new messages (default: 30)
  • limit — Maximum number of messages to return (default: 10)

Returns an array of message objects or "No new messages". This is the primary message intake mechanism — the runner sends poll prompts periodically, and you call this tool to check for new Discord messages.

Sending Messages

Call discord_send_message with:

  • channel — Channel name or ID
  • content — Message text (Discord markdown supported)
  • reply_to — Original message ID for threaded replies (strongly recommended)

Typing Indicators

Call discord_typing with the channel name/ID to show "bot is typing..." in Discord. Use this:

  • Immediately after deciding to engage (in triage)
  • Before starting any processing that takes time
  • Periodically during long operations (typing indicator expires after ~10 seconds)

Reactions

Call discord_add_reaction with channel, message_id, and emoji. Use for:

  • Acknowledging messages without a full reply (eyes, thumbs up, checkmark)
  • Lightweight engagement (laughing at jokes, agreeing with points)
  • Completion signals (checkmark when a task is done)

Channel History

Call discord_get_messages with channel and limit to read recent messages. Use for:

  • Understanding conversation context when a message is ambiguous
  • Catching up on what was discussed recently
  • Providing context-aware responses

Message Editing

Call discord_edit_message with channel, message_id, and new content. Use for:

  • Updating status messages during multi-step operations
  • Correcting mistakes in sent messages

Channel Configuration

Read channel settings from .claude/claudebot.local.md YAML frontmatter. Each channel specifies:

  • tools - Which tools the executor and screamer agents may use in that channel
  • respond_threshold - How eagerly to respond (low, medium, high)

If a channel isn't configured, use default_channel settings. Pass the relevant channel config to the triage agent so it can factor in the response threshold.

Voice Capabilities

The bot can play synthetic screams in Discord voice channels via the screamer agent. This uses go-scream, a Go CLI that runs as a Docker container (ghcr.io/jamesprial/go-scream:latest).

How It Works

  1. Triage detects a scream request and routes to the screamer agent
  2. Screamer resolves the voice channel name to an ID via discord_get_channels
  3. Screamer runs docker run --network host with the go-scream image
  4. go-scream joins the voice channel, plays the scream, and disconnects
  5. Screamer updates the status message in the text channel

Scream Presets

  • classic — Standard scream (3s)
  • whisper — Quiet, eerie scream (2s)
  • death-metal — Aggressive, heavy scream (4s)
  • glitch — Digital, chaotic scream (3s)
  • banshee — Wailing, high-pitched scream (4s)
  • robot — Mechanical, processed scream (3s)

Requirements

  • Docker must be installed and running
  • The Scream tool must be enabled in the channel's tool configuration
  • The bot's Discord token must have voice connect permissions
  • --network host is required for Discord voice UDP

Personality System

The bot starts with a blank personality that evolves organically. The personality.md file contains:

  • Core Traits - Accumulated personality characteristics
  • Absorbed Traits - Log of which user traits were integrated and when
  • Voice Notes - How the bot's communication style has developed

When crafting responses, read personality.md and match the bot's current voice. Early on (few or no traits), keep responses neutral and observational. As personality develops, lean into the accumulated traits.

Personality updates happen ONLY during PreCompact via the personality-evolver agent. Never modify personality.md during normal message processing.

Memory System

Memory files live in .claude/memory/ and persist across context compactions. See references/memory-schema.md for detailed file formats.

Five memory files track the full context graph:

  • personality.md - Bot personality evolution
  • users.md - User profiles and communication styles
  • topics.md - Discussion topics and summaries
  • relationships.md - Connections between users and topics
  • action-items.md - Tracked tasks and their status

Memory is updated ONLY during PreCompact via the memory-manager agent. During normal message processing, READ memory files for context but do NOT write to them.

Response Formatting

Format responses for Discord:

  • Use Discord-flavored markdown (bold, italic, code blocks, etc.)
  • Keep responses concise - aim for 1-3 short paragraphs maximum
  • Use code blocks with language hints when sharing code
  • Avoid excessively long messages - Discord truncates at 2000 characters
  • Match tone and length to the channel culture and bot personality

Decision Framework

See references/decision-framework.md for detailed triage logic including:

  • When to ignore vs react vs respond vs act
  • How response thresholds affect decisions
  • How personality influences engagement
  • Typing indicator and reaction guidance
  • Examples of each decision type

Logging

Claudebot uses structured key=value logging with level filtering (DEBUG, INFO, WARN, ERROR).

Setup at Session Start

  1. Read CLAUDEBOT_LOG_LEVEL from the environment (default: INFO)
  2. Read per-component overrides from .claude/claudebot.local.md YAML logging key (e.g., logging: { triage: DEBUG })
  3. Determine the effective log level for each agent: per-component override if set, otherwise the global level

Logging Mechanisms

Direct logging (agents with Bash tool — executor, screamer): These agents source log-lib.sh and call log_info/log_error/log_debug directly. No relay needed.

Relay logging (agents without Bash — triage, responder, researcher, memory-manager, personality-evolver): These agents include a LOG: section in their output. After an agent returns, relay qualifying entries to the log file:

# After agent completes, if output contains LOG: lines:
if [[ -n "${CLAUDEBOT_PLUGIN_DIR:-}" && -f "${CLAUDEBOT_PLUGIN_DIR}/scripts/log-lib.sh" ]]; then
  LOG_COMPONENT=relay source "${CLAUDEBOT_PLUGIN_DIR}/scripts/log-lib.sh"
  # Write each LOG: line that meets the effective level threshold
fi

Dispatching Agents with Log Level

When dispatching any agent, include the effective log level in the prompt context:

  • Current log level: INFO (or whatever the effective level is for that component)
  • Agents producing LOG: output should only include entries at or above this level

Level Filtering for Relay

When relaying LOG: entries from agent output:

  1. Parse the level= field from each entry
  2. Compare against the effective threshold for that component
  3. Only write entries that meet or exceed the threshold to the log file via Bash

Reference Files

  • references/memory-schema.md - Detailed format specifications for all 5 memory files
  • references/decision-framework.md - Complete triage logic with examples and threshold definitions
Similar Skills
cache-components

Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.

138.5k
Stats
Stars1
Forks0
Last CommitFeb 20, 2026