프로토타입 · 미리 보기: 공식 레지스트리의 모든 서버를 담고 있으며 30분마다 동기화해요. 리뷰와 계정 기능은 다음 단계에서 열려요.
PopNx MCPAI를 쓰는 사람을 위한 MCP 서버 · 쉬운 말로 설명해요

Discord MCP

제작자: jaimenbell버전 0.1.1i★ –i내 컴퓨터에서 실행
레지스트리 이름io.github.jaimenbell/discord-mcp

설치

개요

제작자가 쓴 설명(영어 원문)

MCP server for the Discord REST API: 5 read tools always on, 7 write tools env-gated, default off.

PopNx MCP의 세 기둥

이 세 가지는 절대 하나의 점수로 합치지 않아요. 의견, 측정, 인기는 서로 다른 것이니까요.

할 수 있는 일

이 서버는 아직 쉬운 말로 된 요약을 쓰지 못했어요. 아래는 레지스트리에서 읽어 온 사실이에요.

  • 연결 방식: 내 컴퓨터에서 실행
  • 전송 방식: stdio
  • 카테고리: 채팅 및 이메일

설치

쓰고 있는 AI 앱을 고른 다음 설정을 복사하세요.

설치하기 전에

  • 기본 점검: 1개 중 1개 통과
  • 내 컴퓨터에서 내 사용자 계정의 권한(파일, 네트워크, 앱)으로 실행돼요.
  • 레지스트리에 입력해야 할 키가 나와 있지 않아요.

필요한 것

  • PyPIPython의 uv 설치(uvx 명령어용)

어떤 앱을 쓰세요?

위에서 앱을 고르세요. 기억해 두었다가 다음부터는 버튼에 “…에 설치”라고 표시해요.

Claude Desktop → Settings → Developer → Edit Config를 열고 claude_desktop_config.json에 이 내용을 붙여 넣으세요

{
  "mcpServers": {
    "discord": {
      "command": "uvx",
      "args": [
        "jaimenbell-discord-mcp"
      ]
    }
  }
}

터미널에서 이 명령어를 실행하세요

claude mcp add discord -- uvx jaimenbell-discord-mcp

Cursor에서 열기

또는 설정을 직접 복사하기

프로젝트의 .cursor/mcp.json 또는 ~/.cursor/mcp.json에 붙여 넣으세요

{
  "mcpServers": {
    "discord": {
      "command": "uvx",
      "args": [
        "jaimenbell-discord-mcp"
      ]
    }
  }
}

브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.

VS Code에서 열기

또는 설정을 직접 복사하기

프로젝트의 .vscode/mcp.json에 붙여 넣으세요

{
  "servers": {
    "discord": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "jaimenbell-discord-mcp"
      ]
    }
  }
}

브라우저가 앱을 열지 물어본 다음, 앱이 설정을 보여 주고 확인을 요청해요. 키 값은 비워 두니 직접 입력하세요.

이 서버는 내 컴퓨터에서 실행되는데, ChatGPT는 인터넷에 있는 서버에만 연결할 수 있어요. 다른 앱을 고르세요.

선택한 앱은 이 기기의 쿠키에만 저장돼요. 계정은 필요 없어요.

이 설정은 제작자의 레지스트리 정보로 만들었어요. README와 다르면 README를 따르세요.

할 수 있는 일

내 컴퓨터에서 실행돼요. 설치하면 AI 앱에 도구 목록이 나타나요.

기본 점검i

누구나 볼 수 있는 정보를 점검했고, 코드는 읽지 않았어요. 해당하지 않는 항목은 개수에서 뺐어요. · 2026년 11월 8일 점검

  • ✓ 통과

    제작자와 저장소 일치

    레지스트리 이름이 GitHub 계정 jaimenbell 기준으로 확인되었고, 이 계정이 저장소를 소유하고 있어요

  • … 아직 점검 안 함

    계속 관리되고 있음

    아직 GitHub에서 이 저장소를 읽어 오지 않았어요

  • … 아직 점검 안 함

    라이선스 있음

    아직 GitHub에서 이 저장소를 읽어 오지 않았어요

  • – 해당 없음

    엔드포인트 응답

    내 컴퓨터에서 실행되는 서버라 인터넷 엔드포인트가 없어요

  • – 해당 없음

    OAuth로 로그인

    내 컴퓨터에서 실행되며, 대신 로컬 설정을 사용해요

  • … 아직 점검 안 함

    도구 설명에 숨겨진 지시 없음

    내 컴퓨터에서 실행돼요. 도구 목록은 인터넷 엔드포인트가 있는 서버에서만 읽을 수 있어요

