Skip to main content
Glama
better-discord-mcp

better-discord-mcp

by Sys0xdbg

better-discord-mcp

An MCP server that lets an AI client (Claude Desktop / Claude Code) read and control Discord through a BetterDiscord plugin. It drives your logged-in Discord client, so it can read any channel you can see, send messages, and perform moderation (ban / kick / timeout / delete) wherever your account has permission.

Claude ──stdio──▶ MCP server ──WebSocket(127.0.0.1:6473)──▶ BD plugin ──▶ Discord

⚠️ Important: Terms of Service

This automates a user account, not a bot account. Automating a user account ("selfbotting") violates Discord's Terms of Service and can result in account termination, regardless of intent. Use only on your own or explicitly authorized servers, ideally with a test account. You accept the risk.

For ToS-compliant moderation, build a real Discord bot instead — but that cannot "see your client" the way this does.

Related MCP server: Discord MCP Server

Setup

1. Install the BetterDiscord plugin

  • Copy plugin/DiscordMCP.plugin.js into your BetterDiscord plugins folder:

    • Windows: %AppData%\BetterDiscord\plugins\

  • Open Discord → Settings → Plugins → enable DiscordMCP.

  • It will keep trying to connect to the bridge every 3s (toast shows status).

2. Install server deps

npm install

3. Register the MCP server with your client

Claude Code:

claude mcp add discord -- node "/absolute/path/to/better-discord-mcp/server/index.js"

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "discord": {
      "command": "node",
      "args": ["/absolute/path/to/better-discord-mcp/server/index.js"]
    }
  }
}

The server hosts the WebSocket bridge; the plugin connects to it. Start order doesn't matter — the plugin auto-reconnects. Use the discord_status tool to confirm the link is up.

Tools

Read / info

Tool

Purpose

discord_status

Is the plugin connected?

discord_get_context

Current guild / channel / user

discord_get_guilds

List your servers

discord_get_channels

Channels in a guild

discord_get_messages

Recent messages in a channel

discord_search_messages

Search a guild or channel

discord_get_user

User / guild-member info

discord_get_roles

List a guild's roles

discord_get_dms

List open DM channels

Messaging

Tool

Purpose

discord_send_message

Send a message

discord_edit_message

Edit your own message

discord_add_reaction / discord_remove_reaction

React to a message

discord_trigger_typing

Show typing indicator

discord_open_dm

Open/fetch a DM with a user

Moderation (🔒 gated — need confirm:true)

Tool

Purpose

discord_delete_message 🔒

Delete a message

discord_purge_messages 🔒

Bulk-delete recent messages (<14 days)

discord_ban_user 🔒

Ban (needs Ban Members)

discord_kick_user 🔒

Kick (needs Kick Members)

discord_timeout_user 🔒

Timeout / un-timeout a member

discord_add_role

Add a role (Manage Roles)

discord_remove_role 🔒

Remove a role (Manage Roles)

🔒 = destructive: the first call returns a confirmation preview and does nothing; re-call with confirm:true to execute. Disable with DISCORD_MCP_REQUIRE_CONFIRM=false.

Full surface (~100 tools)

This exposes essentially all of Discord's REST-driven features. Beyond the common tools above, there are named tools for: audit log, bans (list/get/unban), threads (create/edit/join/leave/members/archived lists), forum posts, channel permission overwrites, channel/role reordering, polls, replies & embeds, crossposting, scheduled events, AutoMod rules, stickers, integrations, webhooks (create/edit/execute), invites (resolve/join), friends/block/notes, status, prune, voice mute/deafen & status, welcome screen, vanity url, and more. See COVERAGE.md for the complete map and what is not reachable.

discord_request — raw escape hatch

For anything without a named tool (templates, onboarding, slash-command registration, brand-new endpoints), call any REST endpoint directly:

discord_request(method="post", path="/guilds/123/templates", body={ "name": "..." })

Non-GET raw calls are also gated by the confirmation rule.

What is NOT possible via this bridge

Voice audio (joining/streaming/listening), live event streaming, and the full online-member list are gateway/WebRTC, not REST — this bridge can't drive them. It can move/mute/deafen members and set voice channel status. Use polling (get_messages) instead of live message events.

Config

  • DISCORD_MCP_PORT (default 6473) — must match this.port in the plugin.

  • DISCORD_MCP_TIMEOUT (default 15000 ms) — per-request timeout.

  • DISCORD_MCP_REQUIRE_CONFIRM (default true) — gate destructive tools.

