discord-ops 0.2.0 → 0.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/CHANGELOG.md +19 -1
- package/README.md +198 -70
- package/dist/cli/index.js +45 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/setup.d.ts +7 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +397 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/client.d.ts +2 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +8 -3
- package/dist/client.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +21 -5
- package/dist/config/index.js.map +1 -1
- package/dist/config/schema.d.ts +9 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +3 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/server.d.ts +4 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +30 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/channels/index.d.ts +1 -0
- package/dist/tools/channels/index.d.ts.map +1 -1
- package/dist/tools/channels/index.js +1 -0
- package/dist/tools/channels/index.js.map +1 -1
- package/dist/tools/channels/permissions.d.ts +3 -0
- package/dist/tools/channels/permissions.d.ts.map +1 -0
- package/dist/tools/channels/permissions.js +34 -0
- package/dist/tools/channels/permissions.js.map +1 -0
- package/dist/tools/guilds/index.d.ts +1 -0
- package/dist/tools/guilds/index.d.ts.map +1 -1
- package/dist/tools/guilds/index.js +1 -0
- package/dist/tools/guilds/index.js.map +1 -1
- package/dist/tools/guilds/invites.d.ts +4 -0
- package/dist/tools/guilds/invites.d.ts.map +1 -0
- package/dist/tools/guilds/invites.js +93 -0
- package/dist/tools/guilds/invites.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +14 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/messaging/index.d.ts +3 -0
- package/dist/tools/messaging/index.d.ts.map +1 -1
- package/dist/tools/messaging/index.js +3 -0
- package/dist/tools/messaging/index.js.map +1 -1
- package/dist/tools/messaging/pin.d.ts +3 -0
- package/dist/tools/messaging/pin.d.ts.map +1 -0
- package/dist/tools/messaging/pin.js +24 -0
- package/dist/tools/messaging/pin.js.map +1 -0
- package/dist/tools/messaging/search.d.ts +3 -0
- package/dist/tools/messaging/search.d.ts.map +1 -0
- package/dist/tools/messaging/search.js +61 -0
- package/dist/tools/messaging/search.js.map +1 -0
- package/dist/tools/messaging/unpin.d.ts +3 -0
- package/dist/tools/messaging/unpin.d.ts.map +1 -0
- package/dist/tools/messaging/unpin.js +24 -0
- package/dist/tools/messaging/unpin.js.map +1 -0
- package/dist/tools/threads/archive.d.ts +3 -0
- package/dist/tools/threads/archive.d.ts.map +1 -0
- package/dist/tools/threads/archive.js +33 -0
- package/dist/tools/threads/archive.js.map +1 -0
- package/dist/tools/threads/index.d.ts +1 -0
- package/dist/tools/threads/index.d.ts.map +1 -1
- package/dist/tools/threads/index.js +1 -0
- package/dist/tools/threads/index.js.map +1 -1
- package/dist/transport/http.d.ts +6 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +81 -0
- package/dist/transport/http.js.map +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
# discord-ops
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e335fdf: Flexible token configuration for multi-org MCP setups
|
|
8
|
+
- `DISCORD_OPS_TOKEN_ENV` meta-variable lets you point the default token at any env var (not just `DISCORD_TOKEN`)
|
|
9
|
+
- Default token is now optional when all projects specify `token_env` — enables multi-org setups where each project uses its own bot
|
|
10
|
+
- Improved error messages when token resolution fails
|
|
11
|
+
- Updated README with multi-org setup examples and token resolution documentation
|
|
12
|
+
|
|
3
13
|
## 0.3.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
|
6
16
|
|
|
7
|
-
-
|
|
17
|
+
- 6e421f2: Add 8 new tools (pin/unpin message, search messages, archive thread, set channel permissions, get/create invites), HTTP/SSE transport, dry-run mode for destructive operations, and interactive CLI setup wizard.
|
|
18
|
+
|
|
19
|
+
## 0.2.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- 17 new tools: moderation (kick, ban, unban, timeout), role CRUD + assign, webhook CRUD + execute, audit log query, channel moderation (purge, slowmode, edit, delete)
|
|
24
|
+
- Security hardening: rate limiting, permission pre-flight checks, snowflake validation, self-protection guards, error sanitization
|
|
25
|
+
- Local CI infrastructure (act-ci.sh + act-ci.yml)
|
|
8
26
|
|
|
9
27
|
## 0.1.0
|
|
10
28
|
|
package/README.md
CHANGED
|
@@ -8,10 +8,14 @@ Agency-grade Discord MCP server with multi-guild project routing.
|
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- **
|
|
11
|
+
- **42 MCP tools** — messaging, channels, moderation, roles, webhooks, audit log, threads, guilds, invites, permissions, search
|
|
12
12
|
- **Multi-guild project routing** — `send_message({ project: "my-app", channel: "builds" })` instead of raw channel IDs
|
|
13
13
|
- **Notification routing** — map notification types (ci_build, deploy, error) to channels per project
|
|
14
|
-
- **Multi-bot support** — manage multiple Discord bots from a single MCP server
|
|
14
|
+
- **Multi-bot support** — manage multiple Discord bots from a single MCP server with per-project tokens
|
|
15
|
+
- **Flexible token configuration** — configurable default token env var, optional default token when all projects use per-project tokens
|
|
16
|
+
- **HTTP/SSE + stdio transports** — stdio for Claude Code, HTTP/SSE for remote MCP clients
|
|
17
|
+
- **Dry-run mode** — simulate destructive operations without calling Discord API
|
|
18
|
+
- **Interactive setup wizard** — `discord-ops setup` walks through config creation
|
|
15
19
|
- **Security hardening** — rate limiting, permission pre-flight checks, snowflake ID validation, self-protection guards
|
|
16
20
|
- **Lazy login** — tools enumerate before Discord connects; first tool call triggers login
|
|
17
21
|
- **Zod validation** — all inputs validated before execution
|
|
@@ -25,14 +29,18 @@ Agency-grade Discord MCP server with multi-guild project routing.
|
|
|
25
29
|
# Install
|
|
26
30
|
npm install -g discord-ops
|
|
27
31
|
|
|
28
|
-
#
|
|
29
|
-
|
|
32
|
+
# Interactive setup (creates ~/.discord-ops.json)
|
|
33
|
+
discord-ops setup
|
|
30
34
|
|
|
31
|
-
#
|
|
35
|
+
# Or manual setup
|
|
36
|
+
export DISCORD_TOKEN="your-bot-token"
|
|
32
37
|
discord-ops health
|
|
33
38
|
|
|
34
39
|
# Start MCP server (stdio)
|
|
35
40
|
discord-ops
|
|
41
|
+
|
|
42
|
+
# Start MCP server (HTTP/SSE)
|
|
43
|
+
discord-ops serve --port 3000
|
|
36
44
|
```
|
|
37
45
|
|
|
38
46
|
## Claude Code Integration
|
|
@@ -53,6 +61,44 @@ Add to your `.mcp.json`:
|
|
|
53
61
|
}
|
|
54
62
|
```
|
|
55
63
|
|
|
64
|
+
### Multi-org setup (per-project tokens, no default)
|
|
65
|
+
|
|
66
|
+
When each project uses its own bot token, you don't need `DISCORD_TOKEN` at all:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"mcpServers": {
|
|
71
|
+
"discord": {
|
|
72
|
+
"command": "npx",
|
|
73
|
+
"args": ["-y", "discord-ops"],
|
|
74
|
+
"env": {
|
|
75
|
+
"PROJECT_A_TOKEN": "bot-token-for-project-a",
|
|
76
|
+
"PROJECT_B_TOKEN": "bot-token-for-project-b"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Custom default token env var
|
|
84
|
+
|
|
85
|
+
If another tool already claims `DISCORD_TOKEN`, use `DISCORD_OPS_TOKEN_ENV` to point at a different env var:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"discord": {
|
|
91
|
+
"command": "npx",
|
|
92
|
+
"args": ["-y", "discord-ops"],
|
|
93
|
+
"env": {
|
|
94
|
+
"DISCORD_OPS_TOKEN_ENV": "MY_DISCORD_BOT_TOKEN",
|
|
95
|
+
"MY_DISCORD_BOT_TOKEN": "your-bot-token"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
56
102
|
## Project Routing
|
|
57
103
|
|
|
58
104
|
The killer feature: route messages by project name and channel alias instead of raw IDs.
|
|
@@ -81,6 +127,31 @@ The killer feature: route messages by project name and channel alias instead of
|
|
|
81
127
|
}
|
|
82
128
|
```
|
|
83
129
|
|
|
130
|
+
### Per-project bot tokens
|
|
131
|
+
|
|
132
|
+
Projects can specify their own bot token via `token_env`:
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"projects": {
|
|
137
|
+
"org-a": {
|
|
138
|
+
"guild_id": "111111111111111111",
|
|
139
|
+
"channels": { "dev": "CHANNEL_ID" },
|
|
140
|
+
"default_channel": "dev",
|
|
141
|
+
"token_env": "ORG_A_DISCORD_TOKEN"
|
|
142
|
+
},
|
|
143
|
+
"org-b": {
|
|
144
|
+
"guild_id": "222222222222222222",
|
|
145
|
+
"channels": { "dev": "CHANNEL_ID" },
|
|
146
|
+
"default_channel": "dev",
|
|
147
|
+
"token_env": "ORG_B_DISCORD_TOKEN"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
When all projects have `token_env`, the default `DISCORD_TOKEN` is optional. Each project connects with its own bot.
|
|
154
|
+
|
|
84
155
|
### Per-project config (`.discord-ops.json` in repo root)
|
|
85
156
|
|
|
86
157
|
```json
|
|
@@ -108,83 +179,140 @@ send_message({ channel_id: "123456789", content: "Hello" })
|
|
|
108
179
|
|
|
109
180
|
## Tools
|
|
110
181
|
|
|
111
|
-
### Messaging
|
|
112
|
-
|
|
113
|
-
| Tool
|
|
114
|
-
|
|
|
115
|
-
| `send_message`
|
|
116
|
-
| `get_messages`
|
|
117
|
-
| `edit_message`
|
|
118
|
-
| `delete_message`
|
|
119
|
-
| `add_reaction`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
| `
|
|
131
|
-
| `
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
|
140
|
-
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
|
149
|
-
|
|
|
182
|
+
### Messaging (8 tools)
|
|
183
|
+
|
|
184
|
+
| Tool | Description |
|
|
185
|
+
| ----------------- | ------------------------------------------------- |
|
|
186
|
+
| `send_message` | Send a message with project routing |
|
|
187
|
+
| `get_messages` | Fetch recent messages |
|
|
188
|
+
| `edit_message` | Edit a bot message |
|
|
189
|
+
| `delete_message` | Delete a message |
|
|
190
|
+
| `add_reaction` | React to a message |
|
|
191
|
+
| `pin_message` | Pin a message in a channel |
|
|
192
|
+
| `unpin_message` | Unpin a message |
|
|
193
|
+
| `search_messages` | Search messages by content, author, or date range |
|
|
194
|
+
|
|
195
|
+
### Channels (8 tools)
|
|
196
|
+
|
|
197
|
+
| Tool | Description |
|
|
198
|
+
| ----------------- | ----------------------------------------------------- |
|
|
199
|
+
| `list_channels` | List guild channels |
|
|
200
|
+
| `get_channel` | Get channel details |
|
|
201
|
+
| `create_channel` | Create a channel |
|
|
202
|
+
| `edit_channel` | Edit channel properties |
|
|
203
|
+
| `delete_channel` | Delete a channel |
|
|
204
|
+
| `purge_messages` | Bulk-delete messages (max 100, < 14 days old) |
|
|
205
|
+
| `set_slowmode` | Set or disable slowmode |
|
|
206
|
+
| `set_permissions` | Set channel permission overrides for a role or member |
|
|
207
|
+
|
|
208
|
+
### Moderation (4 tools)
|
|
209
|
+
|
|
210
|
+
| Tool | Description |
|
|
211
|
+
| ---------------- | -------------------------- |
|
|
212
|
+
| `kick_member` | Kick a member from a guild |
|
|
213
|
+
| `ban_member` | Ban a user from a guild |
|
|
214
|
+
| `unban_member` | Unban a user |
|
|
215
|
+
| `timeout_member` | Timeout (mute) a member |
|
|
216
|
+
|
|
217
|
+
### Roles (5 tools)
|
|
218
|
+
|
|
219
|
+
| Tool | Description |
|
|
220
|
+
| ------------- | ---------------------------------- |
|
|
221
|
+
| `list_roles` | List guild roles |
|
|
222
|
+
| `create_role` | Create a new role |
|
|
223
|
+
| `edit_role` | Edit role properties |
|
|
224
|
+
| `delete_role` | Delete a role |
|
|
150
225
|
| `assign_role` | Add or remove a role from a member |
|
|
151
226
|
|
|
152
|
-
### Webhooks
|
|
227
|
+
### Webhooks (6 tools)
|
|
153
228
|
|
|
154
|
-
| Tool
|
|
155
|
-
|
|
|
156
|
-
| `create_webhook`
|
|
157
|
-
| `get_webhook`
|
|
158
|
-
| `list_webhooks`
|
|
159
|
-
| `edit_webhook`
|
|
160
|
-
| `delete_webhook`
|
|
161
|
-
| `execute_webhook` | Send a message via webhook
|
|
229
|
+
| Tool | Description |
|
|
230
|
+
| ----------------- | ------------------------------------ |
|
|
231
|
+
| `create_webhook` | Create a webhook on a channel |
|
|
232
|
+
| `get_webhook` | Get webhook details |
|
|
233
|
+
| `list_webhooks` | List webhooks for a guild or channel |
|
|
234
|
+
| `edit_webhook` | Edit webhook properties |
|
|
235
|
+
| `delete_webhook` | Delete a webhook |
|
|
236
|
+
| `execute_webhook` | Send a message via webhook |
|
|
162
237
|
|
|
163
|
-
### Audit
|
|
238
|
+
### Audit (1 tool)
|
|
164
239
|
|
|
165
|
-
| Tool
|
|
166
|
-
|
|
|
240
|
+
| Tool | Description |
|
|
241
|
+
| ----------------- | ---------------------------------- |
|
|
167
242
|
| `query_audit_log` | Query guild audit log with filters |
|
|
168
243
|
|
|
169
|
-
###
|
|
244
|
+
### Guilds & Members (6 tools)
|
|
245
|
+
|
|
246
|
+
| Tool | Description |
|
|
247
|
+
| --------------- | ----------------------------------- |
|
|
248
|
+
| `list_guilds` | List bot's guilds |
|
|
249
|
+
| `get_guild` | Get guild details |
|
|
250
|
+
| `get_invites` | Get all active invites for a guild |
|
|
251
|
+
| `create_invite` | Create an invite link for a channel |
|
|
252
|
+
| `list_members` | List guild members |
|
|
253
|
+
| `get_member` | Get member details |
|
|
254
|
+
|
|
255
|
+
### Threads (3 tools)
|
|
256
|
+
|
|
257
|
+
| Tool | Description |
|
|
258
|
+
| ---------------- | -------------------------------------- |
|
|
259
|
+
| `create_thread` | Create a thread |
|
|
260
|
+
| `list_threads` | List active threads |
|
|
261
|
+
| `archive_thread` | Archive (and optionally lock) a thread |
|
|
170
262
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
|
174
|
-
|
|
|
175
|
-
| `list_members` | List guild members |
|
|
176
|
-
| `get_member` | Get member details |
|
|
177
|
-
| `create_thread` | Create a thread |
|
|
178
|
-
| `list_threads` | List active threads |
|
|
263
|
+
### System (1 tool)
|
|
264
|
+
|
|
265
|
+
| Tool | Description |
|
|
266
|
+
| -------------- | ------------------------ |
|
|
179
267
|
| `health_check` | Bot status + permissions |
|
|
180
268
|
|
|
269
|
+
## CLI
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
discord-ops Start MCP server (stdio transport)
|
|
273
|
+
discord-ops serve Start MCP server (HTTP/SSE transport)
|
|
274
|
+
discord-ops setup Interactive setup wizard
|
|
275
|
+
discord-ops health Run health check + permission audit
|
|
276
|
+
discord-ops --dry-run Simulate destructive operations
|
|
277
|
+
discord-ops --help Show help
|
|
278
|
+
discord-ops --version Show version
|
|
279
|
+
```
|
|
280
|
+
|
|
181
281
|
## Environment Variables
|
|
182
282
|
|
|
183
|
-
| Variable
|
|
184
|
-
|
|
|
185
|
-
| `DISCORD_TOKEN` |
|
|
186
|
-
| `
|
|
187
|
-
| `
|
|
283
|
+
| Variable | Required | Description |
|
|
284
|
+
| ----------------------- | -------- | --------------------------------------------------------------------------- |
|
|
285
|
+
| `DISCORD_TOKEN` | No\* | Default Discord bot token (\*required unless all projects have `token_env`) |
|
|
286
|
+
| `DISCORD_OPS_TOKEN_ENV` | No | Override which env var holds the default token (default: `DISCORD_TOKEN`) |
|
|
287
|
+
| `<PROJECT>_TOKEN` | No | Per-project bot tokens (configured via `token_env` in project config) |
|
|
288
|
+
| `DISCORD_OPS_CONFIG` | No | Path to global config file (default: `~/.discord-ops.json`) |
|
|
289
|
+
| `DISCORD_OPS_LOG_LEVEL` | No | `debug`, `info`, `warn`, `error` (default: `info`) |
|
|
290
|
+
| `DISCORD_OPS_DRY_RUN` | No | Enable dry-run mode (any truthy value) |
|
|
291
|
+
| `DRY_RUN` | No | Enable dry-run mode (any truthy value, alias) |
|
|
292
|
+
|
|
293
|
+
### Token resolution
|
|
294
|
+
|
|
295
|
+
1. If `DISCORD_OPS_TOKEN_ENV` is set, its value names the env var holding the default token (e.g., `DISCORD_OPS_TOKEN_ENV=MY_BOT_TOKEN` reads `MY_BOT_TOKEN`).
|
|
296
|
+
2. Otherwise, the default token comes from `DISCORD_TOKEN`.
|
|
297
|
+
3. Per-project tokens override the default: if a project config has `"token_env": "ORG_A_TOKEN"`, that project's bot uses `ORG_A_TOKEN`.
|
|
298
|
+
4. If all projects have `token_env` set with valid values, no default token is needed at all.
|
|
299
|
+
|
|
300
|
+
## Dry-Run Mode
|
|
301
|
+
|
|
302
|
+
Enable dry-run to simulate destructive operations (delete, ban, kick, etc.) without actually calling the Discord API:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
# Via CLI flag
|
|
306
|
+
discord-ops --dry-run
|
|
307
|
+
|
|
308
|
+
# Via environment variable
|
|
309
|
+
DISCORD_OPS_DRY_RUN=1 discord-ops
|
|
310
|
+
|
|
311
|
+
# Via env alias
|
|
312
|
+
DRY_RUN=true discord-ops
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
In dry-run mode, destructive tools return a simulated success response showing what would have happened.
|
|
188
316
|
|
|
189
317
|
## Development
|
|
190
318
|
|
package/dist/cli/index.js
CHANGED
|
@@ -3,7 +3,9 @@ import { loadConfig } from "../config/index.js";
|
|
|
3
3
|
import { DiscordClient } from "../client.js";
|
|
4
4
|
import { createServer } from "../server.js";
|
|
5
5
|
import { startStdioTransport } from "../transport/stdio.js";
|
|
6
|
+
import { startHttpTransport } from "../transport/http.js";
|
|
6
7
|
import { logger, setLogLevel } from "../utils/logger.js";
|
|
8
|
+
import { runSetup } from "./setup.js";
|
|
7
9
|
async function main() {
|
|
8
10
|
const args = process.argv.slice(2);
|
|
9
11
|
// Handle --help
|
|
@@ -13,7 +15,7 @@ async function main() {
|
|
|
13
15
|
}
|
|
14
16
|
// Handle --version
|
|
15
17
|
if (args.includes("--version") || args.includes("-v")) {
|
|
16
|
-
console.log("discord-ops 0.
|
|
18
|
+
console.log("discord-ops 0.3.0");
|
|
17
19
|
process.exit(0);
|
|
18
20
|
}
|
|
19
21
|
// Handle health subcommand
|
|
@@ -21,6 +23,14 @@ async function main() {
|
|
|
21
23
|
await runHealthCheck();
|
|
22
24
|
return;
|
|
23
25
|
}
|
|
26
|
+
// Handle setup subcommand
|
|
27
|
+
if (args[0] === "setup") {
|
|
28
|
+
await runSetup();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// Parse global flags
|
|
32
|
+
const dryRun = args.includes("--dry-run");
|
|
33
|
+
const serverOptions = { dryRun };
|
|
24
34
|
// Configure log level
|
|
25
35
|
const logLevel = process.env.DISCORD_OPS_LOG_LEVEL;
|
|
26
36
|
if (logLevel)
|
|
@@ -30,8 +40,27 @@ async function main() {
|
|
|
30
40
|
// Create lazy Discord client
|
|
31
41
|
const discord = new DiscordClient(config.defaultToken);
|
|
32
42
|
// Create MCP server with tool context
|
|
33
|
-
const server = createServer({ discord, config });
|
|
34
|
-
//
|
|
43
|
+
const server = createServer({ discord, config }, serverOptions);
|
|
44
|
+
// Handle serve subcommand (HTTP/SSE transport)
|
|
45
|
+
if (args[0] === "serve") {
|
|
46
|
+
const portIndex = args.indexOf("--port");
|
|
47
|
+
const port = portIndex !== -1 ? parseInt(args[portIndex + 1], 10) : undefined;
|
|
48
|
+
if (portIndex !== -1 && (!port || isNaN(port))) {
|
|
49
|
+
console.error("Invalid --port value");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
await startHttpTransport(server, { port });
|
|
53
|
+
// Graceful shutdown
|
|
54
|
+
const shutdown = async () => {
|
|
55
|
+
logger.info("Shutting down...");
|
|
56
|
+
await discord.destroy();
|
|
57
|
+
process.exit(0);
|
|
58
|
+
};
|
|
59
|
+
process.on("SIGINT", shutdown);
|
|
60
|
+
process.on("SIGTERM", shutdown);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Default: start stdio transport
|
|
35
64
|
await startStdioTransport(server);
|
|
36
65
|
// Graceful shutdown
|
|
37
66
|
const shutdown = async () => {
|
|
@@ -48,7 +77,9 @@ async function runHealthCheck() {
|
|
|
48
77
|
const discord = new DiscordClient(config.defaultToken);
|
|
49
78
|
// Collect unique tokens: default + any project-specific ones
|
|
50
79
|
const tokens = new Map(); // token → project names
|
|
51
|
-
|
|
80
|
+
if (config.defaultToken) {
|
|
81
|
+
tokens.set(config.defaultToken, ["(default)"]);
|
|
82
|
+
}
|
|
52
83
|
for (const [name, project] of Object.entries(config.global.projects)) {
|
|
53
84
|
if (project.token_env) {
|
|
54
85
|
const t = process.env[project.token_env];
|
|
@@ -91,15 +122,24 @@ discord-ops - Agency-grade Discord MCP server
|
|
|
91
122
|
|
|
92
123
|
USAGE:
|
|
93
124
|
discord-ops Start MCP server (stdio transport)
|
|
125
|
+
discord-ops serve Start MCP server (HTTP/SSE transport)
|
|
126
|
+
discord-ops setup Interactive setup wizard
|
|
94
127
|
discord-ops health Run health check + permission audit
|
|
95
128
|
discord-ops --help Show this help
|
|
96
129
|
discord-ops --version Show version
|
|
97
130
|
|
|
131
|
+
OPTIONS:
|
|
132
|
+
--dry-run Simulate destructive operations without calling Discord API
|
|
133
|
+
--port <port> HTTP port for serve mode (default: 3000)
|
|
134
|
+
|
|
98
135
|
ENVIRONMENT:
|
|
99
|
-
DISCORD_TOKEN Default Discord bot token (required)
|
|
136
|
+
DISCORD_TOKEN Default Discord bot token (required unless all projects have token_env)
|
|
137
|
+
DISCORD_OPS_TOKEN_ENV Override which env var holds the default token (default: DISCORD_TOKEN)
|
|
100
138
|
<PROJECT>_TOKEN Per-project bot tokens (configured via token_env in config)
|
|
101
139
|
DISCORD_OPS_CONFIG Path to global config file (default: ~/.discord-ops.json)
|
|
102
140
|
DISCORD_OPS_LOG_LEVEL Log level: debug, info, warn, error (default: info)
|
|
141
|
+
DISCORD_OPS_DRY_RUN Enable dry-run mode (any truthy value)
|
|
142
|
+
DRY_RUN Enable dry-run mode (any truthy value, alias)
|
|
103
143
|
|
|
104
144
|
CONFIG FILES:
|
|
105
145
|
~/.discord-ops.json Global project routing config
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interactive setup wizard for discord-ops configuration.
|
|
3
|
+
* Walks users through bot token verification, guild selection,
|
|
4
|
+
* channel aliasing, and notification routing.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runSetup(): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/cli/setup.ts"],"names":[],"mappings":"AA2CA;;;;GAIG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAqH9C"}
|