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,215 @@
|
|
|
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 registerProfilePrivacyTools(server: McpServer): void {
|
|
6
|
+
// 1. Update Profile Name
|
|
7
|
+
server.registerTool(
|
|
8
|
+
"neuron_update_profile_name",
|
|
9
|
+
{
|
|
10
|
+
title: "Update Profile Name",
|
|
11
|
+
description: "Update the bot's WhatsApp display name on the given channel.",
|
|
12
|
+
inputSchema: z.object({
|
|
13
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
14
|
+
name: z.string().min(1).describe("New display name"),
|
|
15
|
+
}),
|
|
16
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
17
|
+
},
|
|
18
|
+
async (args) => {
|
|
19
|
+
try {
|
|
20
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/profile/name`, {
|
|
21
|
+
name: args.name,
|
|
22
|
+
});
|
|
23
|
+
return jsonResult(res);
|
|
24
|
+
} catch (error) { return errorResult(error); }
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// 2. Update Profile Picture
|
|
29
|
+
server.registerTool(
|
|
30
|
+
"neuron_update_profile_picture",
|
|
31
|
+
{
|
|
32
|
+
title: "Update Profile Picture",
|
|
33
|
+
description: "Update the bot's WhatsApp profile picture from an image URL.",
|
|
34
|
+
inputSchema: z.object({
|
|
35
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
36
|
+
imageUrl: z.string().url().describe("URL of the image to set as profile picture"),
|
|
37
|
+
}),
|
|
38
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
39
|
+
},
|
|
40
|
+
async (args) => {
|
|
41
|
+
try {
|
|
42
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/profile/picture`, {
|
|
43
|
+
imageUrl: args.imageUrl,
|
|
44
|
+
});
|
|
45
|
+
return jsonResult(res);
|
|
46
|
+
} catch (error) { return errorResult(error); }
|
|
47
|
+
},
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// 3. Remove Profile Picture
|
|
51
|
+
server.registerTool(
|
|
52
|
+
"neuron_remove_profile_picture",
|
|
53
|
+
{
|
|
54
|
+
title: "Remove Profile Picture",
|
|
55
|
+
description: "Remove the bot's WhatsApp profile picture, reverting to the default.",
|
|
56
|
+
inputSchema: z.object({
|
|
57
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
58
|
+
}),
|
|
59
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
60
|
+
},
|
|
61
|
+
async (args) => {
|
|
62
|
+
try {
|
|
63
|
+
const res = await api("DELETE", `/whatsapp-actions/${args.channelId}/profile/picture`);
|
|
64
|
+
return jsonResult(res);
|
|
65
|
+
} catch (error) { return errorResult(error); }
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
// 4. Update Profile Status
|
|
70
|
+
server.registerTool(
|
|
71
|
+
"neuron_update_profile_status",
|
|
72
|
+
{
|
|
73
|
+
title: "Update Profile Status",
|
|
74
|
+
description: "Update the bot's WhatsApp status/bio text.",
|
|
75
|
+
inputSchema: z.object({
|
|
76
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
77
|
+
status: z.string().min(1).describe("New status/bio text"),
|
|
78
|
+
}),
|
|
79
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
80
|
+
},
|
|
81
|
+
async (args) => {
|
|
82
|
+
try {
|
|
83
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/profile/status`, {
|
|
84
|
+
status: args.status,
|
|
85
|
+
});
|
|
86
|
+
return jsonResult(res);
|
|
87
|
+
} catch (error) { return errorResult(error); }
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
// 5. Get Privacy Settings
|
|
92
|
+
server.registerTool(
|
|
93
|
+
"neuron_get_privacy_settings",
|
|
94
|
+
{
|
|
95
|
+
title: "Get Privacy Settings",
|
|
96
|
+
description: "Fetch the bot's current WhatsApp privacy settings (last seen, online, profile picture, status, read receipts, groups add).",
|
|
97
|
+
inputSchema: z.object({
|
|
98
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
99
|
+
}),
|
|
100
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
101
|
+
},
|
|
102
|
+
async (args) => {
|
|
103
|
+
try {
|
|
104
|
+
const res = await api("GET", `/whatsapp-actions/${args.channelId}/privacy`);
|
|
105
|
+
return jsonResult(res);
|
|
106
|
+
} catch (error) { return errorResult(error); }
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
// 6. Update Privacy Setting
|
|
111
|
+
server.registerTool(
|
|
112
|
+
"neuron_update_privacy_setting",
|
|
113
|
+
{
|
|
114
|
+
title: "Update Privacy Setting",
|
|
115
|
+
description: "Update a specific WhatsApp privacy setting. Settings: lastSeen (all/contacts/contact_blacklist/none), online (all/match_last_seen), profilePicture (all/contacts/contact_blacklist/none), status (all/contacts/contact_blacklist/none), readReceipts (all/none), groupsAdd (all/contacts/contact_blacklist).",
|
|
116
|
+
inputSchema: z.object({
|
|
117
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
118
|
+
setting: z.enum(["lastSeen", "online", "profilePicture", "status", "readReceipts", "groupsAdd"]).describe("Privacy setting to update"),
|
|
119
|
+
value: z.string().min(1).describe("New value for the setting (see description for allowed values per setting)"),
|
|
120
|
+
}),
|
|
121
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
122
|
+
},
|
|
123
|
+
async (args) => {
|
|
124
|
+
try {
|
|
125
|
+
const res = await api("PUT", `/whatsapp-actions/${args.channelId}/privacy/${args.setting}`, {
|
|
126
|
+
value: args.value,
|
|
127
|
+
});
|
|
128
|
+
return jsonResult(res);
|
|
129
|
+
} catch (error) { return errorResult(error); }
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
// 7. Block Contact
|
|
134
|
+
server.registerTool(
|
|
135
|
+
"neuron_block_contact",
|
|
136
|
+
{
|
|
137
|
+
title: "Block Contact",
|
|
138
|
+
description: "Block a WhatsApp contact. Blocked contacts cannot message the bot or see its profile.",
|
|
139
|
+
inputSchema: z.object({
|
|
140
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
141
|
+
jid: z.string().describe("Contact JID or phone number to block (e.g. '2348012345678' or '2348012345678@s.whatsapp.net')"),
|
|
142
|
+
}),
|
|
143
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },
|
|
144
|
+
},
|
|
145
|
+
async (args) => {
|
|
146
|
+
try {
|
|
147
|
+
const res = await api("POST", `/whatsapp-actions/${args.channelId}/block`, {
|
|
148
|
+
jid: args.jid,
|
|
149
|
+
});
|
|
150
|
+
return jsonResult(res);
|
|
151
|
+
} catch (error) { return errorResult(error); }
|
|
152
|
+
},
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
// 8. Unblock Contact
|
|
156
|
+
server.registerTool(
|
|
157
|
+
"neuron_unblock_contact",
|
|
158
|
+
{
|
|
159
|
+
title: "Unblock Contact",
|
|
160
|
+
description: "Unblock a previously blocked WhatsApp contact.",
|
|
161
|
+
inputSchema: z.object({
|
|
162
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
163
|
+
jid: z.string().describe("Contact JID or phone number to unblock"),
|
|
164
|
+
}),
|
|
165
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
166
|
+
},
|
|
167
|
+
async (args) => {
|
|
168
|
+
try {
|
|
169
|
+
const res = await api("POST", `/whatsapp-actions/${args.channelId}/unblock`, {
|
|
170
|
+
jid: args.jid,
|
|
171
|
+
});
|
|
172
|
+
return jsonResult(res);
|
|
173
|
+
} catch (error) { return errorResult(error); }
|
|
174
|
+
},
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// 9. Get Blocklist
|
|
178
|
+
server.registerTool(
|
|
179
|
+
"neuron_get_blocklist",
|
|
180
|
+
{
|
|
181
|
+
title: "Get Blocklist",
|
|
182
|
+
description: "Fetch the list of all blocked WhatsApp contacts for the bot on the given channel.",
|
|
183
|
+
inputSchema: z.object({
|
|
184
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
185
|
+
}),
|
|
186
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
187
|
+
},
|
|
188
|
+
async (args) => {
|
|
189
|
+
try {
|
|
190
|
+
const res = await api("GET", `/whatsapp-actions/${args.channelId}/blocklist`);
|
|
191
|
+
return jsonResult(res);
|
|
192
|
+
} catch (error) { return errorResult(error); }
|
|
193
|
+
},
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
// 10. Get Business Profile
|
|
197
|
+
server.registerTool(
|
|
198
|
+
"neuron_get_business_profile",
|
|
199
|
+
{
|
|
200
|
+
title: "Get Business Profile",
|
|
201
|
+
description: "Fetch the WhatsApp Business profile of an external contact, including description, website, category, and business hours.",
|
|
202
|
+
inputSchema: z.object({
|
|
203
|
+
channelId: z.string().describe("WhatsApp channel identifier (UUID)"),
|
|
204
|
+
jid: z.string().describe("Contact JID or phone number to look up (e.g. '2348012345678' or '2348012345678@s.whatsapp.net')"),
|
|
205
|
+
}),
|
|
206
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
207
|
+
},
|
|
208
|
+
async (args) => {
|
|
209
|
+
try {
|
|
210
|
+
const res = await api("GET", `/whatsapp-actions/${args.channelId}/business-profile/${args.jid}`);
|
|
211
|
+
return jsonResult(res);
|
|
212
|
+
} catch (error) { return errorResult(error); }
|
|
213
|
+
},
|
|
214
|
+
);
|
|
215
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* Register reflection tools (bot self-learning reflections)
|
|
7
|
+
*/
|
|
8
|
+
export function registerReflectionsTools(server: McpServer): void {
|
|
9
|
+
// 1. List Reflections
|
|
10
|
+
server.registerTool(
|
|
11
|
+
"neuron_list_reflections",
|
|
12
|
+
{
|
|
13
|
+
title: "List Reflections",
|
|
14
|
+
description: "Retrieve pending reflections that the bot has generated from conversations, awaiting human review. Optionally filter by approval status.",
|
|
15
|
+
inputSchema: z.object({
|
|
16
|
+
botId: z.string().describe("Unique identifier (UUID) of the bot to list reflections for"),
|
|
17
|
+
status: z.enum(["pending", "approved", "rejected"]).optional().describe("Filter reflections by approval status (default: all statuses)"),
|
|
18
|
+
}),
|
|
19
|
+
annotations: {
|
|
20
|
+
readOnlyHint: true,
|
|
21
|
+
destructiveHint: false,
|
|
22
|
+
idempotentHint: true,
|
|
23
|
+
openWorldHint: false,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
async (args) => {
|
|
27
|
+
const { botId, status } = args;
|
|
28
|
+
const params: Record<string, string> = {};
|
|
29
|
+
|
|
30
|
+
if (status !== undefined) {
|
|
31
|
+
params.status = status;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const response = await api("GET", `/reflections/bot/${botId}`, undefined, params);
|
|
35
|
+
|
|
36
|
+
if (response.success) {
|
|
37
|
+
return jsonResult(response.data);
|
|
38
|
+
} else {
|
|
39
|
+
return errorResult(response.error || "Failed to list reflections");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// 2. Approve Reflection
|
|
45
|
+
server.registerTool(
|
|
46
|
+
"neuron_approve_reflection",
|
|
47
|
+
{
|
|
48
|
+
title: "Approve Reflection",
|
|
49
|
+
description: "Approve a bot-generated reflection to incorporate the learned insight into the bot's future behavior and responses.",
|
|
50
|
+
inputSchema: z.object({
|
|
51
|
+
id: z.string().describe("Unique identifier (UUID) of the reflection to approve"),
|
|
52
|
+
}),
|
|
53
|
+
annotations: {
|
|
54
|
+
readOnlyHint: false,
|
|
55
|
+
destructiveHint: false,
|
|
56
|
+
idempotentHint: true,
|
|
57
|
+
openWorldHint: false,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
async (args) => {
|
|
61
|
+
const response = await api("PUT", `/reflections/${args.id}/approve`);
|
|
62
|
+
|
|
63
|
+
if (response.success) {
|
|
64
|
+
return jsonResult(response.data || { message: "Reflection approved successfully" });
|
|
65
|
+
} else {
|
|
66
|
+
return errorResult(response.error || "Failed to approve reflection");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// 3. Reject Reflection
|
|
72
|
+
server.registerTool(
|
|
73
|
+
"neuron_reject_reflection",
|
|
74
|
+
{
|
|
75
|
+
title: "Reject Reflection",
|
|
76
|
+
description: "Reject a bot-generated reflection to prevent it from being incorporated into the bot's learned behavior.",
|
|
77
|
+
inputSchema: z.object({
|
|
78
|
+
id: z.string().describe("Unique identifier (UUID) of the reflection to reject"),
|
|
79
|
+
}),
|
|
80
|
+
annotations: {
|
|
81
|
+
readOnlyHint: false,
|
|
82
|
+
destructiveHint: false,
|
|
83
|
+
idempotentHint: true,
|
|
84
|
+
openWorldHint: false,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
async (args) => {
|
|
88
|
+
const response = await api("PUT", `/reflections/${args.id}/reject`);
|
|
89
|
+
|
|
90
|
+
if (response.success) {
|
|
91
|
+
return jsonResult(response.data || { message: "Reflection rejected successfully" });
|
|
92
|
+
} else {
|
|
93
|
+
return errorResult(response.error || "Failed to reject reflection");
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// 4. Sync Reflections
|
|
99
|
+
server.registerTool(
|
|
100
|
+
"neuron_sync_reflections",
|
|
101
|
+
{
|
|
102
|
+
title: "Sync Reflections",
|
|
103
|
+
description: "Synchronize all approved reflections into the bot's active knowledge base, applying learned insights to future conversations.",
|
|
104
|
+
inputSchema: z.object({
|
|
105
|
+
botId: z.string().describe("Unique identifier (UUID) of the bot to sync reflections for"),
|
|
106
|
+
}),
|
|
107
|
+
annotations: {
|
|
108
|
+
readOnlyHint: false,
|
|
109
|
+
destructiveHint: false,
|
|
110
|
+
idempotentHint: true,
|
|
111
|
+
openWorldHint: false,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
async (args) => {
|
|
115
|
+
const response = await api("POST", `/reflections/bot/${args.botId}/sync`);
|
|
116
|
+
|
|
117
|
+
if (response.success) {
|
|
118
|
+
return jsonResult(response.data || { message: "Reflections synced successfully" });
|
|
119
|
+
} else {
|
|
120
|
+
return errorResult(response.error || "Failed to sync reflections");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
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 registerScheduledMessageTools(server: McpServer): void {
|
|
6
|
+
// List scheduled messages
|
|
7
|
+
server.registerTool(
|
|
8
|
+
"neuron_list_scheduled_messages",
|
|
9
|
+
{
|
|
10
|
+
title: "List Scheduled Messages",
|
|
11
|
+
description:
|
|
12
|
+
"Retrieve a paginated list of scheduled messages for the current organization, with optional filtering by status (scheduled, sent, failed, cancelled).",
|
|
13
|
+
inputSchema: z.object({
|
|
14
|
+
status: z
|
|
15
|
+
.string()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Filter by status: 'scheduled', 'sent', 'failed', or 'cancelled'"),
|
|
18
|
+
page: z
|
|
19
|
+
.number()
|
|
20
|
+
.int()
|
|
21
|
+
.positive()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Page number for pagination (default: 1)"),
|
|
24
|
+
limit: z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.positive()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Number of items per page (default: 20)"),
|
|
30
|
+
}),
|
|
31
|
+
annotations: {
|
|
32
|
+
readOnlyHint: true,
|
|
33
|
+
destructiveHint: false,
|
|
34
|
+
idempotentHint: true,
|
|
35
|
+
openWorldHint: false,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
async (params) => {
|
|
39
|
+
try {
|
|
40
|
+
const result = await api("GET", "/scheduled-messages", undefined, {
|
|
41
|
+
status: params.status,
|
|
42
|
+
page: params.page,
|
|
43
|
+
limit: params.limit,
|
|
44
|
+
});
|
|
45
|
+
return jsonResult(result);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return errorResult(error);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Get a scheduled message
|
|
53
|
+
server.registerTool(
|
|
54
|
+
"neuron_get_scheduled_message",
|
|
55
|
+
{
|
|
56
|
+
title: "Get Scheduled Message",
|
|
57
|
+
description:
|
|
58
|
+
"Retrieve detailed information about a specific scheduled message, including its status, send time, and message content.",
|
|
59
|
+
inputSchema: z.object({
|
|
60
|
+
id: z.string().describe("Unique identifier (UUID) of the scheduled message"),
|
|
61
|
+
}),
|
|
62
|
+
annotations: {
|
|
63
|
+
readOnlyHint: true,
|
|
64
|
+
destructiveHint: false,
|
|
65
|
+
idempotentHint: true,
|
|
66
|
+
openWorldHint: false,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
async (params) => {
|
|
70
|
+
try {
|
|
71
|
+
const result = await api("GET", `/scheduled-messages/${params.id}`);
|
|
72
|
+
return jsonResult(result);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
return errorResult(error);
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
// Update a scheduled message
|
|
80
|
+
server.registerTool(
|
|
81
|
+
"neuron_update_scheduled_message",
|
|
82
|
+
{
|
|
83
|
+
title: "Update Scheduled Message",
|
|
84
|
+
description:
|
|
85
|
+
"Update the message content, media, or send time of a scheduled message. Only messages with status 'scheduled' can be updated.",
|
|
86
|
+
inputSchema: z.object({
|
|
87
|
+
id: z.string().describe("Unique identifier (UUID) of the scheduled message to update"),
|
|
88
|
+
message: z.string().optional().describe("New message text content"),
|
|
89
|
+
messageType: z
|
|
90
|
+
.string()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe("New message type: 'text', 'image', 'audio', 'video', or 'document'"),
|
|
93
|
+
mediaUrl: z.string().optional().describe("New media URL to attach"),
|
|
94
|
+
contactName: z.string().optional().describe("Updated display name for the recipient"),
|
|
95
|
+
sendAt: z
|
|
96
|
+
.string()
|
|
97
|
+
.optional()
|
|
98
|
+
.describe("New ISO 8601 date-time for scheduled delivery (must be in the future)"),
|
|
99
|
+
}),
|
|
100
|
+
annotations: {
|
|
101
|
+
readOnlyHint: false,
|
|
102
|
+
destructiveHint: false,
|
|
103
|
+
idempotentHint: true,
|
|
104
|
+
openWorldHint: false,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
async (params) => {
|
|
108
|
+
try {
|
|
109
|
+
const { id, ...body } = params;
|
|
110
|
+
const result = await api("PUT", `/scheduled-messages/${id}`, body);
|
|
111
|
+
return jsonResult(result);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
return errorResult(error);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// Cancel a scheduled message
|
|
119
|
+
server.registerTool(
|
|
120
|
+
"neuron_cancel_scheduled_message",
|
|
121
|
+
{
|
|
122
|
+
title: "Cancel Scheduled Message",
|
|
123
|
+
description:
|
|
124
|
+
"Cancel a scheduled message to prevent it from being sent. Only messages with status 'scheduled' can be cancelled. This action cannot be undone.",
|
|
125
|
+
inputSchema: z.object({
|
|
126
|
+
id: z.string().describe("Unique identifier (UUID) of the scheduled message to cancel"),
|
|
127
|
+
}),
|
|
128
|
+
annotations: {
|
|
129
|
+
readOnlyHint: false,
|
|
130
|
+
destructiveHint: true,
|
|
131
|
+
idempotentHint: true,
|
|
132
|
+
openWorldHint: false,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
async (params) => {
|
|
136
|
+
try {
|
|
137
|
+
const result = await api("DELETE", `/scheduled-messages/${params.id}`);
|
|
138
|
+
return jsonResult(result);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
return errorResult(error);
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
}
|