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.
- 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 +4 -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,271 @@
|
|
|
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
|
+
export function registerNewsletterTools(server: McpServer): void {
|
|
6
|
+
// 1. List newsletters
|
|
7
|
+
server.registerTool(
|
|
8
|
+
"neuron_list_newsletters",
|
|
9
|
+
{
|
|
10
|
+
title: "List Newsletters",
|
|
11
|
+
description: "Retrieve a paginated list of all WhatsApp Channel newsletters for the organization, with optional filtering by WhatsApp session channel.",
|
|
12
|
+
inputSchema: z.object({
|
|
13
|
+
channelId: z.string().optional().describe("Filter newsletters by WhatsApp session channel identifier (UUID)"),
|
|
14
|
+
page: z.number().int().positive().optional().describe("Page number for pagination (default: 1)"),
|
|
15
|
+
limit: z.number().int().positive().optional().describe("Number of items per page (default: 20)"),
|
|
16
|
+
}),
|
|
17
|
+
annotations: {
|
|
18
|
+
readOnlyHint: true,
|
|
19
|
+
destructiveHint: false,
|
|
20
|
+
idempotentHint: true,
|
|
21
|
+
openWorldHint: false,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
async (args) => {
|
|
25
|
+
try {
|
|
26
|
+
const response = await api("GET", "/newsletters", undefined, {
|
|
27
|
+
channelId: args.channelId,
|
|
28
|
+
page: args.page,
|
|
29
|
+
limit: args.limit,
|
|
30
|
+
});
|
|
31
|
+
return jsonResult(response);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
return errorResult(error);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
// 2. Create newsletter
|
|
39
|
+
server.registerTool(
|
|
40
|
+
"neuron_create_newsletter",
|
|
41
|
+
{
|
|
42
|
+
title: "Create Newsletter",
|
|
43
|
+
description: "Create a new WhatsApp Channel newsletter for one-way broadcast updates. Requires a connected Baileys session on the specified channel.",
|
|
44
|
+
inputSchema: z.object({
|
|
45
|
+
channelId: z.string().describe("Identifier (UUID) of the WhatsApp session channel to create the newsletter on"),
|
|
46
|
+
name: z.string().describe("Display name of the newsletter visible to subscribers"),
|
|
47
|
+
description: z.string().optional().describe("Description of the newsletter's purpose and content"),
|
|
48
|
+
}),
|
|
49
|
+
annotations: {
|
|
50
|
+
readOnlyHint: false,
|
|
51
|
+
destructiveHint: false,
|
|
52
|
+
idempotentHint: false,
|
|
53
|
+
openWorldHint: false,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
async (args) => {
|
|
57
|
+
try {
|
|
58
|
+
const response = await api("POST", "/newsletters", args);
|
|
59
|
+
return jsonResult(response);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return errorResult(error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// 3. Get newsletter
|
|
67
|
+
server.registerTool(
|
|
68
|
+
"neuron_get_newsletter",
|
|
69
|
+
{
|
|
70
|
+
title: "Get Newsletter",
|
|
71
|
+
description: "Retrieve detailed information about a specific WhatsApp Channel newsletter, including subscriber count and metadata.",
|
|
72
|
+
inputSchema: z.object({
|
|
73
|
+
id: z.string().describe("Unique identifier (UUID) of the newsletter to retrieve"),
|
|
74
|
+
}),
|
|
75
|
+
annotations: {
|
|
76
|
+
readOnlyHint: true,
|
|
77
|
+
destructiveHint: false,
|
|
78
|
+
idempotentHint: true,
|
|
79
|
+
openWorldHint: false,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
async (args) => {
|
|
83
|
+
try {
|
|
84
|
+
const response = await api("GET", `/newsletters/${args.id}`);
|
|
85
|
+
return jsonResult(response);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return errorResult(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// 4. Update newsletter
|
|
93
|
+
server.registerTool(
|
|
94
|
+
"neuron_update_newsletter",
|
|
95
|
+
{
|
|
96
|
+
title: "Update Newsletter",
|
|
97
|
+
description: "Update the name or description of an existing WhatsApp Channel newsletter. Only provided fields are changed.",
|
|
98
|
+
inputSchema: z.object({
|
|
99
|
+
id: z.string().describe("Unique identifier (UUID) of the newsletter to update"),
|
|
100
|
+
name: z.string().optional().describe("New display name for the newsletter"),
|
|
101
|
+
description: z.string().optional().describe("New description for the newsletter"),
|
|
102
|
+
}),
|
|
103
|
+
annotations: {
|
|
104
|
+
readOnlyHint: false,
|
|
105
|
+
destructiveHint: false,
|
|
106
|
+
idempotentHint: true,
|
|
107
|
+
openWorldHint: false,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
async (args) => {
|
|
111
|
+
try {
|
|
112
|
+
const { id, ...updateData } = args;
|
|
113
|
+
const response = await api("PUT", `/newsletters/${id}`, updateData);
|
|
114
|
+
return jsonResult(response);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return errorResult(error);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// 5. Delete newsletter
|
|
122
|
+
server.registerTool(
|
|
123
|
+
"neuron_delete_newsletter",
|
|
124
|
+
{
|
|
125
|
+
title: "Delete Newsletter",
|
|
126
|
+
description: "Permanently delete a WhatsApp Channel newsletter and remove it from WhatsApp. This action cannot be undone.",
|
|
127
|
+
inputSchema: z.object({
|
|
128
|
+
id: z.string().describe("Unique identifier (UUID) of the newsletter to delete"),
|
|
129
|
+
}),
|
|
130
|
+
annotations: {
|
|
131
|
+
readOnlyHint: false,
|
|
132
|
+
destructiveHint: true,
|
|
133
|
+
idempotentHint: true,
|
|
134
|
+
openWorldHint: false,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
async (args) => {
|
|
138
|
+
try {
|
|
139
|
+
const response = await api("DELETE", `/newsletters/${args.id}`);
|
|
140
|
+
return jsonResult(response);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
return errorResult(error);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// 6. Post to newsletter
|
|
148
|
+
server.registerTool(
|
|
149
|
+
"neuron_post_to_newsletter",
|
|
150
|
+
{
|
|
151
|
+
title: "Post to Newsletter",
|
|
152
|
+
description: "Post a message to a WhatsApp Channel newsletter. All subscribers receive the message. Provide at least one of text or mediaUrl. This triggers delivery and cannot be undone.",
|
|
153
|
+
inputSchema: z.object({
|
|
154
|
+
id: z.string().describe("Unique identifier (UUID) of the newsletter to post to"),
|
|
155
|
+
text: z.string().optional().describe("Message text or caption to post to the newsletter"),
|
|
156
|
+
messageType: z.enum(["text", "image", "video", "document"]).default("text").describe("Type of message to send (default: 'text')"),
|
|
157
|
+
mediaUrl: z.string().optional().describe("URL of the media file to attach (required for image, video, or document types)"),
|
|
158
|
+
}),
|
|
159
|
+
annotations: {
|
|
160
|
+
readOnlyHint: false,
|
|
161
|
+
destructiveHint: false,
|
|
162
|
+
idempotentHint: false,
|
|
163
|
+
openWorldHint: false,
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
async (args) => {
|
|
167
|
+
try {
|
|
168
|
+
const body: Record<string, string | undefined> = {
|
|
169
|
+
text: args.text,
|
|
170
|
+
messageType: args.messageType,
|
|
171
|
+
mediaUrl: args.mediaUrl,
|
|
172
|
+
};
|
|
173
|
+
const response = await api("POST", `/newsletters/${args.id}/post`, body);
|
|
174
|
+
return jsonResult(response);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
return errorResult(error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
// 6b. Post to WhatsApp Status / Story
|
|
182
|
+
server.registerTool(
|
|
183
|
+
"neuron_post_to_status",
|
|
184
|
+
{
|
|
185
|
+
title: "Post to WhatsApp Status",
|
|
186
|
+
description:
|
|
187
|
+
"Post a WhatsApp Status / Story from a connected direct (Baileys) WhatsApp number. Visible to the account's synced contacts for 24 hours — you do NOT specify recipients (the contact list is built automatically; pass statusJidList only to target a subset). Provide at least one of text or mediaUrl. channelId is optional and auto-resolves to the default connected number. This triggers delivery and cannot be undone.",
|
|
188
|
+
inputSchema: z.object({
|
|
189
|
+
text: z.string().optional().describe("Status text (for a text story) or caption (for media)"),
|
|
190
|
+
messageType: z.enum(["text", "image", "video", "audio"]).default("text").describe("Type of status (default: 'text')"),
|
|
191
|
+
mediaUrl: z.string().optional().describe("URL of the image/video/audio to post (required for non-text statuses)"),
|
|
192
|
+
channelId: z.string().optional().describe("WhatsApp session channel UUID to post from. Omit to auto-resolve."),
|
|
193
|
+
backgroundColor: z.string().optional().describe("Text-status background colour as hex, e.g. '#315575'"),
|
|
194
|
+
font: z.number().int().min(0).max(9).optional().describe("Text-status font index (0–9)"),
|
|
195
|
+
}),
|
|
196
|
+
annotations: {
|
|
197
|
+
readOnlyHint: false,
|
|
198
|
+
destructiveHint: false,
|
|
199
|
+
idempotentHint: false,
|
|
200
|
+
openWorldHint: false,
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
async (args) => {
|
|
204
|
+
try {
|
|
205
|
+
const response = await api("POST", "/conversations/compose-story", {
|
|
206
|
+
text: args.text,
|
|
207
|
+
messageType: args.messageType,
|
|
208
|
+
mediaUrl: args.mediaUrl,
|
|
209
|
+
channelId: args.channelId,
|
|
210
|
+
backgroundColor: args.backgroundColor,
|
|
211
|
+
font: args.font,
|
|
212
|
+
});
|
|
213
|
+
return jsonResult(response);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
return errorResult(error);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// 7. Refresh newsletter metadata
|
|
221
|
+
server.registerTool(
|
|
222
|
+
"neuron_refresh_newsletter",
|
|
223
|
+
{
|
|
224
|
+
title: "Refresh Newsletter",
|
|
225
|
+
description: "Re-fetch metadata (name, description, subscriber count) for a WhatsApp Channel newsletter from WhatsApp to synchronize local data.",
|
|
226
|
+
inputSchema: z.object({
|
|
227
|
+
id: z.string().describe("Unique identifier (UUID) of the newsletter to refresh"),
|
|
228
|
+
}),
|
|
229
|
+
annotations: {
|
|
230
|
+
readOnlyHint: false,
|
|
231
|
+
destructiveHint: false,
|
|
232
|
+
idempotentHint: true,
|
|
233
|
+
openWorldHint: false,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
async (args) => {
|
|
237
|
+
try {
|
|
238
|
+
const response = await api("POST", `/newsletters/${args.id}/refresh`);
|
|
239
|
+
return jsonResult(response);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
return errorResult(error);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// 8. Sync newsletters from WhatsApp
|
|
247
|
+
server.registerTool(
|
|
248
|
+
"neuron_sync_newsletters",
|
|
249
|
+
{
|
|
250
|
+
title: "Sync Newsletters",
|
|
251
|
+
description: "Synchronize and import WhatsApp Channels from a connected WhatsApp session into Neuron. Discovers channels created outside Neuron.",
|
|
252
|
+
inputSchema: z.object({
|
|
253
|
+
channelId: z.string().describe("Identifier (UUID) of the WhatsApp session channel to sync newsletters from"),
|
|
254
|
+
}),
|
|
255
|
+
annotations: {
|
|
256
|
+
readOnlyHint: false,
|
|
257
|
+
destructiveHint: false,
|
|
258
|
+
idempotentHint: true,
|
|
259
|
+
openWorldHint: false,
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
async (args) => {
|
|
263
|
+
try {
|
|
264
|
+
const response = await api("POST", "/newsletters/sync", { channelId: args.channelId });
|
|
265
|
+
return jsonResult(response);
|
|
266
|
+
} catch (error) {
|
|
267
|
+
return errorResult(error);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
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
|
+
export function registerOrganizationTools(server: McpServer): void {
|
|
6
|
+
// Get Organization
|
|
7
|
+
server.registerTool(
|
|
8
|
+
"neuron_get_organization",
|
|
9
|
+
{
|
|
10
|
+
title: "Get Organization",
|
|
11
|
+
description: "Retrieve detailed information about a specific organization, including its name, settings, and configuration.",
|
|
12
|
+
inputSchema: z.object({
|
|
13
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization to retrieve"),
|
|
14
|
+
}),
|
|
15
|
+
annotations: {
|
|
16
|
+
readOnlyHint: true,
|
|
17
|
+
destructiveHint: false,
|
|
18
|
+
idempotentHint: true,
|
|
19
|
+
openWorldHint: false,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
async (params) => {
|
|
23
|
+
try {
|
|
24
|
+
const result = await api("GET", `/organizations/${params.orgId}`);
|
|
25
|
+
return jsonResult(result);
|
|
26
|
+
} catch (error) {
|
|
27
|
+
return errorResult(error);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// Update Organization
|
|
33
|
+
server.registerTool(
|
|
34
|
+
"neuron_update_organization",
|
|
35
|
+
{
|
|
36
|
+
title: "Update Organization",
|
|
37
|
+
description: "Update organization settings such as name, description, or configuration preferences. Only provided fields are changed.",
|
|
38
|
+
inputSchema: z.object({
|
|
39
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization to update"),
|
|
40
|
+
name: z.string().optional().describe("New display name for the organization"),
|
|
41
|
+
autoOptOutBroadcast: z.boolean().optional().describe("Auto-exclude a contact from broadcasts when they send a broadcast opt-out message (e.g. 'stop messaging me'). Off by default."),
|
|
42
|
+
autoSuppressHostile: z.boolean().optional().describe("Auto-exclude a contact from broadcasts when they are hostile about being contacted (e.g. cursing us out for messaging them). Off by default."),
|
|
43
|
+
}),
|
|
44
|
+
annotations: {
|
|
45
|
+
readOnlyHint: false,
|
|
46
|
+
destructiveHint: false,
|
|
47
|
+
idempotentHint: true,
|
|
48
|
+
openWorldHint: false,
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
async (params) => {
|
|
52
|
+
try {
|
|
53
|
+
const { orgId, ...body } = params;
|
|
54
|
+
const result = await api("PUT", `/organizations/${orgId}`, body);
|
|
55
|
+
return jsonResult(result);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return errorResult(error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Update WhatsApp Credentials
|
|
63
|
+
server.registerTool(
|
|
64
|
+
"neuron_update_whatsapp_credentials",
|
|
65
|
+
{
|
|
66
|
+
title: "Update WhatsApp Credentials",
|
|
67
|
+
description: "Update WhatsApp Business API credentials for the organization. These credentials are required for sending messages via the WhatsApp Cloud API.",
|
|
68
|
+
inputSchema: z.object({
|
|
69
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
70
|
+
whatsappPhoneNumberId: z.string().describe("WhatsApp phone number ID from the Meta Business dashboard"),
|
|
71
|
+
whatsappBusinessAccountId: z.string().describe("WhatsApp Business Account ID from the Meta Business dashboard"),
|
|
72
|
+
whatsappAccessToken: z.string().describe("WhatsApp access token for API authentication (keep confidential)"),
|
|
73
|
+
}),
|
|
74
|
+
annotations: {
|
|
75
|
+
readOnlyHint: false,
|
|
76
|
+
destructiveHint: false,
|
|
77
|
+
idempotentHint: true,
|
|
78
|
+
openWorldHint: false,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
async (params) => {
|
|
82
|
+
try {
|
|
83
|
+
const { orgId, ...body } = params;
|
|
84
|
+
const result = await api("PUT", `/organizations/${orgId}/whatsapp`, body);
|
|
85
|
+
return jsonResult(result);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return errorResult(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// Set Default Channel
|
|
93
|
+
server.registerTool(
|
|
94
|
+
"neuron_set_default_channel",
|
|
95
|
+
{
|
|
96
|
+
title: "Set Default WhatsApp Channel",
|
|
97
|
+
description:
|
|
98
|
+
"Set or clear the default WhatsApp channel for the organization. The default channel is used by neuron_send_whatsapp for auto-resolving which channel to send through.",
|
|
99
|
+
inputSchema: z.object({
|
|
100
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
101
|
+
channelId: z.string().nullable().describe("Identifier (UUID) of the channel to set as default, or null to clear the default"),
|
|
102
|
+
}),
|
|
103
|
+
annotations: {
|
|
104
|
+
readOnlyHint: false,
|
|
105
|
+
destructiveHint: false,
|
|
106
|
+
idempotentHint: true,
|
|
107
|
+
openWorldHint: false,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
async (params) => {
|
|
111
|
+
try {
|
|
112
|
+
const result = await api("PUT", `/organizations/${params.orgId}/default-channel`, {
|
|
113
|
+
channelId: params.channelId,
|
|
114
|
+
});
|
|
115
|
+
return jsonResult(result);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
return errorResult(error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// List Members
|
|
123
|
+
server.registerTool(
|
|
124
|
+
"neuron_list_members",
|
|
125
|
+
{
|
|
126
|
+
title: "List Organization Members",
|
|
127
|
+
description: "Retrieve a list of all members in the organization, including their roles and permissions.",
|
|
128
|
+
inputSchema: z.object({
|
|
129
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
130
|
+
}),
|
|
131
|
+
annotations: {
|
|
132
|
+
readOnlyHint: true,
|
|
133
|
+
destructiveHint: false,
|
|
134
|
+
idempotentHint: true,
|
|
135
|
+
openWorldHint: false,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
async (params) => {
|
|
139
|
+
try {
|
|
140
|
+
const result = await api("GET", `/organizations/${params.orgId}/members`);
|
|
141
|
+
return jsonResult(result);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
return errorResult(error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// Invite Member
|
|
149
|
+
server.registerTool(
|
|
150
|
+
"neuron_invite_member",
|
|
151
|
+
{
|
|
152
|
+
title: "Invite Organization Member",
|
|
153
|
+
description: "Send an invitation to a new member to join the organization. The invitee receives an email with a link to accept.",
|
|
154
|
+
inputSchema: z.object({
|
|
155
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
156
|
+
email: z.string().email().describe("Email address of the person to invite"),
|
|
157
|
+
name: z.string().describe("Full name of the person being invited"),
|
|
158
|
+
role: z.string().optional().describe("Role to assign to the member (e.g., 'admin', 'agent', 'viewer')"),
|
|
159
|
+
canViewConversations: z.boolean().optional().describe("Whether the invited member can view conversations (default: true)"),
|
|
160
|
+
}),
|
|
161
|
+
annotations: {
|
|
162
|
+
readOnlyHint: false,
|
|
163
|
+
destructiveHint: false,
|
|
164
|
+
idempotentHint: false,
|
|
165
|
+
openWorldHint: false,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
async (params) => {
|
|
169
|
+
try {
|
|
170
|
+
const { orgId, ...body } = params;
|
|
171
|
+
const result = await api("POST", `/organizations/${orgId}/members`, body);
|
|
172
|
+
return jsonResult(result);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
return errorResult(error);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// List Invitations
|
|
180
|
+
server.registerTool(
|
|
181
|
+
"neuron_list_invitations",
|
|
182
|
+
{
|
|
183
|
+
title: "List Invitations",
|
|
184
|
+
description: "Retrieve a list of all pending invitations for the organization that have not yet been accepted or revoked.",
|
|
185
|
+
inputSchema: z.object({
|
|
186
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
187
|
+
}),
|
|
188
|
+
annotations: {
|
|
189
|
+
readOnlyHint: true,
|
|
190
|
+
destructiveHint: false,
|
|
191
|
+
idempotentHint: true,
|
|
192
|
+
openWorldHint: false,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
async (params) => {
|
|
196
|
+
try {
|
|
197
|
+
const result = await api("GET", `/organizations/${params.orgId}/invitations`);
|
|
198
|
+
return jsonResult(result);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
return errorResult(error);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Revoke Invitation
|
|
206
|
+
server.registerTool(
|
|
207
|
+
"neuron_revoke_invitation",
|
|
208
|
+
{
|
|
209
|
+
title: "Revoke Invitation",
|
|
210
|
+
description: "Revoke a pending organization invitation so it can no longer be accepted. This action cannot be undone.",
|
|
211
|
+
inputSchema: z.object({
|
|
212
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
213
|
+
invitationId: z.string().describe("Unique identifier (UUID) of the invitation to revoke"),
|
|
214
|
+
}),
|
|
215
|
+
annotations: {
|
|
216
|
+
readOnlyHint: false,
|
|
217
|
+
destructiveHint: true,
|
|
218
|
+
idempotentHint: true,
|
|
219
|
+
openWorldHint: false,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
async (params) => {
|
|
223
|
+
try {
|
|
224
|
+
const result = await api("DELETE", `/organizations/${params.orgId}/invitations/${params.invitationId}`);
|
|
225
|
+
return jsonResult(result);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
return errorResult(error);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
// Update Member Permissions
|
|
233
|
+
server.registerTool(
|
|
234
|
+
"neuron_update_member",
|
|
235
|
+
{
|
|
236
|
+
title: "Update Member Permissions",
|
|
237
|
+
description: "Update a member's permissions within the organization, such as conversation access. Only provided fields are changed.",
|
|
238
|
+
inputSchema: z.object({
|
|
239
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
240
|
+
userId: z.string().describe("Unique identifier (UUID) of the member to update"),
|
|
241
|
+
canViewConversations: z.boolean().describe("Whether the member can view conversations"),
|
|
242
|
+
}),
|
|
243
|
+
annotations: {
|
|
244
|
+
readOnlyHint: false,
|
|
245
|
+
destructiveHint: false,
|
|
246
|
+
idempotentHint: true,
|
|
247
|
+
openWorldHint: false,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
async (params) => {
|
|
251
|
+
try {
|
|
252
|
+
const { orgId, userId, ...body } = params;
|
|
253
|
+
const result = await api("PATCH", `/organizations/${orgId}/members/${userId}`, body);
|
|
254
|
+
return jsonResult(result);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
return errorResult(error);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
// Remove Member
|
|
262
|
+
server.registerTool(
|
|
263
|
+
"neuron_remove_member",
|
|
264
|
+
{
|
|
265
|
+
title: "Remove Organization Member",
|
|
266
|
+
description: "Permanently remove a member from the organization. The member loses all access immediately. This action cannot be undone.",
|
|
267
|
+
inputSchema: z.object({
|
|
268
|
+
orgId: z.string().describe("Unique identifier (UUID) of the organization"),
|
|
269
|
+
userId: z.string().describe("Unique identifier (UUID) of the member to remove"),
|
|
270
|
+
}),
|
|
271
|
+
annotations: {
|
|
272
|
+
readOnlyHint: false,
|
|
273
|
+
destructiveHint: true,
|
|
274
|
+
idempotentHint: true,
|
|
275
|
+
openWorldHint: false,
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
async (params) => {
|
|
279
|
+
try {
|
|
280
|
+
const result = await api("DELETE", `/organizations/${params.orgId}/members/${params.userId}`);
|
|
281
|
+
return jsonResult(result);
|
|
282
|
+
} catch (error) {
|
|
283
|
+
return errorResult(error);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
);
|
|
287
|
+
}
|