Skip to content

Commit c000738

Browse files
committed
feat: complete rewrite from AppleScript to discord.js Bot API (v2.0.0)
Major architectural change: Replaced AppleScript UI automation with Discord Bot API using discord.js. This makes the MCP server cross-platform, 100x faster, and significantly more reliable. BREAKING CHANGES: - Now requires Discord bot token instead of Discord desktop app - Removed macOS-only AppleScript dependencies - Added multi-server workflow (list_guilds, select_guild) - Removed tools: check_discord_status, focus_discord, create_server New Features: - Cross-platform support (Windows, Linux, macOS) - Multi-server management with guild selection - 18 tools across 5 categories (Guild, Channels, Roles, Settings, Templates) - Direct Discord API access (100x faster than UI automation) - Comprehensive error handling with Discord API error mapping - Rate limiting and throttling for template application Added: - src/client/ - Discord client singleton and configuration - src/services/ - Guild and template services - src/tools/guild.ts - Guild management tools (NEW) - docs/BOT_SETUP.md - Comprehensive bot setup guide - MIGRATION_COMPLETE.md - Full migration summary Modified: - All tool implementations rewritten to use discord.js - Complete documentation rewrite (README, CLAUDE.md) - Version bump to 2.0.0 Removed: - src/automation/ - AppleScript automation layer - src/tools/server.ts - Old AppleScript-based tools - src/templates/executor.ts - Old template orchestrator Dependencies: - Added: discord.js@^14.25.1 - Kept: @modelcontextprotocol/sdk, zod, typescript, tsup
1 parent 8145c0c commit c000738

File tree

24 files changed

+3819
-9497
lines changed

24 files changed

+3819
-9497
lines changed

CLAUDE.md

Lines changed: 254 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code when working with this repository.
44

55
## Project Overview
66

7-
Discord Server Setup MCP is an MCP (Model Context Protocol) server that automates Discord server setup on macOS using AppleScript/JXA automation. It exposes tools for AI assistants to create servers, channels, categories, roles, and configure server settings by controlling the Discord desktop application.
7+
Discord Server Setup MCP is an MCP (Model Context Protocol) server that automates Discord server setup using the Discord Bot API. It exposes tools for AI assistants to create servers, channels, categories, roles, and configure server settings by controlling Discord through a bot.
88

99
## Build and Development Commands
1010

@@ -21,95 +21,126 @@ npm run typecheck # Run TypeScript type checking (tsc --noEmit)
2121
### Core Components
2222

2323
- **MCP Server** (`src/index.ts`): Entry point that registers all tools with the MCP SDK and handles stdio transport
24-
- **Automation Layer** (`src/automation/`): AppleScript/JXA execution engine for controlling Discord
25-
- **Tools** (`src/tools/`): MCP tool implementations organized by domain
26-
- **Templates** (`src/templates/`): Pre-built server configuration templates
27-
- **Utils** (`src/utils/`): Validation schemas (Zod) and error handling
24+
- **Client Management** (`src/client/`): Discord.js client singleton with lazy initialization and config loading
25+
- **Guild Service** (`src/services/guild.ts`): Multi-server management and guild resolution
26+
- **Tool Implementations** (`src/tools/`): MCP tool implementations organized by domain
27+
- **Template System** (`src/templates/`): Pre-built server configuration templates
28+
- **Template Service** (`src/services/templates.ts`): Orchestrates template application
29+
- **Error Handling** (`src/utils/errors.ts`): Custom error classes mapped from Discord API codes
30+
- **Validation** (`src/utils/validation.ts`): Zod schemas for input validation (legacy, being replaced)
2831

2932
### Directory Structure
3033

3134
```
3235
src/
33-
├── index.ts # MCP server entry point, tool registration
34-
├── automation/
35-
│ ├── executor.ts # AppleScript execution with timeout/error handling
36-
│ ├── discord.ts # Discord-specific automation (click, type, navigate)
37-
│ └── waiter.ts # Timing and delay utilities
36+
├── index.ts # MCP server entry point, tool registration
37+
├── client/
38+
│ ├── discord.ts # Discord.js client singleton & lifecycle
39+
│ └── config.ts # Configuration loading (token, env vars)
40+
├── services/
41+
│ ├── guild.ts # Guild selection & resolution
42+
│ └── templates.ts # Template application orchestration
3843
├── tools/
39-
│ ├── index.ts # Re-exports all tools
40-
│ ├── server.ts # check_discord_status, create_server, focus_discord
41-
│ ├── channels.ts # create_category, create_channel, edit/delete_channel
42-
│ ├── roles.ts # create_role, edit_role, delete_role, reorder_roles
43-
│ ├── settings.ts # Server settings (verification, content filter, etc.)
44-
│ └── templates.ts # list_templates, preview_template, apply_template
44+
│ ├── index.ts # Re-exports all tools (not currently used)
45+
│ ├── guild.ts # list_guilds, select_guild, get_guild_info
46+
│ ├── channels.ts # create_category, create_channel, edit_channel, delete_channel
47+
│ ├── roles.ts # create_role, edit_role, delete_role, reorder_roles
48+
│ ├── settings.ts # Server settings tools
49+
│ └── templates.ts # list_templates, preview_template, apply_template
4550
├── templates/
46-
│ ├── types.ts # Template type definitions
47-
│ ├── index.ts # Template registry
48-
│ ├── gaming.ts # Gaming community template
49-
│ ├── community.ts # General community template
50-
│ ├── business.ts # Professional workspace template
51-
│ └── study-group.ts # Academic collaboration template
51+
│ ├── types.ts # Template type definitions
52+
│ ├── index.ts # Template registry
53+
│ ├── gaming.ts # Gaming community template
54+
│ ├── community.ts # General community template
55+
│ ├── business.ts # Professional workspace template
56+
│ └── study-group.ts # Academic collaboration template
5257
└── utils/
53-
├── errors.ts # Custom error classes (DiscordNotRunning, etc.)
54-
└── validation.ts # Zod schemas for all inputs
58+
└── errors.ts # Custom error classes (Discord API error mapping)
5559
```
5660

5761
### Key Patterns
5862

5963
**Tool Registration Pattern**: Each tool module exports:
6064
- Tool definition (name, description, inputSchema)
6165
- Input schema (Zod schema)
62-
- Handler function (async for automation, sync for templates)
66+
- Handler function (async for API calls, sync for local operations)
6367

6468
```typescript
65-
// Example from tools/server.ts
66-
export const checkDiscordStatusToolDefinition = { name, description, inputSchema };
67-
export const CheckDiscordStatusInputSchema = z.object({ ... });
68-
export async function checkDiscordStatusHandler(input: CheckDiscordStatusInput): Promise<Result> { ... }
69+
// Example from tools/guild.ts
70+
export const listGuildsToolDefinition = { name, description, inputSchema };
71+
export const ListGuildsInputSchema = z.object({ ... });
72+
export async function listGuildsHandler(input: ListGuildsInput): Promise<Result> { ... }
6973
```
7074

71-
**AppleScript Execution**: All Discord automation goes through `src/automation/executor.ts`:
72-
- `executeAppleScript(script, options)` - Run AppleScript code
73-
- `executeJXA(script, options)` - Run JavaScript for Automation
74-
- Built-in timeout handling (default 30s)
75-
- Error parsing and custom error types
75+
**Discord Client Access**: All Discord operations go through `src/client/discord.ts`:
76+
- `getDiscordClient()` - Get/initialize Discord client (lazy, singleton)
77+
- `closeDiscordClient()` - Clean shutdown on MCP server exit
78+
- Automatic reconnection handled by discord.js
79+
- Client uses Guilds and GuildMembers intents only
7680

77-
**Validation**: All inputs validated with Zod schemas in `src/utils/validation.ts`:
78-
- Comprehensive schemas for roles, channels, categories, servers
79-
- Validation helpers: `validateInput()`, `safeValidateInput()`, `formatValidationError()`
81+
**Guild Resolution**: Multi-server support via `src/services/guild.ts`:
82+
- `setCurrentGuild(id)` - Store context
83+
- `resolveGuild(client, idOrName?)` - Smart resolution with priority:
84+
1. Explicit parameter
85+
2. Current context
86+
3. Config default
87+
- Supports lookup by ID or name
88+
89+
**Error Handling**: Discord API errors mapped to user-friendly types:
90+
- `wrapDiscordError()` maps Discord API error codes to DiscordMCPError subclasses
91+
- Each error includes: code, message, recoverable flag, suggestion
92+
- Common errors: GuildNotFoundError, InsufficientPermissionsError, RateLimitError
8093

8194
## Technology Stack
8295

8396
- **Runtime**: Node.js 18+
8497
- **Language**: TypeScript (ES2022 target, ESNext modules)
8598
- **Build**: tsup (fast bundler)
8699
- **MCP SDK**: @modelcontextprotocol/sdk
100+
- **Discord API**: discord.js v14
87101
- **Validation**: Zod for runtime type validation
88-
- **Automation**: macOS AppleScript/JXA via osascript
89102

90103
## Key Constraints
91104

92-
1. **macOS Only**: AppleScript automation requires macOS
93-
2. **Desktop App Required**: Only works with Discord desktop app (not web)
94-
3. **Visual Automation**: Discord must be visible on screen during operations
95-
4. **Accessibility Permissions**: The running app needs Accessibility access in System Preferences
96-
5. **Single Server Context**: Operations work on the currently active/selected server
105+
1. **Bot Token Required**: Must have valid Discord bot token configured
106+
2. **Bot Permissions**: Requires Manage Server, Manage Roles, Manage Channels permissions
107+
3. **Server Members Intent**: Bot must have privileged SERVER MEMBERS INTENT enabled
108+
4. **Rate Limits**: Discord API has rate limits - template service includes throttling
109+
5. **Role Hierarchy**: Bot can only manage roles below its highest role
97110

98111
## Error Handling
99112

100113
Custom error classes in `src/utils/errors.ts`:
101-
- `DiscordNotRunningError` - Discord app not running
102-
- `AccessibilityDeniedError` - Missing Accessibility permissions
103-
- `UIElementNotFoundError` - Cannot find expected UI element
104-
- `TimeoutError` - Operation timed out
105-
- `DiscordStateError` - Discord in unexpected state
114+
- `BotNotReadyError` - Bot not connected to Discord
115+
- `ConfigurationError` - Missing or invalid bot token
116+
- `GuildNotFoundError` - Guild not found or bot lacks access
117+
- `GuildNotSelectedError` - No guild specified for operation
118+
- `InsufficientPermissionsError` - Bot lacks required permissions
119+
- `RateLimitError` - Discord API rate limit hit
120+
- `ChannelNotFoundError` - Channel not found
121+
- `RoleNotFoundError` - Role not found
122+
- `ValidationError` - Input validation failed
123+
- `TemplateError` - Template not found or invalid
106124

107-
## Testing
125+
All errors map Discord API codes to user-friendly messages with actionable suggestions.
108126

109-
No automated tests currently exist. Manual testing requires:
110-
1. Discord desktop app installed and logged in
111-
2. Accessibility permissions granted
112-
3. Discord visible on screen
127+
## Configuration
128+
129+
The server uses environment variables or config file for bot token:
130+
1. `DISCORD_BOT_TOKEN` environment variable (highest priority)
131+
2. `~/.discord-mcp/config.json` file
132+
133+
Config schema (Zod):
134+
```typescript
135+
{
136+
discordToken: string (required)
137+
defaultGuildId?: string
138+
rateLimit?: {
139+
maxRetries: number (default 3)
140+
retryDelay: number (default 1000ms)
141+
}
142+
}
143+
```
113144

114145
## MCP Configuration
115146

