Skip to main content
Glama
RestartFU

Discord MCP

by RestartFU
README.md
# Discord MCP

A Python MCP server for reading messages, inspecting channels and servers, and managing Discord through its REST API. Runs locally over stdio with one environment variable: `DISCORD_TOKEN`.

**The token is sent verbatim in the `Authorization` header. This server never adds `Bot`, `Bearer`, or another prefix.** It does not attempt to detect or change the credential type.

## Install

Requires Python 3.11+.

```bash
git clone https://github.com/RestartFU/discord-mcp.git
cd discord-mcp
python3 -m venv .venv
.venv/bin/pip install .
```

Configure an MCP client with the absolute path to the installed executable:

```json
{
  "mcpServers": {
    "discord": {
      "command": "/absolute/path/to/discord-mcp/.venv/bin/discord-mcp",
      "env": {
        "DISCORD_TOKEN": "your-token-exactly-as-supplied"
      }
    }
  }
}
```

On Windows, use `.venv\\Scripts\\discord-mcp.exe`. You can also supply `DISCORD_TOKEN` through the parent process environment and omit `env`. `.env` files are not loaded automatically. Keep credentials out of source control.

Start by calling `get_current_user`, then `list_guilds`, `list_channels`, and `read_messages`. Enable Discord Developer Mode to copy IDs, or use the IDs returned by these tools. IDs are strings to preserve precision.

## Tools

| Area | Tools |
| --- | --- |
| Identity and servers | `get_current_user`, `get_user`, `list_guilds`, `get_guild` |
| Channels | `list_channels`, `get_channel`, `create_channel`, `update_channel`, `delete_channel` |
| Messages | `read_messages`, `get_message`, `search_messages`, `send_message`, `edit_message`, `delete_message` |
| Reactions and pins | `add_reaction`, `list_pins`, `pin_message`, `unpin_message` |
| DMs and threads | `create_dm`, `list_active_threads`, `create_thread` |
| Members and roles | `list_members`, `get_member`, `update_member`, `list_roles`, `create_role`, `add_member_role`, `remove_member_role` |
| Invites | `list_invites`, `create_invite` |
| General REST | `discord_request` with GET, POST, PUT, PATCH, DELETE, query, JSON body, audit reason, and multipart uploads |

`discord_request` covers other REST operations such as bans, kicks, permission overwrites, webhooks, emojis, scheduled events, archived threads, polls, and role edits. It accepts only API-relative paths under `https://discord.com/api/v10`; the credential is not forwarded to redirects or arbitrary hosts.

Example: inspect permission overwrites with `get_channel`, then update one:

```json
{
  "method": "PUT",
  "path": "/channels/CHANNEL_ID/permissions/ROLE_ID",
  "body": {"type": 0, "allow": "1024", "deny": "0"},
  "reason": "Allow the selected role to view this channel"
}
```

Upload a file by passing `files` alongside a message body to `discord_request`:

```json
{
  "method": "POST",
  "path": "/channels/CHANNEL_ID/messages",
  "body": {"content": "Attached note", "allowed_mentions": {"parse": []}},
  "files": [{"filename": "note.txt", "data_base64": "SGVsbG8h", "content_type": "text/plain"}]
}
```

Uploads are limited to 10 files and 10 MiB total per request. The dedicated send/edit tools suppress mention parsing; the general REST tool uses your payload as supplied.

## Access and behavior

This is REST access, not a complete Discord desktop client: no voice/video streaming, Gateway event subscription, or automatic CAPTCHA handling. Operations succeed only where Discord accepts the supplied Authorization value and grants the required permissions. Raw credentials are not guaranteed to work with every endpoint. Discord's [documented authentication](https://docs.discord.com/developers/reference) uses typed Authorization values; this implementation deliberately leaves your supplied value unchanged.

History returns at most 100 messages per request; use the oldest message ID as `before` for older pages. Server and member lists also support pagination. Search may return an indexing response instead of results. See Discord's [message documentation](https://docs.discord.com/developers/resources/message) for content access requirements and endpoint fields.

Requests are serialized per process, and [429 rate limits](https://docs.discord.com/developers/topics/rate-limits) are retried up to three times using Discord's delay. Long waits are returned as errors and retained as a local cooldown. Network errors and 5xx responses are not retried automatically because a write may already have succeeded. Multiple server processes do not share rate-limit state.

The credential is redacted from returned data and API error text. Tool results can still contain private Discord content, invite codes, or webhook credentials; the MCP client receiving them must be trusted. Tool annotations identify reads and destructive operations. The general REST tool is conservatively marked destructive because it can write or delete.

## Development

```bash
.venv/bin/pip install -e '.[dev]'
.venv/bin/ruff check .
.venv/bin/ruff format --check .
.venv/bin/pytest
```

Tests use mocked Discord HTTP responses and a real MCP stdio handshake; no Discord token or live messages are required. The implementation uses the [official MCP Python SDK](https://py.sdk.modelcontextprotocol.io/v1/), pinned to its 1.x API.

TDQS

B3.4/5.0

Scored across 32 tools

Disambiguation4/5

Most tools map cleanly to distinct Discord resources (messages, channels, roles, members, guilds). The main ambiguity is discord_request, which overlaps with nearly every other tool by design, but its generic nature is clearly described as a catch-all REST endpoint accessor.

Naming Consistency4/5

The vast majority of tools follow a consistent verb_noun pattern: read_messages, delete_message, list_roles, create_channel, get_guild, add_member_role. Minor deviations exist, such as discord_request as a standalone generic tool and get_current_user not matching the list/get style perfectly, but the overall pattern is predictable.

Tool Count4/5

32 tools is on the heavier side but justified for a Discord server integration covering messages, channels, members, roles, threads, invites, and reactions. The generic discord_request tool helps keep the count from being even larger, and every tool addresses a concrete Discord operation.

Completeness4/5

The surface covers core interaction and moderation workflows well: message lifecycle, channel lifecycle, role assignment, member updates, invites, threads, pins, reactions, and DMs. Notable gaps include no dedicated webhook/emoji/event tools, though discord_request explicitly covers those REST operations, so agents can work around the gap.

Maintenance

ActivityMaintained
ResponsivenessNo issues