@mahesvara/discord-mcpserver 1.1.2 → 1.1.4

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Oratorian
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Oratorian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -156,13 +156,13 @@ An MCP (Model Context Protocol) server that enables LLMs to control Discord serv
156
156
  **Option A: Install globally from npm**
157
157
 
158
158
  ```bash
159
- npm install -g @mahesvara/discord-mcp-server
159
+ npm install -g @mahesvara/discord-mcpserver
160
160
  ```
161
161
 
162
162
  **Option B: Run directly with npx (no install required)**
163
163
 
164
164
  ```bash
165
- npx @mahesvara/discord-mcp-server
165
+ npx @mahesvara/discord-mcpserver
166
166
  ```
167
167
 
168
168
  ## Usage
@@ -177,7 +177,7 @@ Add to your MCP client configuration (e.g., Claude Desktop or Claude Code):
177
177
  {
178
178
  "mcpServers": {
179
179
  "discord": {
180
- "command": "discord-mcp-server",
180
+ "command": "discord-mcpserver",
181
181
  "env": {
182
182
  "DISCORD_BOT_TOKEN": "your_bot_token_here"
183
183
  }
@@ -193,7 +193,7 @@ Add to your MCP client configuration (e.g., Claude Desktop or Claude Code):
193
193
  "mcpServers": {
194
194
  "discord": {
195
195
  "command": "npx",
196
- "args": ["-y", "@mahesvara/discord-mcp-server"],
196
+ "args": ["-y", "@mahesvara/discord-mcpserver"],
197
197
  "env": {
198
198
  "DISCORD_BOT_TOKEN": "your_bot_token_here"
199
199
  }
@@ -226,22 +226,22 @@ For remote access, run the server with HTTP transport enabled:
226
226
 
227
227
  **Linux/macOS:**
228
228
  ```bash
229
- DISCORD_BOT_TOKEN=your_token TRANSPORT=http PORT=3000 HOST=0.0.0.0 discord-mcp-server
229
+ DISCORD_BOT_TOKEN=your_token TRANSPORT=http PORT=3000 HOST=0.0.0.0 discord-mcpserver
230
230
  ```
231
231
 
232
232
  **Windows (Command Prompt):**
233
233
  ```cmd
234
- set DISCORD_BOT_TOKEN=your_token && set TRANSPORT=http && set PORT=3000 && set HOST=0.0.0.0 && discord-mcp-server
234
+ set DISCORD_BOT_TOKEN=your_token && set TRANSPORT=http && set PORT=3000 && set HOST=0.0.0.0 && discord-mcpserver
235
235
  ```
236
236
 
237
237
  **Windows (PowerShell):**
238
238
  ```powershell
239
- $env:DISCORD_BOT_TOKEN="your_token"; $env:TRANSPORT="http"; $env:PORT="3000"; $env:HOST="0.0.0.0"; discord-mcp-server
239
+ $env:DISCORD_BOT_TOKEN="your_token"; $env:TRANSPORT="http"; $env:PORT="3000"; $env:HOST="0.0.0.0"; discord-mcpserver
240
240
  ```
241
241
 
242
242
  **Or use a `.env` file** (works on all platforms):
243
243
  ```bash
244
- discord-mcp-server
244
+ discord-mcpserver
245
245
  ```
246
246
 
247
247
  Then configure your MCP client to connect via HTTP:
@@ -43,7 +43,7 @@ export declare function truncateIfNeeded(text: string, limit?: number): string;
43
43
  /**
44
44
  * Format response based on format preference
45
45
  */
46
- export declare function formatResponse<T>(data: T, format: ResponseFormat, markdownFormatter: (item: T) => string): string;
46
+ export declare function formatResponse<T>(data: T | T[], format: ResponseFormat, markdownFormatter: (item: T) => string): string;
47
47
  export declare function guildToMarkdown(guild: DiscordGuild): string;
48
48
  export declare function channelToMarkdown(channel: DiscordChannel): string;
49
49
  export declare function memberToMarkdown(member: DiscordMember): string;
@@ -63,7 +63,7 @@ Returns:
63
63
  }
64
64
  }
65
65
  const formatted = filteredChannels.map(c => formatChannel(c));
66
- const text = formatResponse(formatted, params.response_format, (items) => items.map(channelToMarkdown).join("\n\n"));
66
+ const text = formatResponse(formatted, params.response_format, channelToMarkdown);
67
67
  return {
68
68
  content: [{ type: "text", text: truncateIfNeeded(text) }],
69
69
  };
@@ -41,7 +41,7 @@ Returns:
41
41
  roles: emoji.roles.cache.map(r => r.name),
42
42
  url: emoji.url,
43
43
  }));
44
- const result = formatResponse(emojis, params.response_format, (items) => items.map(e => `${e.animated ? '(animated) ' : ''}**${e.name}** - ID: ${e.id}`).join('\n'));
44
+ const result = formatResponse(emojis, params.response_format, (e) => `${e.animated ? '(animated) ' : ''}**${e.name}** - ID: ${e.id}`);
45
45
  return {
46
46
  content: [{ type: "text", text: truncateIfNeeded(result) }],
47
47
  };
@@ -185,7 +185,7 @@ Returns:
185
185
  available: sticker.available,
186
186
  url: sticker.url,
187
187
  }));
188
- const result = formatResponse(stickerList, params.response_format, (items) => items.map(s => `**${s.name}** (ID: ${s.id})\nDescription: ${s.description || 'None'}\nTags: ${s.tags || 'None'}`).join('\n\n'));
188
+ const result = formatResponse(stickerList, params.response_format, (s) => `**${s.name}** (ID: ${s.id})\nDescription: ${s.description || 'None'}\nTags: ${s.tags || 'None'}`);
189
189
  return {
190
190
  content: [{ type: "text", text: truncateIfNeeded(result) }],
191
191
  };
@@ -44,7 +44,7 @@ Returns:
44
44
  userCount: event.userCount,
45
45
  creator: event.creator?.username,
46
46
  }));
47
- const result = formatResponse(eventList, params.response_format, (items) => items.map(e => `**${e.name}** (ID: ${e.id})\nStatus: ${e.status}\nStart: ${e.scheduledStartTime}\nLocation: ${e.location || e.channel || 'TBD'}\nAttending: ${e.userCount || 0}`).join('\n\n'));
47
+ const result = formatResponse(eventList, params.response_format, (e) => `**${e.name}** (ID: ${e.id})\nStatus: ${e.status}\nStart: ${e.scheduledStartTime}\nLocation: ${e.location || e.channel || 'TBD'}\nAttending: ${e.userCount || 0}`);
48
48
  return {
49
49
  content: [{ type: "text", text: truncateIfNeeded(result) }],
50
50
  };
@@ -24,7 +24,7 @@ Returns:
24
24
  try {
25
25
  const client = await getClient();
26
26
  const guilds = client.guilds.cache.map(formatGuild);
27
- const text = formatResponse(guilds, params.response_format, (items) => items.map(guildToMarkdown).join("\n\n"));
27
+ const text = formatResponse(guilds, params.response_format, guildToMarkdown);
28
28
  return {
29
29
  content: [{ type: "text", text: truncateIfNeeded(text) }],
30
30
  };
@@ -42,7 +42,7 @@ Returns:
42
42
  createdAt: invite.createdAt?.toISOString(),
43
43
  expiresAt: invite.expiresAt?.toISOString() || 'Never',
44
44
  }));
45
- const result = formatResponse(inviteList, params.response_format, (items) => items.map(i => `**${i.code}** - #${i.channel}\nUses: ${i.uses}/${i.maxUses} | Expires: ${i.expiresAt}\nCreated by: ${i.inviter}`).join('\n\n'));
45
+ const result = formatResponse(inviteList, params.response_format, (i) => `**${i.code}** - #${i.channel}\nUses: ${i.uses}/${i.maxUses} | Expires: ${i.expiresAt}\nCreated by: ${i.inviter}`);
46
46
  return {
47
47
  content: [{ type: "text", text: truncateIfNeeded(result) }],
48
48
  };
@@ -38,7 +38,7 @@ Returns:
38
38
  // Convert Collection to array
39
39
  const membersArray = Array.from(membersResult.values());
40
40
  const formatted = membersArray.map((m) => formatMember(m));
