neuron-mcp-server 1.0.0 → 1.1.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 (150) hide show
  1. package/.env +13 -0
  2. package/AI_PERSONALITY_DESIGN_RESEARCH.md +1020 -0
  3. package/Dockerfile +18 -0
  4. package/README.md +146 -131
  5. package/dist/client.d.ts +6 -0
  6. package/dist/client.js +50 -12
  7. package/dist/client.js.map +1 -1
  8. package/dist/index.js +51 -7
  9. package/dist/index.js.map +1 -1
  10. package/dist/tools/ai.js +9 -3
  11. package/dist/tools/ai.js.map +1 -1
  12. package/dist/tools/approvals.d.ts +2 -0
  13. package/dist/tools/approvals.js +181 -0
  14. package/dist/tools/approvals.js.map +1 -0
  15. package/dist/tools/audit.js +7 -4
  16. package/dist/tools/audit.js.map +1 -1
  17. package/dist/tools/auth.js +119 -19
  18. package/dist/tools/auth.js.map +1 -1
  19. package/dist/tools/billing.js +22 -6
  20. package/dist/tools/billing.js.map +1 -1
  21. package/dist/tools/blog.js +98 -34
  22. package/dist/tools/blog.js.map +1 -1
  23. package/dist/tools/bot-api-keys.js +27 -12
  24. package/dist/tools/bot-api-keys.js.map +1 -1
  25. package/dist/tools/bot-api.js +53 -27
  26. package/dist/tools/bot-api.js.map +1 -1
  27. package/dist/tools/bots.js +116 -68
  28. package/dist/tools/bots.js.map +1 -1
  29. package/dist/tools/broadcasts.js +78 -38
  30. package/dist/tools/broadcasts.js.map +1 -1
  31. package/dist/tools/builtin-tools.js +19 -12
  32. package/dist/tools/builtin-tools.js.map +1 -1
  33. package/dist/tools/campaigns.js +149 -61
  34. package/dist/tools/campaigns.js.map +1 -1
  35. package/dist/tools/channels.js +163 -53
  36. package/dist/tools/channels.js.map +1 -1
  37. package/dist/tools/contact-lists.js +111 -51
  38. package/dist/tools/contact-lists.js.map +1 -1
  39. package/dist/tools/contacts.js +117 -44
  40. package/dist/tools/contacts.js.map +1 -1
  41. package/dist/tools/conversations.js +95 -50
  42. package/dist/tools/conversations.js.map +1 -1
  43. package/dist/tools/flows.d.ts +2 -0
  44. package/dist/tools/flows.js +242 -0
  45. package/dist/tools/flows.js.map +1 -0
  46. package/dist/tools/group-management.d.ts +2 -0
  47. package/dist/tools/group-management.js +239 -0
  48. package/dist/tools/group-management.js.map +1 -0
  49. package/dist/tools/leads.d.ts +2 -0
  50. package/dist/tools/leads.js +100 -0
  51. package/dist/tools/leads.js.map +1 -0
  52. package/dist/tools/list-campaigns.d.ts +2 -0
  53. package/dist/tools/list-campaigns.js +152 -0
  54. package/dist/tools/list-campaigns.js.map +1 -0
  55. package/dist/tools/list-pool.js +250 -33
  56. package/dist/tools/list-pool.js.map +1 -1
  57. package/dist/tools/media.js +12 -7
  58. package/dist/tools/media.js.map +1 -1
  59. package/dist/tools/newsletters.js +106 -26
  60. package/dist/tools/newsletters.js.map +1 -1
  61. package/dist/tools/organizations.js +76 -35
  62. package/dist/tools/organizations.js.map +1 -1
  63. package/dist/tools/outbound-webhooks.js +32 -20
  64. package/dist/tools/outbound-webhooks.js.map +1 -1
  65. package/dist/tools/payouts.js +44 -17
  66. package/dist/tools/payouts.js.map +1 -1
  67. package/dist/tools/personas.d.ts +2 -0
  68. package/dist/tools/personas.js +141 -0
  69. package/dist/tools/personas.js.map +1 -0
  70. package/dist/tools/polls.d.ts +2 -0
  71. package/dist/tools/polls.js +30 -0
  72. package/dist/tools/polls.js.map +1 -0
  73. package/dist/tools/pool.js +101 -43
  74. package/dist/tools/pool.js.map +1 -1
  75. package/dist/tools/products.d.ts +2 -0
  76. package/dist/tools/products.js +277 -0
  77. package/dist/tools/products.js.map +1 -0
  78. package/dist/tools/profile-privacy.d.ts +2 -0
  79. package/dist/tools/profile-privacy.js +195 -0
  80. package/dist/tools/profile-privacy.js.map +1 -0
  81. package/dist/tools/reflections.js +25 -13
  82. package/dist/tools/reflections.js.map +1 -1
  83. package/dist/tools/scheduled-messages.d.ts +2 -0
  84. package/dist/tools/scheduled-messages.js +124 -0
  85. package/dist/tools/scheduled-messages.js.map +1 -0
  86. package/dist/tools/social-channels.d.ts +2 -0
  87. package/dist/tools/social-channels.js +318 -0
  88. package/dist/tools/social-channels.js.map +1 -0
  89. package/dist/tools/tasks.d.ts +2 -0
  90. package/dist/tools/tasks.js +155 -0
  91. package/dist/tools/tasks.js.map +1 -0
  92. package/dist/tools/tools.js +86 -40
  93. package/dist/tools/tools.js.map +1 -1
  94. package/dist/tools/wallets.js +34 -12
  95. package/dist/tools/wallets.js.map +1 -1
  96. package/dist/tools/webhooks.js +35 -20
  97. package/dist/tools/webhooks.js.map +1 -1
  98. package/dist/tools/whatsapp-actions.d.ts +2 -0
  99. package/dist/tools/whatsapp-actions.js +186 -0
  100. package/dist/tools/whatsapp-actions.js.map +1 -0
  101. package/package.json +4 -31
  102. package/scripts/setup-delivahere-bot.ts +804 -0
  103. package/scripts/test-delivahere-bot.ts +128 -0
  104. package/scripts/update-letschop-prompt.ts +194 -0
  105. package/server.json +26 -0
  106. package/smithery.yaml +19 -0
  107. package/src/client.ts +169 -0
  108. package/src/index.ts +256 -0
  109. package/src/tools/ai.ts +35 -0
  110. package/src/tools/approvals.ts +231 -0
  111. package/src/tools/audit.ts +49 -0
  112. package/src/tools/auth.ts +536 -0
  113. package/src/tools/billing.ts +79 -0
  114. package/src/tools/blog.ts +264 -0
  115. package/src/tools/bot-api-keys.ts +87 -0
  116. package/src/tools/bot-api.ts +193 -0
  117. package/src/tools/bots.ts +320 -0
  118. package/src/tools/broadcasts.ts +224 -0
  119. package/src/tools/builtin-tools.ts +108 -0
  120. package/src/tools/campaigns.ts +429 -0
  121. package/src/tools/channels.ts +520 -0
  122. package/src/tools/contact-lists.ts +320 -0
  123. package/src/tools/contacts.ts +395 -0
  124. package/src/tools/conversations.ts +349 -0
  125. package/src/tools/flows.ts +298 -0
  126. package/src/tools/group-management.ts +265 -0
  127. package/src/tools/knowledge-bases.ts +451 -0
  128. package/src/tools/leads.ts +104 -0
  129. package/src/tools/list-campaigns.ts +190 -0
  130. package/src/tools/list-pool.ts +389 -0
  131. package/src/tools/media.ts +50 -0
  132. package/src/tools/newsletters.ts +271 -0
  133. package/src/tools/organizations.ts +287 -0
  134. package/src/tools/outbound-webhooks.ts +181 -0
  135. package/src/tools/payouts.ts +133 -0
  136. package/src/tools/personas.ts +145 -0
  137. package/src/tools/polls.ts +32 -0
  138. package/src/tools/pool.ts +293 -0
  139. package/src/tools/products.ts +280 -0
  140. package/src/tools/profile-privacy.ts +215 -0
  141. package/src/tools/reflections.ts +124 -0
  142. package/src/tools/scheduled-messages.ts +144 -0
  143. package/src/tools/social-channels.ts +396 -0
  144. package/src/tools/tasks.ts +198 -0
  145. package/src/tools/tools.ts +255 -0
  146. package/src/tools/wallets.ts +107 -0
  147. package/src/tools/webhooks.ts +166 -0
  148. package/src/tools/whatsapp-actions.ts +203 -0
  149. package/tsconfig.json +20 -0
  150. package/LICENSE +0 -21