How API calls are authenticated

Current Discord builds obfuscate the internal REST client (getAPIBaseURL) and the token module (getToken), so the plugin doesn't rely on them. Instead it sniffs your Authorization header from Discord's own outgoing requests (hooking XMLHttpRequest/fetch) and then calls https://discord.com/api/v9 directly with fetch. This is version-proof — it survives Discord updates.

One consequence: the token is only captured after Discord makes an authenticated request. Most live traffic goes over the gateway WebSocket, so right after enabling the plugin you may need to switch channels once to trigger a REST call. After that the token is cached for the session.

Troubleshooting

  • not connected: Discord must be running with the plugin enabled. Check the plugin toast / Discord devtools console (Ctrl+Shift+I) for errors.

  • Auth token not captured yet: click into a different channel once (forces a REST request the plugin can read the token from), then retry.

  • Discord API 401/403: your account lacks permission for that action, or the captured token is stale — toggle the plugin off/on and switch channels.

  • Diagnostics: discord_request(path="__debug__") dumps module/token state for debugging without touching devtools.

Available Tools

128 tools
discord_accept_inviteB

Join a server via invite code.

Inputs: code (required), confirm.

discord_add_friendB

Send a friend request (by userId, or username+discriminator).

Inputs: userId, username, discriminator.

discord_add_reactionB

Add a reaction. Use a unicode emoji (e.g. 👍) or custom as name:id.

Inputs: emoji (required), channelId (required), messageId (required).

discord_add_roleB

Add a role to a member (requires Manage Roles).

Inputs: roleId (required), userId (required), guildId (required), reason.

discord_ban_userA

Ban a user from a guild (requires your account to have Ban Members).

Inputs: userId (required), guildId (required), reason, confirm, +1 more.

discord_block_userC

Block a user.

Inputs: userId (required).

discord_bulk_banB

Ban many users at once (up to 200). Requires Ban Members + Manage Guild.

Inputs: guildId (required), userIds (required), reason, confirm, +1 more.

discord_create_automod_ruleC

Create an AutoMod rule. rule = raw Discord AutoMod rule object.

Inputs: rule (required), guildId (required).

discord_create_channelB

Create a channel or category in a guild. type: 0=text, 2=voice, 4=category, 5=announcement, 13=stage, 15=forum. Put a channel under a category with parentId.

Inputs: name (required), guildId (required), nsfw, type, +7 more.

discord_create_emojiB

Create a custom emoji. imageDataUri must be a data URI (data:image/png;base64,...).

Inputs: name (required), guildId (required), imageDataUri (required).

discord_create_forum_postC

Create a forum post (thread + starter message).

Inputs: name (required), content (required), channelId (required), tagIds, +1 more.

discord_create_group_dmB

Create a group DM with the given user IDs.

Inputs: userIds (required).

discord_create_guildA

Create a new server (you become owner). icon is a data URI or URL.

Inputs: name (required), icon.

discord_create_inviteB

Create an invite link for a channel.

Inputs: channelId (required), unique, maxUses, temporary, +1 more.

discord_create_pollC

Create a poll message.

Inputs: answers (required), question (required), channelId (required), multiselect, +1 more.

discord_create_roleC

Create a role. permissions is a permission bitfield as a string.

Inputs: name (required), guildId (required), color, hoist, +3 more.

discord_create_scheduled_eventC

Create a scheduled event. entityType: 1=stage,2=voice,3=external. Times are ISO8601.

Inputs: name (required), guildId (required), startTime (required), entityType (required), +4 more.

discord_create_threadC

Create a thread. Pass messageId to thread off a message, otherwise a standalone thread in the channel.

Inputs: name (required), channelId (required), type, messageId, +2 more.

discord_create_webhookC

Create a webhook on a channel.

Inputs: name (required), channelId (required).

discord_crosspost_messageC

Publish (crosspost) a message from an announcement channel.

Inputs: channelId (required), messageId (required).

discord_delete_automod_ruleC

Delete an AutoMod rule.

Inputs: ruleId (required), guildId (required), confirm.

discord_delete_channelA

Delete a channel or category (deleting a category does NOT delete its channels).

Inputs: channelId (required), reason, confirm.

discord_delete_channel_permissionC

Remove a permission overwrite.

Inputs: channelId (required), overwriteId (required).

discord_delete_emojiC

Delete a custom emoji.

Inputs: emojiId (required), guildId (required), confirm.

discord_delete_guildB

Delete a server you own. Irreversible.