41
- const text = formatResponse(formatted, params.response_format, (items) => items.map(memberToMarkdown).join("\n\n"));
41
+ const text = formatResponse(formatted, params.response_format, memberToMarkdown);
42
42
  return {
43
43
  content: [{ type: "text", text: truncateIfNeeded(text) }],
44
44
  };
@@ -82,7 +82,7 @@ Returns:
82
82
  options.after = params.after;
83
83
  const messages = await channel.messages.fetch(options);
84
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"));
85
+ const text = formatResponse(Array.from(formatted.values()), params.response_format, messageToMarkdown);
86
86
  return {
87
87
  content: [{ type: "text", text: truncateIfNeeded(text) }],
88
88
  };
@@ -214,7 +214,7 @@ Returns:
214
214
  username: ban.user.username,
215
215
  reason: ban.reason || 'No reason provided',
216
216
  }));
217
- const result = formatResponse(banList, params.response_format, (items) => items.map(b => `**${b.username}** (${b.userId})\nReason: ${b.reason}`).join('\n\n'));
217
+ const result = formatResponse(banList, params.response_format, (b) => `**${b.username}** (${b.userId})\nReason: ${b.reason}`);
218
218
  return {
219
219
  content: [{ type: "text", text: truncateIfNeeded(result) }],
220
220
  };
@@ -340,7 +340,7 @@ Returns:
340
340
  new: c.new,
341
341
  })),
342
342
  }));
343
- const result = formatResponse(entries, params.response_format, (items) => items.map(e => `**Action ${e.action}** by ${e.executor}\nTarget: ${e.target}\nReason: ${e.reason}\nTime: ${e.createdAt}`).join('\n\n'));
343
+ const result = formatResponse(entries, params.response_format, (e) => `**Action ${e.action}** by ${e.executor}\nTarget: ${e.target}\nReason: ${e.reason}\nTime: ${e.createdAt}`);
344
344
  return {
345
345
  content: [{ type: "text", text: truncateIfNeeded(result) }],
346
346
  };
@@ -388,7 +388,7 @@ Returns:
388
388
  triggerType: rule.triggerType,
389
389
  actions: rule.actions.map(a => ({ type: a.type, metadata: a.metadata })),
390
390
  }));
391
- const text = formatResponse(ruleList, params.response_format, (items) => items.map(r => `**${r.name}** (${r.id})\nEnabled: ${r.enabled}\nTrigger: ${r.triggerType}\nActions: ${r.actions.map(a => a.type).join(', ')}`).join('\n\n'));
391
+ const text = formatResponse(ruleList, params.response_format, (r) => `**${r.name}** (${r.id})\nEnabled: ${r.enabled}\nTrigger: ${r.triggerType}\nActions: ${r.actions.map(a => a.type).join(', ')}`);
392
392
  return {
393
393
  content: [{ type: "text", text: truncateIfNeeded(text) }],
394
394
  };
@@ -54,7 +54,7 @@ Returns:
54
54
  .filter(r => r.name !== "@everyone")
55
55
  .sort((a, b) => b.position - a.position)
56
56
  .map(formatRole);
57
- const text = formatResponse(Array.from(roles.values()), params.response_format, (items) => items.map(roleToMarkdown).join("\n\n"));
57
+ const text = formatResponse(Array.from(roles.values()), params.response_format, roleToMarkdown);
58
58
  return {
59
59
  content: [{ type: "text", text: truncateIfNeeded(text) }],
60
60
  };
@@ -57,7 +57,7 @@ Returns:
57
57
  owner: wh.owner?.username || 'Unknown',
58
58
  avatar: wh.avatarURL(),
59
59
  }));
60
- const result = formatResponse(webhookList, params.response_format, (items) => items.map(w => `**${w.name}** (ID: ${w.id})\nChannel: <#${w.channel}>\nOwner: ${w.owner}`).join('\n\n'));
60
+ const result = formatResponse(webhookList, params.response_format, (w) => `**${w.name}** (ID: ${w.id})\nChannel: <#${w.channel}>\nOwner: ${w.owner}`);
61
61
  return {
62
62
  content: [{ type: "text", text: truncateIfNeeded(result) }],
63
63
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mahesvara/discord-mcpserver",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "MCP server for controlling Discord servers via bot token",
5
5
  "author": "Mahesvara",
6
6
  "repository": {