This document records the actual installation and integration experience of connecting Claude Code to Discord via the official Channels plugin (research preview, 2026/03).
Environment:
- OS: WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2)
- Claude Code: v2.1.81
- Model: Claude Opus 4.6 (1M context)
- Runtime: Bun
- Go to Discord Developer Portal
- Click New Application, name it
- Navigate to Bot section:
- Create username
- Click Reset Token and copy (shown only once)
- Enable Message Content Intent under Privileged Gateway Intents
- Navigate to OAuth2 > URL Generator:
- Scope:
bot - Permissions: View Channels, Send Messages, Send Messages in Threads, Read Message History, Attach Files, Add Reactions
- Integration type: Guild Install
- Scope:
- Open generated URL to add bot to your server
Inside a Claude Code session:
/plugin marketplace add anthropics/claude-plugins-official
/plugin install discord@claude-plugins-official
Write the token directly to the .env file:
mkdir -p .claude/channels/discord
echo "DISCORD_BOT_TOKEN=<YOUR_TOKEN>" > .claude/channels/discord/.env
chmod 600 .claude/channels/discord/.envWarning: Do NOT pass the token as a command argument (e.g.,
/discord:configure <token>). This leaks the token into conversation history. Write it to the.envfile directly instead.
./start.sh discord
# or both channels:
./start.sh telegram discord-
DM the Bot on Discord
-
Bot replies with a 6-character pairing code
-
In Claude Code terminal:
/discord:access pair <CODE> -
Bot confirms: "Paired! Say hi to Claude."
-
Lock access to allowlist only:
/discord:access policy allowlist
| Direction | How | Status |
|---|---|---|
| Discord -> Claude Code | User DMs Bot, appears as <channel> in session |
Verified |
| Claude Code -> Discord | mcp__plugin_discord_discord__reply tool with chat_id |
Verified |
| Tool | Description | Tested |
|---|---|---|
reply |
Send message to Discord (supports text, file attachments up to 25MB, max 10 files) | Yes |
react |
Add emoji reaction (unicode or custom <:name:id>) |
- |
edit_message |
Edit a previously sent Bot message | - |
fetch_messages |
Pull up to 100 recent messages (oldest-first) | - |
download_attachment |
Download file attached to incoming message | - |
Note: Discord plugin has fetch_messages which Telegram does not — allows reading recent channel history.
Same pattern as Telegram:
- Claude Code sends an approval request to Discord via
reply - Session pauses, waiting for next conversation turn
- User replies
approveorrejecton Discord - Reply arrives as a
<channel>message in the session - Claude Code proceeds based on the response
Add Discord reply to the permission whitelist so the Bot can always respond:
{
"permissions": {
"allow": [
"mcp__plugin_discord_discord__reply"
]
}
}Discord App (Desktop/Mobile/Web)
| (WebSocket Gateway, plugin connects outbound)
Discord Plugin (Bun subprocess, MCP Server)
| (stdio transport)
Claude Code Session (local, full filesystem access)
- No inbound ports needed - plugin connects outbound via WebSocket
- WSL2 compatible - no firewall configuration required
- No external server - everything runs locally
| File | Purpose |
|---|---|
start.sh |
Launch script with --channels flag |
.env.example |
Template for environment variables |
.gitignore |
Excludes secrets, channel state, local settings |
.claude/settings.local.json |
Permission whitelist (gitignored) |
.claude/channels/discord/.env |
Bot token (gitignored) |
.claude/channels/discord/access.json |
Access control & allowlist (gitignored) |
docs/discord/plan.md |
Planning document |
docs/discord/install.md |
This document |
docs/issues.md |
Known issues (cross-channel) |
| Aspect | Telegram | Discord |
|---|---|---|
| Connection | HTTP long-polling | WebSocket Gateway |
| Message history | Not available | fetch_messages (up to 100) |
| ID format | Numeric chat_id | Snowflake IDs (numeric) |
| Group access | Via allowlist | Opt-in per channel ID |
| File limit | 50MB per file | 25MB per file, max 10 files |
- Offline messages are lost - Bot only receives messages while the session is running
- Permission blocking - Non-whitelisted tool calls block the session until approved in terminal; whitelist frequently-used safe tools
- State directory path mismatch - See docs/issues.md for details on the
DISCORD_STATE_DIRvs skill path mismatch - Token security - Never pass bot tokens as command arguments; write directly to
.envfile - Bot API rate limits - Discord has stricter rate limits than Telegram; the plugin handles this internally