Inputs: guildId (required), confirm.

discord_delete_integrationC

Delete a guild integration.

Inputs: guildId (required), integrationId (required), confirm.

discord_delete_inviteC

Revoke an invite by code.

Inputs: code (required), confirm.

discord_delete_messageB

Delete a message in a channel.

Inputs: channelId (required), messageId (required), confirm.

discord_delete_roleC

Delete a role from a guild.

Inputs: roleId (required), guildId (required), reason, confirm.

discord_delete_scheduled_eventC

Delete a scheduled event.

Inputs: eventId (required), guildId (required), confirm.

discord_delete_stickerC

Delete a guild sticker.

Inputs: guildId (required), stickerId (required), confirm.

discord_delete_webhookA

Delete a webhook.

Inputs: webhookId (required), confirm.

discord_edit_automod_ruleC

Edit an AutoMod rule. fields = raw Discord AutoMod fields.

Inputs: fields (required), ruleId (required), guildId (required).

discord_edit_channelC

Edit a channel/category (name, topic, parent/category, position, slowmode, nsfw, voice bitrate/limit).

Inputs: channelId (required), name, nsfw, topic, +6 more.

discord_edit_emojiB

Rename a custom emoji (or restrict to roleIds).

Inputs: emojiId (required), guildId (required), name, roleIds.

discord_edit_guildC

Edit guild name/description/icon (iconDataUri is a data URI).

Inputs: guildId (required), name, reason, description, +1 more.

discord_edit_messageA

Edit one of your own messages.

Inputs: content (required), channelId (required), messageId (required).

discord_edit_profileB

Edit your own account: username, avatar, banner (data URI or URL), bio.

Inputs: bio, avatar, banner, username.

discord_edit_roleB

Edit a role's name/permissions/color/hoist/mentionable.

Inputs: roleId (required), guildId (required), name, color, +4 more.

discord_edit_scheduled_eventC

Edit a scheduled event. fields = raw Discord event fields.

Inputs: fields (required), eventId (required), guildId (required).

discord_edit_stageC

Edit the current Stage topic.

Inputs: topic (required), channelId (required).

discord_edit_stickerB

Edit a guild sticker's name/description/tags.

Inputs: guildId (required), stickerId (required), name, tags, +1 more.

discord_edit_threadC

Archive/unarchive, lock/unlock, or rename a thread.

Inputs: threadId (required), name, locked, archived, +1 more.

discord_edit_webhookB

Edit a webhook's name/channel.

Inputs: webhookId (required), name, channelId.

discord_edit_welcome_screenC

Edit the welcome screen. fields = raw Discord welcome-screen fields.

Inputs: fields (required), guildId (required).

discord_edit_widget_settingsB

Enable/disable the guild widget and set its invite channel.

Inputs: guildId (required), enabled, channelId.

discord_end_pollC

End a poll early.

Inputs: channelId (required), messageId (required).

discord_end_stageC

End the current Stage.

Inputs: channelId (required), confirm.

discord_execute_webhookC

Post a message via a webhook (needs webhook token).

Inputs: token (required), webhookId (required), embeds, content, +2 more.

discord_follow_announcementC

Follow an announcement channel into a target channel.

Inputs: channelId (required), targetChannelId (required).

discord_get_audit_logC

Read the guild audit log.

Inputs: guildId (required), limit, userId, actionType.

discord_get_banC

Get a single ban entry.

Inputs: userId (required), guildId (required).

discord_get_channelB

Get a single channel's details.

Inputs: channelId (required).

discord_get_channel_invitesC

List invites for a channel.

Inputs: channelId (required).

discord_get_channelsA

List channels in a guild.

Inputs: guildId (required).

discord_get_connectionsA

List your linked accounts (Steam, Spotify, etc.).

Inputs: no named parameters.

discord_get_contextA

Get the currently selected guild, channel, and the logged-in user.

Inputs: no named parameters.

discord_get_dmsA

List your open DM and group-DM channels.

Inputs: no named parameters.

discord_get_guild_infoC

Get details about a guild.

Inputs: guildId (required).

discord_get_guildsA

List all guilds (servers) the user is in.

Inputs: no named parameters.

discord_get_inviteB

Resolve an invite code (with member counts).

Inputs: code (required).

discord_get_invitesC

List a guild's invites.

Inputs: guildId (required).

discord_get_messageC

Fetch a single message.

Inputs: channelId (required), messageId (required).

discord_get_messagesA

