neuron-mcp-server 1.0.1 → 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.
- package/.env +13 -0
- package/AI_PERSONALITY_DESIGN_RESEARCH.md +1020 -0
- package/Dockerfile +18 -0
- package/README.md +146 -131
- package/dist/client.d.ts +6 -0
- package/dist/client.js +50 -12
- package/dist/client.js.map +1 -1
- package/dist/index.js +51 -7
- package/dist/index.js.map +1 -1
- package/dist/tools/ai.js +9 -3
- package/dist/tools/ai.js.map +1 -1
- package/dist/tools/approvals.d.ts +2 -0
- package/dist/tools/approvals.js +181 -0
- package/dist/tools/approvals.js.map +1 -0
- package/dist/tools/audit.js +7 -4
- package/dist/tools/audit.js.map +1 -1
- package/dist/tools/auth.js +119 -19
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/billing.js +22 -6
- package/dist/tools/billing.js.map +1 -1
- package/dist/tools/blog.js +98 -34
- package/dist/tools/blog.js.map +1 -1
- package/dist/tools/bot-api-keys.js +27 -12
- package/dist/tools/bot-api-keys.js.map +1 -1
- package/dist/tools/bot-api.js +53 -27
- package/dist/tools/bot-api.js.map +1 -1
- package/dist/tools/bots.js +116 -68
- package/dist/tools/bots.js.map +1 -1
- package/dist/tools/broadcasts.js +78 -38
- package/dist/tools/broadcasts.js.map +1 -1
- package/dist/tools/builtin-tools.js +19 -12
- package/dist/tools/builtin-tools.js.map +1 -1
- package/dist/tools/campaigns.js +149 -61
- package/dist/tools/campaigns.js.map +1 -1
- package/dist/tools/channels.js +163 -53
- package/dist/tools/channels.js.map +1 -1
- package/dist/tools/contact-lists.js +111 -51
- package/dist/tools/contact-lists.js.map +1 -1
- package/dist/tools/contacts.js +117 -44
- package/dist/tools/contacts.js.map +1 -1
- package/dist/tools/conversations.js +95 -50
- package/dist/tools/conversations.js.map +1 -1
- package/dist/tools/flows.d.ts +2 -0
- package/dist/tools/flows.js +242 -0
- package/dist/tools/flows.js.map +1 -0
- package/dist/tools/group-management.d.ts +2 -0
- package/dist/tools/group-management.js +239 -0
- package/dist/tools/group-management.js.map +1 -0
- package/dist/tools/leads.d.ts +2 -0
- package/dist/tools/leads.js +100 -0
- package/dist/tools/leads.js.map +1 -0
- package/dist/tools/list-campaigns.d.ts +2 -0
- package/dist/tools/list-campaigns.js +152 -0
- package/dist/tools/list-campaigns.js.map +1 -0
- package/dist/tools/list-pool.js +250 -33
- package/dist/tools/list-pool.js.map +1 -1
- package/dist/tools/media.js +12 -7
- package/dist/tools/media.js.map +1 -1
- package/dist/tools/newsletters.js +106 -26
- package/dist/tools/newsletters.js.map +1 -1
- package/dist/tools/organizations.js +76 -35
- package/dist/tools/organizations.js.map +1 -1
- package/dist/tools/outbound-webhooks.js +32 -20
- package/dist/tools/outbound-webhooks.js.map +1 -1
- package/dist/tools/payouts.js +44 -17
- package/dist/tools/payouts.js.map +1 -1
- package/dist/tools/personas.d.ts +2 -0
- package/dist/tools/personas.js +141 -0
- package/dist/tools/personas.js.map +1 -0
- package/dist/tools/polls.d.ts +2 -0
- package/dist/tools/polls.js +30 -0
- package/dist/tools/polls.js.map +1 -0
- package/dist/tools/pool.js +101 -43
- package/dist/tools/pool.js.map +1 -1
- package/dist/tools/products.d.ts +2 -0
- package/dist/tools/products.js +277 -0
- package/dist/tools/products.js.map +1 -0
- package/dist/tools/profile-privacy.d.ts +2 -0
- package/dist/tools/profile-privacy.js +195 -0
- package/dist/tools/profile-privacy.js.map +1 -0
- package/dist/tools/reflections.js +25 -13
- package/dist/tools/reflections.js.map +1 -1
- package/dist/tools/scheduled-messages.d.ts +2 -0
- package/dist/tools/scheduled-messages.js +124 -0
- package/dist/tools/scheduled-messages.js.map +1 -0
- package/dist/tools/social-channels.d.ts +2 -0
- package/dist/tools/social-channels.js +318 -0
- package/dist/tools/social-channels.js.map +1 -0
- package/dist/tools/tasks.d.ts +2 -0
- package/dist/tools/tasks.js +155 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/tools.js +86 -40
- package/dist/tools/tools.js.map +1 -1
- package/dist/tools/wallets.js +34 -12
- package/dist/tools/wallets.js.map +1 -1
- package/dist/tools/webhooks.js +35 -20
- package/dist/tools/webhooks.js.map +1 -1
- package/dist/tools/whatsapp-actions.d.ts +2 -0
- package/dist/tools/whatsapp-actions.js +186 -0
- package/dist/tools/whatsapp-actions.js.map +1 -0
- package/package.json +3 -31
- package/scripts/setup-delivahere-bot.ts +804 -0
- package/scripts/test-delivahere-bot.ts +128 -0
- package/scripts/update-letschop-prompt.ts +194 -0
- package/server.json +26 -0
- package/smithery.yaml +19 -0
- package/src/client.ts +169 -0
- package/src/index.ts +256 -0
- package/src/tools/ai.ts +35 -0
- package/src/tools/approvals.ts +231 -0
- package/src/tools/audit.ts +49 -0
- package/src/tools/auth.ts +536 -0
- package/src/tools/billing.ts +79 -0
- package/src/tools/blog.ts +264 -0
- package/src/tools/bot-api-keys.ts +87 -0
- package/src/tools/bot-api.ts +193 -0
- package/src/tools/bots.ts +320 -0
- package/src/tools/broadcasts.ts +224 -0
- package/src/tools/builtin-tools.ts +108 -0
- package/src/tools/campaigns.ts +429 -0
- package/src/tools/channels.ts +520 -0
- package/src/tools/contact-lists.ts +320 -0
- package/src/tools/contacts.ts +395 -0
- package/src/tools/conversations.ts +349 -0
- package/src/tools/flows.ts +298 -0
- package/src/tools/group-management.ts +265 -0
- package/src/tools/knowledge-bases.ts +451 -0
- package/src/tools/leads.ts +104 -0
- package/src/tools/list-campaigns.ts +190 -0
- package/src/tools/list-pool.ts +389 -0
- package/src/tools/media.ts +50 -0
- package/src/tools/newsletters.ts +271 -0
- package/src/tools/organizations.ts +287 -0
- package/src/tools/outbound-webhooks.ts +181 -0
- package/src/tools/payouts.ts +133 -0
- package/src/tools/personas.ts +145 -0
- package/src/tools/polls.ts +32 -0
- package/src/tools/pool.ts +293 -0
- package/src/tools/products.ts +280 -0
- package/src/tools/profile-privacy.ts +215 -0
- package/src/tools/reflections.ts +124 -0
- package/src/tools/scheduled-messages.ts +144 -0
- package/src/tools/social-channels.ts +396 -0
- package/src/tools/tasks.ts +198 -0
- package/src/tools/tools.ts +255 -0
- package/src/tools/wallets.ts +107 -0
- package/src/tools/webhooks.ts +166 -0
- package/src/tools/whatsapp-actions.ts +203 -0
- package/tsconfig.json +20 -0
- package/LICENSE +0 -21
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { api, jsonResult, errorResult } from "../client.js";
|
|
4
|
+
|
|
5
|
+
/** Shared "where do the members come from" schema for create / add / remove. */
|
|
6
|
+
const memberSources = {
|
|
7
|
+
fromGroupIds: z.array(z.string()).optional().describe("Copy/combine members live from these WhatsApp group JIDs"),
|
|
8
|
+
listIds: z.array(z.string()).optional().describe("Contact list ids or slugs — pulls every member"),
|
|
9
|
+
contactIds: z.array(z.string()).optional().describe("Existing contact ids"),
|
|
10
|
+
phones: z.array(z.string()).optional().describe("Raw phone numbers, e.g. pasted from a CSV"),
|
|
11
|
+
allContacts: z.boolean().optional().describe("Union the org's entire address book"),
|
|
12
|
+
tags: z.array(z.string()).optional().describe("Keep only contacts carrying one of these tags"),
|
|
13
|
+
excludeListIds: z.array(z.string()).optional().describe("Subtract every member of these lists"),
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function registerGroupManagementTools(server: McpServer): void {
|
|
17
|
+
// 0. Create Group
|
|
18
|
+
server.registerTool(
|
|
19
|
+
"neuron_create_group",
|
|
20
|
+
{
|
|
21
|
+
title: "Create WhatsApp Group",
|
|
22
|
+
description:
|
|
23
|
+
"Create a new WhatsApp group and seed its members from any combination of sources: other groups (combine/copy), contact lists, individual contacts, pasted phone numbers, or the whole address book. Optionally pass a unique `slug` to address the group later without its JID. Members blocked by privacy come back in the failed list. Uses the org's default connected session unless `channelId` is given.",
|
|
24
|
+
inputSchema: z.object({
|
|
25
|
+
subject: z.string().min(1).max(100).describe("Group name"),
|
|
26
|
+
channelId: z.string().optional().describe("Session (connected WhatsApp number) UUID. Omit to use the default."),
|
|
27
|
+
slug: z.string().optional().describe("Optional org-unique handle (lowercase letters, numbers, hyphens)"),
|
|
28
|
+
description: z.string().optional().describe("Optional group description"),
|
|
29
|
+
ifExists: z.enum(["return", "error"]).optional().describe("When the slug is already taken: 'error' (default) fails, 'return' returns the existing group and adds any given members to it (idempotent create)."),
|
|
30
|
+
...memberSources,
|
|
31
|
+
}),
|
|
32
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
33
|
+
},
|
|
34
|
+
async ({ subject, channelId, slug, description, ifExists, ...sources }) => {
|
|
35
|
+
try {
|
|
36
|
+
const res = await api("POST", `/groups`, { subject, channelId, slug, description, ifExists, sources });
|
|
37
|
+
return jsonResult(res);
|
|
38
|
+
} catch (error) { return errorResult(error); }
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// 0b. Add Group Members (from sources)
|
|
43
|
+
server.registerTool(
|
|
44
|
+
"neuron_add_group_members",
|
|
45
|
+
{
|
|
46
|
+
title: "Add Members to Group",
|
|
47
|
+
description:
|
|
48
|
+
"Add members to an existing group, resolved from any combination of sources (other groups, contact lists, contacts, pasted phones, all contacts). Address the group by its id, slug, or JID.",
|
|
49
|
+
inputSchema: z.object({
|
|
50
|
+
group: z.string().describe("Group id, slug, or JID (ending in @g.us)"),
|
|
51
|
+
...memberSources,
|
|
52
|
+
}),
|
|
53
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
54
|
+
},
|
|
55
|
+
async ({ group, ...sources }) => {
|
|
56
|
+
try {
|
|
57
|
+
const res = await api("POST", `/groups/${encodeURIComponent(group)}/members`, { sources });
|
|
58
|
+
return jsonResult(res);
|
|
59
|
+
} catch (error) { return errorResult(error); }
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// 0c. Remove Group Members (from sources)
|
|
64
|
+
server.registerTool(
|
|
65
|
+
"neuron_remove_group_members",
|
|
66
|
+
{
|
|
67
|
+
title: "Remove Members from Group",
|
|
68
|
+
description:
|
|
69
|
+
"Remove members from a group, resolved from any combination of sources — e.g. remove everyone on a contact list. Address the group by its id, slug, or JID.",
|
|
70
|
+
inputSchema: z.object({
|
|
71
|
+
group: z.string().describe("Group id, slug, or JID (ending in @g.us)"),
|
|
72
|
+
...memberSources,
|
|
73
|
+
}),
|
|
74
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
75
|
+
},
|
|
76
|
+
async ({ group, ...sources }) => {
|
|
77
|
+
try {
|
|
78
|
+
const res = await api("DELETE", `/groups/${encodeURIComponent(group)}/members`, { sources });
|
|
79
|
+
return jsonResult(res);
|
|
80
|
+
} catch (error) { return errorResult(error); }
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// 1. Update Group Subject
|
|
85
|
+
server.registerTool(
|
|
86
|
+
"neuron_update_group_subject",
|
|
87
|
+
{
|
|
88
|
+
title: "Update Group Subject",
|
|
89
|
+
description: "Update the name/subject of a WhatsApp group. Requires the bot to be a group admin.",
|
|
90
|
+
inputSchema: z.object({
|
|
91
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
92
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
93
|
+
subject: z.string().min(1).describe("New group name/subject"),
|
|
94
|
+
}),
|
|
95
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
96
|
+
},
|
|
97
|
+
async (args) => {
|
|
98
|
+
try {
|
|
99
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/subject`, {
|
|
100
|
+
subject: args.subject,
|
|
101
|
+
});
|
|
102
|
+
return jsonResult(res);
|
|
103
|
+
} catch (error) { return errorResult(error); }
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// 2. Update Group Description
|
|
108
|
+
server.registerTool(
|
|
109
|
+
"neuron_update_group_description",
|
|
110
|
+
{
|
|
111
|
+
title: "Update Group Description",
|
|
112
|
+
description: "Update the description of a WhatsApp group. Requires the bot to be a group admin.",
|
|
113
|
+
inputSchema: z.object({
|
|
114
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
115
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
116
|
+
description: z.string().describe("New group description (can be empty string to clear)"),
|
|
117
|
+
}),
|
|
118
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
119
|
+
},
|
|
120
|
+
async (args) => {
|
|
121
|
+
try {
|
|
122
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/description`, {
|
|
123
|
+
description: args.description,
|
|
124
|
+
});
|
|
125
|
+
return jsonResult(res);
|
|
126
|
+
} catch (error) { return errorResult(error); }
|
|
127
|
+
},
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
// 3. Update Group Settings
|
|
131
|
+
server.registerTool(
|
|
132
|
+
"neuron_update_group_settings",
|
|
133
|
+
{
|
|
134
|
+
title: "Update Group Settings",
|
|
135
|
+
description: "Change WhatsApp group settings: 'announcement' (only admins send), 'not_announcement' (everyone sends), 'locked' (only admins edit info), 'unlocked' (everyone edits info). Requires admin.",
|
|
136
|
+
inputSchema: z.object({
|
|
137
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
138
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
139
|
+
setting: z.enum(["announcement", "not_announcement", "locked", "unlocked"]).describe("Group setting to apply"),
|
|
140
|
+
}),
|
|
141
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
142
|
+
},
|
|
143
|
+
async (args) => {
|
|
144
|
+
try {
|
|
145
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/settings`, {
|
|
146
|
+
setting: args.setting,
|
|
147
|
+
});
|
|
148
|
+
return jsonResult(res);
|
|
149
|
+
} catch (error) { return errorResult(error); }
|
|
150
|
+
},
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
// 4. Update Group Members
|
|
154
|
+
server.registerTool(
|
|
155
|
+
"neuron_update_group_members",
|
|
156
|
+
{
|
|
157
|
+
title: "Update Group Members",
|
|
158
|
+
description: "Add, remove, promote, or demote members in a WhatsApp group. Provide phone numbers or JIDs. Requires admin privileges.",
|
|
159
|
+
inputSchema: z.object({
|
|
160
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
161
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
162
|
+
participants: z.array(z.string()).min(1).describe("Array of phone numbers or JIDs (e.g. ['2348012345678'] or ['2348012345678@s.whatsapp.net'])"),
|
|
163
|
+
action: z.enum(["add", "remove", "promote", "demote"]).describe("Action to perform on the participants"),
|
|
164
|
+
}),
|
|
165
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
166
|
+
},
|
|
167
|
+
async (args) => {
|
|
168
|
+
try {
|
|
169
|
+
const res = await api("POST", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/members`, {
|
|
170
|
+
participants: args.participants,
|
|
171
|
+
action: args.action,
|
|
172
|
+
});
|
|
173
|
+
return jsonResult(res);
|
|
174
|
+
} catch (error) { return errorResult(error); }
|
|
175
|
+
},
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
// 5. Set Group Join Approval
|
|
179
|
+
server.registerTool(
|
|
180
|
+
"neuron_set_group_join_approval",
|
|
181
|
+
{
|
|
182
|
+
title: "Set Group Join Approval",
|
|
183
|
+
description: "Enable or disable join approval mode for a WhatsApp group. When enabled, join requests must be manually approved by admins. Requires admin.",
|
|
184
|
+
inputSchema: z.object({
|
|
185
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
186
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
187
|
+
enabled: z.boolean().describe("true to require admin approval for joins, false to allow direct joins"),
|
|
188
|
+
}),
|
|
189
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
190
|
+
},
|
|
191
|
+
async (args) => {
|
|
192
|
+
try {
|
|
193
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/join-approval`, {
|
|
194
|
+
enabled: args.enabled,
|
|
195
|
+
});
|
|
196
|
+
return jsonResult(res);
|
|
197
|
+
} catch (error) { return errorResult(error); }
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
// 6. Handle Join Requests
|
|
202
|
+
server.registerTool(
|
|
203
|
+
"neuron_handle_join_requests",
|
|
204
|
+
{
|
|
205
|
+
title: "Handle Join Requests",
|
|
206
|
+
description: "Approve or reject pending join requests for a WhatsApp group. Requires admin privileges.",
|
|
207
|
+
inputSchema: z.object({
|
|
208
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
209
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
210
|
+
participants: z.array(z.string()).min(1).describe("Array of phone numbers or JIDs of requesters"),
|
|
211
|
+
action: z.enum(["approve", "reject"]).describe("Whether to approve or reject the join requests"),
|
|
212
|
+
}),
|
|
213
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
214
|
+
},
|
|
215
|
+
async (args) => {
|
|
216
|
+
try {
|
|
217
|
+
const res = await api("POST", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/join-requests`, {
|
|
218
|
+
participants: args.participants,
|
|
219
|
+
action: args.action,
|
|
220
|
+
});
|
|
221
|
+
return jsonResult(res);
|
|
222
|
+
} catch (error) { return errorResult(error); }
|
|
223
|
+
},
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// 7. Revoke Group Invite
|
|
227
|
+
server.registerTool(
|
|
228
|
+
"neuron_revoke_group_invite",
|
|
229
|
+
{
|
|
230
|
+
title: "Revoke Group Invite",
|
|
231
|
+
description: "Revoke the current group invite link and generate a new one. The old link will stop working. Requires admin.",
|
|
232
|
+
inputSchema: z.object({
|
|
233
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
234
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
235
|
+
}),
|
|
236
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
237
|
+
},
|
|
238
|
+
async (args) => {
|
|
239
|
+
try {
|
|
240
|
+
const res = await api("POST", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/revoke-invite`);
|
|
241
|
+
return jsonResult(res);
|
|
242
|
+
} catch (error) { return errorResult(error); }
|
|
243
|
+
},
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// 8. Leave Group
|
|
247
|
+
server.registerTool(
|
|
248
|
+
"neuron_leave_group",
|
|
249
|
+
{
|
|
250
|
+
title: "Leave Group",
|
|
251
|
+
description: "Make the bot leave a WhatsApp group. This action is irreversible — the bot will need to be re-added by an admin.",
|
|
252
|
+
inputSchema: z.object({
|
|
253
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
254
|
+
groupJid: z.string().describe("Group JID (ending in @g.us)"),
|
|
255
|
+
}),
|
|
256
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false },
|
|
257
|
+
},
|
|
258
|
+
async (args) => {
|
|
259
|
+
try {
|
|
260
|
+
const res = await api("POST", `/whatsapp-actions/${args.channelId}/groups/${args.groupJid}/leave`);
|
|
261
|
+
return jsonResult(res);
|
|
262
|
+
} catch (error) { return errorResult(error); }
|
|
263
|
+
},
|
|
264
|
+
);
|
|
265
|
+
}
|