@quadslab.io/discord-mcp 1.0.0

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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +474 -0
  3. package/dist/discord-client.d.ts +57 -0
  4. package/dist/discord-client.js +188 -0
  5. package/dist/discord-client.js.map +1 -0
  6. package/dist/index.d.ts +9 -0
  7. package/dist/index.js +135 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/mcp-server.d.ts +15 -0
  10. package/dist/mcp-server.js +65 -0
  11. package/dist/mcp-server.js.map +1 -0
  12. package/dist/tools/automod.d.ts +6 -0
  13. package/dist/tools/automod.js +376 -0
  14. package/dist/tools/automod.js.map +1 -0
  15. package/dist/tools/channels.d.ts +6 -0
  16. package/dist/tools/channels.js +840 -0
  17. package/dist/tools/channels.js.map +1 -0
  18. package/dist/tools/emojis.d.ts +6 -0
  19. package/dist/tools/emojis.js +295 -0
  20. package/dist/tools/emojis.js.map +1 -0
  21. package/dist/tools/events.d.ts +6 -0
  22. package/dist/tools/events.js +304 -0
  23. package/dist/tools/events.js.map +1 -0
  24. package/dist/tools/forums.d.ts +6 -0
  25. package/dist/tools/forums.js +276 -0
  26. package/dist/tools/forums.js.map +1 -0
  27. package/dist/tools/guild.d.ts +6 -0
  28. package/dist/tools/guild.js +88 -0
  29. package/dist/tools/guild.js.map +1 -0
  30. package/dist/tools/index.d.ts +13 -0
  31. package/dist/tools/index.js +142 -0
  32. package/dist/tools/index.js.map +1 -0
  33. package/dist/tools/members.d.ts +6 -0
  34. package/dist/tools/members.js +628 -0
  35. package/dist/tools/members.js.map +1 -0
  36. package/dist/tools/messages.d.ts +6 -0
  37. package/dist/tools/messages.js +688 -0
  38. package/dist/tools/messages.js.map +1 -0
  39. package/dist/tools/reactions.d.ts +6 -0
  40. package/dist/tools/reactions.js +137 -0
  41. package/dist/tools/reactions.js.map +1 -0
  42. package/dist/tools/roles.d.ts +6 -0
  43. package/dist/tools/roles.js +469 -0
  44. package/dist/tools/roles.js.map +1 -0
  45. package/dist/tools/server.d.ts +6 -0
  46. package/dist/tools/server.js +607 -0
  47. package/dist/tools/server.js.map +1 -0
  48. package/dist/tools/stage.d.ts +6 -0
  49. package/dist/tools/stage.js +153 -0
  50. package/dist/tools/stage.js.map +1 -0
  51. package/dist/tools/threads.d.ts +6 -0
  52. package/dist/tools/threads.js +331 -0
  53. package/dist/tools/threads.js.map +1 -0
  54. package/dist/tools/utils.d.ts +21 -0
  55. package/dist/tools/utils.js +315 -0
  56. package/dist/tools/utils.js.map +1 -0
  57. package/dist/tools/webhooks.d.ts +6 -0
  58. package/dist/tools/webhooks.js +195 -0
  59. package/dist/tools/webhooks.js.map +1 -0
  60. package/package.json +48 -0
