@mahesvara/discord-mcpserver 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -9
- package/dist/schemas/channel.d.ts +61 -0
- package/dist/schemas/channel.js +21 -2
- package/dist/schemas/community.d.ts +144 -6
- package/dist/schemas/community.js +51 -0
- package/dist/services/discord.js +13 -0
- package/dist/tools/channel.js +36 -0
- package/dist/tools/community.js +236 -4
- package/dist/types.d.ts +16 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -7,14 +7,22 @@ An MCP (Model Context Protocol) server that enables LLMs to control Discord serv
|
|
|
7
7
|
### Guild/Server Management
|
|
8
8
|
- `discord_list_guilds` - List all servers the bot has access to
|
|
9
9
|
- `discord_get_guild` - Get detailed info about a specific server
|
|
10
|
+
- `discord_edit_guild` - Edit server settings (name, verification level, system channels, etc.)
|
|
11
|
+
- `discord_leave_guild` - Leave a server
|
|
10
12
|
|
|
11
13
|
### Channel Management
|
|
12
14
|
- `discord_list_channels` - List channels in a server (filter by type)
|
|
13
|
-
- `discord_get_channel` - Get channel details
|
|
14
|
-
- `discord_create_channel` - Create text/voice channels
|
|
15
|
-
- `discord_edit_channel` - Edit channel name, topic, position, category, and more
|
|
15
|
+
- `discord_get_channel` - Get channel details (includes forum tags for forum channels)
|
|
16
|
+
- `discord_create_channel` - Create text/voice/forum channels and categories
|
|
17
|
+
- `discord_edit_channel` - Edit channel name, topic, position, category, forum tags, and more
|
|
16
18
|
- `discord_delete_channel` - Delete a channel or category
|
|
17
19
|
|
|
20
|
+
### Forum Channel Features
|
|
21
|
+
- Create forum channels with `type: "forum"`
|
|
22
|
+
- Set default reaction emoji, sort order, and layout
|
|
23
|
+
- Manage forum tags (create, edit, delete)
|
|
24
|
+
- Tags support custom emojis and moderation settings
|
|
25
|
+
|
|
18
26
|
### Permission Management
|
|
19
27
|
- `discord_set_channel_permissions` - Set permission overrides for roles/members on channels
|
|
20
28
|
- `discord_remove_channel_permissions` - Remove permission overrides
|
|
@@ -39,6 +47,8 @@ An MCP (Model Context Protocol) server that enables LLMs to control Discord serv
|
|
|
39
47
|
- `discord_ban_member` - Ban a member (with message deletion option)
|
|
40
48
|
- `discord_unban_member` - Unban a user
|
|
41
49
|
- `discord_set_nickname` - Set/clear member nickname
|
|
50
|
+
- `discord_move_member` - Move member to a different voice channel
|
|
51
|
+
- `discord_timeout_member` - Timeout/mute a member (up to 28 days)
|
|
42
52
|
|
|
43
53
|
### Role Management
|
|
44
54
|
- `discord_list_roles` - List all server roles
|
|
@@ -50,12 +60,30 @@ An MCP (Model Context Protocol) server that enables LLMs to control Discord serv
|
|
|
50
60
|
- `discord_set_role_positions` - Reorder role hierarchy
|
|
51
61
|
|
|
52
62
|
### Server Administration
|
|
53
|
-
- `discord_edit_guild` - Edit server settings (name, verification level, system channels, etc.)
|
|
54
|
-
- `discord_timeout_member` - Timeout/mute a member (up to 28 days)
|
|
55
63
|
- `discord_list_bans` - List all banned users
|
|
56
64
|
- `discord_prune_members` - Remove inactive members (with dry-run option)
|
|
57
65
|
- `discord_get_audit_log` - View audit log entries
|
|
58
66
|
|
|
67
|
+
### Community Features
|
|
68
|
+
- `discord_get_community_settings` - View community settings (rules channel, features, etc.)
|
|
69
|
+
- `discord_setup_community` - Configure community channels (rules, updates, safety alerts)
|
|
70
|
+
|
|
71
|
+
### Welcome Screen
|
|
72
|
+
- `discord_get_welcome_screen` - Get welcome screen configuration
|
|
73
|
+
- `discord_edit_welcome_screen` - Edit welcome screen (description, channels, emojis)
|
|
74
|
+
|
|
75
|
+
### Onboarding
|
|
76
|
+
- `discord_get_onboarding` - Get onboarding configuration
|
|
77
|
+
- `discord_edit_onboarding` - Edit existing onboarding settings
|
|
78
|
+
- `discord_setup_onboarding` - Setup onboarding from scratch (prompts, default channels, roles)
|
|
79
|
+
|
|
80
|
+
### Auto Moderation
|
|
81
|
+
- `discord_list_automod_rules` - List auto moderation rules
|
|
82
|
+
- `discord_get_automod_rule` - Get details of an auto mod rule
|
|
83
|
+
- `discord_create_automod_rule` - Create auto moderation rule
|
|
84
|
+
- `discord_edit_automod_rule` - Edit auto moderation rule
|
|
85
|
+
- `discord_delete_automod_rule` - Delete auto moderation rule
|
|
86
|
+
|
|
59
87
|
### Emoji Management
|
|
60
88
|
- `discord_list_emojis` - List custom emojis
|
|
61
89
|
- `discord_create_emoji` - Create emoji from image URL
|
|
@@ -95,7 +123,7 @@ An MCP (Model Context Protocol) server that enables LLMs to control Discord serv
|
|
|
95
123
|
|
|
96
124
|
### 2. Invite the Bot to Your Server
|
|
97
125
|
|
|
98
|
-
1. Go to OAuth2
|
|
126
|
+
1. Go to OAuth2 -> URL Generator
|
|
99
127
|
2. Select scopes: `bot`, `applications.commands`
|
|
100
128
|
3. Select bot permissions (choose based on features you need):
|
|
101
129
|
|
|
@@ -182,6 +210,7 @@ The server supports loading environment variables from a `.env` file in the curr
|
|
|
182
210
|
DISCORD_BOT_TOKEN=your_bot_token_here
|
|
183
211
|
TRANSPORT=http
|
|
184
212
|
PORT=3000
|
|
213
|
+
HOST=localhost
|
|
185
214
|
```
|
|
186
215
|
|
|
187
216
|
| Variable | Description | Default |
|
|
@@ -189,6 +218,7 @@ PORT=3000
|
|
|
189
218
|
| `DISCORD_BOT_TOKEN` | Your Discord bot token (required) | - |
|
|
190
219
|
| `TRANSPORT` | Transport mode: `stdio` or `http` | `stdio` |
|
|
191
220
|
| `PORT` | HTTP server port (when using http transport) | `3000` |
|
|
221
|
+
| `HOST` | HTTP server host (use `0.0.0.0` for remote access) | `localhost` |
|
|
192
222
|
|
|
193
223
|
### HTTP Transport
|
|
194
224
|
|
|
@@ -196,17 +226,17 @@ For remote access, run the server with HTTP transport enabled:
|
|
|
196
226
|
|
|
197
227
|
**Linux/macOS:**
|
|
198
228
|
```bash
|
|
199
|
-
DISCORD_BOT_TOKEN=your_token TRANSPORT=http PORT=3000 discord-mcp-server
|
|
229
|
+
DISCORD_BOT_TOKEN=your_token TRANSPORT=http PORT=3000 HOST=0.0.0.0 discord-mcp-server
|
|
200
230
|
```
|
|
201
231
|
|
|
202
232
|
**Windows (Command Prompt):**
|
|
203
233
|
```cmd
|
|
204
|
-
set DISCORD_BOT_TOKEN=your_token && set TRANSPORT=http && set PORT=3000 && discord-mcp-server
|
|
234
|
+
set DISCORD_BOT_TOKEN=your_token && set TRANSPORT=http && set PORT=3000 && set HOST=0.0.0.0 && discord-mcp-server
|
|
205
235
|
```
|
|
206
236
|
|
|
207
237
|
**Windows (PowerShell):**
|
|
208
238
|
```powershell
|
|
209
|
-
$env:DISCORD_BOT_TOKEN="your_token"; $env:TRANSPORT="http"; $env:PORT="3000"; discord-mcp-server
|
|
239
|
+
$env:DISCORD_BOT_TOKEN="your_token"; $env:TRANSPORT="http"; $env:PORT="3000"; $env:HOST="0.0.0.0"; discord-mcp-server
|
|
210
240
|
```
|
|
211
241
|
|
|
212
242
|
**Or use a `.env` file** (works on all platforms):
|
|
@@ -229,6 +259,85 @@ Then configure your MCP client to connect via HTTP:
|
|
|
229
259
|
|
|
230
260
|
## Tool Examples
|
|
231
261
|
|
|
262
|
+
### Create a Forum Channel with Tags
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"tool": "discord_create_channel",
|
|
267
|
+
"params": {
|
|
268
|
+
"guild_id": "1234567890123456789",
|
|
269
|
+
"name": "help-forum",
|
|
270
|
+
"type": "forum",
|
|
271
|
+
"topic": "Ask questions and get help",
|
|
272
|
+
"default_reaction_emoji": "✅",
|
|
273
|
+
"default_sort_order": "latest_activity",
|
|
274
|
+
"default_forum_layout": "list_view",
|
|
275
|
+
"available_tags": [
|
|
276
|
+
{ "name": "Solved", "emoji_name": "✅", "moderated": false },
|
|
277
|
+
{ "name": "Bug", "emoji_name": "🐛", "moderated": false },
|
|
278
|
+
{ "name": "Question", "emoji_name": "❓", "moderated": false },
|
|
279
|
+
{ "name": "Announcement", "emoji_name": "📢", "moderated": true }
|
|
280
|
+
]
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Setup Server Onboarding
|
|
286
|
+
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"tool": "discord_setup_onboarding",
|
|
290
|
+
"params": {
|
|
291
|
+
"guild_id": "1234567890123456789",
|
|
292
|
+
"default_channel_ids": ["1111111111111111111"],
|
|
293
|
+
"prompts": [
|
|
294
|
+
{
|
|
295
|
+
"type": "multiple_choice",
|
|
296
|
+
"title": "What are you interested in?",
|
|
297
|
+
"single_select": false,
|
|
298
|
+
"required": true,
|
|
299
|
+
"options": [
|
|
300
|
+
{ "title": "Gaming", "emoji_name": "🎮", "role_ids": ["2222222222222222222"] },
|
|
301
|
+
{ "title": "Tech", "emoji_name": "💻", "role_ids": ["3333333333333333333"] }
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Configure Community Settings
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"tool": "discord_setup_community",
|
|
314
|
+
"params": {
|
|
315
|
+
"guild_id": "1234567890123456789",
|
|
316
|
+
"rules_channel_id": "1111111111111111111",
|
|
317
|
+
"public_updates_channel_id": "2222222222222222222",
|
|
318
|
+
"description": "A friendly gaming community",
|
|
319
|
+
"preferred_locale": "en-US"
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Edit Welcome Screen
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"tool": "discord_edit_welcome_screen",
|
|
329
|
+
"params": {
|
|
330
|
+
"guild_id": "1234567890123456789",
|
|
331
|
+
"enabled": true,
|
|
332
|
+
"description": "Welcome to our server!",
|
|
333
|
+
"welcome_channels": [
|
|
334
|
+
{ "channel_id": "1111111111111111111", "description": "Read the rules", "emoji_name": "📜" },
|
|
335
|
+
{ "channel_id": "2222222222222222222", "description": "Introduce yourself", "emoji_name": "👋" }
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
232
341
|
### Create a Category
|
|
233
342
|
|
|
234
343
|
```json
|
|
@@ -361,6 +470,7 @@ Depending on which tools you use, your bot needs these permissions:
|
|
|
361
470
|
| Webhooks | Manage Webhooks |
|
|
362
471
|
| Events | Manage Events |
|
|
363
472
|
| Audit Log | View Audit Log |
|
|
473
|
+
| Community/Onboarding | Manage Guild |
|
|
364
474
|
|
|
365
475
|
## Tool Examples
|
|
366
476
|
|
|
@@ -34,6 +34,22 @@ export declare const CreateChannelSchema: z.ZodObject<{
|
|
|
34
34
|
default_reaction_emoji: z.ZodOptional<z.ZodString>;
|
|
35
35
|
default_sort_order: z.ZodOptional<z.ZodEnum<["latest_activity", "creation_date"]>>;
|
|
36
36
|
default_forum_layout: z.ZodOptional<z.ZodEnum<["not_set", "list_view", "gallery_view"]>>;
|
|
37
|
+
available_tags: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
38
|
+
name: z.ZodString;
|
|
39
|
+
moderated: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
emoji_id: z.ZodOptional<z.ZodString>;
|
|
41
|
+
emoji_name: z.ZodOptional<z.ZodString>;
|
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
name: string;
|
|
44
|
+
moderated?: boolean | undefined;
|
|
45
|
+
emoji_id?: string | undefined;
|
|
46
|
+
emoji_name?: string | undefined;
|
|
47
|
+
}, {
|
|
48
|
+
name: string;
|
|
49
|
+
moderated?: boolean | undefined;
|
|
50
|
+
emoji_id?: string | undefined;
|
|
51
|
+
emoji_name?: string | undefined;
|
|
52
|
+
}>, "many">>;
|
|
37
53
|
}, "strict", z.ZodTypeAny, {
|
|
38
54
|
name: string;
|
|
39
55
|
type: "text" | "voice" | "category" | "forum";
|
|
@@ -46,6 +62,12 @@ export declare const CreateChannelSchema: z.ZodObject<{
|
|
|
46
62
|
default_reaction_emoji?: string | undefined;
|
|
47
63
|
default_sort_order?: "latest_activity" | "creation_date" | undefined;
|
|
48
64
|
default_forum_layout?: "not_set" | "list_view" | "gallery_view" | undefined;
|
|
65
|
+
available_tags?: {
|
|
66
|
+
name: string;
|
|
67
|
+
moderated?: boolean | undefined;
|
|
68
|
+
emoji_id?: string | undefined;
|
|
69
|
+
emoji_name?: string | undefined;
|
|
70
|
+
}[] | undefined;
|
|
49
71
|
}, {
|
|
50
72
|
name: string;
|
|
51
73
|
guild_id: string;
|
|
@@ -58,6 +80,12 @@ export declare const CreateChannelSchema: z.ZodObject<{
|
|
|
58
80
|
default_reaction_emoji?: string | undefined;
|
|
59
81
|
default_sort_order?: "latest_activity" | "creation_date" | undefined;
|
|
60
82
|
default_forum_layout?: "not_set" | "list_view" | "gallery_view" | undefined;
|
|
83
|
+
available_tags?: {
|
|
84
|
+
name: string;
|
|
85
|
+
moderated?: boolean | undefined;
|
|
86
|
+
emoji_id?: string | undefined;
|
|
87
|
+
emoji_name?: string | undefined;
|
|
88
|
+
}[] | undefined;
|
|
61
89
|
}>;
|
|
62
90
|
export declare const DeleteChannelSchema: z.ZodObject<{
|
|
63
91
|
channel_id: z.ZodString;
|
|
@@ -78,6 +106,25 @@ export declare const EditChannelSchema: z.ZodObject<{
|
|
|
78
106
|
default_reaction_emoji: z.ZodOptional<z.ZodString>;
|
|
79
107
|
default_sort_order: z.ZodOptional<z.ZodEnum<["latest_activity", "creation_date"]>>;
|
|
80
108
|
default_forum_layout: z.ZodOptional<z.ZodEnum<["not_set", "list_view", "gallery_view"]>>;
|
|
109
|
+
available_tags: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
110
|
+
id: z.ZodOptional<z.ZodString>;
|
|
111
|
+
name: z.ZodString;
|
|
112
|
+
moderated: z.ZodOptional<z.ZodBoolean>;
|
|
113
|
+
emoji_id: z.ZodOptional<z.ZodString>;
|
|
114
|
+
emoji_name: z.ZodOptional<z.ZodString>;
|
|
115
|
+
}, "strip", z.ZodTypeAny, {
|
|
116
|
+
name: string;
|
|
117
|
+
moderated?: boolean | undefined;
|
|
118
|
+
emoji_id?: string | undefined;
|
|
119
|
+
emoji_name?: string | undefined;
|
|
120
|
+
id?: string | undefined;
|
|
121
|
+
}, {
|
|
122
|
+
name: string;
|
|
123
|
+
moderated?: boolean | undefined;
|
|
124
|
+
emoji_id?: string | undefined;
|
|
125
|
+
emoji_name?: string | undefined;
|
|
126
|
+
id?: string | undefined;
|
|
127
|
+
}>, "many">>;
|
|
81
128
|
}, "strict", z.ZodTypeAny, {
|
|
82
129
|
channel_id: string;
|
|
83
130
|
name?: string | undefined;
|
|
@@ -89,6 +136,13 @@ export declare const EditChannelSchema: z.ZodObject<{
|
|
|
89
136
|
default_reaction_emoji?: string | undefined;
|
|
90
137
|
default_sort_order?: "latest_activity" | "creation_date" | undefined;
|
|
91
138
|
default_forum_layout?: "not_set" | "list_view" | "gallery_view" | undefined;
|
|
139
|
+
available_tags?: {
|
|
140
|
+
name: string;
|
|
141
|
+
moderated?: boolean | undefined;
|
|
142
|
+
emoji_id?: string | undefined;
|
|
143
|
+
emoji_name?: string | undefined;
|
|
144
|
+
id?: string | undefined;
|
|
145
|
+
}[] | undefined;
|
|
92
146
|
position?: number | undefined;
|
|
93
147
|
}, {
|
|
94
148
|
channel_id: string;
|
|
@@ -101,6 +155,13 @@ export declare const EditChannelSchema: z.ZodObject<{
|
|
|
101
155
|
default_reaction_emoji?: string | undefined;
|
|
102
156
|
default_sort_order?: "latest_activity" | "creation_date" | undefined;
|
|
103
157
|
default_forum_layout?: "not_set" | "list_view" | "gallery_view" | undefined;
|
|
158
|
+
available_tags?: {
|
|
159
|
+
name: string;
|
|
160
|
+
moderated?: boolean | undefined;
|
|
161
|
+
emoji_id?: string | undefined;
|
|
162
|
+
emoji_name?: string | undefined;
|
|
163
|
+
id?: string | undefined;
|
|
164
|
+
}[] | undefined;
|
|
104
165
|
position?: number | undefined;
|
|
105
166
|
}>;
|
|
106
167
|
export declare const PermissionOverwriteSchema: z.ZodObject<{
|
package/dist/schemas/channel.js
CHANGED
|
@@ -49,7 +49,16 @@ export const CreateChannelSchema = z.object({
|
|
|
49
49
|
.describe("Default sort order for forum posts"),
|
|
50
50
|
default_forum_layout: z.enum(["not_set", "list_view", "gallery_view"])
|
|
51
51
|
.optional()
|
|
52
|
-
.describe("Default layout for forum channel")
|
|
52
|
+
.describe("Default layout for forum channel"),
|
|
53
|
+
available_tags: z.array(z.object({
|
|
54
|
+
name: z.string().max(20).describe("Tag name (max 20 chars)"),
|
|
55
|
+
moderated: z.boolean().optional().describe("Whether only moderators can apply this tag"),
|
|
56
|
+
emoji_id: z.string().optional().describe("Custom emoji ID for the tag"),
|
|
57
|
+
emoji_name: z.string().optional().describe("Unicode emoji for the tag (e.g., '🎮')")
|
|
58
|
+
}))
|
|
59
|
+
.max(20)
|
|
60
|
+
.optional()
|
|
61
|
+
.describe("Available tags for forum posts (max 20 tags)")
|
|
53
62
|
}).strict();
|
|
54
63
|
export const DeleteChannelSchema = z.object({
|
|
55
64
|
channel_id: ChannelIdSchema
|
|
@@ -95,7 +104,17 @@ export const EditChannelSchema = z.object({
|
|
|
95
104
|
.describe("Default sort order for forum posts"),
|
|
96
105
|
default_forum_layout: z.enum(["not_set", "list_view", "gallery_view"])
|
|
97
106
|
.optional()
|
|
98
|
-
.describe("Default layout for forum channel")
|
|
107
|
+
.describe("Default layout for forum channel"),
|
|
108
|
+
available_tags: z.array(z.object({
|
|
109
|
+
id: z.string().optional().describe("Tag ID (required when editing existing tags)"),
|
|
110
|
+
name: z.string().max(20).describe("Tag name (max 20 chars)"),
|
|
111
|
+
moderated: z.boolean().optional().describe("Whether only moderators can apply this tag"),
|
|
112
|
+
emoji_id: z.string().optional().describe("Custom emoji ID for the tag"),
|
|
113
|
+
emoji_name: z.string().optional().describe("Unicode emoji for the tag (e.g., '🎮')")
|
|
114
|
+
}))
|
|
115
|
+
.max(20)
|
|
116
|
+
.optional()
|
|
117
|
+
.describe("Available tags for forum posts (max 20 tags)")
|
|
99
118
|
}).strict();
|
|
100
119
|
// Permission schemas
|
|
101
120
|
export const PermissionOverwriteSchema = z.object({
|
|
@@ -80,17 +80,17 @@ export declare const EditOnboardingSchema: z.ZodObject<{
|
|
|
80
80
|
}, "strip", z.ZodTypeAny, {
|
|
81
81
|
title: string;
|
|
82
82
|
description?: string | undefined;
|
|
83
|
-
id?: string | undefined;
|
|
84
83
|
emoji_id?: string | undefined;
|
|
85
84
|
emoji_name?: string | undefined;
|
|
85
|
+
id?: string | undefined;
|
|
86
86
|
role_ids?: string[] | undefined;
|
|
87
87
|
channel_ids?: string[] | undefined;
|
|
88
88
|
}, {
|
|
89
89
|
title: string;
|
|
90
90
|
description?: string | undefined;
|
|
91
|
-
id?: string | undefined;
|
|
92
91
|
emoji_id?: string | undefined;
|
|
93
92
|
emoji_name?: string | undefined;
|
|
93
|
+
id?: string | undefined;
|
|
94
94
|
role_ids?: string[] | undefined;
|
|
95
95
|
channel_ids?: string[] | undefined;
|
|
96
96
|
}>, "many">;
|
|
@@ -99,9 +99,9 @@ export declare const EditOnboardingSchema: z.ZodObject<{
|
|
|
99
99
|
options: {
|
|
100
100
|
title: string;
|
|
101
101
|
description?: string | undefined;
|
|
102
|
-
id?: string | undefined;
|
|
103
102
|
emoji_id?: string | undefined;
|
|
104
103
|
emoji_name?: string | undefined;
|
|
104
|
+
id?: string | undefined;
|
|
105
105
|
role_ids?: string[] | undefined;
|
|
106
106
|
channel_ids?: string[] | undefined;
|
|
107
107
|
}[];
|
|
@@ -115,9 +115,9 @@ export declare const EditOnboardingSchema: z.ZodObject<{
|
|
|
115
115
|
options: {
|
|
116
116
|
title: string;
|
|
117
117
|
description?: string | undefined;
|
|
118
|
-
id?: string | undefined;
|
|
119
118
|
emoji_id?: string | undefined;
|
|
120
119
|
emoji_name?: string | undefined;
|
|
120
|
+
id?: string | undefined;
|
|
121
121
|
role_ids?: string[] | undefined;
|
|
122
122
|
channel_ids?: string[] | undefined;
|
|
123
123
|
}[];
|
|
@@ -138,9 +138,9 @@ export declare const EditOnboardingSchema: z.ZodObject<{
|
|
|
138
138
|
options: {
|
|
139
139
|
title: string;
|
|
140
140
|
description?: string | undefined;
|
|
141
|
-
id?: string | undefined;
|
|
142
141
|
emoji_id?: string | undefined;
|
|
143
142
|
emoji_name?: string | undefined;
|
|
143
|
+
id?: string | undefined;
|
|
144
144
|
role_ids?: string[] | undefined;
|
|
145
145
|
channel_ids?: string[] | undefined;
|
|
146
146
|
}[];
|
|
@@ -160,9 +160,9 @@ export declare const EditOnboardingSchema: z.ZodObject<{
|
|
|
160
160
|
options: {
|
|
161
161
|
title: string;
|
|
162
162
|
description?: string | undefined;
|
|
163
|
-
id?: string | undefined;
|
|
164
163
|
emoji_id?: string | undefined;
|
|
165
164
|
emoji_name?: string | undefined;
|
|
165
|
+
id?: string | undefined;
|
|
166
166
|
role_ids?: string[] | undefined;
|
|
167
167
|
channel_ids?: string[] | undefined;
|
|
168
168
|
}[];
|
|
@@ -175,7 +175,145 @@ export declare const EditOnboardingSchema: z.ZodObject<{
|
|
|
175
175
|
default_channel_ids?: string[] | undefined;
|
|
176
176
|
mode?: "onboarding_default" | "onboarding_advanced" | undefined;
|
|
177
177
|
}>;
|
|
178
|
+
export declare const SetupOnboardingSchema: z.ZodObject<{
|
|
179
|
+
guild_id: z.ZodString;
|
|
180
|
+
default_channel_ids: z.ZodArray<z.ZodString, "many">;
|
|
181
|
+
prompts: z.ZodArray<z.ZodObject<{
|
|
182
|
+
type: z.ZodEnum<["multiple_choice", "dropdown"]>;
|
|
183
|
+
title: z.ZodString;
|
|
184
|
+
single_select: z.ZodDefault<z.ZodBoolean>;
|
|
185
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
186
|
+
in_onboarding: z.ZodDefault<z.ZodBoolean>;
|
|
187
|
+
options: z.ZodArray<z.ZodObject<{
|
|
188
|
+
title: z.ZodString;
|
|
189
|
+
description: z.ZodOptional<z.ZodString>;
|
|
190
|
+
emoji_id: z.ZodOptional<z.ZodString>;
|
|
191
|
+
emoji_name: z.ZodOptional<z.ZodString>;
|
|
192
|
+
role_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
193
|
+
channel_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
194
|
+
}, "strip", z.ZodTypeAny, {
|
|
195
|
+
title: string;
|
|
196
|
+
description?: string | undefined;
|
|
197
|
+
emoji_id?: string | undefined;
|
|
198
|
+
emoji_name?: string | undefined;
|
|
199
|
+
role_ids?: string[] | undefined;
|
|
200
|
+
channel_ids?: string[] | undefined;
|
|
201
|
+
}, {
|
|
202
|
+
title: string;
|
|
203
|
+
description?: string | undefined;
|
|
204
|
+
emoji_id?: string | undefined;
|
|
205
|
+
emoji_name?: string | undefined;
|
|
206
|
+
role_ids?: string[] | undefined;
|
|
207
|
+
channel_ids?: string[] | undefined;
|
|
208
|
+
}>, "many">;
|
|
209
|
+
}, "strip", z.ZodTypeAny, {
|
|
210
|
+
title: string;
|
|
211
|
+
options: {
|
|
212
|
+
title: string;
|
|
213
|
+
description?: string | undefined;
|
|
214
|
+
emoji_id?: string | undefined;
|
|
215
|
+
emoji_name?: string | undefined;
|
|
216
|
+
role_ids?: string[] | undefined;
|
|
217
|
+
channel_ids?: string[] | undefined;
|
|
218
|
+
}[];
|
|
219
|
+
type: "multiple_choice" | "dropdown";
|
|
220
|
+
single_select: boolean;
|
|
221
|
+
required: boolean;
|
|
222
|
+
in_onboarding: boolean;
|
|
223
|
+
}, {
|
|
224
|
+
title: string;
|
|
225
|
+
options: {
|
|
226
|
+
title: string;
|
|
227
|
+
description?: string | undefined;
|
|
228
|
+
emoji_id?: string | undefined;
|
|
229
|
+
emoji_name?: string | undefined;
|
|
230
|
+
role_ids?: string[] | undefined;
|
|
231
|
+
channel_ids?: string[] | undefined;
|
|
232
|
+
}[];
|
|
233
|
+
type: "multiple_choice" | "dropdown";
|
|
234
|
+
single_select?: boolean | undefined;
|
|
235
|
+
required?: boolean | undefined;
|
|
236
|
+
in_onboarding?: boolean | undefined;
|
|
237
|
+
}>, "many">;
|
|
238
|
+
mode: z.ZodDefault<z.ZodEnum<["onboarding_default", "onboarding_advanced"]>>;
|
|
239
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
240
|
+
}, "strict", z.ZodTypeAny, {
|
|
241
|
+
guild_id: string;
|
|
242
|
+
enabled: boolean;
|
|
243
|
+
prompts: {
|
|
244
|
+
title: string;
|
|
245
|
+
options: {
|
|
246
|
+
title: string;
|
|
247
|
+
description?: string | undefined;
|
|
248
|
+
emoji_id?: string | undefined;
|
|
249
|
+
emoji_name?: string | undefined;
|
|
250
|
+
role_ids?: string[] | undefined;
|
|
251
|
+
channel_ids?: string[] | undefined;
|
|
252
|
+
}[];
|
|
253
|
+
type: "multiple_choice" | "dropdown";
|
|
254
|
+
single_select: boolean;
|
|
255
|
+
required: boolean;
|
|
256
|
+
in_onboarding: boolean;
|
|
257
|
+
}[];
|
|
258
|
+
default_channel_ids: string[];
|
|
259
|
+
mode: "onboarding_default" | "onboarding_advanced";
|
|
260
|
+
}, {
|
|
261
|
+
guild_id: string;
|
|
262
|
+
prompts: {
|
|
263
|
+
title: string;
|
|
264
|
+
options: {
|
|
265
|
+
title: string;
|
|
266
|
+
description?: string | undefined;
|
|
267
|
+
emoji_id?: string | undefined;
|
|
268
|
+
emoji_name?: string | undefined;
|
|
269
|
+
role_ids?: string[] | undefined;
|
|
270
|
+
channel_ids?: string[] | undefined;
|
|
271
|
+
}[];
|
|
272
|
+
type: "multiple_choice" | "dropdown";
|
|
273
|
+
single_select?: boolean | undefined;
|
|
274
|
+
required?: boolean | undefined;
|
|
275
|
+
in_onboarding?: boolean | undefined;
|
|
276
|
+
}[];
|
|
277
|
+
default_channel_ids: string[];
|
|
278
|
+
enabled?: boolean | undefined;
|
|
279
|
+
mode?: "onboarding_default" | "onboarding_advanced" | undefined;
|
|
280
|
+
}>;
|
|
281
|
+
export declare const SetupCommunitySchema: z.ZodObject<{
|
|
282
|
+
guild_id: z.ZodString;
|
|
283
|
+
rules_channel_id: z.ZodString;
|
|
284
|
+
public_updates_channel_id: z.ZodString;
|
|
285
|
+
description: z.ZodOptional<z.ZodString>;
|
|
286
|
+
preferred_locale: z.ZodOptional<z.ZodString>;
|
|
287
|
+
safety_alerts_channel_id: z.ZodOptional<z.ZodString>;
|
|
288
|
+
}, "strict", z.ZodTypeAny, {
|
|
289
|
+
guild_id: string;
|
|
290
|
+
rules_channel_id: string;
|
|
291
|
+
public_updates_channel_id: string;
|
|
292
|
+
description?: string | undefined;
|
|
293
|
+
preferred_locale?: string | undefined;
|
|
294
|
+
safety_alerts_channel_id?: string | undefined;
|
|
295
|
+
}, {
|
|
296
|
+
guild_id: string;
|
|
297
|
+
rules_channel_id: string;
|
|
298
|
+
public_updates_channel_id: string;
|
|
299
|
+
description?: string | undefined;
|
|
300
|
+
preferred_locale?: string | undefined;
|
|
301
|
+
safety_alerts_channel_id?: string | undefined;
|
|
302
|
+
}>;
|
|
303
|
+
export declare const GetCommunitySettingsSchema: z.ZodObject<{
|
|
304
|
+
guild_id: z.ZodString;
|
|
305
|
+
response_format: z.ZodDefault<z.ZodNativeEnum<typeof import("../types.js").ResponseFormat>>;
|
|
306
|
+
}, "strict", z.ZodTypeAny, {
|
|
307
|
+
response_format: import("../types.js").ResponseFormat;
|
|
308
|
+
guild_id: string;
|
|
309
|
+
}, {
|
|
310
|
+
guild_id: string;
|
|
311
|
+
response_format?: import("../types.js").ResponseFormat | undefined;
|
|
312
|
+
}>;
|
|
178
313
|
export type GetWelcomeScreenInput = z.infer<typeof GetWelcomeScreenSchema>;
|
|
179
314
|
export type EditWelcomeScreenInput = z.infer<typeof EditWelcomeScreenSchema>;
|
|
180
315
|
export type GetOnboardingInput = z.infer<typeof GetOnboardingSchema>;
|
|
181
316
|
export type EditOnboardingInput = z.infer<typeof EditOnboardingSchema>;
|
|
317
|
+
export type SetupOnboardingInput = z.infer<typeof SetupOnboardingSchema>;
|
|
318
|
+
export type SetupCommunityInput = z.infer<typeof SetupCommunitySchema>;
|
|
319
|
+
export type GetCommunitySettingsInput = z.infer<typeof GetCommunitySettingsSchema>;
|
|
@@ -58,3 +58,54 @@ export const EditOnboardingSchema = z.object({
|
|
|
58
58
|
.optional()
|
|
59
59
|
.describe("Onboarding mode")
|
|
60
60
|
}).strict();
|
|
61
|
+
// Setup Onboarding schema - for initial configuration
|
|
62
|
+
export const SetupOnboardingSchema = z.object({
|
|
63
|
+
guild_id: GuildIdSchema,
|
|
64
|
+
default_channel_ids: z.array(ChannelIdSchema)
|
|
65
|
+
.min(1)
|
|
66
|
+
.describe("Channels shown to new members by default (at least one required)"),
|
|
67
|
+
prompts: z.array(z.object({
|
|
68
|
+
type: z.enum(["multiple_choice", "dropdown"]).describe("Prompt type"),
|
|
69
|
+
title: z.string().max(100).describe("Prompt title"),
|
|
70
|
+
single_select: z.boolean().default(true).describe("Whether only one option can be selected"),
|
|
71
|
+
required: z.boolean().default(false).describe("Whether this prompt is required"),
|
|
72
|
+
in_onboarding: z.boolean().default(true).describe("Whether shown during onboarding"),
|
|
73
|
+
options: z.array(z.object({
|
|
74
|
+
title: z.string().max(50).describe("Option title"),
|
|
75
|
+
description: z.string().max(100).optional().describe("Option description"),
|
|
76
|
+
emoji_id: z.string().optional().describe("Custom emoji ID"),
|
|
77
|
+
emoji_name: z.string().optional().describe("Unicode emoji or custom emoji name"),
|
|
78
|
+
role_ids: z.array(RoleIdSchema).optional().describe("Roles to assign when selected (at least one role OR channel required)"),
|
|
79
|
+
channel_ids: z.array(ChannelIdSchema).optional().describe("Channels to show when selected (at least one role OR channel required)")
|
|
80
|
+
})).min(1).describe("Available options for this prompt")
|
|
81
|
+
})).min(1).describe("Onboarding prompts/questions (at least one required)"),
|
|
82
|
+
mode: z.enum(["onboarding_default", "onboarding_advanced"])
|
|
83
|
+
.default("onboarding_default")
|
|
84
|
+
.describe("Onboarding mode"),
|
|
85
|
+
enabled: z.boolean()
|
|
86
|
+
.default(true)
|
|
87
|
+
.describe("Whether to enable onboarding after setup")
|
|
88
|
+
}).strict();
|
|
89
|
+
// Setup Community schema
|
|
90
|
+
export const SetupCommunitySchema = z.object({
|
|
91
|
+
guild_id: GuildIdSchema,
|
|
92
|
+
rules_channel_id: ChannelIdSchema
|
|
93
|
+
.describe("Channel for server rules (required for Community)"),
|
|
94
|
+
public_updates_channel_id: ChannelIdSchema
|
|
95
|
+
.describe("Channel for Discord community updates (required for Community)"),
|
|
96
|
+
description: z.string()
|
|
97
|
+
.max(120)
|
|
98
|
+
.optional()
|
|
99
|
+
.describe("Server description (max 120 chars)"),
|
|
100
|
+
preferred_locale: z.string()
|
|
101
|
+
.optional()
|
|
102
|
+
.describe("Preferred language (e.g., 'en-US', 'de', 'fr')"),
|
|
103
|
+
safety_alerts_channel_id: ChannelIdSchema
|
|
104
|
+
.optional()
|
|
105
|
+
.describe("Channel for safety alerts from Discord")
|
|
106
|
+
}).strict();
|
|
107
|
+
// Get Community Settings schema
|
|
108
|
+
export const GetCommunitySettingsSchema = z.object({
|
|
109
|
+
guild_id: GuildIdSchema,
|
|
110
|
+
response_format: ResponseFormatSchema
|
|
111
|
+
}).strict();
|
package/dist/services/discord.js
CHANGED
|
@@ -74,6 +74,19 @@ export function formatChannel(channel) {
|
|
|
74
74
|
if (channel.type === ChannelType.GuildText && 'topic' in channel) {
|
|
75
75
|
baseChannel.topic = channel.topic ?? undefined;
|
|
76
76
|
}
|
|
77
|
+
// Forum channel specific fields
|
|
78
|
+
if (channel.type === ChannelType.GuildForum && 'availableTags' in channel) {
|
|
79
|
+
const forumChannel = channel;
|
|
80
|
+
baseChannel.availableTags = forumChannel.availableTags?.map((tag) => ({
|
|
81
|
+
id: tag.id,
|
|
82
|
+
name: tag.name,
|
|
83
|
+
moderated: tag.moderated,
|
|
84
|
+
emoji: tag.emoji ? { id: tag.emoji.id, name: tag.emoji.name } : null,
|
|
85
|
+
}));
|
|
86
|
+
baseChannel.defaultReactionEmoji = forumChannel.defaultReactionEmoji;
|
|
87
|
+
baseChannel.defaultSortOrder = forumChannel.defaultSortOrder;
|
|
88
|
+
baseChannel.defaultForumLayout = forumChannel.defaultForumLayout;
|
|
89
|
+
}
|
|
77
90
|
return baseChannel;
|
|
78
91
|
}
|
|
79
92
|
/**
|
package/dist/tools/channel.js
CHANGED
|
@@ -131,6 +131,11 @@ Args:
|
|
|
131
131
|
- default_reaction_emoji (string, optional): Default emoji for forum posts (emoji char or custom ID)
|
|
132
132
|
- default_sort_order ('latest_activity' | 'creation_date', optional): Sort order for forum posts
|
|
133
133
|
- default_forum_layout ('not_set' | 'list_view' | 'gallery_view', optional): Forum layout
|
|
134
|
+
- available_tags (array, optional): Tags for forum posts (max 20)
|
|
135
|
+
- name (string): Tag name (max 20 chars)
|
|
136
|
+
- moderated (boolean, optional): Only mods can apply this tag
|
|
137
|
+
- emoji_name (string, optional): Unicode emoji (e.g., '🎮')
|
|
138
|
+
- emoji_id (string, optional): Custom emoji ID
|
|
134
139
|
|
|
135
140
|
Returns:
|
|
136
141
|
The created channel's details`,
|
|
@@ -214,6 +219,17 @@ Returns:
|
|
|
214
219
|
};
|
|
215
220
|
channelOptions.defaultForumLayout = layoutMap[params.default_forum_layout];
|
|
216
221
|
}
|
|
222
|
+
if (params.available_tags && params.available_tags.length > 0) {
|
|
223
|
+
channelOptions.availableTags = params.available_tags.map(tag => ({
|
|
224
|
+
name: tag.name,
|
|
225
|
+
moderated: tag.moderated ?? false,
|
|
226
|
+
emoji: tag.emoji_id
|
|
227
|
+
? { id: tag.emoji_id, name: tag.emoji_name }
|
|
228
|
+
: tag.emoji_name
|
|
229
|
+
? { id: null, name: tag.emoji_name }
|
|
230
|
+
: undefined,
|
|
231
|
+
}));
|
|
232
|
+
}
|
|
217
233
|
}
|
|
218
234
|
const channel = await guild.channels.create(channelOptions);
|
|
219
235
|
const typeLabel = params.type === "category" ? "category" : "channel";
|
|
@@ -284,6 +300,14 @@ Args:
|
|
|
284
300
|
- default_reaction_emoji (string, optional): Default emoji for forum posts (emoji char or custom ID, 'none' to remove)
|
|
285
301
|
- default_sort_order ('latest_activity' | 'creation_date', optional): Sort order for forum posts
|
|
286
302
|
- default_forum_layout ('not_set' | 'list_view' | 'gallery_view', optional): Forum layout
|
|
303
|
+
- available_tags (array, optional): Tags for forum posts (max 20)
|
|
304
|
+
WARNING: This REPLACES all existing tags! To keep existing tags, first use discord_get_channel
|
|
305
|
+
to get current tags with their IDs, then include them in this array with their id field.
|
|
306
|
+
- id (string): Tag ID - REQUIRED to preserve existing tags, omit only for new tags
|
|
307
|
+
- name (string): Tag name (max 20 chars)
|
|
308
|
+
- moderated (boolean, optional): Only mods can apply this tag
|
|
309
|
+
- emoji_name (string, optional): Unicode emoji (e.g., '🎮')
|
|
310
|
+
- emoji_id (string, optional): Custom emoji ID
|
|
287
311
|
|
|
288
312
|
Returns:
|
|
289
313
|
Updated channel details`,
|
|
@@ -346,6 +370,18 @@ Returns:
|
|
|
346
370
|
};
|
|
347
371
|
updates.defaultForumLayout = layoutMap[params.default_forum_layout];
|
|
348
372
|
}
|
|
373
|
+
if (params.available_tags !== undefined) {
|
|
374
|
+
updates.availableTags = params.available_tags.map(tag => ({
|
|
375
|
+
id: tag.id,
|
|
376
|
+
name: tag.name,
|
|
377
|
+
moderated: tag.moderated ?? false,
|
|
378
|
+
emoji: tag.emoji_id
|
|
379
|
+
? { id: tag.emoji_id, name: tag.emoji_name }
|
|
380
|
+
: tag.emoji_name
|
|
381
|
+
? { id: null, name: tag.emoji_name }
|
|
382
|
+
: undefined,
|
|
383
|
+
}));
|
|
384
|
+
}
|
|
349
385
|
await channel.edit(updates);
|
|
350
386
|
return {
|
|
351
387
|
content: [{ type: "text", text: `Updated channel ${params.channel_id}` }],
|
package/dist/tools/community.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GetWelcomeScreenSchema, EditWelcomeScreenSchema, GetOnboardingSchema, EditOnboardingSchema, } from "../schemas/index.js";
|
|
1
|
+
import { GetWelcomeScreenSchema, EditWelcomeScreenSchema, GetOnboardingSchema, EditOnboardingSchema, SetupOnboardingSchema, SetupCommunitySchema, GetCommunitySettingsSchema, } from "../schemas/index.js";
|
|
2
2
|
import { getClient, formatResponse, } from "../services/discord.js";
|
|
3
3
|
export function registerCommunityTools(server) {
|
|
4
4
|
// ============================================================================
|
|
@@ -240,15 +240,15 @@ Returns:
|
|
|
240
240
|
const hasRoles = o.role_ids && o.role_ids.length > 0;
|
|
241
241
|
const hasChannels = o.channel_ids && o.channel_ids.length > 0;
|
|
242
242
|
if (!hasRoles && !hasChannels) {
|
|
243
|
-
throw new Error(`Option "${o.title}" must have at least one role_ids or channel_ids`);
|
|
243
|
+
throw new Error(`Option "${o.title}" must have at least one role_ids or channel_ids. Received: role_ids=${JSON.stringify(o.role_ids)}, channel_ids=${JSON.stringify(o.channel_ids)}`);
|
|
244
244
|
}
|
|
245
245
|
return {
|
|
246
246
|
id: o.id,
|
|
247
247
|
title: o.title,
|
|
248
248
|
description: o.description,
|
|
249
249
|
emoji: o.emoji_id ? { id: o.emoji_id, name: o.emoji_name } : o.emoji_name || undefined,
|
|
250
|
-
|
|
251
|
-
|
|
250
|
+
roles: o.role_ids || [],
|
|
251
|
+
channels: o.channel_ids || [],
|
|
252
252
|
};
|
|
253
253
|
}),
|
|
254
254
|
}));
|
|
@@ -265,4 +265,236 @@ Returns:
|
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
});
|
|
268
|
+
server.registerTool("discord_setup_onboarding", {
|
|
269
|
+
title: "Setup Server Onboarding",
|
|
270
|
+
description: `Setup and enable onboarding for a server from scratch.
|
|
271
|
+
|
|
272
|
+
This tool configures the complete onboarding experience for new members.
|
|
273
|
+
The server must have Community features enabled.
|
|
274
|
+
|
|
275
|
+
Requirements:
|
|
276
|
+
- Server must have Community features enabled (done in Discord Server Settings)
|
|
277
|
+
- At least one default channel must be specified
|
|
278
|
+
- At least one prompt with options must be provided
|
|
279
|
+
- Each option must have at least one role_ids OR channel_ids
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
- guild_id (string): Discord server/guild ID
|
|
283
|
+
- default_channel_ids (string[]): Channels shown to all new members (required, at least one)
|
|
284
|
+
- prompts (array): Onboarding questions (required, at least one)
|
|
285
|
+
- type ('multiple_choice' | 'dropdown'): Prompt type
|
|
286
|
+
- title (string): Question title
|
|
287
|
+
- single_select (boolean): Allow only one selection (default: true)
|
|
288
|
+
- required (boolean): Must answer to continue (default: false)
|
|
289
|
+
- in_onboarding (boolean): Show during onboarding (default: true)
|
|
290
|
+
- options (array): Available choices (at least one)
|
|
291
|
+
- title (string): Option title
|
|
292
|
+
- description (string, optional): Option description
|
|
293
|
+
- emoji_name (string, optional): Unicode emoji (e.g., '🎮')
|
|
294
|
+
- role_ids (string[], optional): Roles to assign when selected
|
|
295
|
+
- channel_ids (string[], optional): Channels to show when selected
|
|
296
|
+
- mode ('onboarding_default' | 'onboarding_advanced', optional): Mode (default: 'onboarding_default')
|
|
297
|
+
- enabled (boolean, optional): Enable after setup (default: true)
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
Confirmation with onboarding status`,
|
|
301
|
+
inputSchema: SetupOnboardingSchema,
|
|
302
|
+
annotations: {
|
|
303
|
+
readOnlyHint: false,
|
|
304
|
+
destructiveHint: false,
|
|
305
|
+
idempotentHint: false,
|
|
306
|
+
openWorldHint: true,
|
|
307
|
+
},
|
|
308
|
+
}, async (params) => {
|
|
309
|
+
try {
|
|
310
|
+
const client = await getClient();
|
|
311
|
+
const guild = client.guilds.cache.get(params.guild_id);
|
|
312
|
+
if (!guild) {
|
|
313
|
+
return {
|
|
314
|
+
isError: true,
|
|
315
|
+
content: [{ type: "text", text: `Guild not found: ${params.guild_id}` }],
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
// Check if community features are enabled
|
|
319
|
+
if (!guild.features.includes('COMMUNITY')) {
|
|
320
|
+
return {
|
|
321
|
+
isError: true,
|
|
322
|
+
content: [{ type: "text", text: `Server "${guild.name}" does not have Community features enabled. Please enable Community in Discord Server Settings > Enable Community first.` }],
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
const promptTypeMap = { multiple_choice: 0, dropdown: 1 };
|
|
326
|
+
const modeMap = { onboarding_default: 0, onboarding_advanced: 1 };
|
|
327
|
+
// Build the onboarding data
|
|
328
|
+
const onboardingData = {
|
|
329
|
+
enabled: params.enabled ?? true,
|
|
330
|
+
defaultChannelIds: params.default_channel_ids,
|
|
331
|
+
mode: modeMap[params.mode || 'onboarding_default'],
|
|
332
|
+
prompts: params.prompts.map(p => ({
|
|
333
|
+
type: promptTypeMap[p.type],
|
|
334
|
+
title: p.title,
|
|
335
|
+
singleSelect: p.single_select ?? true,
|
|
336
|
+
required: p.required ?? false,
|
|
337
|
+
inOnboarding: p.in_onboarding ?? true,
|
|
338
|
+
options: p.options.map(o => {
|
|
339
|
+
// Validate that each option has at least one role or channel
|
|
340
|
+
const hasRoles = o.role_ids && o.role_ids.length > 0;
|
|
341
|
+
const hasChannels = o.channel_ids && o.channel_ids.length > 0;
|
|
342
|
+
if (!hasRoles && !hasChannels) {
|
|
343
|
+
throw new Error(`Option "${o.title}" must have at least one role_ids or channel_ids`);
|
|
344
|
+
}
|
|
345
|
+
return {
|
|
346
|
+
title: o.title,
|
|
347
|
+
description: o.description,
|
|
348
|
+
emoji: o.emoji_id ? { id: o.emoji_id, name: o.emoji_name } : o.emoji_name || undefined,
|
|
349
|
+
roles: o.role_ids || [],
|
|
350
|
+
channels: o.channel_ids || [],
|
|
351
|
+
};
|
|
352
|
+
}),
|
|
353
|
+
})),
|
|
354
|
+
};
|
|
355
|
+
const onboarding = await guild.editOnboarding(onboardingData);
|
|
356
|
+
return {
|
|
357
|
+
content: [{ type: "text", text: `Onboarding setup complete for "${guild.name}"!\nEnabled: ${onboarding.enabled}\nMode: ${params.mode || 'onboarding_default'}\nDefault Channels: ${params.default_channel_ids.length}\nPrompts: ${onboarding.prompts.size}` }],
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
return {
|
|
362
|
+
isError: true,
|
|
363
|
+
content: [{ type: "text", text: `Error setting up onboarding: ${error.message}` }],
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
// ============================================================================
|
|
368
|
+
// COMMUNITY SETUP TOOLS
|
|
369
|
+
// ============================================================================
|
|
370
|
+
server.registerTool("discord_get_community_settings", {
|
|
371
|
+
title: "Get Community Settings",
|
|
372
|
+
description: `Get the community settings for a server.
|
|
373
|
+
|
|
374
|
+
Shows rules channel, updates channel, and other community-related settings.
|
|
375
|
+
|
|
376
|
+
Args:
|
|
377
|
+
- guild_id (string): Discord server/guild ID
|
|
378
|
+
- response_format ('markdown' | 'json'): Output format (default: 'json')
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
Community settings including channels and features`,
|
|
382
|
+
inputSchema: GetCommunitySettingsSchema,
|
|
383
|
+
annotations: {
|
|
384
|
+
readOnlyHint: true,
|
|
385
|
+
destructiveHint: false,
|
|
386
|
+
idempotentHint: true,
|
|
387
|
+
openWorldHint: true,
|
|
388
|
+
},
|
|
389
|
+
}, async (params) => {
|
|
390
|
+
try {
|
|
391
|
+
const client = await getClient();
|
|
392
|
+
const guild = client.guilds.cache.get(params.guild_id);
|
|
393
|
+
if (!guild) {
|
|
394
|
+
return {
|
|
395
|
+
isError: true,
|
|
396
|
+
content: [{ type: "text", text: `Guild not found: ${params.guild_id}` }],
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
const isCommunity = guild.features.includes('COMMUNITY');
|
|
400
|
+
const settings = {
|
|
401
|
+
isCommunity,
|
|
402
|
+
features: guild.features,
|
|
403
|
+
rulesChannelId: guild.rulesChannelId,
|
|
404
|
+
publicUpdatesChannelId: guild.publicUpdatesChannelId,
|
|
405
|
+
safetyAlertsChannelId: guild.safetyAlertsChannelId,
|
|
406
|
+
systemChannelId: guild.systemChannelId,
|
|
407
|
+
description: guild.description,
|
|
408
|
+
preferredLocale: guild.preferredLocale,
|
|
409
|
+
premiumTier: guild.premiumTier,
|
|
410
|
+
premiumSubscriptionCount: guild.premiumSubscriptionCount,
|
|
411
|
+
vanityURLCode: guild.vanityURLCode,
|
|
412
|
+
};
|
|
413
|
+
const text = formatResponse(settings, params.response_format, (data) => {
|
|
414
|
+
let output = `**Community Settings for ${guild.name}**\n`;
|
|
415
|
+
output += `Community Enabled: ${data.isCommunity ? 'Yes' : 'No'}\n\n`;
|
|
416
|
+
output += `**Channels:**\n`;
|
|
417
|
+
output += `- Rules: ${data.rulesChannelId ? `<#${data.rulesChannelId}>` : 'Not set'}\n`;
|
|
418
|
+
output += `- Public Updates: ${data.publicUpdatesChannelId ? `<#${data.publicUpdatesChannelId}>` : 'Not set'}\n`;
|
|
419
|
+
output += `- Safety Alerts: ${data.safetyAlertsChannelId ? `<#${data.safetyAlertsChannelId}>` : 'Not set'}\n`;
|
|
420
|
+
output += `- System: ${data.systemChannelId ? `<#${data.systemChannelId}>` : 'Not set'}\n\n`;
|
|
421
|
+
output += `**Server Info:**\n`;
|
|
422
|
+
output += `- Description: ${data.description || 'None'}\n`;
|
|
423
|
+
output += `- Locale: ${data.preferredLocale}\n`;
|
|
424
|
+
output += `- Boost Level: ${data.premiumTier} (${data.premiumSubscriptionCount} boosts)\n`;
|
|
425
|
+
output += `- Vanity URL: ${data.vanityURLCode || 'None'}\n\n`;
|
|
426
|
+
output += `**Features:** ${data.features.join(', ')}`;
|
|
427
|
+
return output;
|
|
428
|
+
});
|
|
429
|
+
return {
|
|
430
|
+
content: [{ type: "text", text }],
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
catch (error) {
|
|
434
|
+
return {
|
|
435
|
+
isError: true,
|
|
436
|
+
content: [{ type: "text", text: `Error getting community settings: ${error.message}` }],
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
server.registerTool("discord_setup_community", {
|
|
441
|
+
title: "Setup Community Server",
|
|
442
|
+
description: `Configure the required channels for a Community server.
|
|
443
|
+
|
|
444
|
+
Sets the rules channel and public updates channel which are required for Community features.
|
|
445
|
+
The server must already have Community enabled in Discord Server Settings.
|
|
446
|
+
|
|
447
|
+
Args:
|
|
448
|
+
- guild_id (string): Discord server/guild ID
|
|
449
|
+
- rules_channel_id (string): Channel for server rules (required)
|
|
450
|
+
- public_updates_channel_id (string): Channel for Discord updates (required)
|
|
451
|
+
- description (string, optional): Server description (max 120 chars)
|
|
452
|
+
- preferred_locale (string, optional): Preferred language (e.g., 'en-US', 'de')
|
|
453
|
+
- safety_alerts_channel_id (string, optional): Channel for safety alerts
|
|
454
|
+
|
|
455
|
+
Returns:
|
|
456
|
+
Updated community settings`,
|
|
457
|
+
inputSchema: SetupCommunitySchema,
|
|
458
|
+
annotations: {
|
|
459
|
+
readOnlyHint: false,
|
|
460
|
+
destructiveHint: false,
|
|
461
|
+
idempotentHint: true,
|
|
462
|
+
openWorldHint: true,
|
|
463
|
+
},
|
|
464
|
+
}, async (params) => {
|
|
465
|
+
try {
|
|
466
|
+
const client = await getClient();
|
|
467
|
+
const guild = client.guilds.cache.get(params.guild_id);
|
|
468
|
+
if (!guild) {
|
|
469
|
+
return {
|
|
470
|
+
isError: true,
|
|
471
|
+
content: [{ type: "text", text: `Guild not found: ${params.guild_id}` }],
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
const updateData = {
|
|
475
|
+
rulesChannel: params.rules_channel_id,
|
|
476
|
+
publicUpdatesChannel: params.public_updates_channel_id,
|
|
477
|
+
};
|
|
478
|
+
if (params.description !== undefined) {
|
|
479
|
+
updateData.description = params.description;
|
|
480
|
+
}
|
|
481
|
+
if (params.preferred_locale !== undefined) {
|
|
482
|
+
updateData.preferredLocale = params.preferred_locale;
|
|
483
|
+
}
|
|
484
|
+
if (params.safety_alerts_channel_id !== undefined) {
|
|
485
|
+
updateData.safetyAlertsChannel = params.safety_alerts_channel_id;
|
|
486
|
+
}
|
|
487
|
+
const updated = await guild.edit(updateData);
|
|
488
|
+
const isCommunity = updated.features.includes('COMMUNITY');
|
|
489
|
+
return {
|
|
490
|
+
content: [{ type: "text", text: `Community settings updated for "${updated.name}"!\nCommunity Enabled: ${isCommunity ? 'Yes' : 'No'}\nRules Channel: <#${params.rules_channel_id}>\nPublic Updates: <#${params.public_updates_channel_id}>${params.description ? `\nDescription: ${params.description}` : ''}` }],
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
catch (error) {
|
|
494
|
+
return {
|
|
495
|
+
isError: true,
|
|
496
|
+
content: [{ type: "text", text: `Error setting up community: ${error.message}` }],
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
});
|
|
268
500
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
export interface ForumTag {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
moderated: boolean;
|
|
5
|
+
emoji: {
|
|
6
|
+
id: string | null;
|
|
7
|
+
name: string | null;
|
|
8
|
+
} | null;
|
|
9
|
+
}
|
|
1
10
|
export interface DiscordChannel {
|
|
2
11
|
id: string;
|
|
3
12
|
name: string;
|
|
@@ -6,6 +15,13 @@ export interface DiscordChannel {
|
|
|
6
15
|
position?: number;
|
|
7
16
|
parentId?: string;
|
|
8
17
|
parentName?: string;
|
|
18
|
+
availableTags?: ForumTag[];
|
|
19
|
+
defaultReactionEmoji?: {
|
|
20
|
+
id: string | null;
|
|
21
|
+
name: string | null;
|
|
22
|
+
} | null;
|
|
23
|
+
defaultSortOrder?: number | null;
|
|
24
|
+
defaultForumLayout?: number | null;
|
|
9
25
|
}
|
|
10
26
|
export interface DiscordGuild {
|
|
11
27
|
id: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mahesvara/discord-mcpserver",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "MCP server for controlling Discord servers via bot token",
|
|
5
5
|
"author": "Mahesvara",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"main": "dist/index.js",
|
|
29
29
|
"bin": {
|
|
30
|
-
"discord-
|
|
30
|
+
"discord-mcpserver": "dist/index.js"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|