Read messages from a channel. Use before/after/around (message IDs) to page through history beyond the latest 100.

Inputs: channelId (required), after, limit, around, +1 more.

discord_get_noteC

Get your private note on a user.

Inputs: userId (required).

discord_get_pinnedB

List pinned messages in a channel.

Inputs: channelId (required).

discord_get_poll_votersC

List users who voted for a poll answer.

Inputs: answerId (required), channelId (required), messageId (required), limit.

discord_get_prune_countB

Count members who would be pruned for inactivity.

Inputs: guildId (required), days.

discord_get_reactionsB

List users who reacted with an emoji.

Inputs: emoji (required), channelId (required), messageId (required), limit.

discord_get_rolesC

List a guild's roles.

Inputs: guildId (required).

discord_get_userB

Get info about a user by ID (optionally as a guild member).

Inputs: userId (required), guildId.

discord_get_vanity_urlC

Get the guild's vanity invite.

Inputs: guildId (required).

discord_get_welcome_screenC

Get the guild welcome screen.

Inputs: guildId (required).

discord_get_widget_settingsC

Get the guild widget settings.

Inputs: guildId (required).

discord_grant_permissionC

Add one or more permissions to a role by name (e.g. BAN_MEMBERS). Reads current perms and ORs in the new ones — does not clobber existing perms.

Inputs: roleId (required), guildId (required), permissions (required).

discord_kick_userC

Kick a user from a guild (requires Kick Members).

Inputs: userId (required), guildId (required), reason, confirm.

discord_leave_guildC

Leave a guild.

Inputs: guildId (required), confirm.

discord_list_active_threadsC

List active threads in a guild.

Inputs: guildId (required).

discord_list_archived_threadsC

List archived threads in a channel.

Inputs: channelId (required), limit, private.

discord_list_automod_rulesC

List a guild's AutoMod rules.

Inputs: guildId (required).

discord_list_bansD

List a guild's bans.

Inputs: guildId (required), limit.

discord_list_emojisC

List a guild's custom emojis.

Inputs: guildId (required).

discord_list_guild_webhooksB

List all webhooks in a guild.

Inputs: guildId (required).

discord_list_integrationsC

List guild integrations.

Inputs: guildId (required).

discord_list_permissionsA

List all Discord permission names and their bit values. Use these names with grant/revoke.

Inputs: no named parameters.

discord_list_relationshipsB

List friends/blocked (relationships).

Inputs: no named parameters.

discord_list_scheduled_eventsC

List a guild's scheduled events.

Inputs: guildId (required).

discord_list_stickersA

List a guild's stickers.

Inputs: guildId (required).

discord_list_thread_membersC

List members of a thread.

Inputs: threadId (required).

discord_list_webhooksC

List a channel's webhooks.

Inputs: channelId (required).

discord_modify_user_voice_stateA

Stage moderation: invite a user to speak (suppress:false) or move them to audience (suppress:true).

Inputs: userId (required), guildId (required), channelId (required), suppress.

discord_move_member_voiceA

Move a member to another voice channel (they must already be connected). Omit channelId to disconnect.

Inputs: userId (required), guildId (required), channelId.

discord_open_dmB

Open (or fetch) a DM channel with a user; returns the channelId.

Inputs: userId (required).

discord_pin_messageC

Pin a message.

Inputs: channelId (required), messageId (required).

discord_prune_membersC

Prune (kick) inactive members.

Inputs: guildId (required), days, reason, confirm.

discord_purge_messagesA

Bulk-delete recent messages in a channel (optionally only from one user). Only affects messages newer than 14 days; requires Manage Messages.

Inputs: channelId (required), limit, userId, confirm.

discord_remove_all_reactionsB

Remove all reactions (or all of one emoji) from a message.

Inputs: channelId (required), messageId (required), emoji, confirm.

discord_remove_reactionC

Remove your reaction from a message.

Inputs: emoji (required), channelId (required), messageId (required).

discord_remove_relationshipB

Remove a friend / cancel request / unblock.

Inputs: userId (required), confirm.

discord_remove_roleC

Remove a role from a member (requires Manage Roles).

Inputs: roleId (required), userId (required), guildId (required), reason, +1 more.

discord_remove_user_reactionC

Remove a specific user's reaction.

Inputs: emoji (required), userId (required), channelId (required), messageId (required).

discord_reorder_channelsB

Reorder channels. positions: array of {id, position, parent_id?}.

Inputs: guildId (required), positions (required).

discord_reorder_rolesB