채팅 및 이메일 카테고리의 다른 서버와 비교i

  • 이 카테고리의 다른 서버 1856개 중 0%보다 스타가 많아요
  • 이 카테고리의 다른 서버 1856개 중 24%보다 최근에 레지스트리에 공개됐어요
  • 기본 점검 결과가 이 카테고리의 다른 서버 1856개 중 100%와 같거나 더 좋아요

레지스트리에서 이 카테고리의 활성 서버 전체와 비교했어요. 스타는 게시자가 저장소를 소유한 경우에만 세요.

자주 묻는 질문

Discord MCP, 안전한가요?

해당하는 기본 점검 1개 중 1개를 통과했어요. 코드는 읽지 않았어요. 키나 토큰을 넣기 전에 서버가 어떤 권한을 요구하는지 확인하고, 꼭 필요한 권한만 있는 키를 쓰세요.

어떤 키나 코드가 필요한가요?

레지스트리에 필수 키가 나와 있지 않아요. 다만 처음 쓸 때 로그인을 요구하는 서버도 있어요.

내 컴퓨터에서 실행되나요, 클라우드에서 실행되나요?

내 컴퓨터에서 실행돼요. AI 앱이 필요할 때 실행하고, 데이터는 제작자의 서버를 거치지 않아요(서버 자체가 온라인 서비스를 호출하는 경우는 제외).

아직 관리되고 있나요?

GitHub 저장소는 마지막으로 – 변경됐고, 최신 버전(0.1.1)은 3개월 전 레지스트리에 올라왔어요.

어떤 앱에서 쓸 수 있나요?

Claude Desktop, Claude Code, Cursor, VS Code처럼 MCP를 지원하는 앱에서 쓸 수 있어요. 내 컴퓨터에 Python (uv)도 있어야 해요.

대신 쓸 수 있는 건 뭐가 있나요?

같은 카테고리에는: Vexa, emailmd, MCP WhatsApp Cloud

대안

같은 카테고리에서 다른 제작자가 만든 서버예요. 스타 순으로 정렬했어요.

카드 보는 법:↓ 주간 다운로드i★ GitHub 스타i세 기둥: 리뷰 · 점검 · 사용 정도i업데이트 = 최신 버전을 레지스트리에 공개한 날i

Vexa

Meeting bot and transcripts for Google Meet, Teams and Zoom. Live or after, speakers labelled.

제작자: Vexa-ai널리 사용됨★ 2.9천2개월 전 업데이트

클라우드에서 실행✓ vexa.ai

emailmd

Render markdown into email-safe HTML, lint drafts for deliverability problems, and preview emails.

제작자: anypost성장 중↓ 5.3천/주★ 1.4천33일 전 업데이트

컴퓨터 또는 클라우드✓ emailmd.dev

MCP WhatsApp Cloud

MCP server for WhatsApp Cloud API (Meta) — messages, media, and templates via Graph API

제작자: codespar초기↓ 63/주★ 2775개월 전 업데이트

내 컴퓨터에서 실행

제작자의 README

README 열기

제작자의 저장소에서 쓰인 그대로 가져왔어요. PopNx MCP가 검토하거나 보증한 내용이 아니에요. HTML, 이미지, 스크립트는 제거했어요. 링크를 누르면 이 사이트를 벗어나요.

discord-mcp

An MCP server over the real Discord REST API -- so a Claude agent calls list_channels(guild_id="...") instead of hand-rolling an authenticated httpx request. Built to the github-mcp/bus-mcp standard in this portfolio (own pyproject, fastmcp server, typed errors, real test suite, honest README) -- fifth flagship, first over Discord.

5 read-only tools, always on + 7 write tools, gated OFF by default behind DISCORD_MCP_ENABLE_WRITE=1 -- see "Write tools" below.

Quickstart (60 seconds)

python -m venv .venv

.venv/Scripts/python.exe -m pip install -e ".[test]"

Add to your Claude Desktop/Code MCP config:

{

"mcpServers": { "discord-mcp": { "command": "python", "args": ["C:/path/to/discord-mcp/run_server.py"], "env": { "DISCORD_BOT_TOKEN": "your-bot-token-here" } } } }

