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:

  1. a Discord bot installed in one or more servers
  2. an MCP server exposing Discord tools
  3. 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.
Image

2. Summarize a support channel

Prompt:

Summarize the last 10 messages in #support and tell me if there are unresolved issues.

Expected behavior:

  1. list or resolve the #support channel
  2. fetch recent messages
  3. summarize the discussion
  4. identify open questions
  5. 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.
Image

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:

  1. resolve the mentioned user
  2. resolve the Support role
  3. prepare channel creation
  4. prepare permission overwrites
  5. show dry-run
  6. 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.
Image

4. Draft a moderation warning

Prompt:

Draft a moderation warning for this message, but do not send it.

Expected behavior:

  1. read the referenced message
  2. inspect recent context if allowed
  3. draft the warning
  4. 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.
Image

5. Create a webhook for deployments

Prompt:

Create a webhook called "Deployments" in #deployments for CI notifications.
Dry-run first.

Expected behavior:

  1. resolve #deployments
  2. check bot permission to manage webhooks
  3. create a dry-run plan
  4. execute after confirmation
  5. 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.
Image Image

6. Inspect audit events

Prompt:

Show me recent audit events related to role changes.

Expected behavior:

  1. check permission to read audit logs
  2. fetch recent audit events
  3. filter role-related events
  4. 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.
Image

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:

https://github.com/Rastrian/DiscordMCP