@@ -0,0 +1,315 @@
1
+ import { getGuild, getServerCache } from '../discord-client.js';
2
+ import { ChannelType } from 'discord.js';
3
+ /**
4
+ * Utility functions for smart matching of Discord entities
5
+ * These functions use fuzzy matching to find channels, roles, and members
6
+ * even when the input isn't exact.
7
+ */
8
+ /**
9
+ * Calculate similarity between two strings (0-1)
10
+ */
11
+ function similarity(a, b) {
12
+ const aLower = a.toLowerCase();
13
+ const bLower = b.toLowerCase();
14
+ if (aLower === bLower)
15
+ return 1;
16
+ if (aLower.includes(bLower) || bLower.includes(aLower))
17
+ return 0.8;
18
+ // Handle hyphen/space/underscore variations
19
+ const normalize = (s) => s.replace(/[-_\s]/g, '');
20
+ if (normalize(aLower) === normalize(bLower))
21
+ return 0.95;
22
+ if (normalize(aLower).includes(normalize(bLower)))
23
+ return 0.75;
24
+ return 0;
25
+ }
26
+ /**
27
+ * Clean up channel identifier - remove # prefix, handle mentions
28
+ */
29
+ function cleanChannelIdentifier(identifier) {
30
+ return identifier
31
+ .replace(/^#/, '') // Remove # prefix
32
+ .replace(/^<#(\d+)>$/, '$1') // Handle <#id> mention format
33
+ .trim();
34
+ }
35
+ /**
36
+ * Clean up role identifier - remove @ prefix, handle mentions
37
+ */
38
+ function cleanRoleIdentifier(identifier) {
39
+ return identifier
40
+ .replace(/^@/, '') // Remove @ prefix
41
+ .replace(/^<@&(\d+)>$/, '$1') // Handle <@&id> mention format
42
+ .trim();
43
+ }
44
+ /**
45
+ * Clean up member identifier - remove @ prefix, handle mentions
46
+ */
47
+ function cleanMemberIdentifier(identifier) {
48
+ return identifier
49
+ .replace(/^@/, '') // Remove @ prefix
50
+ .replace(/^<@!?(\d+)>$/, '$1') // Handle <@id> or <@!id> mention format
51
+ .trim();
52
+ }
53
+ /**
54
+ * Smart find a channel that can receive messages - includes text channels, announcement channels, and voice channel text chats
55
+ */
56
+ export async function smartFindTextChannel(identifier) {
57
+ const guild = await getGuild();
58
+ const cache = await getServerCache();
59
+ const cleanId = cleanChannelIdentifier(identifier);
60
+ // Use cache for fuzzy matching first (faster)
61
+ // Include text, announcement, and voice channels (voice channels have text chat)
62
+ const messagableChannelTypes = ['text', 'announcement', 'voice', 'stage'];
63
+ const cachedMessageChannels = cache.channels.filter(c => messagableChannelTypes.includes(c.type));
64
+ // Try exact ID match
65
+ let matchedId = cachedMessageChannels.find(c => c.id === cleanId)?.id;
66
+ // Try exact name match (case-insensitive)
67
+ if (!matchedId) {
68
+ matchedId = cachedMessageChannels.find(c => c.name.toLowerCase() === cleanId.toLowerCase())?.id;
69
+ }
70
+ // Try fuzzy match using cache
71
+ if (!matchedId) {
72
+ let bestScore = 0;
73
+ for (const ch of cachedMessageChannels) {
74
+ const score = similarity(ch.name, cleanId);
75
+ if (score > bestScore && score >= 0.7) {
76
+ bestScore = score;
77
+ matchedId = ch.id;
78
+ }
79
+ }
80
+ }
81
+ // If found via cache, get the actual channel object
82
+ if (matchedId) {
83
+ const channel = guild.channels.cache.get(matchedId);
84
+ if (channel && (channel.type === ChannelType.GuildText ||
85
+ channel.type === ChannelType.GuildAnnouncement ||
86
+ channel.type === ChannelType.GuildVoice ||
87
+ channel.type === ChannelType.GuildStageVoice)) {
88
+ return channel;
89
+ }
90
+ }
91
+ // Not found - provide helpful error with suggestions from cache
92
+ const suggestions = cachedMessageChannels
93
+ .map(c => ({ name: c.name, type: c.type, score: similarity(c.name, cleanId) }))
94
+ .filter(s => s.score > 0.3)
95
+ .sort((a, b) => b.score - a.score)
96
+ .slice(0, 3)
97
+ .map(s => s.type === 'voice' ? `🔊${s.name}` : `#${s.name}`);
98
+ let errorMsg = `Channel "${identifier}" not found.`;
99
+ if (suggestions.length > 0) {
100
+ errorMsg += ` Did you mean: ${suggestions.join(', ')}?`;
101
+ }
102
+ // Also list all available channels if few
103
+ if (cachedMessageChannels.length <= 15) {
104
+ const channelList = cachedMessageChannels.map(c => c.type === 'voice' ? `🔊${c.name}` : `#${c.name}`);
105
+ errorMsg += ` Available channels: ${channelList.join(', ')}`;
106
+ }
107
+ throw new Error(errorMsg);
108
+ }
109
+ /**
110
+ * Smart find any channel (text, voice, category) - uses cached data
111
+ */
112
+ export async function smartFindChannel(identifier) {
113
+ const guild = await getGuild();
114
+ const cache = await getServerCache();
115
+ const cleanId = cleanChannelIdentifier(identifier);
116
+ // Use cache for fuzzy matching
117
+ const cachedChannels = cache.channels;
118
+ // Try exact ID match
119
+ let matchedId = cachedChannels.find(c => c.id === cleanId)?.id;
120
+ // Try exact name match (case-insensitive)
121
+ if (!matchedId) {
122
+ matchedId = cachedChannels.find(c => c.name.toLowerCase() === cleanId.toLowerCase())?.id;
123
+ }
124
+ // Try fuzzy match using cache
125
+ if (!matchedId) {
126
+ let bestScore = 0;
127
+ for (const ch of cachedChannels) {
128
+ const score = similarity(ch.name, cleanId);
129
+ if (score > bestScore && score >= 0.7) {
130
+ bestScore = score;
131
+ matchedId = ch.id;
132
+ }
133
+ }
134
+ }
135
+ // If found via cache, get the actual channel object
136
+ if (matchedId) {
137
+ const channel = guild.channels.cache.get(matchedId);
138
+ if (channel) {
139
+ return channel;
140
+ }
141
+ }
142
+ // Not found - provide helpful error with suggestions from cache
143
+ const suggestions = cachedChannels
144
+ .map(c => ({ name: c.name, score: similarity(c.name, cleanId) }))
145
+ .filter(s => s.score > 0.3)
146
+ .sort((a, b) => b.score - a.score)
147
+ .slice(0, 3)
148
+ .map(s => s.name);
149
+ let errorMsg = `Channel "${identifier}" not found.`;
150
+ if (suggestions.length > 0) {
151
+ errorMsg += ` Did you mean: ${suggestions.join(', ')}?`;
152
+ }
153
+ throw new Error(errorMsg);
154
+ }
155
+ /**
156
+ * Smart find category channel - uses cached data
157
+ */
158
+ export async function smartFindCategory(identifier) {
159
+ const guild = await getGuild();
160
+ const cache = await getServerCache();
161
+ const cleanId = cleanChannelIdentifier(identifier);
162
+ // Use cache for fuzzy matching
163
+ const cachedCategories = cache.channels.filter(c => c.type === 'category');
164
+ // Try exact ID match
165
+ let matchedId = cachedCategories.find(c => c.id === cleanId)?.id;
166
+ // Try exact name match (case-insensitive)
167
+ if (!matchedId) {
168
+ matchedId = cachedCategories.find(c => c.name.toLowerCase() === cleanId.toLowerCase())?.id;
169
+ }
170
+ // Try fuzzy match using cache
171
+ if (!matchedId) {
172
+ let bestScore = 0;
173
+ for (const cat of cachedCategories) {
174
+ const score = similarity(cat.name, cleanId);
175
+ if (score > bestScore && score >= 0.7) {
176
+ bestScore = score;
177
+ matchedId = cat.id;
178
+ }
179
+ }
180
+ }
181
+ // If found via cache, get the actual channel object
182
+ if (matchedId) {
183
+ const channel = guild.channels.cache.get(matchedId);
184
+ if (channel && channel.type === ChannelType.GuildCategory) {
185
+ return channel;
186
+ }
187
+ }
188
+ // Not found - provide helpful error with suggestions from cache
189
+ const suggestions = cachedCategories
190
+ .map(c => ({ name: c.name, score: similarity(c.name, cleanId) }))
191
+ .filter(s => s.score > 0.3)
192
+ .sort((a, b) => b.score - a.score)
193
+ .slice(0, 3)
194
+ .map(s => s.name);
195
+ let errorMsg = `Category "${identifier}" not found.`;
196
+ if (suggestions.length > 0) {
197
+ errorMsg += ` Did you mean: ${suggestions.join(', ')}?`;
198
+ }
199
+ if (cachedCategories.length <= 10) {
200
+ errorMsg += ` Available categories: ${cachedCategories.map(c => c.name).join(', ')}`;
201
+ }
202
+ throw new Error(errorMsg);
203
+ }
204
+ /**
205
+ * Smart find role - uses cached data and fuzzy matching
206
+ */
207
+ export async function smartFindRole(identifier) {
208
+ const guild = await getGuild();
209
+ const cache = await getServerCache();
210
+ const cleanId = cleanRoleIdentifier(identifier);
211
+ // Use cache for fuzzy matching
212
+ const cachedRoles = cache.roles;
213
+ // Try exact ID match
214
+ let matchedId = cachedRoles.find(r => r.id === cleanId)?.id;
215
+ // Try exact name match (case-insensitive)
216
+ if (!matchedId) {
217
+ matchedId = cachedRoles.find(r => r.name.toLowerCase() === cleanId.toLowerCase())?.id;
218
+ }
219
+ // Try fuzzy match using cache
220
+ if (!matchedId) {
221
+ let bestScore = 0;
222
+ for (const role of cachedRoles) {
223
+ const score = similarity(role.name, cleanId);
224
+ if (score > bestScore && score >= 0.7) {
225
+ bestScore = score;
226
+ matchedId = role.id;
227
+ }
228
+ }
229
+ }
230
+ // If found via cache, get the actual role object
231
+ if (matchedId) {
232
+ const role = guild.roles.cache.get(matchedId);
233
+ if (role) {
234
+ return role;
235
+ }
236
+ }
237
+ // Not found - provide helpful error with suggestions from cache
238
+ const suggestions = cachedRoles
239
+ .map(r => ({ name: r.name, score: similarity(r.name, cleanId) }))
240
+ .filter(s => s.score > 0.3)
241
+ .sort((a, b) => b.score - a.score)
242
+ .slice(0, 3)
243
+ .map(s => s.name);
244
+ let errorMsg = `Role "${identifier}" not found.`;
245
+ if (suggestions.length > 0) {
246
+ errorMsg += ` Did you mean: ${suggestions.map(s => `@${s}`).join(', ')}?`;
247
+ }
248
+ if (cachedRoles.length <= 15) {
249
+ errorMsg += ` Available roles: ${cachedRoles.map(r => `@${r.name}`).join(', ')}`;
250
+ }
251
+ throw new Error(errorMsg);
252
+ }
253
+ /**
254
+ * Smart find member - uses cached data and fuzzy matching
255
+ */
256
+ export async function smartFindMember(identifier) {
257
+ const guild = await getGuild();
258
+ const cache = await getServerCache();
259
+ const cleanId = cleanMemberIdentifier(identifier);
260
+ // Use cache for fuzzy matching first
261
+ const cachedMembers = cache.members;
262
+ // Try exact ID match
263
+ let matchedId = cachedMembers.find(m => m.id === cleanId)?.id;
264
+ // Try exact matches (case-insensitive) on various name fields
265
+ if (!matchedId) {
266
+ matchedId = cachedMembers.find(m => m.username.toLowerCase() === cleanId.toLowerCase() ||
267
+ m.displayName.toLowerCase() === cleanId.toLowerCase() ||
268
+ (m.nickname && m.nickname.toLowerCase() === cleanId.toLowerCase()))?.id;
269
+ }
270
+ // Try fuzzy match using cache
271
+ if (!matchedId) {
272
+ let bestScore = 0;
273
+ for (const member of cachedMembers) {
274
+ const scores = [
275
+ similarity(member.username, cleanId),
276
+ similarity(member.displayName, cleanId),
277
+ member.nickname ? similarity(member.nickname, cleanId) : 0,
278
+ ];
279
+ const maxScore = Math.max(...scores);
280
+ if (maxScore > bestScore && maxScore >= 0.6) {
281
+ bestScore = maxScore;
282
+ matchedId = member.id;
283
+ }
284
+ }
285
+ }
286
+ // If found via cache, get the actual member object
287
+ if (matchedId) {
288
+ // Fetch the specific member to ensure we have latest data
289
+ try {
290
+ const member = await guild.members.fetch(matchedId);
291
+ if (member) {
292
+ return member;
293
+ }
294
+ }
295
+ catch {
296
+ // Member might have left, fall through to error
297
+ }
298
+ }
299
+ // Not found - provide helpful error with suggestions from cache
300
+ const suggestions = cachedMembers
301
+ .map(m => ({
302
+ name: m.displayName,
303
+ score: Math.max(similarity(m.username, cleanId), similarity(m.displayName, cleanId), m.nickname ? similarity(m.nickname, cleanId) : 0)
304
+ }))
305
+ .filter(s => s.score > 0.3)
306
+ .sort((a, b) => b.score - a.score)
307
+ .slice(0, 3)
308
+ .map(s => s.name);
309
+ let errorMsg = `Member "${identifier}" not found.`;
310
+ if (suggestions.length > 0) {
311
+ errorMsg += ` Did you mean: ${suggestions.map(s => `@${s}`).join(', ')}?`;
312
+ }
313
+ throw new Error(errorMsg);
314
+ }
315
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
2
+ /**
3
+ * Webhook management tools
4
+ */
5
+ export declare const webhookTools: Tool[];
6
+ export declare function executeWebhookTool(name: string, args: Record<string, unknown>): Promise<string>;
@@ -0,0 +1,195 @@
1
+ import { getGuild, getClient } from '../discord-client.js';
2
+ import { smartFindTextChannel } from './utils.js';
3
+ /**
4
+ * Webhook management tools
5
+ */
6
+ export const webhookTools = [
7
+ {
8
+ name: 'list_webhooks',
9
+ description: 'List all webhooks in the server, optionally filtered to a specific channel. Channel name is fuzzy-matched.',
10
+ inputSchema: {
11
+ type: 'object',
12
+ properties: {
13
+ channel: {
14
+ type: 'string',
15
+ description: 'Channel name or ID to filter webhooks by (fuzzy matched, optional)',
16
+ },
17
+ },
18
+ required: [],
19
+ },
20
+ },
21
+ {
22
+ name: 'create_webhook',
23
+ description: 'Create a new webhook for a channel. Channel name is fuzzy-matched.',
24
+ inputSchema: {
25
+ type: 'object',
26
+ properties: {
27
+ channel: {
28
+ type: 'string',
29
+ description: 'The channel name or ID to create the webhook in (fuzzy matched)',
30
+ },
31
+ name: {
32
+ type: 'string',
33
+ description: 'The name for the webhook',
34
+ },
35
+ avatarUrl: {
36
+ type: 'string',
37
+ description: 'URL of the avatar image for the webhook (optional)',
38
+ },
39
+ reason: {
40
+ type: 'string',
41
+ description: 'The reason for creating this webhook (shown in audit log)',
42
+ },
43
+ },
44
+ required: ['channel', 'name'],
45
+ },
46
+ },
47
+ {
48
+ name: 'delete_webhook',
49
+ description: 'Delete a webhook by its ID.',
50
+ inputSchema: {
51
+ type: 'object',
52
+ properties: {
53
+ webhookId: {
54
+ type: 'string',
55
+ description: 'The ID of the webhook to delete',
56
+ },
57
+ reason: {
58
+ type: 'string',
59
+ description: 'The reason for deleting this webhook (shown in audit log)',
60
+ },
61
+ },
62
+ required: ['webhookId'],
63
+ },
64
+ },
65
+ {
66
+ name: 'send_webhook_message',
67
+ description: 'Send a message via a webhook. Can optionally override the display name and avatar.',
68
+ inputSchema: {
69
+ type: 'object',
70
+ properties: {
71
+ webhookId: {
72
+ type: 'string',
73
+ description: 'The ID of the webhook to send the message through',
74
+ },
75
+ content: {
76
+ type: 'string',
77
+ description: 'The message content to send',
78
+ },
79
+ username: {
80
+ type: 'string',
81
+ description: 'Override the webhook display name for this message (optional)',
82
+ },
83
+ avatarUrl: {
84
+ type: 'string',
85
+ description: 'Override the webhook avatar URL for this message (optional)',
86
+ },
87
+ },
88
+ required: ['webhookId', 'content'],
89
+ },
90
+ },
91
+ ];
92
+ export async function executeWebhookTool(name, args) {
93
+ switch (name) {
94
+ case 'list_webhooks':
95
+ return await listWebhooks(args);
96
+ case 'create_webhook':
97
+ return await createWebhook(args);
98
+ case 'delete_webhook':
99
+ return await deleteWebhook(args);
100
+ case 'send_webhook_message':
101
+ return await sendWebhookMessage(args);
102
+ default:
103
+ throw new Error(`Unknown webhook tool: ${name}`);
104
+ }
105
+ }
106
+ async function listWebhooks(args) {
107
+ const guild = await getGuild();
108
+ const channelIdentifier = args['channel'];
109
+ let webhooks;
110
+ if (channelIdentifier) {
111
+ const channel = await smartFindTextChannel(channelIdentifier);
112
+ if (!channel.isTextBased()) {
113
+ throw new Error(`Channel "${channelIdentifier}" is not a text-based channel and cannot have webhooks.`);
114
+ }
115
+ webhooks = await channel.fetchWebhooks();
116
+ }
117
+ else {
118
+ webhooks = await guild.fetchWebhooks();
119
+ }
120
+ const result = webhooks.map(wh => {
121
+ const channelObj = guild.channels.cache.get(wh.channelId);
122
+ return {
123
+ id: wh.id,
124
+ name: wh.name,
125
+ channelId: wh.channelId,
126
+ channelName: channelObj?.name ?? null,
127
+ url: wh.url,
128
+ creator: wh.owner ? { id: wh.owner.id, username: wh.owner.username } : null,
129
+ avatar: wh.avatar,
130
+ createdAt: wh.createdAt?.toISOString() ?? null,
131
+ };
132
+ });
133
+ return JSON.stringify(result, null, 2);
134
+ }
135
+ async function createWebhook(args) {
136
+ const channelIdentifier = args['channel'];
137
+ const name = args['name'];
138
+ const avatarUrl = args['avatarUrl'];
139
+ const reason = args['reason'];
140
+ const channel = await smartFindTextChannel(channelIdentifier);
141
+ if (!channel.isTextBased()) {
142
+ throw new Error(`Channel "${channelIdentifier}" is not a text-based channel and cannot have webhooks.`);
143
+ }
144
+ const webhook = await channel.createWebhook({
145
+ name,
146
+ avatar: avatarUrl,
147
+ reason: reason ?? 'Created via MCP',
148
+ });
149
+ return JSON.stringify({
150
+ success: true,
151
+ message: `Webhook "${webhook.name}" created successfully`,
152
+ webhook: {
153
+ id: webhook.id,
154
+ name: webhook.name,
155
+ url: webhook.url,
156
+ token: webhook.token,
157
+ channelId: webhook.channelId,
158
+ channelName: channel.name,
159
+ },
160
+ }, null, 2);
161
+ }
162
+ async function deleteWebhook(args) {
163
+ const webhookId = args['webhookId'];
164
+ const reason = args['reason'];
165
+ const client = getClient();
166
+ const webhook = await client.fetchWebhook(webhookId);
167
+ const webhookName = webhook.name;
168
+ await webhook.delete(reason ?? 'Deleted via MCP');
169
+ return JSON.stringify({
170
+ success: true,
171
+ message: `Webhook "${webhookName}" deleted successfully`,
172
+ }, null, 2);
173
+ }
174
+ async function sendWebhookMessage(args) {
175
+ const webhookId = args['webhookId'];
176
+ const content = args['content'];
177
+ const username = args['username'];
178
+ const avatarUrl = args['avatarUrl'];
179
+ const client = getClient();
180
+ const webhook = await client.fetchWebhook(webhookId);
181
+ const message = await webhook.send({
182
+ content,
183
+ username,
184
+ avatarURL: avatarUrl,
185
+ });
186
+ return JSON.stringify({
187
+ success: true,
188
+ message: {
189
+ id: message.id,
190
+ content: message.content,
191
+ channelId: message.channelId,
192
+ },
193
+ }, null, 2);
194
+ }
195
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@quadslab.io/discord-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Full Discord server administration through Claude Code via MCP. 99 tools across 14 categories covering roles, channels, members, messages, moderation, forums, stages, webhooks, events, and more.",
5
+ "type": "module",
6
+ "main": "dist/mcp-server.js",
7
+ "bin": {
8
+ "discord-mcp": "dist/mcp-server.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/mcp-server.js",
13
+ "dev": "npx tsx src/mcp-server.ts"
14
+ },
15
+ "keywords": [
16
+ "discord",
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "claude",
20
+ "claude-code",
21
+ "server-admin",
22
+ "discord-bot",
23
+ "discord-management",
24
+ "anthropic"
25
+ ],
26
+ "author": "QuadsLab",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/HardHeadHackerHead/discord-mcp"
31
+ },
32
+ "homepage": "https://github.com/HardHeadHackerHead/discord-mcp#readme",
33
+ "bugs": {
34
+ "url": "https://github.com/HardHeadHackerHead/discord-mcp/issues"
35
+ },
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.25.2",
41
+ "discord.js": "^14.16.3",
42
+ "dotenv": "^16.4.5"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.10.2",
46
+ "typescript": "^5.7.2"
47
+ }
48
+ }