DiscordMCP: controlling servers through MCP
I started building DiscordMCP, an open source MCP server for Discord.
The idea is simple:
expose Discord operations as MCP tools so an AI client can inspect, organize, and operate Discord servers without using user tokens or self-bot behavior.
The project is not a self-bot. It does not use personal Discord tokens, does not control user accounts, and does not bypass Discord permissions. Everything runs through a Discord bot installed in the server and through official Discord API boundaries.
What it does
DiscordMCP connects three things:
- a Discord bot installed in one or more servers
- an MCP server exposing Discord tools
- an AI client or Discord mention-based agent using those tools
Examples of what I want it to support:
List all channels in this server.
Summarize the last 100 messages from #support.
Create a private support channel for this user and add the Support role.
Create an event for tomorrow at 2 PM GMT-3 in the voice channel "Events".
Draft a moderation warning for this message, but do not send it yet.
Create a webhook for deployment notifications in #deployments.
Show me recent audit events related to role changes.
Why MCP
MCP is useful here because Discord has many operations that map naturally to tools.
Instead of hardcoding a Discord integration into each AI client, DiscordMCP exposes one MCP interface.
A client can ask for a tool call like:
{
"tool": "discord_create_channel",
"arguments": {
"guild_id": "123",
"name": "support-luis",
"type": "text",
"dry_run": true
}
}
The platform can then check:
- who is asking
- which workspace owns the server
- whether the bot is installed
- whether the operation is allowed
- whether the Discord bot has permission
- whether the action should be dry-run only
- whether the action needs confirmation
- what should be written to the audit log
That separation is the main point.
The model asks for work. The platform decides if the work is allowed.
Architecture
graph TD
User["User / AI Client"] --> MCP["MCP Server"]
DiscordUser["Discord User"] --> Gateway["Discord Gateway"]
Gateway --> Agent["Conversational Agent"]
Agent --> Policy["Policy Engine"]
MCP --> Policy
Policy --> Service["Discord Service Layer"]
Service --> API["Discord API"]
Policy --> DB["PostgreSQL"]
Service --> Redis["Redis"]
The current stack is:
- Python 3.12+
- FastAPI
- MCP Python SDK
- pydantic v2
- httpx
- SQLAlchemy 2.x
- PostgreSQL
- Redis
- Docker
- pytest
- ruff
- mypy
MCP tools
The current README describes tools for these Discord areas:
flowchart LR
Tools["DiscordMCP Tools"]
Tools --> Guilds["Guilds<br/>list, get, modify"]
Tools --> Channels["Channels<br/>list, get, create, edit, delete, permissions"]
Tools --> Messages["Messages<br/>list recent, send, get, edit"]
Tools --> Moderation["Moderation<br/>delete message, bulk delete"]
Tools --> Threads["Threads<br/>create thread"]
Tools --> Roles["Roles<br/>list, create, modify, delete, assign, remove"]
Tools --> Members["Members<br/>get, list, kick, ban, timeout, unban"]
Tools --> Webhooks["Webhooks<br/>create, list, modify, delete, execute"]
Tools --> Invites["Invites<br/>create, list, get, delete"]
Tools --> Audit["Audit<br/>list audit events"]
Tools --> Automation["Automation<br/>draft automation"]
For state-changing tools, the default behavior should be conservative.
Dry-run first. Execute only after confirmation when needed.
Practical examples
1. Create an event in a voice channel
Prompt:
Create a Discord event for tomorrow at 2 PM GMT-3 in the voice channel "Events".
The event name should be "Community Sync".
Expected tool flow:
sequenceDiagram
participant Client as AI Client
participant MCP as DiscordMCP
participant Policy as Policy Engine
participant Discord as Discord API
Client->>MCP: Create scheduled event request
MCP->>Policy: Check workspace, guild, channel and bot permissions
Policy-->>MCP: Allowed as dry-run
MCP-->>Client: Shows planned event creation
Client->>MCP: Confirm execution
MCP->>Policy: Re-check permissions
MCP->>Discord: Create scheduled event
Discord-->>MCP: Event created
MCP-->>Client: Return event URL/details
Expected response:
I would create this event:
Name: Community Sync
Date: tomorrow
Time: 14:00 GMT-3
Location: voice channel "Events"
Expected final response after confirmation:
Created the event "Community Sync" for tomorrow at 14:00 GMT-3 in the "Events" voice channel.
2. Summarize a support channel
Prompt:
Summarize the last 10 messages in #support and tell me if there are unresolved issues.
Expected behavior:
- list or resolve the
#supportchannel - fetch recent messages
- summarize the discussion
- identify open questions
- avoid modifying anything
Expected response:
Summary of #support:
- Two users reported login issues after the last deploy.
- One issue was solved by clearing the session cookie.
- One issue is still unresolved and needs backend investigation.
- No moderation or channel changes were made.
3. Create a private support channel
Prompt:
Create a private support channel for @Luis.
Only @Luis and the Support role should access it.
Use the name support-luis.
Dry-run first.
Expected behavior:
- resolve the mentioned user
- resolve the
Supportrole - prepare channel creation
- prepare permission overwrites
- show dry-run
- execute only after confirmation
Expected dry-run response:
Dry-run: I would create the channel #support-luis with these permissions:
Allowed:
- @Luis
- Support role
Denied:
- @everyone
No Discord changes were made.
Expected final response:
Created #support-luis and configured access for @Luis and the Support role.
4. Draft a moderation warning
Prompt:
Draft a moderation warning for this message, but do not send it.
Expected behavior:
- read the referenced message
- inspect recent context if allowed
- draft the warning
- do not send or apply moderation automatically
Expected response:
Draft warning:
Please keep the discussion respectful. You can disagree with other members, but avoid personal attacks. Further messages like this may result in moderation action.
No message was sent.
No moderation action was applied.
5. Create a webhook for deployments
Prompt:
Create a webhook called "Deployments" in #deployments for CI notifications.
Dry-run first.
Expected behavior:
- resolve
#deployments - check bot permission to manage webhooks
- create a dry-run plan
- execute after confirmation
- return webhook metadata safely
Expected dry-run response:
Dry-run: I would create a webhook named "Deployments" in #deployments.
No webhook was created.
Expected final response:
Created the "Deployments" webhook in #deployments.
The webhook URL was not printed here for safety.
6. Inspect audit events
Prompt:
Show me recent audit events related to role changes.
Expected behavior:
- check permission to read audit logs
- fetch recent audit events
- filter role-related events
- return a readable summary
Expected response:
Recent role-related audit events:
1. @Admin created role "Support"
2. @Admin updated permissions for role "Moderator"
3. @Luis assigned role "Member" to @new-user
No changes were made.
Conversational agent inside Discord
DiscordMCP can also work from inside Discord.
A user can mention the bot:
@DiscordMCP summarize the last discussion and tell me what still needs action
Flow:
sequenceDiagram
participant U as Discord User
participant GW as Gateway
participant Agent as Agent
participant LLM as LLM
participant Tools as Discord Tools
participant D as Discord
U->>GW: @mention bot
GW->>Agent: MESSAGE_CREATE
Agent->>Agent: Check allowed channel
Agent->>LLM: Send prompt + context
LLM->>Tools: Request tool call
Tools->>D: Read messages / execute allowed operation
D-->>Tools: Result
Tools-->>LLM: Tool result
LLM-->>Agent: Final answer
Agent-->>U: Reply in Discord
Channel access can be controlled with slash commands:
/allow-chat
/disallow-chat
This matters because the bot should not answer everywhere by default.
A server may want the bot enabled in:
#support#incidents#automation#admin-tools
But disabled in:
#general#random- private staff channels
- sensitive moderation channels
Safety model
For Discord automation, the main risk is not the LLM response.
The risk is letting the LLM mutate server state without checks.
DiscordMCP uses a layered model:
graph LR
A["MCP client auth"] --> B["Workspace membership"]
B --> C["Guild installation"]
C --> D["Platform permission"]
D --> E["Channel policy"]
E --> F["Discord bot permission"]
F --> G["Rate limit"]
G --> H["Dry-run / confirmation"]
H --> I["Execute"]
I --> J["Audit log"]
The important rules are:
- do not use user tokens
- do not bypass Discord permissions
- use bot permissions
- dry-run risky writes
- require confirmation when needed
- audit writes
- redact sensitive data
- keep channel-level policies
- respect rate limits
This makes the project more boring, but also more usable.
Local setup
Clone the repository:
git clone https://github.com/Rastrian/DiscordMCP.git
cd DiscordMCP
Create the environment file:
cp .env.example .env
Configure the required variables:
DISCORD_BOT_TOKEN=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DATABASE_URL=
REDIS_URL=
ALLOWED_GUILD_IDS=
MCP_TRANSPORT=http
ENABLE_GATEWAY=true
AGENT_ENABLED=true
AGENT_API_KEY=
Run with Docker:
docker compose up --build
Health check:
curl http://localhost:8000/health
MCP HTTP endpoint:
http://localhost:8000/mcp
Local STDIO MCP configuration example:
{
"mcpServers": {
"discord": {
"command": "uv",
"args": ["run", "python", "-m", "discord_mcp_platform.mcp.server"],
"env": {
"DISCORD_BOT_TOKEN": "your-bot-token"
}
}
}
}
Development commands:
make install
make dev
make test
make lint
make format
make typecheck
make up
make down
What I want to improve next
The project is still early.
Main next steps:
- improve tests
- add more real-world examples
- document production deployment
- improve MCP client examples
- improve policy examples
- add more Discord API coverage
- improve confirmation flows
- improve observability for tool calls
- add screenshots and demo videos
- publish example workflows for real servers
Good contributions would be:
- missing Discord tools
- bug reports
- security review
- examples using Claude Desktop or other MCP clients
- better Docker deployment examples
- real automation use cases
- documentation improvements
Conclusion
DiscordMCP is an attempt to make Discord automation usable from MCP clients without turning it into a self-bot or an unsafe API wrapper.
The basic idea is:
AI client -> MCP server -> policy checks -> Discord bot -> Discord API
That gives the model a useful interface, but keeps execution behind a controlled layer.
Repository: