discord-mcp
by jonasgantner
README.md
# discord-mcp
A comprehensive Discord MCP server with 66 tools. Built with TypeScript, Bun, and discord.js.
The only Discord MCP server that shows **emoji reactions**, **thread indicators**, and **attachment metadata** inline in message output, so your AI assistant can see the full context of every message without extra API calls.
## Features
- **Reactions in message output** ā see `[šĆ2 ā
Ć1]` on every message
- **Thread indicators** ā `[š§µ thread]` shows which messages have active threads
- **Attachment metadata** ā `[+1att]` with `get_attachment` for URLs and file info
- **File uploads** ā send images, PDFs, and other files via the `files` parameter
- **Auto-chunking** ā messages over 2000 characters are split at paragraph boundaries
- **Incremental reads** ā `after` and `before` params for fetching only new messages
- **66 tools** ā messages, channels, threads, roles, moderation, voice, webhooks, events, permissions, invites, emojis, DMs
- **Automatic rate limiting** ā discord.js handles 429 responses transparently
- **Native runtime** ā Bun/TypeScript, no Docker required
## Quick start
### Prerequisites
- [Bun](https://bun.sh) v1.0+
- A Discord bot token ([create one here](https://discord.com/developers/applications))
### Install
```bash
git clone https://github.com/jonasgantner/discord-mcp.git
cd discord-mcp
bun install
```
### Configure
Set environment variables:
```bash
export DISCORD_TOKEN="your-bot-token"
export DISCORD_GUILD_ID="your-server-id" # optional, used as default for guild-scoped tools
```
### Run
```bash
bun run index.ts
```
The server communicates over stdio (MCP standard).
### Use with Claude Code
Add to `~/.claude/mcp-wrappers/discord.sh`:
```bash
#!/bin/bash
exec bun run /path/to/discord-mcp/index.ts
```
Or configure directly in your MCP settings.
### Use with Claude Desktop
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"discord": {
"command": "bun",
"args": ["run", "/path/to/discord-mcp/index.ts"],
"env": {
"DISCORD_TOKEN": "your-bot-token",
"DISCORD_GUILD_ID": "your-server-id"
}
}
}
}
```
## Message output format
`read_messages` returns rich metadata on every message:
```
- (ID: 123456) **[username]** `2026-04-01T12:00:00Z`: ```message content``` [š§µ thread] [šĆ2 ā
Ć1] [+1att]
```
| Indicator | Meaning |
|---|---|
| `[š§µ thread]` | Message has an active thread |
| `[šĆ2 ā
Ć1]` | Emoji reactions with counts |
| `[+1att]` | Has file attachments |
## Tools (66)
### Messages (7)
`read_messages` Ā· `send_message` Ā· `edit_message` Ā· `delete_message` Ā· `add_reaction` Ā· `remove_reaction` Ā· `get_attachment`
### Users & DMs (5)
`get_user_id_by_name` Ā· `send_private_message` Ā· `edit_private_message` Ā· `delete_private_message` Ā· `read_private_messages`
### Threads (1)
`list_active_threads`
### Channels (7)
`create_text_channel` Ā· `edit_text_channel` Ā· `delete_channel` Ā· `find_channel` Ā· `list_channels` Ā· `get_channel_info` Ā· `move_channel`
### Categories (4)
`create_category` Ā· `delete_category` Ā· `find_category` Ā· `list_channels_in_category`
### Roles (6)
`list_roles` Ā· `create_role` Ā· `edit_role` Ā· `delete_role` Ā· `assign_role` Ā· `remove_role`
### Moderation (7)
`kick_member` Ā· `ban_member` Ā· `unban_member` Ā· `timeout_member` Ā· `remove_timeout` Ā· `set_nickname` Ā· `get_bans`
### Voice & Stage (6)
`create_voice_channel` Ā· `create_stage_channel` Ā· `edit_voice_channel` Ā· `move_member` Ā· `disconnect_member` Ā· `modify_voice_state`
### Webhooks (4)
`create_webhook` Ā· `delete_webhook` Ā· `list_webhooks` Ā· `send_webhook_message`
### Scheduled Events (5)
`create_guild_scheduled_event` Ā· `edit_guild_scheduled_event` Ā· `delete_guild_scheduled_event` Ā· `list_guild_scheduled_events` Ā· `get_guild_scheduled_event_users`
### Permissions (4)
`list_channel_permission_overwrites` Ā· `upsert_role_channel_permissions` Ā· `upsert_member_channel_permissions` Ā· `delete_channel_permission_overwrite`
### Invites (4)
`create_invite` Ā· `list_invites` Ā· `delete_invite` Ā· `get_invite_details`
### Emojis (5)
`list_emojis` Ā· `get_emoji_details` Ā· `create_emoji` Ā· `edit_emoji` Ā· `delete_emoji`
### Server (1)
`get_server_info`
## Comparison
This server was built to replace [SaseQ/discord-mcp](https://github.com/SaseQ/discord-mcp) (the most-starred Discord MCP server). Here's how it compares to existing options:
| Feature | discord-mcp (this) | [SaseQ](https://github.com/SaseQ/discord-mcp) | [barryyip0625](https://github.com/barryyip0625/mcp-discord) | [HardHeadHackerHead](https://github.com/HardHeadHackerHead/discord-mcp) | [PaSympa](https://github.com/PaSympa/discord-mcp) |
|---|---|---|---|---|---|
| Language | TypeScript/Bun | Java/Spring Boot | TypeScript | TypeScript | TypeScript |
| Tools | 66 | ~65 | 42 | 139 | 90 |
| Reactions in read output | **Yes** | No | No | No | No |
| Thread indicators | **Yes** | No | No | No | No |
| File attachments on send | **Yes** | No | No | Yes | No |
| Auto-chunking (>2000 chars) | **Yes** | No | No | No | No |
| Incremental reads (after/before) | **Yes** | No | No | No | No |
| Runtime | Native (Bun) | Docker/JVM | Node.js/Docker | Node.js | Node.js/Docker |
| Docker image size | N/A (no Docker needed) | ~400MB+ | ~150MB | ā | ~73MB |
### Why this server?
Other Discord MCP servers fetch messages but strip context. When your AI reads a channel, it can't see which messages have been reacted to, which have threads, or which have attachments. It has to make separate API calls for each, burning tokens and rate limit budget.
This server puts that context inline on every message, so a single `read_messages` call gives the full picture.
## Bot permissions
The bot needs these Discord gateway intents (configured in the [Developer Portal](https://discord.com/developers/applications)):
- **Server Members Intent** ā for moderation and role tools
- **Message Content Intent** ā for reading message content
- **Presence Intent** ā optional, for voice state tools
Minimum bot permissions (OAuth2 scope `bot`):
- Read Messages/View Channels
- Send Messages
- Manage Messages (for delete/edit)
- Add Reactions
- Read Message History
- Manage Channels (for channel CRUD)
- Manage Roles (for role tools)
- Kick/Ban Members (for moderation)
## Architecture
```
discord-mcp/
āāā index.ts # Entry point: MCP server + discord.js client
āāā client.ts # Client singleton, guild resolver, helpers
āāā tools/
ā āāā _types.ts # ToolDef type, chunk(), message formatter
ā āāā registry.ts # Collects all modules, registers with MCP
ā āāā messages.ts # read/send/edit/delete, reactions, attachments
ā āāā users.ts # DMs, user lookup
ā āāā threads.ts # Active thread listing
ā āāā channels.ts # Channel CRUD
ā āāā categories.ts # Category management
ā āāā roles.ts # Role CRUD + assign/remove
ā āāā moderation.ts # Kick, ban, timeout, nickname
ā āāā voice.ts # Voice/stage channels, member control
ā āāā webhooks.ts # Webhook CRUD + send
ā āāā events.ts # Scheduled events
ā āāā permissions.ts # Permission overwrites
ā āāā invites.ts # Invite management
ā āāā emojis.ts # Custom emoji CRUD
ā āāā server-info.ts # Server metadata
āāā package.json
```
Each tool module exports a `ToolDef[]` array. The registry collects them all and handles MCP registration + error wrapping in one place. Adding a new tool is: define it in the right module, done.
## Credits
Built as a replacement for [SaseQ/discord-mcp](https://github.com/SaseQ/discord-mcp), which pioneered the comprehensive Discord MCP server approach. Tool schemas are inspired by that project's design.
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues