discord-selfbot-mcp 1.2.8 → 1.4.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.
package/README.md CHANGED
@@ -9,12 +9,9 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <img src="https://img.shields.io/badge/license-MIT-green" alt="license">
13
- <img src="https://img.shields.io/badge/language-python-blue" alt="language">
14
- <a href="https://www.npmjs.com/package/discord-selfbot-mcp"><img src="https://img.shields.io/npm/v/discord-selfbot-mcp?color=orange&label=npm" alt="npm"></a>
15
- <img src="https://img.shields.io/badge/mcp-sdk-orange" alt="mcp">
16
- <img src="https://img.shields.io/badge/skill-cli-purple" alt="skill">
17
- <a href="https://github.com/Microck/opencode-studio"><img src="https://img.shields.io/badge/opencode-studio-brown?logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABiElEQVR4nF2Sv0tWcRTGPyeVIpCWwmyJGqQagsqCsL2hhobsD3BvdWhoj/6CiIKaoqXBdMjKRWwQgqZ%2BokSvkIhg9BOT9xPn9Vx79cD3cu6953zP8zznCQB1V0S01d3AKeAKcBVYA94DjyJioru2k9SHE%2Bqc%2Bkd9rL7yf7TUm%2BpQ05yPUM%2Bo626Pp%2BqE2q7GGfWrOpjNnWnAOPAGeAK8Bb4U5D3AJ%2BAQsAAMAHfVvl7gIrAf2Kjiz8BZYB3YC/wFpoGDwHfgEnA0oU7tgHiheEShyXxY/Vn/n6ljye8DcBiYAloRcV3tAdrV1xMRG%2Bo94DywCAwmx33AJHASWK7iiAjzNFOBl7WapPYtYdyo8RlLqVpOVPvq9KoH1NUuOneycaRefqnP1ftdUyiOt5KS%2BqLWdDpVzTXMl5It4Jr6u%2BQ/nhyBc8C7jpowGxGvmxuPqT9qyYuFIKdP71B8WT3SOKexXLrntvqxq3BefaiuFMQ0wqZftxl3M78MjBasfiDN/SAi0kFbtf8ACtKBWZBDoJEAAAAASUVORK5CYII%3D" alt="Add with OpenCode Studio" /></a>
12
+ <a href="https://github.com/Microck/discord.py-self-mcp/releases"><img src="https://img.shields.io/github/v/release/Microck/discord.py-self-mcp?display_name=tag&style=flat-square&label=release&color=000000" alt="release"></a>
13
+ <a href="https://www.npmjs.com/package/discord-selfbot-mcp"><img src="https://flat.badgen.net/npm/dt/discord-selfbot-mcp?label=downloads&color=000000" alt="npm downloads"></a>
14
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-mit-000000?style=flat-square" alt="license"></a>
18
15
  </p>
19
16
 
20
17
  <p align="center">
@@ -186,6 +183,7 @@ powered by the robust `discord.py-self` library.
186
183
  | **system** | 2 | get_user_info, list_guilds |
187
184
  | **messages** | 6 | send_message, read_messages, search_messages, edit_message, delete_message, get_message_attachments |
188
185
  | **channels** | 3 | create_channel, delete_channel, list_channels |
186
+ | **dms** | 1 | list_dm_channels |
189
187
  | **voice** | 2 | join_voice_channel, leave_voice_channel |
190
188
  | **relationships** | 4 | list_friends, send_friend_request, add_friend, remove_friend |
191
189
  | **presence** | 2 | set_status, set_activity |
@@ -197,11 +195,42 @@ powered by the robust `discord.py-self` library.
197
195
  | **reactions** | 2 | add_reaction, remove_reaction |
198
196
  | **discrawl** | 7 | run_discrawl, discrawl_doctor, discrawl_status, discrawl_sync, discrawl_search, discrawl_messages, discrawl_mentions |
199
197
 