Without DISCORD_BOT_TOKEN set, every tool call still returns a clean structured error (Discord's own 401) instead of crashing -- see "Typed errors" below. Write tools also need DISCORD_MCP_ENABLE_WRITE=1 in the same env block, or they refuse locally with policy_refusal -- see "Write tools" below.

What this is / is not

This is a reference portfolio implementation demonstrating an MCP server over a real external SaaS API (Discord) -- it is NOT an official Discord MCP server, and it is not affiliated with Discord Inc. It started from an earlier, separate sibling project's HttpDiscordClient, a stdlib-urllib Discord transport built and verified against a real live guild for that project's own server-provisioning tooling. This repo hand-adapts that client's request-building, header construction (including its deliberately descriptive User-Agent -- see below), and error handling onto httpx (matching this fleet's other MCP servers) as its own standalone client with no dependency on that sibling project. discord-mcp does not import from or depend on that other package at all.

Started as 5 read-only tools with no write capability at all; now ships a 7-tool write group, off by default, mirroring the *_MCP_ENABLE_WRITE-style gate already shipped in github-mcp/bus-mcp/desktop-mcp in this same portfolio -- see "Write tools" below.

Tools

Read (always on, no gate)
ToolDiscord endpointPurpose
list_channelsGET /guilds/{guild_id}/channelsAll channels (every type) in a guild
list_rolesGET /guilds/{guild_id}/rolesAll roles in a guild
list_categoriesGET /guilds/{guild_id}/channels (filtered)Category channels only (Discord type 4) -- Discord has no dedicated categories-only endpoint, so this filters the same channels payload client-side
get_channel_permission_overwritesGET /channels/{channel_id} (permission_overwrites field)Role/member allow+deny bitfields set on one channel
get_member_rolesGET /guilds/{guild_id}/members/{member_id} (roles field)Role ids currently assigned to one guild member
Write (gated behind DISCORD_MCP_ENABLE_WRITE=1, default OFF)
ToolDiscord endpointPurpose
create_channelPOST /guilds/{guild_id}/channelsCreate a text/voice/category channel
edit_channelPATCH /channels/{channel_id}Rename/re-topic/re-parent/reorder an existing channel
create_rolePOST /guilds/{guild_id}/rolesCreate a role
edit_rolePATCH /guilds/{guild_id}/roles/{role_id}Edit an existing role
edit_guildPATCH /guilds/{guild_id}Update guild-level identity (name/icon/banner/description)
delete_channelDELETE /channels/{channel_id}Destructive. Delete a channel
create_messagePOST /channels/{channel_id}/messagesPost a message to a text channel (content: non-empty, <= 2000 chars)

Write tools

Seven write tools were added on top of the original 5 read-only tools, mirroring the exact write-gate pattern already shipped in this portfolio (github-mcp's GITHUB_MCP_ENABLE_WRITE, desktop-mcp's DESKTOP_MCP_ENABLE_*, and most closely bus-mcp's BUS_MCP_ENABLE_WRITE + gated_write decorator, copied as the reference template). create_message was added a night later than the other 6, once it became clear that none of create_channel/edit_channel/create_role/edit_role/edit_guild/delete_channel can actually post content to a channel -- it reuses the exact same gate and the post() helper create_channel/create_role already added to client.py, no new HTTP plumbing.

  • Off by default. Set DISCORD_MCP_ENABLE_WRITE=1 (or true/yes/on) in the server's environment to enable the write group. Unset (or any other value) means every write tool call refuses locally, with zero Discord API calls attempted, returning a structured policy_refusal error:
  {"ok": false, "error": {"type": "policy_refusal", "message": "Tool group 'write' is disabled. Set DISCORD_MCP_ENABLE_WRITE=1 in the server's environment to enable it.", "group": "write", "tool": "create_channel", "required_env": "DISCORD_MCP_ENABLE_WRITE"}}
  • Enforced at the route layer, not just the MCP-tool layer. The @config.gated_write decorator wraps each write function directly in discord_mcp/routes.py (not merely the @mcp.tool wrapper in server.py), so the gate is unit-testable without spinning up fastmcp or a real transport, and can't be bypassed by any alternate calling path into routes.py.
  • Read fresh from the environment on every call, never cached at import time -- an operator can arm/disarm the write group without restarting the server process, and tests can monkeypatch it per-test.
  • `delete_channel` gets no separate or lower bar. Despite being genuinely destructive/irreversible against a real guild, it is gated behind the exact same DISCORD_MCP_ENABLE_WRITE env var as the other write tools -- confirmed by dedicated tests in test_routes.py (setting plausible-but-wrong var names like DISCORD_MCP_ENABLE_DELETE does not arm it).
  • Same auth path as the read tools. Write calls reuse the exact same _headers()/pooled httpx.AsyncClient construction in client.py as every read tool -- there is only one auth code path in this repo.
  • `create_message` validates content locally, not just via Discord's own 400. content must be a non-empty string of at most 2000 characters (Discord's real message-length limit) -- checked by client.validate_message_content before any request is built, same "never even attempt the call" discipline as the snowflake-id checks. A violation returns validation_error, not a raw Discord 400.