@@ -121,8 +152,177 @@ The server uses stdio transport. Configure in Claude Desktop at:
121152
"mcpServers": {
122153
"discord-setup": {
123154
"command": "node",
124-
"args": ["/path/to/discord-setup-mcp/dist/index.js"]
155+
"args": ["/path/to/discord-setup-mcp/dist/index.js"],
156+
"env": {
157+
"DISCORD_BOT_TOKEN": "your-bot-token-here",
158+
"DISCORD_DEFAULT_GUILD_ID": "optional-default-guild-id"
159+
}
125160
}
126161
}
127162
}
128163
```
164+
165+
## Tool Implementation Guidelines
166+
167+
### Creating New Tools
168+
169+
1. **Add tool to appropriate file** in `src/tools/`
170+
2. **Define Zod schema** for input validation
171+
3. **Export tool definition** (name, description, inputSchema)
172+
4. **Implement handler function** (async for Discord API calls)
173+
5. **Register tool in** `src/index.ts`
174+
175+
### Error Handling Pattern
176+
177+
```typescript
178+
export async function myToolHandler(input: MyInput): Promise<Result> {
179+
try {
180+
const client = await getDiscordClient();
181+
const guild = await resolveGuild(client, input.guildId);
182+
183+
// Perform Discord API operation
184+
const result = await guild.someOperation();
185+
186+
return {
187+
success: true,
188+
data: { ... },
189+
};
190+
} catch (error) {
191+
const mcpError = wrapDiscordError(error, 'my_tool');
192+
return {
193+
success: false,
194+
error: JSON.stringify(mcpError.toJSON()),
195+
};
196+
}
197+
}
198+
```
199+
200+
### Guild Resolution Pattern
201+
202+
All tools that operate on a guild should:
203+
1. Accept optional `guildId` parameter
204+
2. Use `resolveGuild()` with smart fallback
205+
3. Support both guild ID and name lookup
206+
207+
```typescript
208+
const guild = await resolveGuild(client, input.guildId);
209+
// Uses: input.guildId → current context → config default
210+
```
211+
212+
## Template System
213+
214+
Templates define complete server structures with roles, categories, and channels.
215+
216+
### Template Structure
217+
218+
```typescript
219+
interface ServerTemplate {
220+
id: string
221+
name: string
222+
description: string
223+
roles: TemplateRole[]
224+
categories: TemplateCategory[]
225+
}
226+
```
227+
228+
### Template Application Strategy
229+
230+
The `applyTemplate()` function uses hybrid execution:
231+
1. **Roles**: Sequential (hierarchy must be maintained)
232+
2. **Categories**: Sequential (one at a time)
233+
3. **Channels within category**: Parallel (independent)
234+
4. **Throttling**: 500ms delay between batches to avoid rate limits
235+
236+
### Adding New Templates
237+
238+
1. Create template file in `src/templates/`
239+
2. Define roles with permissions and hierarchy
240+
3. Define categories with nested channels
241+
4. Export template constant
242+
5. Register in `src/templates/index.ts`
243+
244+
## Testing
245+
246+
No automated tests currently exist. Manual testing requires:
247+
1. Discord bot created and configured
248+
2. Bot invited to test server with full permissions
249+
3. Bot token set in environment or config
250+
4. MCP server built and running
251+
252+
**Test workflow:**
253+
```bash
254+
npm run build
255+
node dist/index.js
256+
# Use Claude Desktop or other MCP client to test tools
257+
```
258+
259+
## Common Development Tasks
260+
261+
### Adding a New Tool
262+
263+
1. Create or edit file in `src/tools/`
264+
2. Define Zod schema for input
265+
3. Create tool definition object
266+
4. Implement async handler function
267+
5. Import and register in `src/index.ts`
268+
6. Build and test
269+
270+
### Modifying Error Handling
271+
272+
1. Edit `src/utils/errors.ts`
273+
2. Add new error class extending `DiscordMCPError`
274+
3. Update `wrapDiscordError()` to map Discord API codes
275+
4. Add error code to `ErrorCodes` constant
276+
277+
### Adding a Guild Operation
278+
279+
1. Add service function in `src/services/guild.ts` if needed
280+
2. Create tool in `src/tools/guild.ts`
281+
3. Use `resolveGuild()` for guild resolution
282+
4. Handle errors with `wrapDiscordError()`
283+
284+
## Dependencies
285+
286+
**Production:**
287+
- `discord.js` - Discord Bot API client
288+
- `@modelcontextprotocol/sdk` - MCP SDK
289+
- `zod` - Runtime type validation
290+
291+
**Development:**
292+
- `typescript` - TypeScript compiler
293+
- `tsup` - Fast bundler
294+
- `@types/node` - Node.js type definitions
295+
296+
## Deployment
297+
298+
The MCP server is distributed as compiled JavaScript in `dist/`.
299+
300+
**Build for production:**
301+
```bash
302+
npm run build
303+
```
304+
305+
**Run in production:**
306+
```bash
307+
node dist/index.js
308+
```
309+
310+
The server requires `DISCORD_BOT_TOKEN` to be set via environment variable or config file.
311+
312+
## Migration Notes
313+
314+
This is version 2.0.0, a complete rewrite from AppleScript-based UI automation to Discord Bot API.
315+
316+
### Breaking Changes from 1.x
317+
318+
1. **Platform**: Now cross-platform (was macOS-only)
319+
2. **Authentication**: Requires bot token (was local Discord app)
320+
3. **New tools**: `list_guilds`, `select_guild` required for multi-server workflow
321+
4. **Removed tools**: `check_discord_status`, `focus_discord`, `create_server` (bot API doesn't support server creation in same way)
322+
323+
### Preserved Patterns
324+
325+
- Tool registration pattern unchanged
326+
- Input/output JSON format unchanged
327+
- Error message structure similar
328+
- Template data structure unchanged

0 commit comments

Comments
 (0)