@@ -0,0 +1,520 @@
1
+ import { z } from "zod";
2
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { api, jsonResult, textResult, errorResult } from "../client.js";
4
+
5
+ export function registerChannelsTools(server: McpServer): void {
6
+ // 1. List all channels
7
+ server.registerTool(
8
+ "neuron_list_channels",
9
+ {
10
+ title: "List Channels",
11
+ description: "Retrieve all WhatsApp channels configured in the current organization, including their type and connection status.",
12
+ annotations: {
13
+ readOnlyHint: true,
14
+ destructiveHint: false,
15
+ idempotentHint: true,
16
+ openWorldHint: false,
17
+ },
18
+ inputSchema: z.object({}),
19
+ },
20
+ async () => {
21
+ try {
22
+ const response = await api("GET", "/channels");
23
+ return jsonResult(response);
24
+ } catch (error) {
25
+ return errorResult(error);
26
+ }
27
+ }
28
+ );
29
+
30
+ // 2. Create a new channel
31
+ server.registerTool(
32
+ "neuron_create_channel",
33
+ {
34
+ title: "Create Channel",
35
+ description: "Create a new WhatsApp channel with either Meta Cloud API or Baileys (direct WhatsApp) integration. Meta Cloud channels require metaPhoneNumberId and metaAccessToken.",
36
+ annotations: {
37
+ readOnlyHint: false,
38
+ destructiveHint: false,
39
+ idempotentHint: false,
40
+ openWorldHint: false,
41
+ },
42
+ inputSchema: z.object({
43
+ name: z.string().describe("Display name for the channel"),
44
+ type: z.enum(["meta_cloud", "baileys"]).describe("Integration type: 'meta_cloud' for Meta Cloud API or 'baileys' for direct WhatsApp connection"),
45
+ phoneNumber: z.string().optional().describe("Phone number for the channel (E.164 format, e.g., '+2348012345678')"),
46
+ metaPhoneNumberId: z.string().optional().describe("Meta Phone Number ID (required for meta_cloud type)"),
47
+ metaAccessToken: z.string().optional().describe("Meta Access Token (required for meta_cloud type)"),
48
+ }),
49
+ },
50
+ async (args) => {
51
+ try {
52
+ const response = await api("POST", "/channels", args);
53
+ return jsonResult(response);
54
+ } catch (error) {
55
+ return errorResult(error);
56
+ }
57
+ }
58
+ );
59
+
60
+ // 3. Get channel details
61
+ server.registerTool(
62
+ "neuron_get_channel",
63
+ {
64
+ title: "Get Channel",
65
+ description: "Retrieve detailed information about a specific WhatsApp channel, including its configuration, type, and connection status.",
66
+ annotations: {
67
+ readOnlyHint: true,
68
+ destructiveHint: false,
69
+ idempotentHint: true,
70
+ openWorldHint: false,
71
+ },
72
+ inputSchema: z.object({
73
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
74
+ }),
75
+ },
76
+ async (args) => {
77
+ try {
78
+ const response = await api("GET", `/channels/${args.id}`);
79
+ return jsonResult(response);
80
+ } catch (error) {
81
+ return errorResult(error);
82
+ }
83
+ }
84
+ );
85
+
86
+ // 4. Update channel
87
+ server.registerTool(
88
+ "neuron_update_channel",
89
+ {
90
+ title: "Update Channel",
91
+ description: "Update configuration of an existing WhatsApp channel. Only provided fields are modified; omitted fields remain unchanged.",
92
+ annotations: {
93
+ readOnlyHint: false,
94
+ destructiveHint: false,
95
+ idempotentHint: true,
96
+ openWorldHint: false,
97
+ },
98
+ inputSchema: z.object({
99
+ id: z.string().describe("Unique identifier (UUID) of the channel to update"),
100
+ name: z.string().optional().describe("New display name for the channel"),
101
+ phoneNumber: z.string().optional().describe("New phone number for the channel (E.164 format)"),
102
+ metaPhoneNumberId: z.string().optional().describe("New Meta Phone Number ID (meta_cloud channels only)"),
103
+ metaAccessToken: z.string().optional().describe("New Meta Access Token (meta_cloud channels only)"),
104
+ }),
105
+ },
106
+ async (args) => {
107
+ try {
108
+ const { id, ...updateData } = args;
109
+ const response = await api("PUT", `/channels/${id}`, updateData);
110
+ return jsonResult(response);
111
+ } catch (error) {
112
+ return errorResult(error);
113
+ }
114
+ }
115
+ );
116
+
117
+ // 5. Delete channel
118
+ server.registerTool(
119
+ "neuron_delete_channel",
120
+ {
121
+ title: "Delete Channel",
122
+ description: "Permanently delete a WhatsApp channel and disconnect any active sessions. This action cannot be undone.",
123
+ annotations: {
124
+ readOnlyHint: false,
125
+ destructiveHint: true,
126
+ idempotentHint: true,
127
+ openWorldHint: false,
128
+ },
129
+ inputSchema: z.object({
130
+ id: z.string().describe("Unique identifier (UUID) of the channel to delete"),
131
+ }),
132
+ },
133
+ async (args) => {
134
+ try {
135
+ const response = await api("DELETE", `/channels/${args.id}`);
136
+ return jsonResult(response);
137
+ } catch (error) {
138
+ return errorResult(error);
139
+ }
140
+ }
141
+ );
142
+
143
+ // 6. Assign bot to channel
144
+ server.registerTool(
145
+ "neuron_assign_bot_to_channel",
146
+ {
147
+ title: "Assign Bot to Channel",
148
+ description: "Assign a bot to handle incoming messages on a specific WhatsApp channel. Replaces any previously assigned bot.",
149
+ annotations: {
150
+ readOnlyHint: false,
151
+ destructiveHint: false,
152
+ idempotentHint: true,
153
+ openWorldHint: false,
154
+ },
155
+ inputSchema: z.object({
156
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
157
+ botId: z.string().describe("Unique identifier (UUID) of the bot to assign"),
158
+ }),
159
+ },
160
+ async (args) => {
161
+ try {
162
+ const { id, botId } = args;
163
+ const response = await api("POST", `/channels/${id}/assign-bot`, { botId });
164
+ return jsonResult(response);
165
+ } catch (error) {
166
+ return errorResult(error);
167
+ }
168
+ }
169
+ );
170
+
171
+ // 7. Unassign bot from channel
172
+ server.registerTool(
173
+ "neuron_unassign_bot_from_channel",
174
+ {
175
+ title: "Unassign Bot from Channel",
176
+ description: "Remove the bot assignment from a WhatsApp channel. The channel will stop auto-responding to messages.",
177
+ annotations: {
178
+ readOnlyHint: false,
179
+ destructiveHint: true,
180
+ idempotentHint: true,
181
+ openWorldHint: false,
182
+ },
183
+ inputSchema: z.object({
184
+ id: z.string().describe("Unique identifier (UUID) of the channel to unassign the bot from"),
185
+ }),
186
+ },
187
+ async (args) => {
188
+ try {
189
+ const response = await api("DELETE", `/channels/${args.id}/assign-bot`);
190
+ return jsonResult(response);
191
+ } catch (error) {
192
+ return errorResult(error);
193
+ }
194
+ }
195
+ );
196
+
197
+ // 8. Start channel session (Baileys)
198
+ server.registerTool(
199
+ "neuron_start_channel_session",
200
+ {
201
+ title: "Start Channel Session",
202
+ description: "Start a Baileys (direct WhatsApp) session for the channel. Generates a QR code for device pairing. Only applicable to Baileys-type channels.",
203
+ annotations: {
204
+ readOnlyHint: false,
205
+ destructiveHint: false,
206
+ idempotentHint: true,
207
+ openWorldHint: false,
208
+ },
209
+ inputSchema: z.object({
210
+ id: z.string().describe("Unique identifier (UUID) of the Baileys channel to start"),
211
+ }),
212
+ },
213
+ async (args) => {
214
+ try {
215
+ const response = await api("POST", `/channels/${args.id}/session/start`);
216
+ return jsonResult(response);
217
+ } catch (error) {
218
+ return errorResult(error);
219
+ }
220
+ }
221
+ );
222
+
223
+ // 9. Stop channel session
224
+ server.registerTool(
225
+ "neuron_stop_channel_session",
226
+ {
227
+ title: "Stop Channel Session",
228
+ description: "Stop the active Baileys session for the channel and disconnect from WhatsApp. The channel can be restarted later.",
229
+ annotations: {
230
+ readOnlyHint: false,
231
+ destructiveHint: false,
232
+ idempotentHint: true,
233
+ openWorldHint: false,
234
+ },
235
+ inputSchema: z.object({
236
+ id: z.string().describe("Unique identifier (UUID) of the Baileys channel to stop"),
237
+ }),
238
+ },
239
+ async (args) => {
240
+ try {
241
+ const response = await api("POST", `/channels/${args.id}/session/stop`);
242
+ return jsonResult(response);
243
+ } catch (error) {
244
+ return errorResult(error);
245
+ }
246
+ }
247
+ );
248
+
249
+ // 10. Get channel status
250
+ server.registerTool(
251
+ "neuron_get_channel_status",
252
+ {
253
+ title: "Get Channel Status",
254
+ description: "Retrieve the current connection status and session details for a specific channel (e.g., connected, disconnected, qr_pending).",
255
+ annotations: {
256
+ readOnlyHint: true,
257
+ destructiveHint: false,
258
+ idempotentHint: true,
259
+ openWorldHint: false,
260
+ },
261
+ inputSchema: z.object({
262
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
263
+ }),
264
+ },
265
+ async (args) => {
266
+ try {
267
+ const response = await api("GET", `/channels/${args.id}/session/status`);
268
+ return jsonResult(response);
269
+ } catch (error) {
270
+ return errorResult(error);
271
+ }
272
+ }
273
+ );
274
+
275
+ // 11. Request pair code
276
+ server.registerTool(
277
+ "neuron_request_pair_code",
278
+ {
279
+ title: "Request Pair Code",
280
+ description: "Request a numeric pairing code for a Baileys channel as an alternative to QR code scanning. Requires the phone number to pair with.",
281
+ annotations: {
282
+ readOnlyHint: false,
283
+ destructiveHint: false,
284
+ idempotentHint: false,
285
+ openWorldHint: false,
286
+ },
287
+ inputSchema: z.object({
288
+ id: z.string().describe("Unique identifier (UUID) of the Baileys channel"),
289
+ phoneNumber: z.string().describe("Phone number to generate the pair code for (E.164 format, e.g., '+2348012345678')"),
290
+ }),
291
+ },
292
+ async (args) => {
293
+ try {
294
+ const response = await api("POST", `/channels/${args.id}/pair-code`, { phoneNumber: args.phoneNumber });
295
+ return jsonResult(response);
296
+ } catch (error) {
297
+ return errorResult(error);
298
+ }
299
+ }
300
+ );
301
+
302
+ // 12. List channel groups
303
+ server.registerTool(
304
+ "neuron_list_channel_groups",
305
+ {
306
+ title: "List Channel Groups",
307
+ description: "Retrieve all WhatsApp groups that the channel is participating in, including group metadata.",
308
+ inputSchema: z.object({
309
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
310
+ }),
311
+ annotations: {
312
+ readOnlyHint: true,
313
+ destructiveHint: false,
314
+ idempotentHint: true,
315
+ openWorldHint: false,
316
+ },
317
+ },
318
+ async (args) => {
319
+ try {
320
+ const response = await api("GET", `/channels/${args.id}/groups`);
321
+ return jsonResult(response);
322
+ } catch (error) {
323
+ return errorResult(error);
324
+ }
325
+ }
326
+ );
327
+
328
+ // 13. Get group participants
329
+ server.registerTool(
330
+ "neuron_get_group_participants",
331
+ {
332
+ title: "Get Group Participants",
333
+ description: "Retrieve the list of participants in a specific WhatsApp group accessible through a channel.",
334
+ inputSchema: z.object({
335
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
336
+ groupJid: z.string().describe("JID (Jabber ID) of the WhatsApp group (e.g., '120363XXX@g.us')"),
337
+ }),
338
+ annotations: {
339
+ readOnlyHint: true,
340
+ destructiveHint: false,
341
+ idempotentHint: true,
342
+ openWorldHint: false,
343
+ },
344
+ },
345
+ async (args) => {
346
+ try {
347
+ const response = await api("GET", `/channels/${args.id}/groups/${args.groupJid}/participants`);
348
+ return jsonResult(response);
349
+ } catch (error) {
350
+ return errorResult(error);
351
+ }
352
+ }
353
+ );
354
+
355
+ // 14. List WhatsApp contacts
356
+ server.registerTool(
357
+ "neuron_list_whatsapp_contacts",
358
+ {
359
+ title: "List WhatsApp Contacts",
360
+ description: "Retrieve contacts from the WhatsApp account connected to this channel, with optional search filtering.",
361
+ inputSchema: z.object({
362
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
363
+ q: z.string().optional().describe("Search query to filter contacts by name or phone number"),
364
+ }),
365
+ annotations: {
366
+ readOnlyHint: true,
367
+ destructiveHint: false,
368
+ idempotentHint: true,
369
+ openWorldHint: false,
370
+ },
371
+ },
372
+ async (args) => {
373
+ try {
374
+ const response = await api("GET", `/channels/${args.id}/whatsapp-contacts`, undefined, {
375
+ q: args.q,
376
+ });
377
+ return jsonResult(response);
378
+ } catch (error) {
379
+ return errorResult(error);
380
+ }
381
+ }
382
+ );
383
+
384
+ // 15. Get channel events
385
+ server.registerTool(
386
+ "neuron_get_channel_events",
387
+ {
388
+ title: "Get Channel Events",
389
+ description: "Retrieve the event log for a channel, including connection events, message events, and errors. Supports pagination.",
390
+ inputSchema: z.object({
391
+ id: z.string().describe("Unique identifier (UUID) of the channel"),
392
+ page: z.number().int().positive().optional().describe("Page number for pagination (starts at 1)"),
393
+ limit: z.number().int().positive().optional().describe("Number of events to return per page"),
394
+ }),
395
+ annotations: {
396
+ readOnlyHint: true,
397
+ destructiveHint: false,
398
+ idempotentHint: true,
399
+ openWorldHint: false,
400
+ },
401
+ },
402
+ async (args) => {
403
+ try {
404
+ const response = await api("GET", `/channels/${args.id}/events`, undefined, {
405
+ page: args.page,
406
+ limit: args.limit,
407
+ });
408
+ return jsonResult(response);
409
+ } catch (error) {
410
+ return errorResult(error);
411
+ }
412
+ }
413
+ );
414
+
415
+ // 16. Get channel QR code
416
+ server.registerTool(
417
+ "neuron_get_channel_qr",
418
+ {
419
+ title: "Get Channel QR Code",
420
+ description: "Retrieve the current QR code for pairing a Baileys channel with WhatsApp. A session must be started first.",
421
+ annotations: {
422
+ readOnlyHint: true,
423
+ destructiveHint: false,
424
+ idempotentHint: true,
425
+ openWorldHint: false,
426
+ },
427
+ inputSchema: z.object({
428
+ id: z.string().describe("Unique identifier (UUID) of the Baileys channel"),
429
+ }),
430
+ },
431
+ async (args) => {
432
+ try {
433
+ const response = await api("GET", `/channels/${args.id}/qr`);
434
+ return jsonResult(response);
435
+ } catch (error) {
436
+ return errorResult(error);
437
+ }
438
+ }
439
+ );
440
+
441
+ // List bot channels
442
+ server.registerTool(
443
+ "neuron_list_bot_channels",
444
+ {
445
+ title: "List Bot Channels",
446
+ description: "Retrieve all WhatsApp channels connected to a specific bot, including primary and secondary connections.",
447
+ annotations: {
448
+ readOnlyHint: true,
449
+ destructiveHint: false,
450
+ idempotentHint: true,
451
+ openWorldHint: false,
452
+ },
453
+ inputSchema: z.object({
454
+ botId: z.string().describe("Unique identifier (UUID) of the bot"),
455
+ }),
456
+ },
457
+ async (args) => {
458
+ try {
459
+ const response = await api("GET", `/bots/${args.botId}/channels`);
460
+ return jsonResult(response);
461
+ } catch (error) {
462
+ return errorResult(error);
463
+ }
464
+ }
465
+ );
466
+
467
+ // Add bot channel
468
+ server.registerTool(
469
+ "neuron_add_bot_channel",
470
+ {
471
+ title: "Add Bot Channel",
472
+ description: "Connect an additional WhatsApp channel to a bot as a secondary number. The bot will respond to messages on this channel.",
473
+ annotations: {
474
+ readOnlyHint: false,
475
+ destructiveHint: false,
476
+ idempotentHint: false,
477
+ openWorldHint: false,
478
+ },
479
+ inputSchema: z.object({
480
+ botId: z.string().describe("Unique identifier (UUID) of the bot"),
481
+ channelId: z.string().describe("Unique identifier (UUID) of the WhatsApp channel to connect"),
482
+ }),
483
+ },
484
+ async (args) => {
485
+ try {
486
+ const response = await api("POST", `/bots/${args.botId}/channels`, { channelId: args.channelId });
487
+ return jsonResult(response);
488
+ } catch (error) {
489
+ return errorResult(error);
490
+ }
491
+ }
492
+ );
493
+
494
+ // Remove bot channel
495
+ server.registerTool(
496
+ "neuron_remove_bot_channel",
497
+ {
498
+ title: "Remove Bot Channel",
499
+ description: "Disconnect a WhatsApp channel from a bot. The bot will no longer respond to messages on this channel.",
500
+ annotations: {
501
+ readOnlyHint: false,
502
+ destructiveHint: true,
503
+ idempotentHint: true,
504
+ openWorldHint: false,
505
+ },
506
+ inputSchema: z.object({
507
+ botId: z.string().describe("Unique identifier (UUID) of the bot"),
508
+ channelId: z.string().describe("Unique identifier (UUID) of the WhatsApp channel to disconnect"),
509
+ }),
510
+ },
511
+ async (args) => {
512
+ try {
513
+ const response = await api("DELETE", `/bots/${args.botId}/channels/${args.channelId}`);
514
+ return jsonResult(response);
515
+ } catch (error) {
516
+ return errorResult(error);
517
+ }
518
+ }
519
+ );
520
+ }