icon_base64/banner_base64 on edit_guild -- a flagged assumption

Discord's docs describe PATCH /guilds/{id}'s icon/banner fields as an "image data" string -- a full data URI (data:image/png;base64, ), not a bare base64 payload. edit_guild accepts either:

  • a full data:...;base64,... URI, passed through unchanged, or
  • raw base64 bytes, which are assumed to be PNG and wrapped as data:image/png;base64, .

This PNG assumption is not verified against a real Discord response -- this repo has not confirmed whether Discord accepts, rejects, or silently mis-renders a non-PNG image (JPEG, animated GIF for boosted-server icons, etc.) sent under an image/png label. If you have a non-PNG image, pass a full data:image/...;base64,... URI yourself rather than relying on the default. Flagged here rather than guessed silently.

Typed errors, never a raw crash

Every tool returns {"ok": true, ...} on success or {"ok": false, "error": {...}} on failure -- never an unhandled exception or stack trace.

  • `network_error` -- connection refused, timeout, DNS failure, or a malformed request URL. Discord's API wasn't reachable at all.
  • `auth_error` (401) -- missing or invalid bot token.
  • `permission_error` (403, with Discord's own JSON error body, e.g. {"message": "Missing Access", "code": 50001}) -- the bot lacks the permission/scope for this call, or isn't in the guild.
  • `cloudflare_blocked` (403, with no JSON error body) -- Discord's API docs ask for a descriptive User-Agent; without one, a client's default UA is a well-known bot fingerprint that Discord's Cloudflare edge can reject with a bare 403 *before* the request ever reaches route-level permission checks. This is otherwise indistinguishable from a real permission_error 403 -- Discord's real permission-denied responses always carry a JSON body, so absence of a JSON body on a 403 is the signal this type is built on. This is a best-effort heuristic, not a certainty: a proxy, load balancer, or future Discord change that strips the body on a *different* kind of 403 would also land here. discord-mcp sends the same descriptive User-Agent this heuristic exists to explain (see client.py's _headers()), so in practice this type should rarely fire from this server's own calls -- see "Honest limitations" below.
  • `not_found` (404) -- bad/unknown guild, channel, role, or member id.
  • `rate_limited` (429) -- Discord's rate limit. Carries retry_after_s, parsed straight from Discord's own JSON body (retry_after, in seconds). This server does not auto-retry -- it surfaces the limit as a structured error immediately and leaves any backoff/retry decision to the caller.
  • `decode_error` -- a 2xx response whose body isn't valid JSON (should not happen against the real API; guards against a malformed proxy/mock).
  • `discord_api_error` -- any other 4xx/5xx not covered above.
  • `policy_refusal` (write tools only) -- the write group is disabled; see "Write tools" above. No Discord API call is attempted.
  • `invalid_id` -- a guild/channel/role/member id failed snowflake-shape validation before any request was built (defense against path injection).
  • `validation_error` (create_message only) -- content was empty or exceeded Discord's real 2000-character message limit, caught before any request was built.

Internally, discord_mcp/client.py raises typed DiscordUnreachable / DiscordApiError (with a DiscordDecodeError subclass for the 2xx-non-JSON case) exceptions; discord_mcp/routes.py catches both and normalizes to the dict shape above before a tool ever returns. Tests exercise both layers for every error type, across every HTTP verb (GET/POST/PATCH/DELETE).

Honest limitations
  • The cloudflare_blocked vs. permission_error split is a heuristic (JSON-body-present-or-not), not something Discord documents or guarantees. It is accurate for the specific failure mode it was written to explain (an edge reject due to a missing/generic User-Agent) but a 403 with a stripped body from an unrelated cause (e.g. a misbehaving proxy in between) would also be classified as cloudflare_blocked.
  • get_channel_permission_overwrites and get_member_roles were not exercised against every possible real-world edge case (e.g. a member with zero roles, a channel with zero overwrites) via the live smoke test -- only via respx-mocked unit tests. The live smoke test only calls list_channels/list_roles; it does not exercise any write tool.
  • No pagination is implemented anywhere. list_channels/list_roles are single-request, unpaginated Discord endpoints (Discord doesn't paginate either of these), so this is a non-issue for the tools in scope -- but a guild large enough to need member-list pagination is out of scope entirely (there is no list_members tool here).
  • The icon_base64/`banne

앞부분만 보여 드려요. 나머지는 저장소에서 읽어 보세요

PopNx에게 묻기