@mahesvara/discord-mcpserver 1.0.7 → 1.0.9

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.
Files changed (54) hide show
  1. package/dist/index.js +7 -2835
  2. package/dist/schemas/channel.d.ts +158 -0
  3. package/dist/schemas/channel.js +128 -0
  4. package/dist/schemas/common.d.ts +23 -0
  5. package/dist/schemas/common.js +71 -0
  6. package/dist/schemas/community.d.ts +181 -0
  7. package/dist/schemas/community.js +60 -0
  8. package/dist/schemas/emoji.d.ts +59 -0
  9. package/dist/schemas/emoji.js +29 -0
  10. package/dist/schemas/event.d.ts +62 -0
  11. package/dist/schemas/event.js +33 -0
  12. package/dist/schemas/guild.d.ts +85 -0
  13. package/dist/schemas/guild.js +42 -0
  14. package/dist/schemas/index.d.ts +12 -855
  15. package/dist/schemas/index.js +13 -617
  16. package/dist/schemas/invite.d.ts +40 -0
  17. package/dist/schemas/invite.js +32 -0
  18. package/dist/schemas/member.d.ts +60 -0
  19. package/dist/schemas/member.js +33 -0
  20. package/dist/schemas/message.d.ts +121 -0
  21. package/dist/schemas/message.js +61 -0
  22. package/dist/schemas/moderation.d.ts +343 -0
  23. package/dist/schemas/moderation.js +152 -0
  24. package/dist/schemas/role.d.ts +126 -0
  25. package/dist/schemas/role.js +73 -0
  26. package/dist/schemas/webhook.d.ts +51 -0
  27. package/dist/schemas/webhook.js +33 -0
  28. package/dist/server.d.ts +2 -0
  29. package/dist/server.js +6 -0
  30. package/dist/tools/channel.d.ts +2 -0
  31. package/dist/tools/channel.js +510 -0
  32. package/dist/tools/community.d.ts +2 -0
  33. package/dist/tools/community.js +259 -0
  34. package/dist/tools/emoji.d.ts +2 -0
  35. package/dist/tools/emoji.js +247 -0
  36. package/dist/tools/event.d.ts +2 -0
  37. package/dist/tools/event.js +170 -0
  38. package/dist/tools/guild.d.ts +2 -0
  39. package/dist/tools/guild.js +198 -0
  40. package/dist/tools/index.d.ts +2 -0
  41. package/dist/tools/index.js +24 -0
  42. package/dist/tools/invite.d.ts +2 -0
  43. package/dist/tools/invite.js +143 -0
  44. package/dist/tools/member.d.ts +2 -0
  45. package/dist/tools/member.js +200 -0
  46. package/dist/tools/message.d.ts +2 -0
  47. package/dist/tools/message.js +386 -0
  48. package/dist/tools/moderation.d.ts +2 -0
  49. package/dist/tools/moderation.js +641 -0
  50. package/dist/tools/role.d.ts +2 -0
  51. package/dist/tools/role.js +420 -0
  52. package/dist/tools/webhook.d.ts +2 -0
  53. package/dist/tools/webhook.js +199 -0
  54. package/package.json +1 -1