198
+ ### direct messages
199
+
200
+ `list_dm_channels` enumerates your open 1:1 and group DM channels so you can
201
+ discover a `channel_id` instead of needing to know it in advance. Each row is
202
+ `<channel_id> - [dm|group] <recipient display> (id=<user_id>) [BOT]`. Optional
203
+ args: `include_groups` (default `true`) and `name_contains` (case-insensitive
204
+ filter on recipient name/handle), e.g. find the DM with a person by name and
205
+ feed the id straight into `read_messages` / `send_message`.
206
+
207
+ ### slash commands
208
+
209
+ `send_slash_command` invokes an application command in a channel or DM. Pass
210
+ `application_id` (the bot's user/application ID) for reliable resolution; in a DM
211
+ with a bot it is inferred automatically. The command and any options are
212
+ resolved from the application's registered command list
213
+ (`GET /applications/{id}/commands`), which works for ordinary guild-installed
214
+ bots whose commands the per-channel `/` search index does not return. Subcommands
215
+ are space-separated in `command_name` (e.g. `"config set"`). Example:
216
+
217
+ ```json
218
+ {
219
+ "channel_id": "123456789012345678",
220
+ "command_name": "remind",
221
+ "application_id": "987654321098765432",
222
+ "options": { "text": "stand up", "when": "in 10 minutes" }
223
+ }
224
+ ```
225
+
200
226
  ### discrawl integration
201
227
 
202
228
  Use `run_discrawl` to execute local `discrawl` commands directly from MCP.
203
229
  Use typed tools for common operations (`discrawl_sync`, `discrawl_search`, `discrawl_messages`, etc.) when you want structured params.
204
- This fork prefers a sibling checkout at `../discrawl-self/bin/discrawl` when present, then falls back to `discrawl` in `PATH`.
230
+ By default this MCP uses the Microck fork at `../discrawl-self/bin/discrawl`:
231
+ `https://github.com/Microck/discrawl-self`. It does not silently fall back to a
232
+ global `discrawl` from `PATH`; set `DISCRAWL_BIN` or the tool `binary` argument
233
+ when you intentionally want another executable.
205
234
 
206
235
  Example tool call payload:
207
236
 
@@ -229,7 +258,7 @@ Typed tool payload example:
229
258
 
230
259
  Optional env var:
231
260
 
232
- - `DISCRAWL_BIN` - custom path to discrawl executable. This overrides the default fork-first lookup.
261
+ - `DISCRAWL_BIN` - custom path to discrawl executable. This overrides the default Microck fork lookup.
233
262
 
234
263
  ### attachment access
235
264
 
@@ -336,6 +365,7 @@ discord_py_self_mcp/
336
365
  │ └── solver.py
337
366
  └── tools/
338
367
  ├── channels.py
368
+ ├── dms.py
339
369
  ├── discrawl.py
340
370
  ├── embed.py
341
371
  ├── guilds.py
package/SKILL.md CHANGED
@@ -66,8 +66,11 @@ This server also exposes dedicated MCP tools to run local `discrawl` commands:
66
66
  - `discrawl_messages`
67
67
  - `discrawl_mentions`
68
68
 
69
- By default this MCP prefers a sibling fork build at `../discrawl-self/bin/discrawl`, then falls back to `discrawl` in `PATH`.
70
- Use `DISCRAWL_BIN` if you want to override that:
69
+ By default this MCP uses the Microck fork build at `../discrawl-self/bin/discrawl`
70
+ from `https://github.com/Microck/discrawl-self`. It does not silently fall back
71
+ to a global `discrawl` from `PATH`.
72
+
73
+ Use `DISCRAWL_BIN` if you want to intentionally override that:
71
74
 
72
75
  ```bash
73
76
  DISCRAWL_BIN=/absolute/path/to/discrawl
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "discord-selfbot-mcp",
3
- "version": "1.2.8",
3
+ "version": "1.4.0",
4
4
  "description": "Discord Selfbot MCP server - Node.js wrapper for Python implementation",
5
5
  "main": "index.js",
6
6
  "bin": {
package/scripts/daemon.py CHANGED
@@ -46,7 +46,11 @@ from discord_py_self_mcp.cli_runtime import (
46
46
  ensure_runtime_dir,
47
47
  )
48
48
  from discord_py_self_mcp.logging_utils import log_to_stderr
49
- from discord_py_self_mcp.tool_utils import NON_MESSAGEABLE_TEXT, validate_message_content
49
+ from discord_py_self_mcp.tool_utils import (
50
+ NON_MESSAGEABLE_TEXT,
51
+ build_reply_kwargs,
52
+ validate_message_content,
53
+ )
50
54
  from discord_py_self_mcp.tools.embed import serialize_attachment, serialize_message
51
55
 
52
56
  DAEMON_SCRIPT = SCRIPT_DIR / "daemon.py"
@@ -203,7 +207,9 @@ class DiscordDaemon:
203
207
  )
204
208
  if cmd == "send_message":
205
209
  return await self._send_message(
206
- args.get("channel_id"), args.get("content")
210
+ args.get("channel_id"),
211
+ args.get("content"),
212
+ args.get("reply_to_message_id"),
207
213
  )
208
214
  if cmd == "get_message_attachments":
209
215
  return await self._get_message_attachments(
@@ -313,7 +319,7 @@ class DiscordDaemon:
313
319
  messages.reverse()
314
320
  return {"messages": messages}
315
321
 
316
- async def _send_message(self, channel_id, content):
322
+ async def _send_message(self, channel_id, content, reply_to_message_id=None):
317
323
  content_error = validate_message_content(content or "")
318
324
  if content_error:
319
325
  return {"error": content_error}
@@ -326,7 +332,8 @@ class DiscordDaemon:
326
332
  if not isinstance(channel, discord.abc.Messageable):
327
333
  return {"error": NON_MESSAGEABLE_TEXT}
328
334
 
329
- message = await channel.send(content)
335
+ send_kwargs = build_reply_kwargs(reply_to_message_id, channel_id)
336
+ message = await channel.send(content, **send_kwargs)
330
337
  return {"message_id": message.id, "success": True}
331
338
 
332
339
  async def _get_message_attachments(
package/scripts/dcli.py CHANGED
@@ -4,7 +4,7 @@ Usage: python3 dcli.py <command> [args]
4
4
 
5
5
  Commands:
6
6
  daemon <start|stop|restart|status> - Manage daemon process
7
- send-message --channel ID --content "msg"
7
+ send-message --channel ID --content "msg" [--reply-to MESSAGE_ID]
8
8
  read-messages --channel ID [--limit N] [--after TIME]
9
9
  get-message-attachments --channel ID --message ID [--attachment-index N] [--download --output-dir DIR]
10
10
  list-guilds
@@ -244,11 +244,14 @@ def cmd_get_message_attachments(
244
244
  print(f" {destination}")
245
245
 
246
246
 
247
- def cmd_send_message(channel_id, content):
247
+ def cmd_send_message(channel_id, content, reply_to_message_id=None):
248
+ args = {"channel_id": channel_id, "content": content}
249
+ if reply_to_message_id is not None:
250
+ args["reply_to_message_id"] = reply_to_message_id
248
251
  result = send_request(
249
252
  {
250
253
  "command": "send_message",
251
- "args": {"channel_id": channel_id, "content": content},
254
+ "args": args,
252
255
  }
253
256
  )
254
257
  if "error" in result:
@@ -554,6 +557,7 @@ def main():
554
557
  send_parser = subparsers.add_parser("send-message", help="Send a message")
555
558
  send_parser.add_argument("--channel", "-c", required=True, type=int, help="Channel ID")
556
559
  send_parser.add_argument("--content", "-m", required=True, help="Message content")
560
+ send_parser.add_argument("--reply-to", "-r", type=int, default=None, help="Message ID to reply to")
557
561
 
558
562
  read_parser = subparsers.add_parser("read-messages", help="Read messages from channel")
559
563
  read_parser.add_argument("--channel", "-c", required=True, type=int, help="Channel ID")
@@ -635,7 +639,7 @@ def main():
635
639
  if args.command == "daemon":
636
640
  cmd_daemon(args.action)
637
641
  elif args.command == "send-message":
638
- cmd_send_message(args.channel, args.content)
642
+ cmd_send_message(args.channel, args.content, args.reply_to)
639
643
  elif args.command == "read-messages":
640
644
  cmd_read_messages(args.channel, args.limit, args.after)
641
645
  elif args.command == "get-message-attachments":
package/server.json CHANGED
@@ -6,14 +6,14 @@
6
6
  "url": "https://github.com/Microck/discord.py-self-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "1.2.8",
9
+ "version": "1.4.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "registryBaseUrl": "https://registry.npmjs.org",
14
14
  "identifier": "discord-selfbot-mcp",
15
15
  "runtimeHint": "python",
16
- "version": "1.2.8",
16
+ "version": "1.4.0",
17
17
  "packageArguments": [],
18
18
  "environmentVariables": [
19
19
  {
@@ -38,7 +38,7 @@
38
38
  },
39
39
  {
40
40
  "name": "DISCRAWL_BIN",
41
- "description": "Optional path to discrawl executable for the run_discrawl MCP tool. Overrides the default preference for ../discrawl-self/bin/discrawl.",
41
+ "description": "Optional path to discrawl executable for the run_discrawl MCP tool. Overrides the default Microck fork path at ../discrawl-self/bin/discrawl.",
42
42
  "format": "string",
43
43
  "isRequired": false
44
44
  }