We started with a blank Discord server and one question: can Claude Code set up an entire server from scratch? Not just send a message. Create every channel, assign every role, configure onboarding, set permissions, pin welcome messages, wire up webhooks. The full thing.
The answer required building something that did not exist yet. Eight new MCP tools that give Claude direct access to the Discord REST API. No wrapper libraries, no bot frameworks, no separate bridge process. Just raw HTTP calls to Discord API v10 from inside the SynaBun MCP server.
Why Not Just Use Discord.js
Discord.js is built for persistent bots that maintain a WebSocket connection to the Discord Gateway. It listens for events in real time, tracks presence, handles sharding. That is a lot of machinery for what we actually need, which is: create a channel, set its permissions, move on.
Every operation Claude needs is a stateless HTTP request. Create channel is a POST. Edit role is a PATCH. Delete message is a DELETE. The Discord REST API handles all of this without a persistent connection. So we built a thin service layer using native fetch() in Node 22 with Bot token authentication, rate limit handling, and automatic retry on 429 responses.
Zero new dependencies. The only addition to package.json is discord-api-types for TypeScript definitions.
Eight Tools, Forty Actions
We followed the same action-dispatch pattern used by SynaBun's category system. Instead of registering forty individual tools, which would overwhelm tool discovery, we consolidated into eight tools with an action parameter that routes to the right handler:
- discord_guild — server info, list channels, members, roles, audit log
- discord_channel — create, edit, delete channels and categories, set permission overwrites
- discord_role — create, edit, delete roles, assign and remove from members
- discord_message — send, edit, delete, pin, react, bulk delete, list messages
- discord_member — member info, kick, ban, timeout, nickname
- discord_onboarding — welcome screen, rules channel, verification level, onboarding prompts
- discord_webhook — create, edit, delete, list, execute webhooks
- discord_thread — create, archive, lock, delete threads
Every tool accepts names or IDs interchangeably. Say channel: "general" instead of memorizing snowflake IDs. The service layer resolves names against the guild's channel and role lists, with caching to avoid redundant API calls. If a name is ambiguous, it returns all matches with their IDs so Claude can ask which one you meant.
The Service Layer
The core of the system is services/discord.ts. It handles everything the tools need but should not care about:
- Rate limiting — Discord returns 429 with a
Retry-Afterheader. The service waits and retries automatically, up to three times. - Name resolution — converts human-readable names to Discord snowflake IDs. Checks if the input is all digits first, uses it directly if so.
- Permission bitfields — maps readable flag names like
SEND_MESSAGES, VIEW_CHANNELto the bigint bitfields Discord actually expects. - Guild ID fallback — defaults to the
DISCORD_GUILD_IDenvironment variable so you do not have to pass it on every call. - In-memory caching — 5-minute TTL on guild channels and roles to avoid hitting the API on every name lookup.
The Settings Tab
We added a Discord configuration tab to the Neural Interface. It sits under Connections alongside the existing Claude Code and Cursor integrations. Five sections cover everything needed to get the tools running:
- Bot Connection — token input with visibility toggle, guild ID, and a test button that verifies the token against Discord's API and returns bot info plus guild list
- Required Permissions — a visual grid of all permissions the bot needs, with an auto-generated invite link you can copy
- Server Defaults — default category, welcome channel, rules channel, log channel, moderator role
- Moderation Defaults — ban message delete window, default timeout duration
- Tools Reference — a quick-reference grid of all eight tools and what they do
Everything auto-saves to the .env file with an 800ms debounce. No save buttons, no page reloads.
What This Actually Looks Like
Once the bot token and guild ID are configured, Claude can do things like this in a single conversation:
Create a "Community" category. Under it, create #general with topic "Main discussion", #introductions with slowmode 30 seconds, and #resources as read-only for @everyone but writable for @moderator. Create the moderator role with blue color, hoist it, and assign it to the server owner. Set the welcome screen to feature #introductions and #resources. Set verification level to medium.
That is six tool calls. Each one is a direct REST call to Discord. No scripting, no dashboard clicking, no bot framework in between.
What Comes Next
The tools exist. The settings tab exists. The next step is actually using them to set up a real server from scratch in a single Claude Code session. We will document that process when it happens, including whatever breaks along the way.
The Discord tools are also the foundation for something else we have been thinking about: letting Claude monitor and respond in Discord channels. That would require the WebSocket Gateway, which is a different architecture entirely. But the REST tools we built now handle every setup and moderation operation Discord supports, and they will stay useful regardless of what we add later.
The Discord MCP tools ship with SynaBun. If you are running SynaBun already, update and add your bot token. If you are not, the code is on GitHub.