Content
# Discord MCP Server
A [Model Context Protocol](https://modelcontextprotocol.io) server that connects Claude (or any
MCP client) to Discord servers you manage. It exposes 53 tools covering day-to-day admin work:
channels, threads, roles, members, moderation, AutoMod, messages, polls, webhooks, scheduled
events, invites, the audit log, and a live event journal — plus ready-made audit and report
prompts.
Built with TypeScript, [discord.js](https://discord.js.org) v14, and the official
[MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk). Speaks the
modern **Streamable HTTP** transport by default (sessions, ready for remote hosting), with
a stdio fallback for clients that spawn servers locally.
## Features
- **Live event journal** — the server records gateway events (joins, leaves, bans, message
deletions/edits, role and channel changes) in real time, so Claude can answer "what
happened in my server while I was away?"
- **Servers** — list your servers, inspect server details, read the audit log
- **Channels** — list, create, edit, and delete channels/categories; set per-role or per-user
permission overrides; slowmode, NSFW, topics
- **Threads & forums** — list active/archived threads, create threads and forum posts,
archive/lock/rename them
- **AutoMod** — create, edit, list, and delete Discord's native AutoMod rules: keyword
filters, regex, spam and mention-spam blocking, built-in profanity/slur lists, with
block/alert/timeout actions
- **Roles** — list, create, edit, and delete roles; assign or remove them from members
- **Members** — list and search members, view details, set nicknames, timeout, kick, ban,
unban, list bans
- **Permissions auditing** — computed effective access reports: who can see/post in a
channel and why, and what one member can do server-wide or per channel
- **Messages** — read history, send (with replies and embeds), edit, delete, bulk delete,
pin/unpin, add reactions, create native polls
- **Webhooks** — create, list, and delete webhooks; post through them with per-message
name/avatar overrides
- **Scheduled events** — create, edit, start/complete/cancel, and delete server events
(voice, stage, or external)
- **Invites** — create invite links with expiry/use limits, list active invites
- **Prompts** — `server_health_audit` and `moderation_report` walk Claude through
multi-step admin workflows with one command
### Safety by default
- **Destructive tools are off until you opt in.** Kick, ban, bulk delete, and every
delete tool (channel, role, message, AutoMod rule, webhook, scheduled event) refuse to
run unless the server is started with `DISCORD_ENABLE_DESTRUCTIVE=true` — they are the
†-marked tools in the table below.
- **Server allowlist.** Set `DISCORD_GUILD_IDS` to a comma-separated list of server IDs and
every tool is fenced to those servers, even if the bot happens to be in others.
- **Audit-log reasons.** Moderation and management tools accept a `reason` recorded in
Discord's audit log wherever Discord supports one (message delete/bulk-delete do not).
- **Read-only/destructive annotations.** Tools carry MCP annotations so clients can apply
their own confirmation policies.
## Setup
### 1. Create a Discord bot
1. Go to the [Discord Developer Portal](https://discord.com/developers/applications) and click
**New Application**.
2. Under **Bot**, click **Reset Token** and copy the token — this becomes `DISCORD_TOKEN`.
3. Still under **Bot → Privileged Gateway Intents**, enable **Server Members Intent** and
**Message Content Intent**. (If you skip this, set `DISCORD_PRIVILEGED_INTENTS=false`;
member listing and message content will be unavailable.)
### 2. Invite the bot to your server
Under **OAuth2 → URL Generator**, select the `bot` scope, then pick the permissions you want
the bot to have (for full admin tooling: Manage Channels, Manage Roles, Kick Members, Ban
Members, Moderate Members, Manage Messages, Read Message History, Send Messages, View Audit
Log, Create Instant Invite). Open the generated URL and add the bot to your server.
The bot can never do more than the permissions you grant it here — the tools fail with a
clear error if a permission is missing.
### 3. Build
```bash
npm install
npm run build
```
### 4. Run the server
```bash
DISCORD_TOKEN=your-bot-token npm start
# [discord-mcp] Streamable HTTP server listening on http://127.0.0.1:3000/mcp
```
The server exposes the MCP endpoint at `http://127.0.0.1:3000/mcp` and a `GET /health`
probe. Set `MCP_AUTH_TOKEN` to require a bearer token, which you should always do if the
server is reachable by anyone but you.
### 5. Add to your MCP client
**Claude Code:**
```bash
claude mcp add --transport http discord http://127.0.0.1:3000/mcp \
--header "Authorization: Bearer your-mcp-auth-token"
```
**Claude Desktop / claude.ai custom connectors:** add a remote MCP server pointing at
`http(s)://your-host:3000/mcp`. For claude.ai the server must be reachable from the
internet over HTTPS (put it behind a reverse proxy such as Caddy or nginx, and set
`MCP_ALLOWED_HOSTS` to your public hostname).
**Clients that only spawn local stdio servers** can still use `MCP_TRANSPORT=stdio`:
```json
{
"mcpServers": {
"discord": {
"command": "node",
"args": ["/absolute/path/to/Discord-MCP/dist/index.js"],
"env": {
"DISCORD_TOKEN": "your-bot-token",
"MCP_TRANSPORT": "stdio"
}
}
}
}
```
Then ask something like *"list my Discord servers"* or *"what channels are in my server?"*.
## Configuration
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `DISCORD_TOKEN` | yes | — | Bot token from the developer portal |
| `DISCORD_GUILD_IDS` | no | all servers | Comma-separated allowlist of server IDs the tools may touch |
| `DISCORD_ENABLE_DESTRUCTIVE` | no | `false` | `true` unlocks the nine †-marked destructive tools (kick, ban, bulk delete, and every delete) |
| `DISCORD_PRIVILEGED_INTENTS` | no | `true` | `false` logs in without the Server Members / Message Content privileged intents |
| `MCP_TRANSPORT` | no | `http` | `http` (Streamable HTTP) or `stdio` |
| `MCP_PORT` (or `PORT`) | no | `3000` | HTTP port |
| `MCP_HOST` | no | `127.0.0.1` | Bind address; use `0.0.0.0` when hosting remotely |
| `MCP_AUTH_TOKEN` | no | — | When set, requests must send `Authorization: Bearer <token>` |
| `MCP_ALLOWED_HOSTS` | no | localhost variants | Host-header allowlist (DNS-rebinding protection) when hosting on a public address |
### Transport security
- On the default loopback bind, DNS-rebinding protection is on automatically: requests
whose `Host` header is not a localhost variant are rejected with 403, so a malicious
web page cannot reach the server from your browser.
- Binding to a non-loopback address without `MCP_AUTH_TOKEN` logs a loud warning — anyone
who can reach the port could administer your Discord servers.
- Sessions follow the Streamable HTTP spec: the client receives an `Mcp-Session-Id` on
initialize, presents it on every request, and can end the session with `DELETE /mcp`.
## Tools
| Tool | Description |
| --- | --- |
| `discord_list_servers` | List servers the bot can manage |
| `discord_get_server_info` | Server details, counts, boost tier |
| `discord_get_audit_log` | Recent audit log entries, filterable by action |
| `discord_list_channels` | All channels and categories with IDs |
| `discord_create_channel` | Create text/voice/category/announcement/forum/stage channels |
| `discord_edit_channel` | Rename, retopic, slowmode, NSFW, move, recategorize |
| `discord_delete_channel` † | Permanently delete a channel |
| `discord_set_channel_permissions` | Allow/deny permission overrides for a role or user |
| `discord_list_roles` | All roles with permissions, highest first |
| `discord_create_role` | Create a role (color, permissions, hoist, mentionable) |
| `discord_edit_role` | Edit a role |
| `discord_delete_role` † | Permanently delete a role |
| `discord_add_role_to_member` | Give a member a role |
| `discord_remove_role_from_member` | Take a role from a member |
| `discord_list_members` | List members (needs Server Members intent) |
| `discord_search_members` | Search members by name prefix |
| `discord_get_member` | Member details, roles, permissions |
| `discord_set_nickname` | Set or clear a nickname |
| `discord_timeout_member` | Time out a member, or lift a timeout (0 minutes) |
| `discord_kick_member` † | Kick a member |
| `discord_ban_member` † | Ban a user, optionally purging recent messages |
| `discord_unban_member` | Lift a ban |
| `discord_list_bans` | List banned users with reasons |
| `discord_read_messages` | Read channel history (paginate with `before`) |
| `discord_get_message` | Fetch one message |
| `discord_send_message` | Send a message, reply, or embed |
| `discord_edit_message` | Edit a message the bot sent |
| `discord_delete_message` † | Delete a single message |
| `discord_bulk_delete_messages` † | Delete up to 100 recent messages |
| `discord_pin_message` / `discord_unpin_message` | Manage pins |
| `discord_add_reaction` | React to a message |
| `discord_create_invite` | Create an invite link |
| `discord_list_invites` | List active invites with usage |
| `discord_list_threads` | Active threads server-wide, plus archived per channel |
| `discord_create_thread` | Create a thread or forum post |
| `discord_edit_thread` | Rename, archive, lock, slowmode |
| `discord_list_automod_rules` | List AutoMod rules |
| `discord_create_automod_rule` | Keyword/regex/spam/mention-spam/preset rules with block, alert, and timeout actions |
| `discord_edit_automod_rule` | Edit rule name, state, keyword lists, exemptions |
| `discord_delete_automod_rule` † | Delete an AutoMod rule |
| `discord_audit_channel_access` | Effective view/send/manage access per role, plus user overrides |
| `discord_check_member_permissions` | One member's effective permissions, server-wide or per channel |
| `discord_get_recent_events` | Live event journal: joins, leaves, bans, deletions, edits, role/channel changes |
| `discord_create_poll` | Post a native poll (results readable via `discord_get_message`) |
| `discord_list_webhooks` | List a server's webhooks (URLs are never exposed) |
| `discord_create_webhook` | Create an incoming webhook on a channel |
| `discord_send_webhook_message` | Post through a webhook with optional name/avatar override |
| `discord_delete_webhook` † | Delete a webhook |
| `discord_list_scheduled_events` | List server events with times and interest counts |
| `discord_create_scheduled_event` | Create a voice/stage/external event |
| `discord_edit_scheduled_event` | Edit details or start/complete/cancel |
| `discord_delete_scheduled_event` † | Delete an event outright |
† Disabled unless `DISCORD_ENABLE_DESTRUCTIVE=true`.
### The event journal
While the server runs, its Discord gateway connection records the last 1000 notable events
in memory (member joins/leaves/updates, bans, message deletions and edits, bulk deletes,
channel and role changes) — filtered to allowlisted servers when `DISCORD_GUILD_IDS` is set.
`discord_get_recent_events` queries that buffer by server, event type, and time window.
The journal starts recording when the server connects to Discord (at startup) and resets on
restart; it never leaves the process.
## Development
```bash
npm run dev # run from source with tsx
npm run typecheck # tsc --noEmit
npm run build # compile to dist/
```
All logging goes to stderr. The Discord connection is started eagerly in the background at
startup so the event journal records from boot; a failed initial connect is logged and
retried on the next tool call, where token problems surface as readable tool errors. Each
MCP session gets its own protocol state, but they all share one Discord gateway connection.
Idle HTTP sessions are swept after an hour; clients simply reinitialize.
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available