Reorder roles. positions: array of {id, position}.

Inputs: guildId (required), positions (required).

discord_reply_messageB

Reply to a message (set ping:false to not ping the author).

Inputs: channelId (required), messageId (required), ping, embeds, +1 more.

discord_requestA

Advanced: call ANY Discord REST endpoint directly (covers every feature not wrapped by a named tool). path is relative, e.g. /guilds/{id}/templates.

Inputs: path (required), body, query, method, +1 more.

discord_request_to_speakB

Raise your hand to speak in a Stage (set cancel:true to lower).

Inputs: guildId (required), channelId (required), cancel.

discord_revoke_permissionB

Remove one or more permissions from a role by name. Reads current perms and ANDs them out — leaves other perms intact.

Inputs: roleId (required), guildId (required), permissions (required).

discord_search_membersC

Search guild members by username/nickname prefix.

Inputs: query (required), guildId (required), limit.

discord_search_messagesC

Search messages in a guild (set guildId) or a DM/channel (set channelId).

Inputs: query (required), limit, guildId, authorId, +1 more.

discord_send_embedC

Send a message with rich embeds (Discord embed objects).

Inputs: embeds (required), channelId (required), content.

discord_send_fileA

Send a file/image to a channel. source is a data URI or http(s) URL. For multiple files use the files array.

Inputs: channelId (required), files, source, content, +1 more.

discord_send_messageC

Send a message to a channel.

Inputs: content (required), channelId (required).

discord_set_channel_permissionB

Set a permission overwrite. type 0=role, 1=member. allow/deny are bitfield strings.

Inputs: type (required), channelId (required), overwriteId (required), deny, +2 more.

discord_set_nicknameA

Set a member's nickname (omit userId to set your own). Pass empty/no nickname to clear.

Inputs: guildId (required), reason, userId, nickname.

discord_set_noteC

Set your private note on a user.

Inputs: note (required), userId (required).

discord_set_statusA

Set your status (online/idle/dnd/invisible) and/or custom status text.

Inputs: status, customText.

discord_set_voice_stateC

Server mute/deafen a member (mute/deaf booleans).

Inputs: userId (required), guildId (required), deaf, mute, +1 more.

discord_set_voice_statusC

Set a voice channel's status text (empty to clear).

Inputs: channelId (required), status.

discord_start_stageC

Start a Stage in a stage channel.

Inputs: topic (required), channelId (required), privacyLevel.

discord_statusA

Check whether the BetterDiscord plugin bridge is connected.

Inputs: no named parameters.

discord_thread_add_memberC

Add a member to a thread.

Inputs: userId (required), threadId (required).

discord_thread_joinB

Join a thread.

Inputs: threadId (required).

discord_thread_leaveB

Leave a thread.

Inputs: threadId (required).

discord_thread_remove_memberC

Remove a member from a thread.

Inputs: userId (required), threadId (required).

discord_timeout_userC

Time out (mute) a guild member for a duration in seconds. Pass 0 to remove the timeout.

Inputs: userId (required), guildId (required), durationSeconds (required), reason, +1 more.

discord_trigger_typingC

Show the typing indicator in a channel.

Inputs: channelId (required).

discord_unban_userC

Unban a user.

Inputs: userId (required), guildId (required), reason.

discord_unpin_messageC

Unpin a message.

Inputs: channelId (required), messageId (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.9/5.0

    Scored across 128 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes, but there are several overlapping tools for sending messages (send_message, reply_message, send_embed, send_file, execute_webhook) that could cause confusion for an agent. Overall, the descriptions help disambiguate.

    Naming Consistency5/5

    All tools follow a consistent verb_noun pattern with the 'discord_' prefix in snake_case, e.g., discord_send_message, discord_create_role. No naming inconsistencies.

    Tool Count1/5

    With 128 tools, the server is massively over-scoped. This far exceeds the typical well-scoped range of 3-15 tools, making it difficult for agents to navigate and select the correct tool.

    Completeness5/5

    The tool set covers virtually all Discord API features, including guild, channel, role, permission, webhook, emoji, thread, scheduled events, automod, voice, and user management. A generic discord_request tool ensures no endpoint is missing.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • 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.
      16 npm
      1
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      Enables AI assistants to interact with Discord through the REST API, supporting message reading and sending, channel and guild management, threads, pins, and reactions.
      17
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI assistants to read and control a local Discord desktop client, including viewing channels and messages, managing voice calls and volumes, and setting Rich Presence.
      9
      1
      MIT