The Discord MCP Server is a comprehensive tool for managing Discord bots and servers through a standardized interface, offering 93+ operations across all Discord functionalities.
Core Operations:
Message Management: Send, edit, delete messages; manage reactions, pins, bulk operations; retrieve message history and search with criteria like author, dates, attachments
Channel Operations: Create, edit, delete text/voice/forum channels; manage privacy settings and file uploads
Member & Role Management: Add/remove roles, edit member properties, search member information
Direct Messages & Friends: Create DM channels, manage friend relationships, send friend requests
Advanced Features:
Voice & Audio: Join/leave voice channels, play audio, control volume
Bot Presence: Update status (online, idle, DND), set custom activities (playing, streaming, watching)
Interactive Components: Send embeds, buttons, select menus, modal dialogs
Webhooks: Create, delete, and send webhook messages
Server Administration: Edit server settings, manage welcome screens, retrieve statistics
Content Management: Handle custom emojis, stickers, scheduled events
File Operations: List, download, and clean up message attachments
Security: Automoderation, invite management, bulk privacy controls
This unified master control interface streamlines all Discord bot operations into a single, standardized system.
Provides comprehensive Discord bot management capabilities including server information, channel creation and management, message operations, role and permission management, member moderation, voice channel operations, webhook management, and audit logging through Discord's API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Discord MCP Servercreate a new text channel named announcements in the general category"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Discord MCP Server
⚠️ Security Notice: This project handles Discord credentials and privileged Discord operations. Treat all tokens and secrets as sensitive.
Discord MCP Server exposes Discord.js through one MCP tool with a dynamic symbol router.
Current Architecture
This repository now uses the dynamic Discord.js routing architecture:
MCP tool:
discord_manageHTTP runtime: Hono (
@hono/node-server)Web UI: Svelte app served by the same Hono process under
/appDiscovery operation:
discordjs.meta.symbols(method:automation.read)
Invocation operation format:
discordjs.<kind>.<symbol>(method:automation.write)Example:
discordjs.function.TextChannel%23send
Domain Method Contract
discord_manage uses the contract below:
mode:botoruseridentityId: identity record (for exampledefault-bot)method: one ofserver.read,server.write,channels.read,channels.write,messages.read,messages.write,members.read,members.write,roles.read,roles.write,automation.read,automation.write
operation: dynamic operation key (discordjs.meta.symbolsordiscordjs.<kind>.<symbol>)paramsorargsDiscovery operation
discordjs.meta.symbolsis validated underautomation.read.Invocation operations
discordjs.<kind>.<symbol>are validated underautomation.write.
Static operation keys (get_discordjs_symbols, invoke_discordjs_symbol) are removed and now return validation errors.
Runtime kind behavior:
Dynamic
enumsymbols are discovered directly from Discord.js runtime exports.interface,type,namespace, andexternalremain accepted for compatibility, but may return empty results in runtime-only discovery mode.
Related MCP server: mcp-discord
Branch Model
Canonical branch:
new-architecture-mainRepository default branch:
new-architecture-main
Quick Start
Prerequisites
Node.js 18+
npm
Discord bot token
Install
git clone https://github.com/drvova/discord-mcp.git
cd discord-mcp
npm install
npm --prefix web install
npm run ui:build
npm run buildRun
# stdio mode (default)
npm start
# dev mode
npm run dev
# HTTP/SSE mode
npm run web
# Full web stack (build Svelte + backend, then run HTTP mode)
npm run web:fullConfiguration
Create .env:
DISCORD_TOKEN=your_bot_token_here
DISCORD_GUILD_ID=your_guild_id_here
# Optional user-mode token
# DISCORD_USER_TOKEN=your_discord_user_token
# Optional encrypted identity store
# DISCORD_MCP_MASTER_KEY=your_32_byte_key_material
# DISCORD_MCP_IDENTITY_STORE_PATH=./.discord-mcp-identities.enc
# Optional risk policy override
# DISCORD_MCP_BLOCK_HIGH_RISK=true
# Optional audit log file
# DISCORD_MCP_AUDIT_LOG_PATH=./data/discord-mcp-audit.log
# Optional OAuth (HTTP mode)
# DISCORD_CLIENT_ID=...
# DISCORD_CLIENT_SECRET=...
# DISCORD_OAUTH_REDIRECT_URI=http://localhost:1455/oauth/discord/callback
# Optional web UI + OIDC bridge
# DISCORD_WEB_UI_MOUNT_PATH=/app
# DISCORD_WEB_UI_DIST_PATH=./web/build
# DISCORD_WEB_UI_STORE_PATH=./data/web-ui-state.json
# DISCORD_WEB_UI_SESSION_COOKIE_NAME=discord_mcp_web_session
# DISCORD_WEB_UI_SESSION_TTL_SECONDS=604800
# DISCORD_WEB_ALLOW_DEV_AUTH=true
# Defaults (Codex/OpenAI) are used when omitted:
# issuer=https://auth.openai.com
# authorization_endpoint=https://auth.openai.com/oauth/authorize
# token_endpoint=https://auth.openai.com/oauth/token
# client_id=app_EMoamEEZ73f0CkXaXp7hrann
# redirect_uri=http://localhost:1455/auth/callback
# scopes=openid profile email offline_access
# DISCORD_WEB_OIDC_ISSUER=https://issuer.example.com
# DISCORD_WEB_OIDC_CLIENT_ID=...
# DISCORD_WEB_OIDC_CLIENT_SECRET=...
# DISCORD_WEB_OIDC_REDIRECT_URI=http://localhost:1455/auth/callback
# DISCORD_WEB_OIDC_SCOPES=openid profile email offline_access
# DISCORD_WEB_OIDC_PKCE_REQUIRED=true
# DISCORD_WEB_OIDC_ID_TOKEN_ADD_ORGANIZATIONS=true
# DISCORD_WEB_OIDC_CODEX_SIMPLIFIED_FLOW=true
# DISCORD_WEB_OIDC_REQUESTED_TOKEN=openai-api-key
# DISCORD_WEB_PLANNER_API_KEY=...
# DISCORD_WEB_PLANNER_BASE_URL=https://api.openai.com/v1
# DISCORD_WEB_PLANNER_MODEL=gpt-4o-miniHTTP Endpoints
When MCP_HTTP_PORT (or PORT) is set:
GET /ssePOST /messageGET /healthGET /oauth/discord/startGET /oauth/discord/callbackGET /auth/codex/start(primary Codex-style login entrypoint)GET /auth/codex/callback(callback alias)GET /auth/oidc/start(alias)GET /auth/oidc/callback(alias)GET /auth/callback(Codex-compatible primary callback)GET /api/sessionPOST /api/session/logoutPOST /api/session/identityGET /api/chat/threadsPOST /api/chat/threadsGET /api/chat/threads/:threadId/messagesPOST /api/chat/planPOST /api/chat/executeGET /app/(SvelteKit web UI whenweb/buildexists)
Web UI Runtime (Single Server)
Use one command to build UI + backend and run Hono on :1455:
npm run web:devThis flow:
Builds the SvelteKit app into
web/buildCompiles backend TypeScript
Runs a single Hono server on
http://localhost:1455Serves UI directly at
http://localhost:1455/app/(no Vite proxy required)
Missing Discord OAuth callback env vars (DISCORD_CLIENT_SECRET,
DISCORD_OAUTH_REDIRECT_URI) no longer block HTTP startup; only the
/oauth/discord/* callback exchange remains unavailable until configured.
Typed HTTP Client (hc)
You can use the generated typed client from Hono route types:
import { createHttpClient } from "./src/http-client.js";
const client = createHttpClient("http://localhost:1455");
const healthResponse = await client.health.$get();
const health = await healthResponse.json();
const rpcResponse = await client.index.$post({
json: {
id: 1,
method: "tools/list"
}
});
const rpc = await rpcResponse.json();The MCP JSON-RPC contract on POST / is unchanged (initialize, tools/list, tools/call).
Web UI Flow
The UI is served by Hono at
/app/.Login starts at
/auth/codex/startand returns via/auth/callbackby default (/auth/codex/callbackand/auth/oidc/callbackare aliases).When OIDC is not configured and
DISCORD_WEB_ALLOW_DEV_AUTH=true(default outside production),/auth/codex/startcreates a local dev session automatically.After Codex OAuth callback, token exchange (
requested_token=openai-api-key) must succeed before a web session is created.If token exchange fails (for example
missing organization_id), login is rejected and the UI shows an actionable auth error.Session state is cookie-based and persisted in
DISCORD_WEB_UI_STORE_PATH.Chat planning uses dynamic operation generation and defaults write operations to
dryRun: true.Live writes require explicit confirmation in the UI (
confirmWrites: true).
Usage Examples
1) Discover Symbols
{
"mode": "bot",
"identityId": "default-bot",
"method": "automation.read",
"operation": "discordjs.meta.symbols",
"params": {
"kinds": ["function"],
"query": "TextChannel#send",
"page": 1,
"pageSize": 20,
"includeKindCounts": true
}
}2) Dynamic Invocation (TextChannel#send)
{
"mode": "bot",
"identityId": "default-bot",
"method": "automation.write",
"operation": "discordjs.function.TextChannel%23send",
"params": {
"args": ["hello from dynamic router"],
"target": "channel",
"context": {
"guildId": "123456789012345678",
"channelId": "123456789012345678"
},
"allowWrite": true,
"policyMode": "strict"
}
}3) Dry Run Before Executing
{
"mode": "bot",
"identityId": "default-bot",
"method": "automation.write",
"operation": "discordjs.function.TextChannel%23send",
"params": {
"dryRun": true,
"target": "channel",
"context": {
"channelId": "123456789012345678"
}
}
}Notes on Operation Counts
If you expect thousands of operations in the MCP registry, this is by design:
The MCP registry exposes a small, fixed operation surface.
Discovery is exposed through
discordjs.meta.symbols.Discord.js breadth is exposed through dynamic symbol routing (
discordjs.<kind>.<symbol>).Runtime discovery includes
enumexports (for exampleChannelType,ActivityType).
Security Guidance
Keep tokens private and rotate regularly.
Use minimum Discord permissions required.
Prefer
dryRunfor risky operations.Use
allowWriteonly when intended.Enable audit logging in production.
Scripts
npm run build- compile TypeScriptnpm run dev- build once, then runtsc -w+node --watchnpm start- run compiled stdio servernpm run web- run compiled Hono HTTP/SSE server on port 1455npm run web:build- build then run HTTP/SSEnpm run ui:build- build SvelteKit web UI intoweb/buildnpm run web:full- build UI + backend and run HTTP server