@@ -0,0 +1,386 @@
1
+ import { SendMessageSchema, GetMessagesSchema, DeleteMessageSchema, EditMessageSchema, AddReactionSchema, RemoveReactionSchema, PinMessageSchema, UnpinMessageSchema, GetPinnedMessagesSchema, } from "../schemas/index.js";
2
+ import { getClient, formatMessage, messageToMarkdown, formatResponse, truncateIfNeeded, } from "../services/discord.js";
3
+ export function registerMessageTools(server) {
4
+ server.registerTool("discord_send_message", {
5
+ title: "Send Discord Message",
6
+ description: `Send a message to a Discord channel.
7
+
8
+ Args:
9
+ - channel_id (string): Discord channel ID
10
+ - content (string): Message content (max 2000 characters)
11
+ - reply_to (string, optional): Message ID to reply to
12
+
13
+ Returns:
14
+ The sent message details including ID`,
15
+ inputSchema: SendMessageSchema,
16
+ annotations: {
17
+ readOnlyHint: false,
18
+ destructiveHint: false,
19
+ idempotentHint: false,
20
+ openWorldHint: true,
21
+ },
22
+ }, async (params) => {
23
+ try {
24
+ const client = await getClient();
25
+ const channel = client.channels.cache.get(params.channel_id);
26
+ if (!channel || !('send' in channel)) {
27
+ return {
28
+ isError: true,
29
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
30
+ };
31
+ }
32
+ const options = { content: params.content };
33
+ if (params.reply_to) {
34
+ options.reply = { messageReference: params.reply_to };
35
+ }
36
+ const message = await channel.send(options);
37
+ return {
38
+ content: [{ type: "text", text: `Message sent (ID: ${message.id})` }],
39
+ };
40
+ }
41
+ catch (error) {
42
+ return {
43
+ isError: true,
44
+ content: [{ type: "text", text: `Error sending message: ${error.message}` }],
45
+ };
46
+ }
47
+ });
48
+ server.registerTool("discord_get_messages", {
49
+ title: "Get Discord Messages",
50
+ description: `Retrieve messages from a Discord channel.
51
+
52
+ Args:
53
+ - channel_id (string): Discord channel ID
54
+ - limit (number): Number of messages to retrieve (1-100, default: 20)
55
+ - before (string, optional): Get messages before this message ID
56
+ - after (string, optional): Get messages after this message ID
57
+ - response_format ('markdown' | 'json'): Output format (default: 'json')
58
+
59
+ Returns:
60
+ List of messages with content, author, timestamp, attachments`,
61
+ inputSchema: GetMessagesSchema,
62
+ annotations: {
63
+ readOnlyHint: true,
64
+ destructiveHint: false,
65
+ idempotentHint: true,
66
+ openWorldHint: true,
67
+ },
68
+ }, async (params) => {
69
+ try {
70
+ const client = await getClient();
71
+ const channel = client.channels.cache.get(params.channel_id);
72
+ if (!channel || !('messages' in channel)) {
73
+ return {
74
+ isError: true,
75
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
76
+ };
77
+ }
78
+ const options = { limit: params.limit };
79
+ if (params.before)
80
+ options.before = params.before;
81
+ if (params.after)
82
+ options.after = params.after;
83
+ const messages = await channel.messages.fetch(options);
84
+ const formatted = messages.map((m) => formatMessage(m));
85
+ const text = formatResponse(Array.from(formatted.values()), params.response_format, (items) => items.map(messageToMarkdown).join("\n\n---\n\n"));
86
+ return {
87
+ content: [{ type: "text", text: truncateIfNeeded(text) }],
88
+ };
89
+ }
90
+ catch (error) {
91
+ return {
92
+ isError: true,
93
+ content: [{ type: "text", text: `Error getting messages: ${error.message}` }],
94
+ };
95
+ }
96
+ });
97
+ server.registerTool("discord_delete_message", {
98
+ title: "Delete Discord Message",
99
+ description: `Delete a message from a Discord channel.
100
+
101
+ Args:
102
+ - channel_id (string): Discord channel ID
103
+ - message_id (string): Message ID to delete
104
+
105
+ Returns:
106
+ Confirmation of deletion`,
107
+ inputSchema: DeleteMessageSchema,
108
+ annotations: {
109
+ readOnlyHint: false,
110
+ destructiveHint: true,
111
+ idempotentHint: false,
112
+ openWorldHint: true,
113
+ },
114
+ }, async (params) => {
115
+ try {
116
+ const client = await getClient();
117
+ const channel = client.channels.cache.get(params.channel_id);
118
+ if (!channel || !('messages' in channel)) {
119
+ return {
120
+ isError: true,
121
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
122
+ };
123
+ }
124
+ const message = await channel.messages.fetch(params.message_id);
125
+ await message.delete();
126
+ return {
127
+ content: [{ type: "text", text: `Deleted message ${params.message_id}` }],
128
+ };
129
+ }
130
+ catch (error) {
131
+ return {
132
+ isError: true,
133
+ content: [{ type: "text", text: `Error deleting message: ${error.message}` }],
134
+ };
135
+ }
136
+ });
137
+ server.registerTool("discord_edit_message", {
138
+ title: "Edit Discord Message",
139
+ description: `Edit a message sent by the bot.
140
+
141
+ Args:
142
+ - channel_id (string): Discord channel ID
143
+ - message_id (string): Message ID to edit
144
+ - content (string): New message content (max 2000 characters)
145
+
146
+ Returns:
147
+ Confirmation of edit`,
148
+ inputSchema: EditMessageSchema,
149
+ annotations: {
150
+ readOnlyHint: false,
151
+ destructiveHint: false,
152
+ idempotentHint: true,
153
+ openWorldHint: true,
154
+ },
155
+ }, async (params) => {
156
+ try {
157
+ const client = await getClient();
158
+ const channel = client.channels.cache.get(params.channel_id);
159
+ if (!channel || !('messages' in channel)) {
160
+ return {
161
+ isError: true,
162
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
163
+ };
164
+ }
165
+ const message = await channel.messages.fetch(params.message_id);
166
+ await message.edit(params.content);
167
+ return {
168
+ content: [{ type: "text", text: `Edited message ${params.message_id}` }],
169
+ };
170
+ }
171
+ catch (error) {
172
+ return {
173
+ isError: true,
174
+ content: [{ type: "text", text: `Error editing message: ${error.message}` }],
175
+ };
176
+ }
177
+ });
178
+ server.registerTool("discord_add_reaction", {
179
+ title: "Add Reaction to Message",
180
+ description: `Add an emoji reaction to a message.
181
+
182
+ Args:
183
+ - channel_id (string): Discord channel ID
184
+ - message_id (string): Message ID to react to
185
+ - emoji (string): Emoji to react with (e.g., '\u{1F44D}' or custom emoji format)
186
+
187
+ Returns:
188
+ Confirmation of reaction added`,
189
+ inputSchema: AddReactionSchema,
190
+ annotations: {
191
+ readOnlyHint: false,
192
+ destructiveHint: false,
193
+ idempotentHint: true,
194
+ openWorldHint: true,
195
+ },
196
+ }, async (params) => {
197
+ try {
198
+ const client = await getClient();
199
+ const channel = client.channels.cache.get(params.channel_id);
200
+ if (!channel || !('messages' in channel)) {
201
+ return {
202
+ isError: true,
203
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
204
+ };
205
+ }
206
+ const message = await channel.messages.fetch(params.message_id);
207
+ await message.react(params.emoji);
208
+ return {
209
+ content: [{ type: "text", text: `Added reaction ${params.emoji} to message ${params.message_id}` }],
210
+ };
211
+ }
212
+ catch (error) {
213
+ return {
214
+ isError: true,
215
+ content: [{ type: "text", text: `Error adding reaction: ${error.message}` }],
216
+ };
217
+ }
218
+ });
219
+ server.registerTool("discord_remove_reaction", {
220
+ title: "Remove Reaction from Message",
221
+ description: `Remove the bot's emoji reaction from a message.
222
+
223
+ Args:
224
+ - channel_id (string): Discord channel ID
225
+ - message_id (string): Message ID
226
+ - emoji (string): Emoji to remove
227
+
228
+ Returns:
229
+ Confirmation of reaction removed`,
230
+ inputSchema: RemoveReactionSchema,
231
+ annotations: {
232
+ readOnlyHint: false,
233
+ destructiveHint: false,
234
+ idempotentHint: true,
235
+ openWorldHint: true,
236
+ },
237
+ }, async (params) => {
238
+ try {
239
+ const client = await getClient();
240
+ const channel = client.channels.cache.get(params.channel_id);
241
+ if (!channel || !('messages' in channel)) {
242
+ return {
243
+ isError: true,
244
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
245
+ };
246
+ }
247
+ const message = await channel.messages.fetch(params.message_id);
248
+ const reaction = message.reactions.cache.get(params.emoji);
249
+ if (reaction) {
250
+ await reaction.users.remove(client.user.id);
251
+ }
252
+ return {
253
+ content: [{ type: "text", text: `Removed reaction ${params.emoji} from message ${params.message_id}` }],
254
+ };
255
+ }
256
+ catch (error) {
257
+ return {
258
+ isError: true,
259
+ content: [{ type: "text", text: `Error removing reaction: ${error.message}` }],
260
+ };
261
+ }
262
+ });
263
+ server.registerTool("discord_pin_message", {
264
+ title: "Pin Discord Message",
265
+ description: `Pin a message in a channel.
266
+
267
+ Args:
268
+ - channel_id (string): Discord channel ID
269
+ - message_id (string): Message ID to pin
270
+
271
+ Returns:
272
+ Confirmation of message pinned`,
273
+ inputSchema: PinMessageSchema,
274
+ annotations: {
275
+ readOnlyHint: false,
276
+ destructiveHint: false,
277
+ idempotentHint: true,
278
+ openWorldHint: true,
279
+ },
280
+ }, async (params) => {
281
+ try {
282
+ const client = await getClient();
283
+ const channel = client.channels.cache.get(params.channel_id);
284
+ if (!channel || !('messages' in channel)) {
285
+ return {
286
+ isError: true,
287
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
288
+ };
289
+ }
290
+ const message = await channel.messages.fetch(params.message_id);
291
+ await message.pin();
292
+ return {
293
+ content: [{ type: "text", text: `Pinned message ${params.message_id}` }],
294
+ };
295
+ }
296
+ catch (error) {
297
+ return {
298
+ isError: true,
299
+ content: [{ type: "text", text: `Error pinning message: ${error.message}` }],
300
+ };
301
+ }
302
+ });
303
+ server.registerTool("discord_unpin_message", {
304
+ title: "Unpin Discord Message",
305
+ description: `Unpin a message in a channel.
306
+
307
+ Args:
308
+ - channel_id (string): Discord channel ID
309
+ - message_id (string): Message ID to unpin
310
+
311
+ Returns:
312
+ Confirmation of message unpinned`,
313
+ inputSchema: UnpinMessageSchema,
314
+ annotations: {
315
+ readOnlyHint: false,
316
+ destructiveHint: false,
317
+ idempotentHint: true,
318
+ openWorldHint: true,
319
+ },
320
+ }, async (params) => {
321
+ try {
322
+ const client = await getClient();
323
+ const channel = client.channels.cache.get(params.channel_id);
324
+ if (!channel || !('messages' in channel)) {
325
+ return {
326
+ isError: true,
327
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
328
+ };
329
+ }
330
+ const message = await channel.messages.fetch(params.message_id);
331
+ await message.unpin();
332
+ return {
333
+ content: [{ type: "text", text: `Unpinned message ${params.message_id}` }],
334
+ };
335
+ }
336
+ catch (error) {
337
+ return {
338
+ isError: true,
339
+ content: [{ type: "text", text: `Error unpinning message: ${error.message}` }],
340
+ };
341
+ }
342
+ });
343
+ server.registerTool("discord_get_pinned_messages", {
344
+ title: "Get Pinned Messages",
345
+ description: `Get all pinned messages in a channel.
346
+
347
+ Args:
348
+ - channel_id (string): Discord channel ID
349
+ - response_format ('markdown' | 'json'): Output format (default: 'json')
350
+
351
+ Returns:
352
+ List of pinned messages`,
353
+ inputSchema: GetPinnedMessagesSchema,
354
+ annotations: {
355
+ readOnlyHint: true,
356
+ destructiveHint: false,
357
+ idempotentHint: true,
358
+ openWorldHint: true,
359
+ },
360
+ }, async (params) => {
361
+ try {
362
+ const client = await getClient();
363
+ const channel = client.channels.cache.get(params.channel_id);
364
+ if (!channel || !('messages' in channel)) {
365
+ return {
366
+ isError: true,
367
+ content: [{ type: "text", text: `Text channel not found: ${params.channel_id}` }],
368
+ };
369
+ }
370
+ const messages = await channel.messages.fetchPinned();
371
+ const formatted = messages.map((m) => formatMessage(m));
372
+ const text = formatResponse(Array.from(formatted.values()), params.response_format, (items) => items.length > 0
373
+ ? items.map(messageToMarkdown).join("\n\n---\n\n")
374
+ : "No pinned messages in this channel.");
375
+ return {
376
+ content: [{ type: "text", text: truncateIfNeeded(text) }],
377
+ };
378
+ }
379
+ catch (error) {
380
+ return {
381
+ isError: true,
382
+ content: [{ type: "text", text: `Error getting pinned messages: ${error.message}` }],
383
+ };
384
+ }
385
+ });
386
+ }
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerModerationTools(server: McpServer): void;