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,451 @@
|
|
|
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 knowledge base management tools for the Neuron MCP server.
|
|
7
|
+
* Provides CRUD operations for knowledge bases, entries, and search capabilities.
|
|
8
|
+
*/
|
|
9
|
+
export function registerKnowledgeBaseTools(server: McpServer): void {
|
|
10
|
+
// 1. Create Knowledge Base
|
|
11
|
+
server.registerTool(
|
|
12
|
+
"neuron_create_knowledge_base",
|
|
13
|
+
{
|
|
14
|
+
title: "Create Knowledge Base",
|
|
15
|
+
description: "Create a new knowledge base to store and organize information, documents, and entries.",
|
|
16
|
+
inputSchema: z.object({
|
|
17
|
+
name: z.string().describe("Name of the knowledge base"),
|
|
18
|
+
description: z.string().optional().describe("Optional description of the knowledge base purpose"),
|
|
19
|
+
rootInstruction: z.string().optional().describe("Optional root instruction or context for the knowledge base"),
|
|
20
|
+
}),
|
|
21
|
+
annotations: {
|
|
22
|
+
readOnlyHint: false,
|
|
23
|
+
destructiveHint: false,
|
|
24
|
+
idempotentHint: false,
|
|
25
|
+
openWorldHint: false,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
async (params) => {
|
|
29
|
+
try {
|
|
30
|
+
const result = await api("POST", "knowledge-bases", {
|
|
31
|
+
name: params.name,
|
|
32
|
+
description: params.description,
|
|
33
|
+
rootInstruction: params.rootInstruction,
|
|
34
|
+
});
|
|
35
|
+
return jsonResult(result);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return errorResult(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// 2. List Knowledge Bases
|
|
43
|
+
server.registerTool(
|
|
44
|
+
"neuron_list_knowledge_bases",
|
|
45
|
+
{
|
|
46
|
+
title: "List Knowledge Bases",
|
|
47
|
+
description: "Retrieve all knowledge bases accessible to the current user.",
|
|
48
|
+
inputSchema: z.object({}),
|
|
49
|
+
annotations: {
|
|
50
|
+
readOnlyHint: true,
|
|
51
|
+
destructiveHint: false,
|
|
52
|
+
idempotentHint: true,
|
|
53
|
+
openWorldHint: false,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
async () => {
|
|
57
|
+
try {
|
|
58
|
+
const result = await api("GET", "knowledge-bases");
|
|
59
|
+
return jsonResult(result);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
return errorResult(error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// 3. Get Knowledge Base
|
|
67
|
+
server.registerTool(
|
|
68
|
+
"neuron_get_knowledge_base",
|
|
69
|
+
{
|
|
70
|
+
title: "Get Knowledge Base",
|
|
71
|
+
description: "Retrieve detailed information about a specific knowledge base by its ID.",
|
|
72
|
+
inputSchema: z.object({
|
|
73
|
+
id: z.string().describe("Unique identifier of the knowledge base"),
|
|
74
|
+
}),
|
|
75
|
+
annotations: {
|
|
76
|
+
readOnlyHint: true,
|
|
77
|
+
destructiveHint: false,
|
|
78
|
+
idempotentHint: true,
|
|
79
|
+
openWorldHint: false,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
async (params) => {
|
|
83
|
+
try {
|
|
84
|
+
const result = await api("GET", `knowledge-bases/${params.id}`);
|
|
85
|
+
return jsonResult(result);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return errorResult(error);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
// 4. Update Knowledge Base
|
|
93
|
+
server.registerTool(
|
|
94
|
+
"neuron_update_knowledge_base",
|
|
95
|
+
{
|
|
96
|
+
title: "Update Knowledge Base",
|
|
97
|
+
description: "Update the properties of an existing knowledge base such as name, description, or root instruction.",
|
|
98
|
+
inputSchema: z.object({
|
|
99
|
+
id: z.string().describe("Unique identifier of the knowledge base to update"),
|
|
100
|
+
name: z.string().optional().describe("New name for the knowledge base"),
|
|
101
|
+
description: z.string().optional().describe("New description for the knowledge base"),
|
|
102
|
+
rootInstruction: z.string().optional().describe("New root instruction or context"),
|
|
103
|
+
}),
|
|
104
|
+
annotations: {
|
|
105
|
+
readOnlyHint: false,
|
|
106
|
+
destructiveHint: false,
|
|
107
|
+
idempotentHint: true,
|
|
108
|
+
openWorldHint: false,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
async (params) => {
|
|
112
|
+
try {
|
|
113
|
+
const result = await api("PUT", `knowledge-bases/${params.id}`, {
|
|
114
|
+
name: params.name,
|
|
115
|
+
description: params.description,
|
|
116
|
+
rootInstruction: params.rootInstruction,
|
|
117
|
+
});
|
|
118
|
+
return jsonResult(result);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
return errorResult(error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
// 5. Delete Knowledge Base
|
|
126
|
+
server.registerTool(
|
|
127
|
+
"neuron_delete_knowledge_base",
|
|
128
|
+
{
|
|
129
|
+
title: "Delete Knowledge Base",
|
|
130
|
+
description: "Permanently delete a knowledge base and all its associated entries and documents.",
|
|
131
|
+
inputSchema: z.object({
|
|
132
|
+
id: z.string().describe("Unique identifier of the knowledge base to delete"),
|
|
133
|
+
}),
|
|
134
|
+
annotations: {
|
|
135
|
+
readOnlyHint: false,
|
|
136
|
+
destructiveHint: true,
|
|
137
|
+
idempotentHint: true,
|
|
138
|
+
openWorldHint: false,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
async (params) => {
|
|
142
|
+
try {
|
|
143
|
+
const result = await api("DELETE", `knowledge-bases/${params.id}`);
|
|
144
|
+
return jsonResult(result);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
return errorResult(error);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
// 6. Create Knowledge Base Entry
|
|
152
|
+
server.registerTool(
|
|
153
|
+
"neuron_create_kb_entry",
|
|
154
|
+
{
|
|
155
|
+
title: "Create Knowledge Base Entry",
|
|
156
|
+
description: "Add a new entry (note, document, or information piece) to a knowledge base.",
|
|
157
|
+
inputSchema: z.object({
|
|
158
|
+
id: z.string().describe("Unique identifier of the knowledge base"),
|
|
159
|
+
title: z.string().describe("Title of the entry"),
|
|
160
|
+
content: z.string().describe("Content or body of the entry"),
|
|
161
|
+
source: z.enum(["manual", "document", "url"]).optional().describe("Source type of the entry (default: manual)"),
|
|
162
|
+
folder: z.string().optional().describe("Folder to organize the entry: 'general', 'skills', 'contexts', 'documents', or 'faqs' (default: general)"),
|
|
163
|
+
metadata: z.record(z.unknown()).optional().describe("Optional metadata key-value pairs for the entry"),
|
|
164
|
+
}),
|
|
165
|
+
annotations: {
|
|
166
|
+
readOnlyHint: false,
|
|
167
|
+
destructiveHint: false,
|
|
168
|
+
idempotentHint: false,
|
|
169
|
+
openWorldHint: false,
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
async (params) => {
|
|
173
|
+
try {
|
|
174
|
+
const result = await api("POST", `knowledge-bases/${params.id}/entries`, {
|
|
175
|
+
title: params.title,
|
|
176
|
+
content: params.content,
|
|
177
|
+
source: params.source,
|
|
178
|
+
folder: params.folder,
|
|
179
|
+
metadata: params.metadata,
|
|
180
|
+
});
|
|
181
|
+
return jsonResult(result);
|
|
182
|
+
} catch (error) {
|
|
183
|
+
return errorResult(error);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// 7. List Knowledge Base Entries
|
|
189
|
+
server.registerTool(
|
|
190
|
+
"neuron_list_kb_entries",
|
|
191
|
+
{
|
|
192
|
+
title: "List Knowledge Base Entries",
|
|
193
|
+
description: "Retrieve entries from a knowledge base with optional filtering and pagination.",
|
|
194
|
+
inputSchema: z.object({
|
|
195
|
+
id: z.string().describe("Unique identifier of the knowledge base"),
|
|
196
|
+
page: z.number().optional().describe("Page number for pagination (starts at 1)"),
|
|
197
|
+
limit: z.number().optional().describe("Maximum number of entries to return per page"),
|
|
198
|
+
folder: z.string().optional().describe("Filter entries by folder ('general', 'skills', 'contexts', 'documents', 'faqs')"),
|
|
199
|
+
source: z.string().optional().describe("Filter entries by source type ('manual', 'document', 'url')"),
|
|
200
|
+
}),
|
|
201
|
+
annotations: {
|
|
202
|
+
readOnlyHint: true,
|
|
203
|
+
destructiveHint: false,
|
|
204
|
+
idempotentHint: true,
|
|
205
|
+
openWorldHint: false,
|
|
206
|
+
},
|
|
207
|
+
},
|
|
208
|
+
async (params) => {
|
|
209
|
+
try {
|
|
210
|
+
const queryParams: Record<string, string> = {};
|
|
211
|
+
if (params.page !== undefined) queryParams.page = String(params.page);
|
|
212
|
+
if (params.limit !== undefined) queryParams.limit = String(params.limit);
|
|
213
|
+
if (params.folder) queryParams.folder = params.folder;
|
|
214
|
+
if (params.source) queryParams.source = params.source;
|
|
215
|
+
|
|
216
|
+
const result = await api("GET", `knowledge-bases/${params.id}/entries`, undefined, queryParams);
|
|
217
|
+
return jsonResult(result);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
return errorResult(error);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// 8. Update Knowledge Base Entry
|
|
225
|
+
server.registerTool(
|
|
226
|
+
"neuron_update_kb_entry",
|
|
227
|
+
{
|
|
228
|
+
title: "Update Knowledge Base Entry",
|
|
229
|
+
description: "Update the content, title, folder, or source of an existing knowledge base entry.",
|
|
230
|
+
inputSchema: z.object({
|
|
231
|
+
kbId: z.string().describe("Unique identifier of the knowledge base"),
|
|
232
|
+
entryId: z.string().describe("Unique identifier of the entry to update"),
|
|
233
|
+
title: z.string().optional().describe("New title for the entry"),
|
|
234
|
+
content: z.string().optional().describe("New content for the entry"),
|
|
235
|
+
source: z.enum(["manual", "document", "url"]).optional().describe("New source type for the entry"),
|
|
236
|
+
folder: z.string().optional().describe("New folder: 'general', 'skills', 'contexts', 'documents', or 'faqs'"),
|
|
237
|
+
metadata: z.record(z.unknown()).optional().describe("New metadata key-value pairs"),
|
|
238
|
+
}),
|
|
239
|
+
annotations: {
|
|
240
|
+
readOnlyHint: false,
|
|
241
|
+
destructiveHint: false,
|
|
242
|
+
idempotentHint: true,
|
|
243
|
+
openWorldHint: false,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
async (params) => {
|
|
247
|
+
try {
|
|
248
|
+
const result = await api("PUT", `knowledge-bases/${params.kbId}/entries/${params.entryId}`, {
|
|
249
|
+
title: params.title,
|
|
250
|
+
content: params.content,
|
|
251
|
+
source: params.source,
|
|
252
|
+
folder: params.folder,
|
|
253
|
+
metadata: params.metadata,
|
|
254
|
+
});
|
|
255
|
+
return jsonResult(result);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return errorResult(error);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
// 9. Delete Knowledge Base Entry
|
|
263
|
+
server.registerTool(
|
|
264
|
+
"neuron_delete_kb_entry",
|
|
265
|
+
{
|
|
266
|
+
title: "Delete Knowledge Base Entry",
|
|
267
|
+
description: "Permanently delete a specific entry from a knowledge base.",
|
|
268
|
+
inputSchema: z.object({
|
|
269
|
+
kbId: z.string().describe("Unique identifier of the knowledge base"),
|
|
270
|
+
entryId: z.string().describe("Unique identifier of the entry to delete"),
|
|
271
|
+
}),
|
|
272
|
+
annotations: {
|
|
273
|
+
readOnlyHint: false,
|
|
274
|
+
destructiveHint: true,
|
|
275
|
+
idempotentHint: true,
|
|
276
|
+
openWorldHint: false,
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
async (params) => {
|
|
280
|
+
try {
|
|
281
|
+
const result = await api("DELETE", `knowledge-bases/${params.kbId}/entries/${params.entryId}`);
|
|
282
|
+
return jsonResult(result);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
return errorResult(error);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
// 10. Upload Document
|
|
290
|
+
server.registerTool(
|
|
291
|
+
"neuron_upload_document",
|
|
292
|
+
{
|
|
293
|
+
title: "Upload Document",
|
|
294
|
+
description: "Upload a text document to a knowledge base. The document will be automatically chunked and indexed for semantic search.",
|
|
295
|
+
inputSchema: z.object({
|
|
296
|
+
id: z.string().describe("Unique identifier of the knowledge base"),
|
|
297
|
+
content: z.string().describe("Text content of the document to upload"),
|
|
298
|
+
filename: z.string().describe("Name of the file being uploaded"),
|
|
299
|
+
folder: z.string().optional().describe("Folder path to organize the document within the knowledge base"),
|
|
300
|
+
}),
|
|
301
|
+
annotations: {
|
|
302
|
+
readOnlyHint: false,
|
|
303
|
+
destructiveHint: false,
|
|
304
|
+
idempotentHint: false,
|
|
305
|
+
openWorldHint: false,
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
async (params) => {
|
|
309
|
+
try {
|
|
310
|
+
const result = await api("POST", `knowledge-bases/${params.id}/upload`, {
|
|
311
|
+
content: params.content,
|
|
312
|
+
filename: params.filename,
|
|
313
|
+
folder: params.folder,
|
|
314
|
+
});
|
|
315
|
+
return jsonResult(result);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
return errorResult(error);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
// 11. Search Knowledge
|
|
323
|
+
server.registerTool(
|
|
324
|
+
"neuron_search_knowledge",
|
|
325
|
+
{
|
|
326
|
+
title: "Search Knowledge",
|
|
327
|
+
description: "Perform semantic search across all entries and documents in a knowledge base to find relevant information.",
|
|
328
|
+
inputSchema: z.object({
|
|
329
|
+
id: z.string().describe("Unique identifier of the knowledge base to search"),
|
|
330
|
+
q: z.string().describe("Search query text to find relevant entries"),
|
|
331
|
+
limit: z.number().optional().describe("Maximum number of search results to return"),
|
|
332
|
+
}),
|
|
333
|
+
annotations: {
|
|
334
|
+
readOnlyHint: true,
|
|
335
|
+
destructiveHint: false,
|
|
336
|
+
idempotentHint: true,
|
|
337
|
+
openWorldHint: false,
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
async (params) => {
|
|
341
|
+
try {
|
|
342
|
+
const queryParams: Record<string, string> = {
|
|
343
|
+
q: params.q,
|
|
344
|
+
};
|
|
345
|
+
if (params.limit !== undefined) queryParams.limit = String(params.limit);
|
|
346
|
+
|
|
347
|
+
const result = await api("GET", `knowledge-bases/${params.id}/search`, undefined, queryParams);
|
|
348
|
+
return jsonResult(result);
|
|
349
|
+
} catch (error) {
|
|
350
|
+
return errorResult(error);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
// 12. List Knowledge Base Bots
|
|
356
|
+
server.registerTool(
|
|
357
|
+
"neuron_list_kb_bots",
|
|
358
|
+
{
|
|
359
|
+
title: "List Knowledge Base Bots",
|
|
360
|
+
description: "Retrieve all bots that are connected to or using a specific knowledge base.",
|
|
361
|
+
inputSchema: z.object({
|
|
362
|
+
id: z.string().describe("Unique identifier of the knowledge base"),
|
|
363
|
+
}),
|
|
364
|
+
annotations: {
|
|
365
|
+
readOnlyHint: true,
|
|
366
|
+
destructiveHint: false,
|
|
367
|
+
idempotentHint: true,
|
|
368
|
+
openWorldHint: false,
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
async (params) => {
|
|
372
|
+
try {
|
|
373
|
+
const result = await api("GET", `knowledge-bases/${params.id}/bots`);
|
|
374
|
+
return jsonResult(result);
|
|
375
|
+
} catch (error) {
|
|
376
|
+
return errorResult(error);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
// 13. Ingest Knowledge
|
|
382
|
+
server.registerTool(
|
|
383
|
+
"neuron_ingest_knowledge",
|
|
384
|
+
{
|
|
385
|
+
title: "Ingest Knowledge",
|
|
386
|
+
description: "Ingest content into a knowledge base. Supports deduplication via externalId and optional LLM processing (summarize, extract_facts, or custom instruction).",
|
|
387
|
+
inputSchema: z.object({
|
|
388
|
+
knowledgeBaseId: z.string().describe("Knowledge base ID to ingest into"),
|
|
389
|
+
title: z.string().describe("Title for the knowledge entry"),
|
|
390
|
+
content: z.string().describe("Content to ingest"),
|
|
391
|
+
externalId: z.string().optional().describe("Unique external ID for deduplication (e.g. file path, URL)"),
|
|
392
|
+
sourceUrl: z.string().optional().describe("Source URL for reference"),
|
|
393
|
+
source: z.enum(["api", "mcp"]).default("mcp").describe("Source type (default: mcp)"),
|
|
394
|
+
folder: z.string().optional().describe("Folder: 'general', 'skills', 'contexts', 'documents', or 'faqs' (default: general)"),
|
|
395
|
+
processing: z.object({
|
|
396
|
+
mode: z.enum(["raw", "summarize", "extract_facts", "custom"]).default("raw").describe("Processing mode"),
|
|
397
|
+
instruction: z.string().optional().describe("Custom instruction (only used with 'custom' mode)"),
|
|
398
|
+
}).optional().describe("Optional LLM processing before storage"),
|
|
399
|
+
}),
|
|
400
|
+
annotations: {
|
|
401
|
+
readOnlyHint: false,
|
|
402
|
+
destructiveHint: false,
|
|
403
|
+
idempotentHint: true,
|
|
404
|
+
openWorldHint: false,
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
async (params) => {
|
|
408
|
+
try {
|
|
409
|
+
const result = await api("POST", `knowledge-bases/${params.knowledgeBaseId}/entries`, {
|
|
410
|
+
title: params.title,
|
|
411
|
+
content: params.content,
|
|
412
|
+
source: params.source || "mcp",
|
|
413
|
+
folder: params.folder || "general",
|
|
414
|
+
metadata: {
|
|
415
|
+
...(params.externalId ? { externalId: params.externalId } : {}),
|
|
416
|
+
...(params.sourceUrl ? { sourceUrl: params.sourceUrl } : {}),
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
return jsonResult(result);
|
|
420
|
+
} catch (error) {
|
|
421
|
+
return errorResult(error);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
// 14. Sync Knowledge
|
|
427
|
+
server.registerTool(
|
|
428
|
+
"neuron_sync_knowledge",
|
|
429
|
+
{
|
|
430
|
+
title: "Sync Knowledge",
|
|
431
|
+
description: "Trigger a synchronization operation to refresh embeddings, reindex content, or update the knowledge base state.",
|
|
432
|
+
inputSchema: z.object({
|
|
433
|
+
id: z.string().describe("Unique identifier of the knowledge base to synchronize"),
|
|
434
|
+
}),
|
|
435
|
+
annotations: {
|
|
436
|
+
readOnlyHint: false,
|
|
437
|
+
destructiveHint: false,
|
|
438
|
+
idempotentHint: true,
|
|
439
|
+
openWorldHint: false,
|
|
440
|
+
},
|
|
441
|
+
},
|
|
442
|
+
async (params) => {
|
|
443
|
+
try {
|
|
444
|
+
const result = await api("POST", `knowledge-bases/${params.id}/sync`);
|
|
445
|
+
return jsonResult(result);
|
|
446
|
+
} catch (error) {
|
|
447
|
+
return errorResult(error);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
);
|
|
451
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
const READ = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
6
|
+
const WRITE = { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false };
|
|
7
|
+
|
|
8
|
+
const sourceType = z
|
|
9
|
+
.enum(["csv", "text_paste", "document", "web_scrape", "tool_output", "instagram", "x", "facebook", "tiktok", "stream"])
|
|
10
|
+
.describe("Lead source type. facebook = Meta Ads Library advertisers; web/IG/X/FB scraping needs DeepAPI configured; TikTok has no native provider (use tool_output).");
|
|
11
|
+
|
|
12
|
+
export function registerLeadTools(server: McpServer): void {
|
|
13
|
+
server.registerTool(
|
|
14
|
+
"neuron_list_lead_sources",
|
|
15
|
+
{ title: "List Lead Sources", description: "List configured lead sources for the org.", inputSchema: z.object({}), annotations: READ },
|
|
16
|
+
async () => {
|
|
17
|
+
try { return jsonResult(await api("GET", "/lead-sources")); } catch (e) { return errorResult(e); }
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
server.registerTool(
|
|
22
|
+
"neuron_create_lead_source",
|
|
23
|
+
{
|
|
24
|
+
title: "Create Lead Source",
|
|
25
|
+
description:
|
|
26
|
+
"Create a lead source. `config` depends on type: text_paste {text}; web_scrape {url|urls[]}; document {mediaUrl,mimeType}; tool_output {toolId,args?}; instagram/x {channelId, query?|hashtag?, limit?}; csv {rows[]}; stream {triggerTaskId?} (fed by the ingest endpoint). Set scheduleKind cron/interval/once for recurring (schedule: cron {time,days?} / interval {everyMinutes} / once {runAt}).",
|
|
27
|
+
inputSchema: z.object({
|
|
28
|
+
name: z.string(),
|
|
29
|
+
type: sourceType,
|
|
30
|
+
config: z.record(z.unknown()).optional(),
|
|
31
|
+
scheduleKind: z.enum(["cron", "interval", "once", "manual"]).optional(),
|
|
32
|
+
schedule: z.record(z.unknown()).optional(),
|
|
33
|
+
timezone: z.string().optional(),
|
|
34
|
+
enabled: z.boolean().optional(),
|
|
35
|
+
}),
|
|
36
|
+
annotations: WRITE,
|
|
37
|
+
},
|
|
38
|
+
async (body) => {
|
|
39
|
+
try { return jsonResult(await api("POST", "/lead-sources", body)); } catch (e) { return errorResult(e); }
|
|
40
|
+
},
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
server.registerTool(
|
|
44
|
+
"neuron_run_lead_source",
|
|
45
|
+
{ title: "Run Lead Source", description: "Run a lead source now to pull new leads into the pool (queues the extraction).", inputSchema: z.object({ id: z.string().describe("Lead source UUID") }), annotations: WRITE },
|
|
46
|
+
async ({ id }) => {
|
|
47
|
+
try { return jsonResult(await api("POST", `/lead-sources/${id}/run`)); } catch (e) { return errorResult(e); }
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
server.registerTool(
|
|
52
|
+
"neuron_extract_leads",
|
|
53
|
+
{
|
|
54
|
+
title: "Extract Leads (ad-hoc)",
|
|
55
|
+
description:
|
|
56
|
+
"Run a one-off extraction WITHOUT creating a persistent source, saving the results to the lead pool. Great for pasted text or a web page. `type` + `config` as in neuron_create_lead_source (e.g. type='text_paste', config={text}).",
|
|
57
|
+
inputSchema: z.object({ type: sourceType, config: z.record(z.unknown()) }),
|
|
58
|
+
annotations: WRITE,
|
|
59
|
+
},
|
|
60
|
+
async (body) => {
|
|
61
|
+
try { return jsonResult(await api("POST", "/leads/extract", body)); } catch (e) { return errorResult(e); }
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
server.registerTool(
|
|
66
|
+
"neuron_list_leads",
|
|
67
|
+
{
|
|
68
|
+
title: "List Leads",
|
|
69
|
+
description: "List leads from the pool, filterable by status (new/enriched/contacted/converted/rejected), sourceId, and search.",
|
|
70
|
+
inputSchema: z.object({
|
|
71
|
+
status: z.string().optional(),
|
|
72
|
+
sourceId: z.string().optional(),
|
|
73
|
+
search: z.string().optional(),
|
|
74
|
+
page: z.number().int().positive().optional(),
|
|
75
|
+
limit: z.number().int().positive().optional(),
|
|
76
|
+
}),
|
|
77
|
+
annotations: READ,
|
|
78
|
+
},
|
|
79
|
+
async (params) => {
|
|
80
|
+
try { return jsonResult(await api("GET", "/leads", undefined, params as Record<string, string | number | undefined>)); } catch (e) { return errorResult(e); }
|
|
81
|
+
},
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
server.registerTool(
|
|
85
|
+
"neuron_lead_stats",
|
|
86
|
+
{ title: "Lead Pool Stats", description: "Counts of leads by status.", inputSchema: z.object({}), annotations: READ },
|
|
87
|
+
async () => {
|
|
88
|
+
try { return jsonResult(await api("GET", "/leads/stats")); } catch (e) { return errorResult(e); }
|
|
89
|
+
},
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
server.registerTool(
|
|
93
|
+
"neuron_convert_lead",
|
|
94
|
+
{
|
|
95
|
+
title: "Convert Lead to Contact",
|
|
96
|
+
description: "Promote a phone-bearing lead into a contact (so it can be messaged / added to lists). Optionally add the new contact to a list.",
|
|
97
|
+
inputSchema: z.object({ id: z.string().describe("Lead UUID"), addToList: z.string().optional().describe("Contact list name to add the converted contact to.") }),
|
|
98
|
+
annotations: WRITE,
|
|
99
|
+
},
|
|
100
|
+
async ({ id, addToList }) => {
|
|
101
|
+
try { return jsonResult(await api("POST", `/leads/${id}/convert`, { addToList })); } catch (e) { return errorResult(e); }
|
|
102
|
+
},
|
|
103
|
+
);
|
|
104
|
+
}
|