Skip to main content
Glama

Discord MCP Platform

A multi-server Discord control plane that exposes Discord operations as MCP tools, resources, and prompts for AI clients. Includes a built-in conversational AI agent that responds to Discord @mentions.

What It Does

Users connect their Discord identity via OAuth2, install the platform bot into their servers, and then interact through MCP-compatible AI clients or by @mentioning the bot directly in Discord.

The platform translates natural language requests into safe, authorized Discord operations:

  • "List my servers and channels"

  • "Summarize the last 100 messages in #general"

  • "Create a support channel and set permissions"

  • "Create an automation that answers FAQs in #support"

  • "Draft a moderation warning for this message"

Related MCP server: discord-mcp

What This Is Not

This is not a self-bot. It does not use user tokens, control personal Discord accounts, scrape DMs, or bypass Discord permissions/rate limits. All operations execute through authorized bot accounts using official Discord APIs.

Architecture

graph TD
    subgraph "Clients"
        AI["AI Client / MCP Client"]
        DU["Discord User"]
    end

    subgraph "Platform"
        MCPS["MCP Server<br/>66 tools"]
        GW["Discord Gateway<br/>WebSocket"]
        PE["Policy Engine"]
        AGENT["Agent Service<br/>~60 tools"]
        SVC["Discord Service Layer<br/>107 async REST methods"]
    end

    AI -->|MCP call| MCPS
    DU -->|"@mention"| GW
    MCPS --> PE
    GW --> AGENT
    AGENT --> PE
    PE --> SVC
    SVC -->|API v10| DISC["Discord API"]
graph LR
    subgraph "Authorization Flow"
        direction TB
        A1["1. MCP client auth"] --> A2["2. Workspace membership"]
        A2 --> A3["3. Guild installation check"]
        A3 --> A4["4. Platform role/permission"]
        A4 --> A5["5. Channel policy check"]
        A5 --> A6["6. Discord bot permission"]
        A6 --> A7["7. Rate-limit check"]
        A7 --> A8["8. Execute & audit"]
    end

Features

MCP Server (66 tools)

graph LR
    subgraph "MCP Tools by Domain"
        G["Guild<br/>4 tools"]
        CH["Channel<br/>7 tools"]
        MSG["Message<br/>7 tools"]
        MOD["Moderation<br/>2 tools"]
        THR["Thread<br/>1 tool"]
        ROLE["Role<br/>7 tools"]
        MEM["Member<br/>6 tools"]
        WH["Webhook<br/>6 tools"]
        INV["Invite<br/>8 tools"]
        AUTO["Automation<br/>1 tool"]
        AUD["Audit<br/>1 tool"]
        REA["Reaction<br/>4 tools"]
        EVT["Event<br/>6 tools"]
        AMOD["Automod<br/>5 tools"]
    end

Domain

Tools

Guild

list, get, modify, incident_actions (lockdown)

Channel

list, get, create, edit, delete, edit_permissions, delete_permissions

Message

list_recent, send, get, edit, send_embed, delete, bulk_delete

Moderation

delete, bulk_delete

Thread

create

Role

list, create, modify, delete, reorder, assign, remove

Member

get, list, kick, ban, timeout, unban

Webhook

create, list, get, modify, delete, execute

Invite

create, list, get, delete, target.add, target.remove, target.bulk_add, target.bulk_remove

Automation

draft

Audit

list

Reaction

add, remove, list, remove_user

Event

list, get, create, update, delete, list_users

Automod

list, get, create, update, delete

Pins

pin.list, pin.add, pin.remove

All state-changing tools support dry-run (default on). Risky operations require explicit confirmation. Every write is audited.

Conversational Agent

sequenceDiagram
    participant U as Discord User
    participant GW as Gateway
    participant AG as Agent Service
    participant LLM as LLM API
    participant BOT as Discord Bot

    U->>GW: @mention bot
    GW->>AG: MESSAGE_CREATE event
    AG->>AG: Check guild + channel allowlist
    AG->>AG: Load channel conversation history
    AG->>LLM: Send history + 60 tool definitions
    loop Tool-use loop (max 10 iterations)
        LLM-->>AG: Tool call or text response
        AG->>BOT: Execute tool call
        BOT-->>AG: Tool result
        AG->>LLM: Send tool result
    end
    AG->>BOT: Send final response to channel
    BOT-->>U: Bot reply
  • ~60 agent tools covering the full Discord API surface

  • Per-channel conversation history

  • Per-user cooldown

  • Admin-controlled via /allow-chat and /disallow-chat slash commands

Data Model

