Send Claude Code notifications to Discord channels with rich embeds.
Discord webhooks allow you to send automated messages to channels without requiring a bot user to be online. Messages are formatted as rich embeds with color-coding, timestamps, and session information.
- Open your Discord server
- Go to Server Settings (gear icon)
- Navigate to Integrations tab
- Click "Webhooks" (or "Create Webhook" if none exist)
- Click "New Webhook" button
- Name: Set a name (e.g., "Claude Notifications")
- Channel: Select the target channel from dropdown
- Avatar: (Optional) Upload a custom icon
- Click "Copy Webhook URL"
Your webhook URL will look like:
https://discord.com/api/webhooks/1234567890123456789/AbCdEfGhIjKlMnOpQrStUvWxYz-1234567890
Edit ~/.claude/claude-notifications-go/config.json:
{
"notifications": {
"webhook": {
"enabled": true,
"preset": "discord",
"url": "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"
}
}
}echo '{"session_id":"test","tool_name":"ExitPlanMode"}' | \
bin/claude-notifications handle-hook PreToolUseCheck your Discord channel for the notification!
Messages are sent as rich embeds with:
- Title: Notification type (e.g., "✅ Task Completed")
- Description: Message content with session name
- Color: Status-based color coding
- Footer: Session ID and plugin attribution
- Timestamp: Message creation time
| Status | Color | Hex | Discord Decimal |
|---|---|---|---|
| Task Complete | Green | #28a745 | 2,664,261 |
| Plan Ready | Blue | #007bff | 32,767 |
| Question | Yellow | #ffc107 | 16,761,095 |
| Review Complete | Cyan | #17a2b8 | 1,548,984 |
| Session Limit | Orange | #ff9800 | 16,750,592 |
Claude Code
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Task Completed
[bold-cat] Created new authentication
system with JWT tokens
Session: abc-123 | Claude Notifications
2025-10-19 15:30:45
Messages use Discord's Embeds API:
{
"username": "Claude Code",
"embeds": [
{
"title": "✅ Task Completed",
"description": "[bold-cat] Created new authentication system with JWT tokens",
"color": 2664261,
"footer": {
"text": "Session: abc-123 | Claude Notifications"
},
"timestamp": "2025-10-19T15:30:45Z"
}
]
}{
"notifications": {
"desktop": {
"enabled": true,
"sound": true
},
"webhook": {
"enabled": true,
"preset": "discord",
"url": "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN"
},
"suppressQuestionAfterTaskCompleteSeconds": 12
}
}{
"notifications": {
"webhook": {
"enabled": true,
"preset": "discord",
"url": "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_TOKEN",
"retry": {
"enabled": true,
"maxAttempts": 3,
"initialBackoff": "500ms",
"maxBackoff": "5s"
},
"circuitBreaker": {
"enabled": true,
"failureThreshold": 3,
"successThreshold": 2,
"timeout": "20s"
},
"rateLimit": {
"enabled": true,
"requestsPerMinute": 30
}
}
}
}-
Verify webhook URL:
curl -X POST -H 'Content-Type: application/json' \ --data '{"content":"Test message"}' \ YOUR_WEBHOOK_URL
-
Check logs:
tail -f notification-debug.log | grep webhook -
Verify webhook exists:
- Go to Server Settings → Integrations → Webhooks
- Ensure your webhook is listed and not deleted
To change the target channel:
- Go to Server Settings → Integrations → Webhooks
- Click on your webhook
- Change the Channel dropdown
- Click "Save Changes"
No need to update config.json - the URL stays the same!
Discord rate limits:
- 5 requests per 2 seconds per webhook
- Burst: Up to 5 requests immediately, then rate limited
If you hit rate limits (429 errors), configure rate limiting:
{
"webhook": {
"rateLimit": {
"enabled": true,
"requestsPerMinute": 30
}
}
}If you get 404 errors:
- Webhook may have been deleted
- URL may be incorrect (check for typos)
- Token portion of URL may have been regenerated
Solution: Create a new webhook and update your config.
Discord webhooks are a common attack vector. If an attacker gets your webhook URL, they can:
- Post messages impersonating your notifications
- Spam your channel
- Send malicious links to your team
-
Never commit webhook URLs to git
- Use config files that are .gitignored
- Use environment variables for CI/CD
-
Guard webhook URLs closely
- Treat them like passwords
- Don't share in public channels
- Don't paste in screenshots
-
Limit webhook permissions
- Only give webhook creation rights to trusted members
- Review webhooks regularly in Server Settings
-
Rotate webhooks if compromised
- Delete old webhook
- Create new webhook
- Update config immediately
-
Monitor for unusual activity
- Watch for unexpected messages
- Check webhook metrics for anomalies
-
Use role permissions
- Restrict who can create webhooks in Server Settings → Roles
- Dedicated channel - Create a
#claude-notificationschannel - Custom avatar - Upload Claude icon for easy identification
- Enable retry - Handle transient network failures
- Monitor rate limits - Discord has stricter limits than Slack
- Test thoroughly - Use webhook.site before production
- Secure webhook URLs - See security section above
Override the webhook username per message:
{
"username": "Claude Code - Production",
"embeds": [...]
}Note: This plugin uses a fixed username "Claude Code".
Discord webhooks support mentions in embeds:
- Users:
<@USER_ID> - Roles:
<@&ROLE_ID> - Channels:
<#CHANNEL_ID>
Note: This plugin doesn't include mentions by default.
- Configuration Options - Retry, circuit breaker, rate limiting
- Monitoring - Metrics and debugging
- Troubleshooting - Common issues