erDiagram
    User ||--o{ WorkspaceMembership : "belongs to"
    User ||--o{ OAuthAccount : "has"
    Workspace ||--o{ WorkspaceMembership : "contains"
    Workspace ||--o{ GuildInstallation : "owns"
    Workspace ||--o{ MCPClient : "issues"
    GuildInstallation ||--o{ BotConfig : "has"
    GuildInstallation ||--o{ GuildPolicy : "enforces"
    GuildInstallation ||--o{ ChannelPolicy : "enforces"
    GuildInstallation ||--o{ Automation : "runs"
    GuildInstallation ||--o{ AllowedChatChannel : "allows"
    AuditEvent }o--|| Workspace : "records in"

Infrastructure

  • Discord Gateway WebSocket with auto-reconnect

  • Discord REST client with rate limit tracking and automatic retry

  • Scope-based permission engine with guild/channel allowlists

  • Audit logging with PII redaction

  • 14 database models (PostgreSQL)

  • Redis for caching and rate-limit coordination

Quick Start

cp .env.example .env
# Edit .env with your Discord bot token and other settings
docker compose up --build

Health check:

curl http://localhost:8000/health

Development

make install    # install dependencies
make dev        # run dev server with reload
make test       # run tests (no real Discord token needed)
make lint       # ruff check
make format     # ruff format
make typecheck  # mypy
make version    # print the current version
make up         # docker compose up --build (dev: source mounted, auto-reload)
make down       # docker compose down

docker compose up automatically merges docker-compose.override.yml, which mounts the source tree and enables --reload. For a production-like run without dev conveniences: docker compose -f docker-compose.yml up --build.

Spec Coverage

The official Discord OpenAPI spec is vendored at specs/openapi.json and treated as the source of truth for endpoint coverage.

  • specs/COVERAGE.md — generated report comparing spec endpoints with the REST client and MCP tools (regenerate with python3 scripts/coverage_report.py).

  • scripts/fetch-discord-spec.sh — refreshes the vendored spec; a scheduled agent (Hermes cron, Saturdays 06:00 America/Sao_Paulo) opens a sync PR whenever Discord publishes spec changes.

  • python3 scripts/coverage_report.py --check — regression guard: fails if the number of in-scope implemented endpoints drops below the baseline in specs/.coverage-baseline.

Releases & Versioning

The version lives in exactly one place: src/discord_mcp_platform/_version.py. pyproject.toml declares dynamic = ["version"] and hatchling reads it from there; the FastAPI app and /health report the same value.

To cut a release:

# 1. Bump the version and refresh the committed lockfile
$EDITOR src/discord_mcp_platform/_version.py   # __version__ = "0.2.0"
uv lock
make release-check                             # tests + lint + mypy

# 2. Commit and tag
git add src/discord_mcp_platform/_version.py uv.lock
git commit -m "chore(release): v0.2.0"
git tag v0.2.0
git push origin main --tags

Pushing a v* tag triggers .github/workflows/release.yml, which:

  1. runs the test suite, ruff and mypy;

  2. fails if the tag does not match __version__ (or the lockfile is stale);

  3. builds and pushes ghcr.io/rastrian/discord-mcp-platform with tags <version>, <major>.<minor> and latest — pre-release tags (e.g. v1.2.0-rc1) only get the full version tag, never the rolling ones;

  4. creates a GitHub Release with auto-generated notes.

The recommended way to deploy (e.g. the k3s cluster) is to pin the versioned image:

ghcr.io/rastrian/discord-mcp-platform:0.2.0   # exact pin
ghcr.io/rastrian/discord-mcp-platform:0.2     # track patch releases

The image is multi-stage, runs as a non-root user, and serves /health for probes. Currently linux/amd64 only (arm64 is a follow-up).

Environment Variables

Key variables (see .env.example for full list):

Variable

Description

DISCORD_BOT_TOKEN

Discord bot token

DISCORD_CLIENT_ID

Discord OAuth client ID

DISCORD_CLIENT_SECRET

Discord OAuth client secret

DATABASE_URL

PostgreSQL connection string

REDIS_URL

Redis connection string

ALLOWED_GUILD_IDS

Comma-separated guild allowlist (empty = all)

MCP_TRANSPORT

http or stdio

ENABLE_GATEWAY

Enable Discord Gateway WebSocket

AGENT_ENABLED

Enable conversational AI agent

AGENT_API_KEY

LLM API key for the agent

MCP Client Configuration

Local STDIO mode:

{
  "mcpServers": {
    "discord": {
      "command": "uv",
      "args": ["run", "python", "-m", "discord_mcp_platform.mcp.server"],
      "env": {
        "DISCORD_BOT_TOKEN": "your-bot-token"
      }
    }
  }
}

HTTP mode: the MCP server is available at http://localhost:8000/mcp when MCP_TRANSPORT=http.

Acknowledgements

Discord API types and endpoint coverage are based on the official Discord OpenAPI specification.

Tech Stack

Python 3.12+ | FastAPI | MCP Python SDK | pydantic v2 | httpx | SQLAlchemy 2.x | PostgreSQL | Redis | Docker | pytest

License

This project is licensed under the Apache License 2.0. See LICENSE for details.

Copyright 2026 Luis Gustavo Vaz me@rastrian.dev

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables managing a Discord server using natural language through AI clients like Claude, with 139 admin tools across 20 categories for roles, channels, members, messages, threads, moderation, and more.
    184 npm
    31
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with Discord through the REST API and real-time events, supporting message management, user info, channel operations, and more with security controls.
    9 npm
    1
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables AI clients to manage Discord servers, including channels, messages, roles, members, permissions, threads, invites, events, webhooks, and emoji, through natural language commands.
    55
    127 npm
    1
    MIT