@astramindapp/mcp-server 0.3.1 → 0.5.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/README.md +23 -6
- package/dist/mind-client.d.ts +360 -17
- package/dist/mind-client.d.ts.map +1 -1
- package/dist/mind-client.js +325 -2
- package/dist/mind-client.js.map +1 -1
- package/dist/server.d.ts +14 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1342 -93
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -5,13 +5,22 @@
|
|
|
5
5
|
* Exposes the MIND knowledge graph as MCP tools that any LLM agent can use.
|
|
6
6
|
* This is the universal AI memory layer.
|
|
7
7
|
*
|
|
8
|
-
* Tools:
|
|
8
|
+
* Tools (15):
|
|
9
9
|
* mind_query — Semantic search across the knowledge graph
|
|
10
|
-
* mind_remember — Store content
|
|
10
|
+
* mind_remember — Store/manage content in the graph (auto-categorized)
|
|
11
11
|
* mind_context — Get structured always-loaded context (soul/user/rules)
|
|
12
|
-
* mind_life — Read/write goals, projects, tasks
|
|
13
|
-
* mind_crm — Read/write contacts and
|
|
14
|
-
* mind_graph — Get graph statistics and
|
|
12
|
+
* mind_life — Read/write goals, projects, tasks, calendar events, stats
|
|
13
|
+
* mind_crm — Read/write contacts, interactions, and activities
|
|
14
|
+
* mind_graph — Get graph statistics, diagnostics, and labels
|
|
15
|
+
* mind_admin — Admin-only user and featured mind management
|
|
16
|
+
* mind_sense — MINDsense emotional intelligence layer
|
|
17
|
+
* mind_research — Deep research agent jobs
|
|
18
|
+
* mind_train — Self-training and chat-to-KG sessions
|
|
19
|
+
* mind_social — Thoughts, communities, and feed
|
|
20
|
+
* mind_profile — Profile, prompts, and model preferences
|
|
21
|
+
* mind_insights — ALE insights and analytics
|
|
22
|
+
* mind_automate — Automations and triggers
|
|
23
|
+
* mind_notify — Notifications management
|
|
15
24
|
*/
|
|
16
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
26
|
exports.createMindMcpServer = createMindMcpServer;
|
|
@@ -20,7 +29,7 @@ const zod_1 = require("zod");
|
|
|
20
29
|
function createMindMcpServer(client) {
|
|
21
30
|
const server = new mcp_js_1.McpServer({
|
|
22
31
|
name: "mind",
|
|
23
|
-
version: "0.
|
|
32
|
+
version: "0.2.0",
|
|
24
33
|
});
|
|
25
34
|
// ─── mind_query ─────────────────────────────────────────
|
|
26
35
|
// Semantic search across the user's knowledge graph.
|
|
@@ -28,10 +37,10 @@ function createMindMcpServer(client) {
|
|
|
28
37
|
server.tool("mind_query", "Search your MIND knowledge graph. Returns AI-synthesized answer from your stored documents, entries, and thoughts. Use this BEFORE making decisions — MIND is your memory.", {
|
|
29
38
|
query: zod_1.z.string().describe("What to search for in your knowledge graph"),
|
|
30
39
|
mode: zod_1.z
|
|
31
|
-
.enum(["mix", "hybrid", "
|
|
40
|
+
.enum(["mix", "hybrid", "global", "local", "naive"])
|
|
32
41
|
.optional()
|
|
33
42
|
.default("hybrid")
|
|
34
|
-
.describe("Search mode: hybrid (default, best results — combines semantic + graph traversal), mix (balanced), graph (
|
|
43
|
+
.describe("Search mode: hybrid (default, best results — combines semantic + graph traversal), mix (balanced), global (broad graph search), local (focused graph search), naive (simple vector search)"),
|
|
35
44
|
}, async ({ query, mode }) => {
|
|
36
45
|
try {
|
|
37
46
|
const result = await client.query({ query, mode });
|
|
@@ -43,7 +52,7 @@ function createMindMcpServer(client) {
|
|
|
43
52
|
if (result.sources?.length) {
|
|
44
53
|
text.push("");
|
|
45
54
|
for (const s of result.sources.slice(0, 5)) {
|
|
46
|
-
text.push(`• ${s
|
|
55
|
+
text.push(`• ${s}`);
|
|
47
56
|
}
|
|
48
57
|
}
|
|
49
58
|
return { content: [{ type: "text", text: text.join("\n") }] };
|
|
@@ -56,10 +65,15 @@ function createMindMcpServer(client) {
|
|
|
56
65
|
}
|
|
57
66
|
});
|
|
58
67
|
// ─── mind_remember ──────────────────────────────────────
|
|
59
|
-
// Store content
|
|
60
|
-
//
|
|
61
|
-
server.tool("mind_remember", "Store
|
|
62
|
-
|
|
68
|
+
// Store/manage content in the knowledge graph. Auto-categorized by type.
|
|
69
|
+
// Enhanced: now supports create, delete, search, get, list actions.
|
|
70
|
+
server.tool("mind_remember", "Store and manage content in your MIND knowledge graph. Use for facts, decisions, learnings, research, notes — anything worth remembering. Auto-categorized. Always log outcomes here after completing tasks. Supports create (default), delete, search, get, and list.", {
|
|
71
|
+
action: zod_1.z
|
|
72
|
+
.enum(["create", "delete", "search", "get", "list"])
|
|
73
|
+
.optional()
|
|
74
|
+
.default("create")
|
|
75
|
+
.describe("Action: create (store new content — default), delete (remove by ID), search (find entries), get (retrieve by ID), list (paginated listing)"),
|
|
76
|
+
content: zod_1.z.string().optional().describe("What to remember — the actual content to store (required for create)"),
|
|
63
77
|
type: zod_1.z
|
|
64
78
|
.enum(["document", "entry", "thought"])
|
|
65
79
|
.optional()
|
|
@@ -78,44 +92,155 @@ function createMindMcpServer(client) {
|
|
|
78
92
|
.optional()
|
|
79
93
|
.default("mcp-agent")
|
|
80
94
|
.describe("Source identifier (e.g. 'claude-code', 'openclaw', 'cursor')"),
|
|
81
|
-
|
|
95
|
+
item_id: zod_1.z
|
|
96
|
+
.string()
|
|
97
|
+
.optional()
|
|
98
|
+
.describe("Item ID for delete/get actions"),
|
|
99
|
+
query: zod_1.z
|
|
100
|
+
.string()
|
|
101
|
+
.optional()
|
|
102
|
+
.describe("Search query for search action"),
|
|
103
|
+
page: zod_1.z
|
|
104
|
+
.number()
|
|
105
|
+
.optional()
|
|
106
|
+
.describe("Page number for list action"),
|
|
107
|
+
limit: zod_1.z
|
|
108
|
+
.number()
|
|
109
|
+
.optional()
|
|
110
|
+
.describe("Max items to return for list/search"),
|
|
111
|
+
}, async ({ action, content, type, title, tags, source, item_id, query, page, limit }) => {
|
|
82
112
|
try {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
113
|
+
switch (action) {
|
|
114
|
+
case "create": {
|
|
115
|
+
if (!content) {
|
|
116
|
+
return {
|
|
117
|
+
content: [{ type: "text", text: "Error: content is required to create" }],
|
|
118
|
+
isError: true,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
let result;
|
|
122
|
+
let storedAs;
|
|
123
|
+
switch (type) {
|
|
124
|
+
case "document":
|
|
125
|
+
result = await client.createDocument({
|
|
126
|
+
title: title ?? `Agent Document — ${new Date().toISOString().slice(0, 10)}`,
|
|
127
|
+
content,
|
|
128
|
+
source: source ?? "mcp-agent",
|
|
129
|
+
});
|
|
130
|
+
storedAs = "document";
|
|
131
|
+
break;
|
|
132
|
+
case "thought":
|
|
133
|
+
result = await client.createThought({ content });
|
|
134
|
+
storedAs = "thought";
|
|
135
|
+
break;
|
|
136
|
+
case "entry":
|
|
137
|
+
default:
|
|
138
|
+
result = await client.createEntry({
|
|
139
|
+
title,
|
|
140
|
+
content,
|
|
141
|
+
tags,
|
|
142
|
+
});
|
|
143
|
+
storedAs = "entry";
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
const id = result.id ?? result.entry_id ?? result.thought_id ?? "unknown";
|
|
147
|
+
return {
|
|
148
|
+
content: [
|
|
149
|
+
{
|
|
150
|
+
type: "text",
|
|
151
|
+
text: `✅ Stored to MIND as ${storedAs} (id: ${id})${title ? ` — "${title}"` : ""}`,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
case "delete": {
|
|
157
|
+
if (!item_id) {
|
|
158
|
+
return {
|
|
159
|
+
content: [{ type: "text", text: "Error: item_id is required for delete" }],
|
|
160
|
+
isError: true,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
switch (type) {
|
|
164
|
+
case "document":
|
|
165
|
+
await client.deleteDocument(item_id);
|
|
166
|
+
break;
|
|
167
|
+
case "thought":
|
|
168
|
+
await client.deleteThought(item_id);
|
|
169
|
+
break;
|
|
170
|
+
case "entry":
|
|
171
|
+
default:
|
|
172
|
+
await client.deleteEntry(item_id);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
content: [{ type: "text", text: `✅ Deleted ${type} ${item_id}` }],
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
case "search": {
|
|
180
|
+
if (!query) {
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: "text", text: "Error: query is required for search" }],
|
|
183
|
+
isError: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const result = await client.searchEntries(query, limit);
|
|
187
|
+
const items = result.entries ?? [];
|
|
188
|
+
if (items.length === 0) {
|
|
189
|
+
return { content: [{ type: "text", text: `No results for "${query}".` }] };
|
|
190
|
+
}
|
|
191
|
+
const lines = items.map((e) => `• ${e.title ?? "Untitled"} — ${e.content?.slice(0, 120) ?? ""}... (id: ${e.entry_id})`);
|
|
192
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
193
|
+
}
|
|
194
|
+
case "get": {
|
|
195
|
+
if (!item_id) {
|
|
196
|
+
return {
|
|
197
|
+
content: [{ type: "text", text: "Error: item_id is required for get" }],
|
|
198
|
+
isError: true,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const result = await client.getEntry(item_id);
|
|
202
|
+
const lines = [
|
|
203
|
+
`**${result.title ?? "Untitled"}**`,
|
|
204
|
+
`Type: ${result.entry_type ?? type} | Created: ${result.created_at ?? "unknown"}`,
|
|
205
|
+
`Tags: ${result.tags?.join(", ") ?? "none"}`,
|
|
206
|
+
"",
|
|
207
|
+
result.content ?? "",
|
|
208
|
+
];
|
|
209
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
210
|
+
}
|
|
211
|
+
case "list": {
|
|
212
|
+
switch (type) {
|
|
213
|
+
case "document": {
|
|
214
|
+
const result = await client.listDocuments(page ?? 1, limit ?? 20);
|
|
215
|
+
const docs = result.documents ?? [];
|
|
216
|
+
if (docs.length === 0) {
|
|
217
|
+
return { content: [{ type: "text", text: "No documents found." }] };
|
|
218
|
+
}
|
|
219
|
+
const lines = docs.map((d) => `• ${d.title} (status: ${d.status}, source: ${d.source}) — id: ${d.id}`);
|
|
220
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
221
|
+
}
|
|
222
|
+
case "thought": {
|
|
223
|
+
const result = await client.listThoughts();
|
|
224
|
+
const thoughts = result.thoughts ?? [];
|
|
225
|
+
if (thoughts.length === 0) {
|
|
226
|
+
return { content: [{ type: "text", text: "No thoughts found." }] };
|
|
227
|
+
}
|
|
228
|
+
const lines = thoughts.map((t) => `• ${t.content?.slice(0, 100)}... — id: ${t.id ?? t.thought_id}`);
|
|
229
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
230
|
+
}
|
|
231
|
+
case "entry":
|
|
232
|
+
default: {
|
|
233
|
+
const result = await client.listEntries(limit ?? 20);
|
|
234
|
+
const entries = result.entries ?? [];
|
|
235
|
+
if (entries.length === 0) {
|
|
236
|
+
return { content: [{ type: "text", text: "No entries found." }] };
|
|
237
|
+
}
|
|
238
|
+
const lines = entries.map((e) => `• ${e.title ?? "Untitled"} (${e.entry_type ?? "text"}) — id: ${e.id ?? e.entry_id}`);
|
|
239
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
109
243
|
}
|
|
110
|
-
const id = result.id ?? result.entry_id ?? result.thought_id ?? "unknown";
|
|
111
|
-
return {
|
|
112
|
-
content: [
|
|
113
|
-
{
|
|
114
|
-
type: "text",
|
|
115
|
-
text: `✅ Stored to MIND as ${storedAs} (id: ${id})${title ? ` — "${title}"` : ""}`,
|
|
116
|
-
},
|
|
117
|
-
],
|
|
118
|
-
};
|
|
119
244
|
}
|
|
120
245
|
catch (err) {
|
|
121
246
|
return {
|
|
@@ -160,12 +285,17 @@ function createMindMcpServer(client) {
|
|
|
160
285
|
}
|
|
161
286
|
});
|
|
162
287
|
// ─── mind_life ──────────────────────────────────────────
|
|
163
|
-
// Read/write goals, projects,
|
|
164
|
-
|
|
288
|
+
// Read/write goals, projects, tasks, calendar events, stats.
|
|
289
|
+
// Enhanced: calendar CRUD, stats, move, get.
|
|
290
|
+
server.tool("mind_life", "Manage goals, projects, tasks, and calendar events in MIND Life. Use for tracking work, creating action items, updating progress, completing tasks, managing calendar, and viewing stats.", {
|
|
165
291
|
action: zod_1.z
|
|
166
|
-
.enum([
|
|
167
|
-
|
|
168
|
-
|
|
292
|
+
.enum([
|
|
293
|
+
"list", "create", "update", "complete", "delete", "move", "get",
|
|
294
|
+
"calendar_list", "calendar_create", "calendar_update", "calendar_delete",
|
|
295
|
+
"stats",
|
|
296
|
+
])
|
|
297
|
+
.describe("What to do: list/create/update/complete/delete/move/get items, calendar_list/calendar_create/calendar_update/calendar_delete events, stats (productivity overview)"),
|
|
298
|
+
title: zod_1.z.string().optional().describe("Title for new items or calendar events"),
|
|
169
299
|
description: zod_1.z.string().optional().describe("Description for new items"),
|
|
170
300
|
status: zod_1.z
|
|
171
301
|
.string()
|
|
@@ -176,8 +306,12 @@ function createMindMcpServer(client) {
|
|
|
176
306
|
.optional()
|
|
177
307
|
.describe("Priority: low, medium, high, urgent"),
|
|
178
308
|
due_date: zod_1.z.string().optional().describe("Due date in YYYY-MM-DD format"),
|
|
179
|
-
item_id: zod_1.z.string().optional().describe("Item ID for update/complete/delete actions"),
|
|
180
|
-
|
|
309
|
+
item_id: zod_1.z.string().optional().describe("Item ID for update/complete/delete/move/get actions"),
|
|
310
|
+
start_time: zod_1.z.string().optional().describe("Start time for calendar events (ISO 8601)"),
|
|
311
|
+
end_time: zod_1.z.string().optional().describe("End time for calendar events (ISO 8601)"),
|
|
312
|
+
event_id: zod_1.z.string().optional().describe("Event ID for calendar_update/calendar_delete"),
|
|
313
|
+
all_day: zod_1.z.boolean().optional().describe("Whether the calendar event is all-day"),
|
|
314
|
+
}, async ({ action, title, description, status, priority, due_date, item_id, start_time, end_time, event_id, all_day }) => {
|
|
181
315
|
try {
|
|
182
316
|
switch (action) {
|
|
183
317
|
case "list": {
|
|
@@ -259,6 +393,114 @@ function createMindMcpServer(client) {
|
|
|
259
393
|
content: [{ type: "text", text: `✅ Deleted life item ${item_id}` }],
|
|
260
394
|
};
|
|
261
395
|
}
|
|
396
|
+
case "move": {
|
|
397
|
+
if (!item_id || !status) {
|
|
398
|
+
return {
|
|
399
|
+
content: [{ type: "text", text: "Error: item_id and status are required for move" }],
|
|
400
|
+
isError: true,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
const result = await client.moveLifeItem(item_id, status);
|
|
404
|
+
return {
|
|
405
|
+
content: [{ type: "text", text: `✅ Moved "${result.title}" to ${result.status}` }],
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
case "get": {
|
|
409
|
+
if (!item_id) {
|
|
410
|
+
return {
|
|
411
|
+
content: [{ type: "text", text: "Error: item_id is required for get" }],
|
|
412
|
+
isError: true,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
const result = await client.getLifeItem(item_id);
|
|
416
|
+
const lines = [
|
|
417
|
+
`**${result.title}**`,
|
|
418
|
+
`Status: ${result.status ?? "—"} | Priority: ${result.priority ?? "—"} | Due: ${result.due_date ?? "none"}`,
|
|
419
|
+
result.description ? `\n${result.description}` : "",
|
|
420
|
+
];
|
|
421
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
422
|
+
}
|
|
423
|
+
case "calendar_list": {
|
|
424
|
+
const result = await client.listCalendarEvents();
|
|
425
|
+
const events = result.events ?? [];
|
|
426
|
+
if (events.length === 0) {
|
|
427
|
+
return { content: [{ type: "text", text: "No calendar events found." }] };
|
|
428
|
+
}
|
|
429
|
+
const lines = events.map((e) => `• ${e.title}${e.all_day ? " (all day)" : ""} — ${e.start_time ?? ""}${e.end_time ? ` to ${e.end_time}` : ""} — id: ${e.event_id}`);
|
|
430
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
431
|
+
}
|
|
432
|
+
case "calendar_create": {
|
|
433
|
+
if (!title || !start_time) {
|
|
434
|
+
return {
|
|
435
|
+
content: [{ type: "text", text: "Error: title and start_time are required for calendar_create" }],
|
|
436
|
+
isError: true,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
const result = await client.createCalendarEvent({
|
|
440
|
+
title,
|
|
441
|
+
description,
|
|
442
|
+
start_time,
|
|
443
|
+
end_time,
|
|
444
|
+
all_day,
|
|
445
|
+
});
|
|
446
|
+
return {
|
|
447
|
+
content: [
|
|
448
|
+
{
|
|
449
|
+
type: "text",
|
|
450
|
+
text: `✅ Created calendar event: "${result.title}" (id: ${result.event_id})`,
|
|
451
|
+
},
|
|
452
|
+
],
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
case "calendar_update": {
|
|
456
|
+
if (!event_id) {
|
|
457
|
+
return {
|
|
458
|
+
content: [{ type: "text", text: "Error: event_id is required for calendar_update" }],
|
|
459
|
+
isError: true,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
const patch = {};
|
|
463
|
+
if (title)
|
|
464
|
+
patch.title = title;
|
|
465
|
+
if (description)
|
|
466
|
+
patch.description = description;
|
|
467
|
+
if (start_time)
|
|
468
|
+
patch.start_time = start_time;
|
|
469
|
+
if (end_time)
|
|
470
|
+
patch.end_time = end_time;
|
|
471
|
+
if (all_day !== undefined)
|
|
472
|
+
patch.all_day = all_day;
|
|
473
|
+
const result = await client.updateCalendarEvent(event_id, patch);
|
|
474
|
+
return {
|
|
475
|
+
content: [{ type: "text", text: `✅ Updated calendar event: "${result.title}"` }],
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
case "calendar_delete": {
|
|
479
|
+
if (!event_id) {
|
|
480
|
+
return {
|
|
481
|
+
content: [{ type: "text", text: "Error: event_id is required for calendar_delete" }],
|
|
482
|
+
isError: true,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
await client.deleteCalendarEvent(event_id);
|
|
486
|
+
return {
|
|
487
|
+
content: [{ type: "text", text: `✅ Deleted calendar event ${event_id}` }],
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
case "stats": {
|
|
491
|
+
const result = await client.lifeStats();
|
|
492
|
+
const lines = [
|
|
493
|
+
"📊 MIND Life Stats",
|
|
494
|
+
`• Total items: ${result.total_items}`,
|
|
495
|
+
`• Completion rate: ${(result.completion_rate * 100).toFixed(1)}%`,
|
|
496
|
+
];
|
|
497
|
+
if (result.status_counts) {
|
|
498
|
+
for (const [status, count] of Object.entries(result.status_counts)) {
|
|
499
|
+
lines.push(`• ${status}: ${count}`);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
503
|
+
}
|
|
262
504
|
}
|
|
263
505
|
}
|
|
264
506
|
catch (err) {
|
|
@@ -269,11 +511,12 @@ function createMindMcpServer(client) {
|
|
|
269
511
|
}
|
|
270
512
|
});
|
|
271
513
|
// ─── mind_crm ───────────────────────────────────────────
|
|
272
|
-
// Read/write contacts and
|
|
273
|
-
|
|
514
|
+
// Read/write contacts, interactions, and activities.
|
|
515
|
+
// Enhanced: delete, get, log_activity, list_activities.
|
|
516
|
+
server.tool("mind_crm", "Manage contacts and relationships in MIND CRM. Use for tracking people, companies, leads, interaction history, and activity logging.", {
|
|
274
517
|
action: zod_1.z
|
|
275
|
-
.enum(["list", "create", "update"])
|
|
276
|
-
.describe("What to do: list contacts,
|
|
518
|
+
.enum(["list", "create", "update", "delete", "get", "log_activity", "list_activities"])
|
|
519
|
+
.describe("What to do: list/create/update/delete/get contacts, log_activity (record interaction), list_activities (view interaction history)"),
|
|
277
520
|
name: zod_1.z.string().optional().describe("Contact name (required for create)"),
|
|
278
521
|
email: zod_1.z.string().optional().describe("Contact email"),
|
|
279
522
|
company: zod_1.z.string().optional().describe("Company/organization"),
|
|
@@ -281,8 +524,10 @@ function createMindMcpServer(client) {
|
|
|
281
524
|
stage: zod_1.z.string().optional().describe("Pipeline stage: new, qualified, proposal, closed, lost"),
|
|
282
525
|
source: zod_1.z.string().optional().describe("How you found them"),
|
|
283
526
|
notes: zod_1.z.string().optional().describe("Notes about this contact"),
|
|
284
|
-
contact_id: zod_1.z.string().optional().describe("Contact ID for
|
|
285
|
-
|
|
527
|
+
contact_id: zod_1.z.string().optional().describe("Contact ID for update/delete/get/log_activity/list_activities"),
|
|
528
|
+
activity_type: zod_1.z.string().optional().describe("Activity type for log_activity: call, email, meeting, note"),
|
|
529
|
+
activity_notes: zod_1.z.string().optional().describe("Notes for the activity being logged"),
|
|
530
|
+
}, async ({ action, name, email, company, type, stage, source, notes, contact_id, activity_type, activity_notes }) => {
|
|
286
531
|
try {
|
|
287
532
|
switch (action) {
|
|
288
533
|
case "list": {
|
|
@@ -291,7 +536,7 @@ function createMindMcpServer(client) {
|
|
|
291
536
|
if (contacts.length === 0) {
|
|
292
537
|
return { content: [{ type: "text", text: "No contacts found." }] };
|
|
293
538
|
}
|
|
294
|
-
const lines = contacts.map((c) => `• ${c.name}${c.company ? ` @ ${c.company}` : ""}${c.email ? ` (${c.email})` : ""} — ${c.type ?? "—"} / ${c.stage ?? "—"} — id: ${c.
|
|
539
|
+
const lines = contacts.map((c) => `• ${c.name}${c.company ? ` @ ${c.company}` : ""}${c.email ? ` (${c.email})` : ""} — ${c.type ?? "—"} / ${c.stage ?? "—"} — id: ${c.contact_id}`);
|
|
295
540
|
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
296
541
|
}
|
|
297
542
|
case "create": {
|
|
@@ -314,7 +559,7 @@ function createMindMcpServer(client) {
|
|
|
314
559
|
content: [
|
|
315
560
|
{
|
|
316
561
|
type: "text",
|
|
317
|
-
text: `✅ Created contact: "${result.name}" (id: ${result.
|
|
562
|
+
text: `✅ Created contact: "${result.name}" (id: ${result.contact_id})`,
|
|
318
563
|
},
|
|
319
564
|
],
|
|
320
565
|
};
|
|
@@ -344,6 +589,70 @@ function createMindMcpServer(client) {
|
|
|
344
589
|
content: [{ type: "text", text: `✅ Updated contact: "${result.name}"` }],
|
|
345
590
|
};
|
|
346
591
|
}
|
|
592
|
+
case "delete": {
|
|
593
|
+
if (!contact_id) {
|
|
594
|
+
return {
|
|
595
|
+
content: [{ type: "text", text: "Error: contact_id is required for delete" }],
|
|
596
|
+
isError: true,
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
await client.deleteContact(contact_id);
|
|
600
|
+
return {
|
|
601
|
+
content: [{ type: "text", text: `✅ Deleted contact ${contact_id}` }],
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
case "get": {
|
|
605
|
+
if (!contact_id) {
|
|
606
|
+
return {
|
|
607
|
+
content: [{ type: "text", text: "Error: contact_id is required for get" }],
|
|
608
|
+
isError: true,
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
const result = await client.getContact(contact_id);
|
|
612
|
+
const lines = [
|
|
613
|
+
`**${result.name}**`,
|
|
614
|
+
`Email: ${result.email ?? "—"} | Company: ${result.company ?? "—"}`,
|
|
615
|
+
`Type: ${result.type ?? "—"} | Stage: ${result.stage ?? "—"}`,
|
|
616
|
+
`Created: ${result.created_at ?? "—"}`,
|
|
617
|
+
];
|
|
618
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
619
|
+
}
|
|
620
|
+
case "log_activity": {
|
|
621
|
+
if (!contact_id || !activity_type) {
|
|
622
|
+
return {
|
|
623
|
+
content: [{ type: "text", text: "Error: contact_id and activity_type are required for log_activity" }],
|
|
624
|
+
isError: true,
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
const result = await client.logActivity(contact_id, {
|
|
628
|
+
type: activity_type,
|
|
629
|
+
title: activity_type,
|
|
630
|
+
description: activity_notes,
|
|
631
|
+
});
|
|
632
|
+
return {
|
|
633
|
+
content: [
|
|
634
|
+
{
|
|
635
|
+
type: "text",
|
|
636
|
+
text: `✅ Logged ${activity_type} activity for contact ${contact_id} (id: ${result.activity_id})`,
|
|
637
|
+
},
|
|
638
|
+
],
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
case "list_activities": {
|
|
642
|
+
if (!contact_id) {
|
|
643
|
+
return {
|
|
644
|
+
content: [{ type: "text", text: "Error: contact_id is required for list_activities" }],
|
|
645
|
+
isError: true,
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
const result = await client.listContactActivities(contact_id);
|
|
649
|
+
const activities = result.activities ?? [];
|
|
650
|
+
if (activities.length === 0) {
|
|
651
|
+
return { content: [{ type: "text", text: "No activities found for this contact." }] };
|
|
652
|
+
}
|
|
653
|
+
const lines = activities.map((a) => `• [${a.type}] ${a.title ?? "—"} — ${a.description ?? "—"} — ${a.created_at ?? "—"}`);
|
|
654
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
655
|
+
}
|
|
347
656
|
}
|
|
348
657
|
}
|
|
349
658
|
catch (err) {
|
|
@@ -354,29 +663,73 @@ function createMindMcpServer(client) {
|
|
|
354
663
|
}
|
|
355
664
|
});
|
|
356
665
|
// ─── mind_graph ─────────────────────────────────────────
|
|
357
|
-
// Get graph statistics and
|
|
358
|
-
|
|
666
|
+
// Get graph statistics, diagnostics, and labels.
|
|
667
|
+
// Enhanced: action param with stats (default), diagnostics, labels.
|
|
668
|
+
server.tool("mind_graph", "Get MIND knowledge graph statistics, diagnostics, and label details. Use to check graph health, growth, and entity breakdown.", {
|
|
669
|
+
action: zod_1.z
|
|
670
|
+
.enum(["stats", "diagnostics", "labels"])
|
|
671
|
+
.optional()
|
|
672
|
+
.default("stats")
|
|
673
|
+
.describe("Action: stats (default — overview), diagnostics (health check), labels (entity label breakdown)"),
|
|
674
|
+
}, async ({ action }) => {
|
|
359
675
|
try {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
676
|
+
switch (action) {
|
|
677
|
+
case "stats":
|
|
678
|
+
default: {
|
|
679
|
+
const [graph, profile] = await Promise.all([
|
|
680
|
+
client.graphInfo(),
|
|
681
|
+
client.credits().catch(() => null),
|
|
682
|
+
]);
|
|
683
|
+
const lines = [
|
|
684
|
+
"📊 MIND Graph Status",
|
|
685
|
+
`• Entities: ${graph.total_entities}`,
|
|
686
|
+
`• Relationships: ${graph.total_relationships}`,
|
|
687
|
+
`• Storage: ${graph.storage_status?.status ?? "unknown"}`,
|
|
688
|
+
];
|
|
689
|
+
if (graph.popular_labels?.length) {
|
|
690
|
+
const docCount = graph.popular_labels.reduce((sum, l) => sum + l.count, 0);
|
|
691
|
+
lines.push(`• Items in graph: ${docCount}`);
|
|
692
|
+
}
|
|
693
|
+
if (profile) {
|
|
694
|
+
lines.push(`• Credits: ${profile.credits_balance}/${profile.credits_limit}`);
|
|
695
|
+
lines.push(`• Tier: ${profile.tier}`);
|
|
696
|
+
lines.push(`• Documents: ${profile.documents_count} | Storage: ${profile.storage_used_mb}/${profile.storage_limit_mb} MB`);
|
|
697
|
+
}
|
|
698
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
699
|
+
}
|
|
700
|
+
case "diagnostics": {
|
|
701
|
+
const result = await client.graphDiagnostics();
|
|
702
|
+
const lines = [
|
|
703
|
+
"🔍 MIND Graph Diagnostics",
|
|
704
|
+
`• Status: ${result.status ?? "unknown"}`,
|
|
705
|
+
`• Entity count: ${result.entity_count ?? "—"}`,
|
|
706
|
+
`• Relationship count: ${result.relationship_count ?? "—"}`,
|
|
707
|
+
`• Orphaned entities: ${result.orphaned_entities ?? "—"}`,
|
|
708
|
+
`• Storage health: ${result.storage_health ?? "—"}`,
|
|
709
|
+
];
|
|
710
|
+
const issues = result.issues;
|
|
711
|
+
if (issues?.length) {
|
|
712
|
+
lines.push("", "Issues:");
|
|
713
|
+
for (const issue of issues) {
|
|
714
|
+
lines.push(` ⚠ ${issue}`);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
718
|
+
}
|
|
719
|
+
case "labels": {
|
|
720
|
+
// Use graphInfo and extract popular_labels
|
|
721
|
+
const result = await client.graphInfo();
|
|
722
|
+
const labels = result.popular_labels ?? [];
|
|
723
|
+
if (labels.length === 0) {
|
|
724
|
+
return { content: [{ type: "text", text: "No labels found in graph." }] };
|
|
725
|
+
}
|
|
726
|
+
const lines = ["🏷️ MIND Graph Labels", ""];
|
|
727
|
+
for (const l of labels) {
|
|
728
|
+
lines.push(`• ${l.label ?? "unlabeled"}: ${l.count} entities`);
|
|
729
|
+
}
|
|
730
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
731
|
+
}
|
|
378
732
|
}
|
|
379
|
-
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
380
733
|
}
|
|
381
734
|
catch (err) {
|
|
382
735
|
return {
|
|
@@ -405,6 +758,8 @@ function createMindMcpServer(client) {
|
|
|
405
758
|
email: zod_1.z.string().optional().describe("Email for new user"),
|
|
406
759
|
password: zod_1.z.string().optional().describe("Password for new user (min 8 chars)"),
|
|
407
760
|
source: zod_1.z.string().optional().describe("Source app/partner that created this user (e.g. 'myapp')"),
|
|
761
|
+
generate_api_key: zod_1.z.boolean().optional().describe("If true, also generate a developer API key (mind_...) for the new user"),
|
|
762
|
+
api_key_name: zod_1.z.string().optional().describe("Name for the generated API key (defaults to '{source} integration')"),
|
|
408
763
|
// featured mind fields
|
|
409
764
|
mind_id: zod_1.z.string().optional().describe("Featured mind ID for update operations"),
|
|
410
765
|
title: zod_1.z.string().optional().describe("Display title for the featured mind"),
|
|
@@ -421,7 +776,7 @@ function createMindMcpServer(client) {
|
|
|
421
776
|
// list fields
|
|
422
777
|
query: zod_1.z.string().optional().describe("Search query for list_users"),
|
|
423
778
|
page: zod_1.z.number().optional().describe("Page number for paginated results"),
|
|
424
|
-
}, async ({ action, username, email, password, source, mind_id, title, description, tags, price, featured, display_order, is_public, avatar_url, tier, credits, query, page }) => {
|
|
779
|
+
}, async ({ action, username, email, password, source, generate_api_key, api_key_name, mind_id, title, description, tags, price, featured, display_order, is_public, avatar_url, tier, credits, query, page }) => {
|
|
425
780
|
try {
|
|
426
781
|
switch (action) {
|
|
427
782
|
case "create_user": {
|
|
@@ -431,14 +786,13 @@ function createMindMcpServer(client) {
|
|
|
431
786
|
isError: true,
|
|
432
787
|
};
|
|
433
788
|
}
|
|
434
|
-
const result = await client.adminCreateUser({ username, email, password, source, tier });
|
|
789
|
+
const result = await client.adminCreateUser({ username, email, password, source, tier, generate_api_key, api_key_name });
|
|
790
|
+
let text = `✅ User created: @${result.user?.username} (workspace: ${result.user?.workspace_id}, tier: ${result.user?.tier})`;
|
|
791
|
+
if (result.api_key) {
|
|
792
|
+
text += `\n🔑 API key: ${result.api_key.key}\n Name: ${result.api_key.name}\n Scopes: ${result.api_key.scopes.length} (full access)`;
|
|
793
|
+
}
|
|
435
794
|
return {
|
|
436
|
-
content: [
|
|
437
|
-
{
|
|
438
|
-
type: "text",
|
|
439
|
-
text: `✅ User created: @${result.user?.username} (workspace: ${result.user?.workspace_id}, tier: ${result.user?.tier})`,
|
|
440
|
-
},
|
|
441
|
-
],
|
|
795
|
+
content: [{ type: "text", text }],
|
|
442
796
|
};
|
|
443
797
|
}
|
|
444
798
|
case "create_featured_mind": {
|
|
@@ -559,6 +913,901 @@ function createMindMcpServer(client) {
|
|
|
559
913
|
};
|
|
560
914
|
}
|
|
561
915
|
});
|
|
916
|
+
// ═══════════════════════════════════════════════════════════
|
|
917
|
+
// NEW TOOLS (Phase 2 + Phase 3)
|
|
918
|
+
// ═══════════════════════════════════════════════════════════
|
|
919
|
+
// ─── mind_sense ─────────────────────────────────────────
|
|
920
|
+
// MINDsense emotional intelligence layer.
|
|
921
|
+
server.tool("mind_sense", "Access MINDsense emotional intelligence — the user's living emotional state, signal history, emotional timeline, and KG entity weights. Use this to understand how the user is feeling and what emotionally significant events have occurred.", {
|
|
922
|
+
action: zod_1.z
|
|
923
|
+
.enum(["state", "signals", "timeline", "kg_weights", "spikes", "acknowledge", "summary"])
|
|
924
|
+
.describe("Action: state (current emotion), signals (recent signals), timeline (historical), kg_weights (emotionally weighted entities), spikes (recent spikes), acknowledge (ack a spike), summary (AI emotional summary)"),
|
|
925
|
+
signal_id: zod_1.z.string().optional().describe("Signal ID for acknowledge action"),
|
|
926
|
+
days: zod_1.z.number().optional().default(7).describe("Lookback days for timeline/signals"),
|
|
927
|
+
limit: zod_1.z.number().optional().default(20).describe("Max items to return"),
|
|
928
|
+
}, async ({ action, signal_id, days, limit }) => {
|
|
929
|
+
try {
|
|
930
|
+
switch (action) {
|
|
931
|
+
case "state": {
|
|
932
|
+
const result = await client.mindsenseState();
|
|
933
|
+
const lines = [
|
|
934
|
+
"🧠 MINDsense Emotional State",
|
|
935
|
+
`• Label: ${result.label ?? "neutral"}`,
|
|
936
|
+
`• Valence: ${result.valence ?? "—"} (positive/negative)`,
|
|
937
|
+
`• Arousal: ${result.arousal ?? "—"} (intensity)`,
|
|
938
|
+
`• Trend: ${result.trend ?? "stable"}`,
|
|
939
|
+
`• Sensitivity: ${result.sensitivity ?? "—"}`,
|
|
940
|
+
];
|
|
941
|
+
if (result.dominant_emotion) {
|
|
942
|
+
lines.push(`• Dominant emotion: ${result.dominant_emotion}`);
|
|
943
|
+
}
|
|
944
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
945
|
+
}
|
|
946
|
+
case "signals": {
|
|
947
|
+
const result = await client.mindsenseSignals(days, limit);
|
|
948
|
+
const signals = result.signals ?? [];
|
|
949
|
+
if (signals.length === 0) {
|
|
950
|
+
return { content: [{ type: "text", text: "No emotional signals in the specified period." }] };
|
|
951
|
+
}
|
|
952
|
+
const lines = signals.map((s) => `• [${s.label ?? "—"}] valence: ${s.valence ?? "—"}, arousal: ${s.arousal ?? "—"} — ${s.created_at ?? "—"} (id: ${s.signal_id ?? s.id})`);
|
|
953
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
954
|
+
}
|
|
955
|
+
case "timeline": {
|
|
956
|
+
const result = await client.mindsenseTimeline(days);
|
|
957
|
+
const points = result.timeline ?? [];
|
|
958
|
+
if (points.length === 0) {
|
|
959
|
+
return { content: [{ type: "text", text: "No timeline data for the specified period." }] };
|
|
960
|
+
}
|
|
961
|
+
const lines = ["📈 Emotional Timeline", ""];
|
|
962
|
+
for (const p of points) {
|
|
963
|
+
lines.push(`• ${p.date ?? p.timestamp}: ${p.label ?? "—"} (v: ${p.valence ?? "—"}, a: ${p.arousal ?? "—"})`);
|
|
964
|
+
}
|
|
965
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
966
|
+
}
|
|
967
|
+
case "kg_weights": {
|
|
968
|
+
const result = await client.mindsenseKgWeights(limit);
|
|
969
|
+
const entities = result.entities ?? [];
|
|
970
|
+
if (entities.length === 0) {
|
|
971
|
+
return { content: [{ type: "text", text: "No emotionally weighted entities found." }] };
|
|
972
|
+
}
|
|
973
|
+
const lines = ["🎯 Emotionally Weighted KG Entities", ""];
|
|
974
|
+
for (const e of entities) {
|
|
975
|
+
lines.push(`• ${e.entity ?? e.name}: weight ${e.weight ?? e.score ?? "—"} (${e.emotion ?? "—"})`);
|
|
976
|
+
}
|
|
977
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
978
|
+
}
|
|
979
|
+
case "spikes": {
|
|
980
|
+
const result = await client.mindsenseSpikes(days, limit);
|
|
981
|
+
const spikes = result.spikes ?? [];
|
|
982
|
+
if (spikes.length === 0) {
|
|
983
|
+
return { content: [{ type: "text", text: "No emotional spikes detected." }] };
|
|
984
|
+
}
|
|
985
|
+
const lines = ["⚡ Emotional Spikes", ""];
|
|
986
|
+
for (const s of spikes) {
|
|
987
|
+
lines.push(`• [${s.acknowledged ? "ack" : "NEW"}] ${s.label ?? "—"} — valence: ${s.valence ?? "—"}, arousal: ${s.arousal ?? "—"} — ${s.created_at ?? "—"} (id: ${s.signal_id ?? s.id})`);
|
|
988
|
+
}
|
|
989
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
990
|
+
}
|
|
991
|
+
case "acknowledge": {
|
|
992
|
+
if (!signal_id) {
|
|
993
|
+
return {
|
|
994
|
+
content: [{ type: "text", text: "Error: signal_id is required for acknowledge" }],
|
|
995
|
+
isError: true,
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
await client.mindsenseAcknowledge(signal_id);
|
|
999
|
+
return {
|
|
1000
|
+
content: [{ type: "text", text: `✅ Acknowledged spike signal ${signal_id}` }],
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
case "summary": {
|
|
1004
|
+
const result = await client.mindsenseSummary(days);
|
|
1005
|
+
return {
|
|
1006
|
+
content: [{ type: "text", text: result.summary ?? "No emotional summary available." }],
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
catch (err) {
|
|
1012
|
+
return {
|
|
1013
|
+
content: [{ type: "text", text: `Error in mind_sense: ${err}` }],
|
|
1014
|
+
isError: true,
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
// ─── mind_research ──────────────────────────────────────
|
|
1019
|
+
// Deep research agent jobs.
|
|
1020
|
+
server.tool("mind_research", "Launch and manage deep research jobs. Research runs autonomously — it gathers information, analyzes it, and stores findings in the knowledge graph. Use for competitive analysis, market research, technical deep-dives.", {
|
|
1021
|
+
action: zod_1.z
|
|
1022
|
+
.enum(["start", "status", "list"])
|
|
1023
|
+
.describe("Action: start (launch research), status (check job progress), list (view all jobs)"),
|
|
1024
|
+
topic: zod_1.z.string().optional().describe("Research topic/question for start action"),
|
|
1025
|
+
job_id: zod_1.z.string().optional().describe("Job ID for status action"),
|
|
1026
|
+
limit: zod_1.z.number().optional().default(10).describe("Max jobs to return for list"),
|
|
1027
|
+
}, async ({ action, topic, job_id, limit }) => {
|
|
1028
|
+
try {
|
|
1029
|
+
switch (action) {
|
|
1030
|
+
case "start": {
|
|
1031
|
+
if (!topic) {
|
|
1032
|
+
return {
|
|
1033
|
+
content: [{ type: "text", text: "Error: topic is required to start research" }],
|
|
1034
|
+
isError: true,
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
const result = await client.startResearch(topic);
|
|
1038
|
+
return {
|
|
1039
|
+
content: [
|
|
1040
|
+
{
|
|
1041
|
+
type: "text",
|
|
1042
|
+
text: `✅ Research started: "${topic}" (job_id: ${result.job_id})`,
|
|
1043
|
+
},
|
|
1044
|
+
],
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
case "status": {
|
|
1048
|
+
if (!job_id) {
|
|
1049
|
+
return {
|
|
1050
|
+
content: [{ type: "text", text: "Error: job_id is required for status" }],
|
|
1051
|
+
isError: true,
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
const result = await client.getResearch(job_id);
|
|
1055
|
+
const lines = [
|
|
1056
|
+
`📋 Research Job: ${result.topic ?? result.title ?? job_id}`,
|
|
1057
|
+
`• Status: ${result.status}`,
|
|
1058
|
+
`• Papers found: ${result.papers_count ?? "—"}`,
|
|
1059
|
+
`• Credits used: ${result.credits_used ?? "—"}`,
|
|
1060
|
+
`• Started: ${result.created_at ?? "—"}`,
|
|
1061
|
+
];
|
|
1062
|
+
if (result.research_summary) {
|
|
1063
|
+
lines.push("", `Summary: ${result.research_summary}`);
|
|
1064
|
+
}
|
|
1065
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1066
|
+
}
|
|
1067
|
+
case "list": {
|
|
1068
|
+
const result = await client.listResearch(limit);
|
|
1069
|
+
const jobs = result.jobs ?? [];
|
|
1070
|
+
if (jobs.length === 0) {
|
|
1071
|
+
return { content: [{ type: "text", text: "No research jobs found." }] };
|
|
1072
|
+
}
|
|
1073
|
+
const lines = jobs.map((j) => `• [${j.status}] "${j.topic ?? j.title}" — ${j.created_at ?? "—"} (id: ${j.job_id})`);
|
|
1074
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
catch (err) {
|
|
1079
|
+
return {
|
|
1080
|
+
content: [{ type: "text", text: `Error in mind_research: ${err}` }],
|
|
1081
|
+
isError: true,
|
|
1082
|
+
};
|
|
1083
|
+
}
|
|
1084
|
+
});
|
|
1085
|
+
// ─── mind_train ─────────────────────────────────────────
|
|
1086
|
+
// Self-training and chat-to-KG sessions.
|
|
1087
|
+
server.tool("mind_train", "Train MIND's knowledge graph. Start guided training sessions to teach it about yourself, or save existing chat conversations into the knowledge graph for persistent memory.", {
|
|
1088
|
+
action: zod_1.z
|
|
1089
|
+
.enum(["start", "chat", "status", "list_sessions", "pause", "resume", "save_chat"])
|
|
1090
|
+
.describe("Action: start (begin training), chat (send message), status (check progress), list_sessions (view past), pause/resume (control session), save_chat (save chat to KG)"),
|
|
1091
|
+
message: zod_1.z.string().optional().describe("Training message for chat action"),
|
|
1092
|
+
session_type: zod_1.z
|
|
1093
|
+
.string()
|
|
1094
|
+
.optional()
|
|
1095
|
+
.describe("Training type: basics, network, expertise, history, goals, freeform"),
|
|
1096
|
+
session_id: zod_1.z.string().optional().describe("Session ID for save_chat/pause/resume actions"),
|
|
1097
|
+
}, async ({ action, message, session_type, session_id }) => {
|
|
1098
|
+
try {
|
|
1099
|
+
switch (action) {
|
|
1100
|
+
case "start": {
|
|
1101
|
+
const result = await client.trainingStart(session_type);
|
|
1102
|
+
const sid = String(result.session_id ?? result.id ?? "unknown");
|
|
1103
|
+
const prompt = String(result.prompt ?? result.message ?? "Ready to train.");
|
|
1104
|
+
return {
|
|
1105
|
+
content: [
|
|
1106
|
+
{
|
|
1107
|
+
type: "text",
|
|
1108
|
+
text: `✅ Training session started (type: ${session_type ?? "freeform"}, id: ${sid})\n\n${prompt}`,
|
|
1109
|
+
},
|
|
1110
|
+
],
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
case "chat": {
|
|
1114
|
+
if (!message) {
|
|
1115
|
+
return {
|
|
1116
|
+
content: [{ type: "text", text: "Error: message is required for chat" }],
|
|
1117
|
+
isError: true,
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
const result = await client.trainingChat(message);
|
|
1121
|
+
return {
|
|
1122
|
+
content: [{ type: "text", text: String(result.response ?? result.message ?? "Received.") }],
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
case "status": {
|
|
1126
|
+
const result = await client.trainingStatus();
|
|
1127
|
+
const lines = [
|
|
1128
|
+
"📋 Training Status",
|
|
1129
|
+
`• Active: ${result.active ? "yes" : "no"}`,
|
|
1130
|
+
`• Type: ${String(result.session_type ?? "—")}`,
|
|
1131
|
+
`• Progress: ${String(result.progress ?? "—")}`,
|
|
1132
|
+
`• Items learned: ${String(result.items_learned ?? 0)}`,
|
|
1133
|
+
];
|
|
1134
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1135
|
+
}
|
|
1136
|
+
case "list_sessions": {
|
|
1137
|
+
const result = await client.trainingSessions();
|
|
1138
|
+
const sessions = result.sessions ?? [];
|
|
1139
|
+
if (sessions.length === 0) {
|
|
1140
|
+
return { content: [{ type: "text", text: "No training sessions found." }] };
|
|
1141
|
+
}
|
|
1142
|
+
const lines = sessions.map((s) => `• [${String(s.status ?? "—")}] ${String(s.session_type ?? "freeform")} — ${String(s.created_at ?? "—")} (id: ${String(s.session_id ?? s.id)})`);
|
|
1143
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1144
|
+
}
|
|
1145
|
+
case "pause": {
|
|
1146
|
+
await client.trainingPause();
|
|
1147
|
+
return {
|
|
1148
|
+
content: [{ type: "text", text: "✅ Training session paused." }],
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1151
|
+
case "resume": {
|
|
1152
|
+
const result = await client.trainingResume();
|
|
1153
|
+
const prompt = String(result.prompt ?? result.message ?? "");
|
|
1154
|
+
return {
|
|
1155
|
+
content: [{ type: "text", text: `✅ Training session resumed.\n\n${prompt}` }],
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
case "save_chat": {
|
|
1159
|
+
if (!session_id) {
|
|
1160
|
+
return {
|
|
1161
|
+
content: [{ type: "text", text: "Error: session_id is required for save_chat" }],
|
|
1162
|
+
isError: true,
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
const result = await client.saveChatToMind(session_id);
|
|
1166
|
+
return {
|
|
1167
|
+
content: [
|
|
1168
|
+
{
|
|
1169
|
+
type: "text",
|
|
1170
|
+
text: `✅ Chat session saved to knowledge graph (${String(result.items_saved ?? result.count ?? 0)} items extracted)`,
|
|
1171
|
+
},
|
|
1172
|
+
],
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
catch (err) {
|
|
1178
|
+
return {
|
|
1179
|
+
content: [{ type: "text", text: `Error in mind_train: ${err}` }],
|
|
1180
|
+
isError: true,
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
// ─── mind_social ────────────────────────────────────────
|
|
1185
|
+
// Thoughts, communities, and feed.
|
|
1186
|
+
server.tool("mind_social", "Interact with MIND's social layer — create thoughts (posts), browse the feed, manage communities, and engage with other users' content.", {
|
|
1187
|
+
action: zod_1.z
|
|
1188
|
+
.enum([
|
|
1189
|
+
"create_thought", "get_thought", "delete_thought", "like_thought",
|
|
1190
|
+
"feed", "user_feed", "search_feed",
|
|
1191
|
+
"create_community", "list_communities", "get_community",
|
|
1192
|
+
"join_community", "leave_community",
|
|
1193
|
+
"create_post", "list_posts",
|
|
1194
|
+
])
|
|
1195
|
+
.describe("Social action — thoughts, feed browsing, community management"),
|
|
1196
|
+
content: zod_1.z.string().optional().describe("Content for thoughts or posts"),
|
|
1197
|
+
thought_id: zod_1.z.string().optional().describe("Thought ID for get/delete/like"),
|
|
1198
|
+
community_id: zod_1.z.string().optional().describe("Community ID for community actions and posts"),
|
|
1199
|
+
post_id: zod_1.z.string().optional().describe("Post ID for post actions"),
|
|
1200
|
+
username: zod_1.z.string().optional().describe("Username for user_feed"),
|
|
1201
|
+
name: zod_1.z.string().optional().describe("Community name for create_community"),
|
|
1202
|
+
description: zod_1.z.string().optional().describe("Community description"),
|
|
1203
|
+
page: zod_1.z.number().optional().describe("Page number for paginated results"),
|
|
1204
|
+
limit: zod_1.z.number().optional().describe("Max items per page"),
|
|
1205
|
+
}, async ({ action, content, thought_id, community_id, post_id, username, name, description, page, limit: lim }) => {
|
|
1206
|
+
try {
|
|
1207
|
+
switch (action) {
|
|
1208
|
+
case "create_thought": {
|
|
1209
|
+
if (!content) {
|
|
1210
|
+
return {
|
|
1211
|
+
content: [{ type: "text", text: "Error: content is required for create_thought" }],
|
|
1212
|
+
isError: true,
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
const result = await client.socialCreateThought(content);
|
|
1216
|
+
return {
|
|
1217
|
+
content: [
|
|
1218
|
+
{
|
|
1219
|
+
type: "text",
|
|
1220
|
+
text: `✅ Thought posted (id: ${result.thought_id ?? result.id})`,
|
|
1221
|
+
},
|
|
1222
|
+
],
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
case "get_thought": {
|
|
1226
|
+
if (!thought_id) {
|
|
1227
|
+
return {
|
|
1228
|
+
content: [{ type: "text", text: "Error: thought_id is required for get_thought" }],
|
|
1229
|
+
isError: true,
|
|
1230
|
+
};
|
|
1231
|
+
}
|
|
1232
|
+
const result = await client.socialGetThought(thought_id);
|
|
1233
|
+
const lines = [
|
|
1234
|
+
`@${result.username ?? "—"}: ${result.content}`,
|
|
1235
|
+
`Likes: ${result.likes ?? 0} | Reposts: ${result.reposts ?? 0} | ${result.created_at ?? ""}`,
|
|
1236
|
+
];
|
|
1237
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1238
|
+
}
|
|
1239
|
+
case "delete_thought": {
|
|
1240
|
+
if (!thought_id) {
|
|
1241
|
+
return {
|
|
1242
|
+
content: [{ type: "text", text: "Error: thought_id is required for delete_thought" }],
|
|
1243
|
+
isError: true,
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
await client.socialDeleteThought(thought_id);
|
|
1247
|
+
return {
|
|
1248
|
+
content: [{ type: "text", text: `✅ Deleted thought ${thought_id}` }],
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
case "like_thought": {
|
|
1252
|
+
if (!thought_id) {
|
|
1253
|
+
return {
|
|
1254
|
+
content: [{ type: "text", text: "Error: thought_id is required for like_thought" }],
|
|
1255
|
+
isError: true,
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
await client.socialLikeThought(thought_id);
|
|
1259
|
+
return {
|
|
1260
|
+
content: [{ type: "text", text: `✅ Liked thought ${thought_id}` }],
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
case "feed": {
|
|
1264
|
+
const result = await client.socialFeed(page, lim);
|
|
1265
|
+
const items = result.thoughts ?? [];
|
|
1266
|
+
if (items.length === 0) {
|
|
1267
|
+
return { content: [{ type: "text", text: "Feed is empty." }] };
|
|
1268
|
+
}
|
|
1269
|
+
const lines = items.map((t) => `• @${String(t.username ?? "—")}: ${String(t.content ?? "").slice(0, 120)} (❤ ${String(t.likes ?? 0)}) — id: ${String(t.thought_id ?? t.id)}`);
|
|
1270
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1271
|
+
}
|
|
1272
|
+
case "user_feed": {
|
|
1273
|
+
if (!username) {
|
|
1274
|
+
return {
|
|
1275
|
+
content: [{ type: "text", text: "Error: username is required for user_feed" }],
|
|
1276
|
+
isError: true,
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1279
|
+
const result = await client.socialUserFeed(username, page, lim);
|
|
1280
|
+
const items = result.thoughts ?? [];
|
|
1281
|
+
if (items.length === 0) {
|
|
1282
|
+
return { content: [{ type: "text", text: `No thoughts from @${username}.` }] };
|
|
1283
|
+
}
|
|
1284
|
+
const lines = items.map((t) => `• ${String(t.content ?? "").slice(0, 120)} (❤ ${String(t.likes ?? 0)}) — id: ${String(t.thought_id ?? t.id)}`);
|
|
1285
|
+
return { content: [{ type: "text", text: `@${username}'s thoughts:\n${lines.join("\n")}` }] };
|
|
1286
|
+
}
|
|
1287
|
+
case "search_feed": {
|
|
1288
|
+
if (!content) {
|
|
1289
|
+
return {
|
|
1290
|
+
content: [{ type: "text", text: "Error: content (search query) is required for search_feed" }],
|
|
1291
|
+
isError: true,
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
const result = await client.socialSearchFeed(content, page, lim);
|
|
1295
|
+
const items = result.thoughts ?? [];
|
|
1296
|
+
if (items.length === 0) {
|
|
1297
|
+
return { content: [{ type: "text", text: `No results for "${content}".` }] };
|
|
1298
|
+
}
|
|
1299
|
+
const lines = items.map((t) => `• @${String(t.username ?? "—")}: ${String(t.content ?? "").slice(0, 120)} — id: ${String(t.thought_id ?? t.id)}`);
|
|
1300
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1301
|
+
}
|
|
1302
|
+
case "create_community": {
|
|
1303
|
+
if (!name) {
|
|
1304
|
+
return {
|
|
1305
|
+
content: [{ type: "text", text: "Error: name is required for create_community" }],
|
|
1306
|
+
isError: true,
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
const result = await client.socialCreateCommunity(name, description);
|
|
1310
|
+
return {
|
|
1311
|
+
content: [
|
|
1312
|
+
{
|
|
1313
|
+
type: "text",
|
|
1314
|
+
text: `✅ Community created: "${result.name}" (id: ${result.community_id ?? result.id})`,
|
|
1315
|
+
},
|
|
1316
|
+
],
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
case "list_communities": {
|
|
1320
|
+
const result = await client.socialListCommunities(page, lim);
|
|
1321
|
+
const communities = result.communities ?? [];
|
|
1322
|
+
if (communities.length === 0) {
|
|
1323
|
+
return { content: [{ type: "text", text: "No communities found." }] };
|
|
1324
|
+
}
|
|
1325
|
+
const lines = communities.map((c) => `• ${c.name} — ${c.member_count ?? 0} members (id: ${c.community_id ?? c.id})`);
|
|
1326
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1327
|
+
}
|
|
1328
|
+
case "get_community": {
|
|
1329
|
+
if (!community_id) {
|
|
1330
|
+
return {
|
|
1331
|
+
content: [{ type: "text", text: "Error: community_id is required for get_community" }],
|
|
1332
|
+
isError: true,
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
const result = await client.socialGetCommunity(community_id);
|
|
1336
|
+
const lines = [
|
|
1337
|
+
`**${result.name}**`,
|
|
1338
|
+
result.description ?? "",
|
|
1339
|
+
`Members: ${result.member_count ?? 0} | Posts: ${result.post_count ?? 0}`,
|
|
1340
|
+
];
|
|
1341
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1342
|
+
}
|
|
1343
|
+
case "join_community": {
|
|
1344
|
+
if (!community_id) {
|
|
1345
|
+
return {
|
|
1346
|
+
content: [{ type: "text", text: "Error: community_id is required for join_community" }],
|
|
1347
|
+
isError: true,
|
|
1348
|
+
};
|
|
1349
|
+
}
|
|
1350
|
+
await client.socialJoinCommunity(community_id);
|
|
1351
|
+
return {
|
|
1352
|
+
content: [{ type: "text", text: `✅ Joined community ${community_id}` }],
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
case "leave_community": {
|
|
1356
|
+
if (!community_id) {
|
|
1357
|
+
return {
|
|
1358
|
+
content: [{ type: "text", text: "Error: community_id is required for leave_community" }],
|
|
1359
|
+
isError: true,
|
|
1360
|
+
};
|
|
1361
|
+
}
|
|
1362
|
+
await client.socialLeaveCommunity(community_id);
|
|
1363
|
+
return {
|
|
1364
|
+
content: [{ type: "text", text: `✅ Left community ${community_id}` }],
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
case "create_post": {
|
|
1368
|
+
if (!community_id || !content) {
|
|
1369
|
+
return {
|
|
1370
|
+
content: [{ type: "text", text: "Error: community_id and content are required for create_post" }],
|
|
1371
|
+
isError: true,
|
|
1372
|
+
};
|
|
1373
|
+
}
|
|
1374
|
+
const result = await client.socialCreatePost(community_id, content);
|
|
1375
|
+
return {
|
|
1376
|
+
content: [
|
|
1377
|
+
{
|
|
1378
|
+
type: "text",
|
|
1379
|
+
text: `✅ Post created in community ${community_id} (id: ${result.post_id ?? result.id})`,
|
|
1380
|
+
},
|
|
1381
|
+
],
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
case "list_posts": {
|
|
1385
|
+
if (!community_id) {
|
|
1386
|
+
return {
|
|
1387
|
+
content: [{ type: "text", text: "Error: community_id is required for list_posts" }],
|
|
1388
|
+
isError: true,
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
const result = await client.socialListPosts(community_id, page, lim);
|
|
1392
|
+
const posts = result.posts ?? [];
|
|
1393
|
+
if (posts.length === 0) {
|
|
1394
|
+
return { content: [{ type: "text", text: "No posts in this community." }] };
|
|
1395
|
+
}
|
|
1396
|
+
const lines = posts.map((p) => `• @${p.username ?? "—"}: ${p.content?.slice(0, 120) ?? ""} — id: ${p.post_id ?? p.id}`);
|
|
1397
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
catch (err) {
|
|
1402
|
+
return {
|
|
1403
|
+
content: [{ type: "text", text: `Error in mind_social: ${err}` }],
|
|
1404
|
+
isError: true,
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
});
|
|
1408
|
+
// ─── mind_profile ───────────────────────────────────────
|
|
1409
|
+
// Profile, prompts, and model preferences.
|
|
1410
|
+
server.tool("mind_profile", "Manage your MIND profile, AI prompt settings, and model preferences. Update your bio, set custom system prompts for chat and thought generation, and choose your preferred LLM model.", {
|
|
1411
|
+
action: zod_1.z
|
|
1412
|
+
.enum([
|
|
1413
|
+
"get", "update",
|
|
1414
|
+
"get_chat_prompt", "set_chat_prompt",
|
|
1415
|
+
"get_thought_prompt", "set_thought_prompt",
|
|
1416
|
+
"get_model", "set_model", "list_models",
|
|
1417
|
+
])
|
|
1418
|
+
.describe("Action: get/update profile, get/set chat/thought prompts, get/set/list LLM models"),
|
|
1419
|
+
username: zod_1.z.string().optional().describe("Username for get action (defaults to current user)"),
|
|
1420
|
+
bio: zod_1.z.string().optional().describe("Bio for update action"),
|
|
1421
|
+
display_name: zod_1.z.string().optional().describe("Display name for update action"),
|
|
1422
|
+
prompt: zod_1.z.string().optional().describe("System prompt content for set_chat_prompt/set_thought_prompt"),
|
|
1423
|
+
model_id: zod_1.z.string().optional().describe("Model ID for set_model"),
|
|
1424
|
+
}, async ({ action, username, bio, display_name, prompt, model_id }) => {
|
|
1425
|
+
try {
|
|
1426
|
+
switch (action) {
|
|
1427
|
+
case "get": {
|
|
1428
|
+
const result = await client.profileGet(username);
|
|
1429
|
+
const lines = [
|
|
1430
|
+
`**@${result.username}**`,
|
|
1431
|
+
result.display_name ? `Name: ${result.display_name}` : "",
|
|
1432
|
+
result.bio ? `Bio: ${result.bio}` : "",
|
|
1433
|
+
`Tier: ${result.tier ?? "free"}`,
|
|
1434
|
+
`Joined: ${result.created_at ?? "—"}`,
|
|
1435
|
+
].filter(Boolean);
|
|
1436
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1437
|
+
}
|
|
1438
|
+
case "update": {
|
|
1439
|
+
const patch = {};
|
|
1440
|
+
if (bio)
|
|
1441
|
+
patch.bio = bio;
|
|
1442
|
+
if (display_name)
|
|
1443
|
+
patch.display_name = display_name;
|
|
1444
|
+
if (username)
|
|
1445
|
+
patch.username = username;
|
|
1446
|
+
const result = await client.profileUpdate(patch);
|
|
1447
|
+
return {
|
|
1448
|
+
content: [{ type: "text", text: `✅ Profile updated: @${result.username}` }],
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
case "get_chat_prompt": {
|
|
1452
|
+
const result = await client.getChatPrompt();
|
|
1453
|
+
return {
|
|
1454
|
+
content: [{ type: "text", text: `Chat system prompt:\n\n${result.prompt ?? "No custom prompt set."}` }],
|
|
1455
|
+
};
|
|
1456
|
+
}
|
|
1457
|
+
case "set_chat_prompt": {
|
|
1458
|
+
if (!prompt) {
|
|
1459
|
+
return {
|
|
1460
|
+
content: [{ type: "text", text: "Error: prompt is required for set_chat_prompt" }],
|
|
1461
|
+
isError: true,
|
|
1462
|
+
};
|
|
1463
|
+
}
|
|
1464
|
+
await client.setChatPrompt(prompt);
|
|
1465
|
+
return {
|
|
1466
|
+
content: [{ type: "text", text: "✅ Chat system prompt updated." }],
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
case "get_thought_prompt": {
|
|
1470
|
+
const result = await client.getThoughtPrompt();
|
|
1471
|
+
return {
|
|
1472
|
+
content: [{ type: "text", text: `Thought generation prompt:\n\n${result.prompt ?? "No custom prompt set."}` }],
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
case "set_thought_prompt": {
|
|
1476
|
+
if (!prompt) {
|
|
1477
|
+
return {
|
|
1478
|
+
content: [{ type: "text", text: "Error: prompt is required for set_thought_prompt" }],
|
|
1479
|
+
isError: true,
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
await client.setThoughtPrompt(prompt);
|
|
1483
|
+
return {
|
|
1484
|
+
content: [{ type: "text", text: "✅ Thought generation prompt updated." }],
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1487
|
+
case "get_model": {
|
|
1488
|
+
const result = await client.getModel();
|
|
1489
|
+
return {
|
|
1490
|
+
content: [
|
|
1491
|
+
{
|
|
1492
|
+
type: "text",
|
|
1493
|
+
text: `Current model: ${result.model_id ?? result.model ?? "default"} (${result.provider ?? "—"})`,
|
|
1494
|
+
},
|
|
1495
|
+
],
|
|
1496
|
+
};
|
|
1497
|
+
}
|
|
1498
|
+
case "set_model": {
|
|
1499
|
+
if (!model_id) {
|
|
1500
|
+
return {
|
|
1501
|
+
content: [{ type: "text", text: "Error: model_id is required for set_model" }],
|
|
1502
|
+
isError: true,
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
const result = await client.setModel(model_id);
|
|
1506
|
+
return {
|
|
1507
|
+
content: [{ type: "text", text: `✅ Model set to: ${result.model_id ?? model_id}` }],
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
case "list_models": {
|
|
1511
|
+
const result = await client.listModels();
|
|
1512
|
+
const models = result.models ?? [];
|
|
1513
|
+
if (models.length === 0) {
|
|
1514
|
+
return { content: [{ type: "text", text: "No models available." }] };
|
|
1515
|
+
}
|
|
1516
|
+
const lines = models.map((m) => `• ${m.name ?? m.model_id} (${m.provider ?? "—"}) — ${m.description ?? ""}${m.is_free ? " [FREE]" : ""}`);
|
|
1517
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
catch (err) {
|
|
1522
|
+
return {
|
|
1523
|
+
content: [{ type: "text", text: `Error in mind_profile: ${err}` }],
|
|
1524
|
+
isError: true,
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
});
|
|
1528
|
+
// ─── mind_insights ──────────────────────────────────────
|
|
1529
|
+
// ALE insights and analytics.
|
|
1530
|
+
server.tool("mind_insights", "Access insights from MIND's Autonomous Learning Engine — patterns detected in your knowledge graph, weekly summaries, and proactive intelligence. Also trigger on-demand analysis.", {
|
|
1531
|
+
action: zod_1.z
|
|
1532
|
+
.enum(["list", "unread_count", "view", "feedback", "analyze", "weekly_summary", "context"])
|
|
1533
|
+
.describe("Action: list (recent insights), unread_count, view (mark seen), feedback (rate), analyze (trigger analysis), weekly_summary, context (ALE context)"),
|
|
1534
|
+
insight_id: zod_1.z.string().optional().describe("Insight ID for view/feedback actions"),
|
|
1535
|
+
rating: zod_1.z
|
|
1536
|
+
.enum(["helpful", "not_helpful"])
|
|
1537
|
+
.optional()
|
|
1538
|
+
.describe("Rating for feedback action"),
|
|
1539
|
+
limit: zod_1.z.number().optional().default(10).describe("Max insights to return"),
|
|
1540
|
+
}, async ({ action, insight_id, rating, limit }) => {
|
|
1541
|
+
try {
|
|
1542
|
+
switch (action) {
|
|
1543
|
+
case "list": {
|
|
1544
|
+
const result = await client.insightsList(limit);
|
|
1545
|
+
const insights = result.insights ?? [];
|
|
1546
|
+
if (insights.length === 0) {
|
|
1547
|
+
return { content: [{ type: "text", text: "No insights available." }] };
|
|
1548
|
+
}
|
|
1549
|
+
const lines = insights.map((i) => `• [${i.type ?? "insight"}] ${i.title ?? i.content?.slice(0, 100) ?? "—"} — ${i.created_at ?? ""} (id: ${i.insight_id ?? i.id})`);
|
|
1550
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1551
|
+
}
|
|
1552
|
+
case "unread_count": {
|
|
1553
|
+
const result = await client.insightsUnreadCount();
|
|
1554
|
+
return {
|
|
1555
|
+
content: [{ type: "text", text: `Unread insights: ${result.count ?? 0}` }],
|
|
1556
|
+
};
|
|
1557
|
+
}
|
|
1558
|
+
case "view": {
|
|
1559
|
+
if (!insight_id) {
|
|
1560
|
+
return {
|
|
1561
|
+
content: [{ type: "text", text: "Error: insight_id is required for view" }],
|
|
1562
|
+
isError: true,
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
const result = await client.insightsView(insight_id);
|
|
1566
|
+
const lines = [
|
|
1567
|
+
`**${result.title ?? "Insight"}**`,
|
|
1568
|
+
`Type: ${result.type ?? "—"} | Created: ${result.created_at ?? "—"}`,
|
|
1569
|
+
"",
|
|
1570
|
+
result.content ?? "No content.",
|
|
1571
|
+
];
|
|
1572
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1573
|
+
}
|
|
1574
|
+
case "feedback": {
|
|
1575
|
+
if (!insight_id || !rating) {
|
|
1576
|
+
return {
|
|
1577
|
+
content: [{ type: "text", text: "Error: insight_id and rating are required for feedback" }],
|
|
1578
|
+
isError: true,
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
await client.insightsFeedback(insight_id, rating);
|
|
1582
|
+
return {
|
|
1583
|
+
content: [{ type: "text", text: `✅ Feedback recorded for insight ${insight_id}: ${rating}` }],
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1586
|
+
case "analyze": {
|
|
1587
|
+
const result = await client.insightsAnalyze();
|
|
1588
|
+
return {
|
|
1589
|
+
content: [
|
|
1590
|
+
{
|
|
1591
|
+
type: "text",
|
|
1592
|
+
text: `✅ Analysis triggered. ${result.message ?? result.status ?? "Processing..."}`,
|
|
1593
|
+
},
|
|
1594
|
+
],
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
case "weekly_summary": {
|
|
1598
|
+
const result = await client.insightsWeeklySummary();
|
|
1599
|
+
return {
|
|
1600
|
+
content: [{ type: "text", text: result.summary ?? "No weekly summary available." }],
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
case "context": {
|
|
1604
|
+
const result = await client.insightsContext();
|
|
1605
|
+
return {
|
|
1606
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
catch (err) {
|
|
1612
|
+
return {
|
|
1613
|
+
content: [{ type: "text", text: `Error in mind_insights: ${err}` }],
|
|
1614
|
+
isError: true,
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
});
|
|
1618
|
+
// ─── mind_automate ──────────────────────────────────────
|
|
1619
|
+
// Automations and triggers.
|
|
1620
|
+
server.tool("mind_automate", "Create and manage automations in MIND — scheduled workflows, event triggers, and rules that run automatically. Connect CRM events to actions, schedule recurring tasks, and build custom pipelines.", {
|
|
1621
|
+
action: zod_1.z
|
|
1622
|
+
.enum(["list", "create", "update", "delete", "run_now", "history"])
|
|
1623
|
+
.describe("Action: list/create/update/delete automations, run_now (trigger immediately), history (execution log)"),
|
|
1624
|
+
automation_id: zod_1.z.string().optional().describe("Automation ID for update/delete/run_now/history"),
|
|
1625
|
+
name: zod_1.z.string().optional().describe("Automation name for create/update"),
|
|
1626
|
+
trigger_type: zod_1.z
|
|
1627
|
+
.string()
|
|
1628
|
+
.optional()
|
|
1629
|
+
.describe("Trigger type: schedule, webhook, event"),
|
|
1630
|
+
trigger_config: zod_1.z
|
|
1631
|
+
.string()
|
|
1632
|
+
.optional()
|
|
1633
|
+
.describe("JSON config string for the trigger (e.g. cron expression, event name)"),
|
|
1634
|
+
action_type: zod_1.z.string().optional().describe("Action type to execute when triggered"),
|
|
1635
|
+
action_config: zod_1.z
|
|
1636
|
+
.string()
|
|
1637
|
+
.optional()
|
|
1638
|
+
.describe("JSON config string for the action"),
|
|
1639
|
+
enabled: zod_1.z.boolean().optional().describe("Whether the automation is enabled"),
|
|
1640
|
+
}, async ({ action, automation_id, name, trigger_type, trigger_config, action_type, action_config, enabled }) => {
|
|
1641
|
+
try {
|
|
1642
|
+
switch (action) {
|
|
1643
|
+
case "list": {
|
|
1644
|
+
const result = await client.listAutomations();
|
|
1645
|
+
const automations = result.automations ?? [];
|
|
1646
|
+
if (automations.length === 0) {
|
|
1647
|
+
return { content: [{ type: "text", text: "No automations found." }] };
|
|
1648
|
+
}
|
|
1649
|
+
const lines = automations.map((a) => `• [${a.enabled ? "ON" : "OFF"}] ${a.task} — interval: ${a.interval} (runs: ${a.total_runs}, id: ${a.id})`);
|
|
1650
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1651
|
+
}
|
|
1652
|
+
case "create": {
|
|
1653
|
+
if (!name || !trigger_type || !action_type) {
|
|
1654
|
+
return {
|
|
1655
|
+
content: [{ type: "text", text: "Error: name, trigger_type, and action_type are required for create" }],
|
|
1656
|
+
isError: true,
|
|
1657
|
+
};
|
|
1658
|
+
}
|
|
1659
|
+
const result = await client.createAutomation({
|
|
1660
|
+
name,
|
|
1661
|
+
trigger_type,
|
|
1662
|
+
trigger_config: trigger_config ? JSON.parse(trigger_config) : undefined,
|
|
1663
|
+
action_type,
|
|
1664
|
+
action_config: action_config ? JSON.parse(action_config) : undefined,
|
|
1665
|
+
enabled: enabled ?? true,
|
|
1666
|
+
});
|
|
1667
|
+
return {
|
|
1668
|
+
content: [
|
|
1669
|
+
{
|
|
1670
|
+
type: "text",
|
|
1671
|
+
text: `✅ Automation created: "${result.name}" (id: ${result.automation_id ?? result.id})`,
|
|
1672
|
+
},
|
|
1673
|
+
],
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
case "update": {
|
|
1677
|
+
if (!automation_id) {
|
|
1678
|
+
return {
|
|
1679
|
+
content: [{ type: "text", text: "Error: automation_id is required for update" }],
|
|
1680
|
+
isError: true,
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
const patch = {};
|
|
1684
|
+
if (name)
|
|
1685
|
+
patch.name = name;
|
|
1686
|
+
if (trigger_type)
|
|
1687
|
+
patch.trigger_type = trigger_type;
|
|
1688
|
+
if (trigger_config)
|
|
1689
|
+
patch.trigger_config = JSON.parse(trigger_config);
|
|
1690
|
+
if (action_type)
|
|
1691
|
+
patch.action_type = action_type;
|
|
1692
|
+
if (action_config)
|
|
1693
|
+
patch.action_config = JSON.parse(action_config);
|
|
1694
|
+
if (enabled !== undefined)
|
|
1695
|
+
patch.enabled = enabled;
|
|
1696
|
+
const result = await client.updateAutomation(automation_id, patch);
|
|
1697
|
+
return {
|
|
1698
|
+
content: [{ type: "text", text: `✅ Updated automation: "${result.name}"` }],
|
|
1699
|
+
};
|
|
1700
|
+
}
|
|
1701
|
+
case "delete": {
|
|
1702
|
+
if (!automation_id) {
|
|
1703
|
+
return {
|
|
1704
|
+
content: [{ type: "text", text: "Error: automation_id is required for delete" }],
|
|
1705
|
+
isError: true,
|
|
1706
|
+
};
|
|
1707
|
+
}
|
|
1708
|
+
await client.deleteAutomation(automation_id);
|
|
1709
|
+
return {
|
|
1710
|
+
content: [{ type: "text", text: `✅ Deleted automation ${automation_id}` }],
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
case "run_now": {
|
|
1714
|
+
if (!automation_id) {
|
|
1715
|
+
return {
|
|
1716
|
+
content: [{ type: "text", text: "Error: automation_id is required for run_now" }],
|
|
1717
|
+
isError: true,
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
const result = await client.automationsRunNow(automation_id);
|
|
1721
|
+
return {
|
|
1722
|
+
content: [
|
|
1723
|
+
{
|
|
1724
|
+
type: "text",
|
|
1725
|
+
text: `✅ Automation triggered: ${result.status ?? "running"} (execution_id: ${result.execution_id ?? result.id ?? "—"})`,
|
|
1726
|
+
},
|
|
1727
|
+
],
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
case "history": {
|
|
1731
|
+
if (!automation_id) {
|
|
1732
|
+
return {
|
|
1733
|
+
content: [{ type: "text", text: "Error: automation_id is required for history" }],
|
|
1734
|
+
isError: true,
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
const result = await client.automationsHistory(automation_id);
|
|
1738
|
+
const executions = result.executions ?? [];
|
|
1739
|
+
if (executions.length === 0) {
|
|
1740
|
+
return { content: [{ type: "text", text: "No execution history found." }] };
|
|
1741
|
+
}
|
|
1742
|
+
const lines = executions.map((e) => `• [${e.status}] ${e.started_at ?? "—"}${e.completed_at ? ` → ${e.completed_at}` : ""} (id: ${e.execution_id ?? e.id})`);
|
|
1743
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
catch (err) {
|
|
1748
|
+
return {
|
|
1749
|
+
content: [{ type: "text", text: `Error in mind_automate: ${err}` }],
|
|
1750
|
+
isError: true,
|
|
1751
|
+
};
|
|
1752
|
+
}
|
|
1753
|
+
});
|
|
1754
|
+
// ─── mind_notify ────────────────────────────────────────
|
|
1755
|
+
// Notifications management.
|
|
1756
|
+
server.tool("mind_notify", "Read and manage MIND notifications — alerts, reminders, insight notifications, and system messages.", {
|
|
1757
|
+
action: zod_1.z
|
|
1758
|
+
.enum(["list", "mark_read", "mark_all_read", "stats"])
|
|
1759
|
+
.describe("Action: list (view notifications), mark_read (single), mark_all_read (all), stats (overview)"),
|
|
1760
|
+
notification_id: zod_1.z.string().optional().describe("Notification ID for mark_read"),
|
|
1761
|
+
limit: zod_1.z.number().optional().default(20).describe("Max notifications to return"),
|
|
1762
|
+
}, async ({ action, notification_id, limit }) => {
|
|
1763
|
+
try {
|
|
1764
|
+
switch (action) {
|
|
1765
|
+
case "list": {
|
|
1766
|
+
const result = await client.notificationsList(limit);
|
|
1767
|
+
const notifications = result.notifications ?? [];
|
|
1768
|
+
if (notifications.length === 0) {
|
|
1769
|
+
return { content: [{ type: "text", text: "No notifications." }] };
|
|
1770
|
+
}
|
|
1771
|
+
const lines = notifications.map((n) => `• [${n.read ? "read" : "NEW"}] ${n.title ?? n.message ?? "—"} — ${n.created_at ?? ""} (id: ${n.notification_id})`);
|
|
1772
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1773
|
+
}
|
|
1774
|
+
case "mark_read": {
|
|
1775
|
+
if (!notification_id) {
|
|
1776
|
+
return {
|
|
1777
|
+
content: [{ type: "text", text: "Error: notification_id is required for mark_read" }],
|
|
1778
|
+
isError: true,
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
await client.notificationsMarkRead(notification_id);
|
|
1782
|
+
return {
|
|
1783
|
+
content: [{ type: "text", text: `✅ Marked notification ${notification_id} as read.` }],
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
case "mark_all_read": {
|
|
1787
|
+
const result = await client.notificationsMarkAllRead();
|
|
1788
|
+
return {
|
|
1789
|
+
content: [{ type: "text", text: `✅ Marked ${result.count ?? "all"} notifications as read.` }],
|
|
1790
|
+
};
|
|
1791
|
+
}
|
|
1792
|
+
case "stats": {
|
|
1793
|
+
const result = await client.notificationsStats();
|
|
1794
|
+
const lines = [
|
|
1795
|
+
"🔔 Notification Stats",
|
|
1796
|
+
`• Total: ${result.total ?? 0}`,
|
|
1797
|
+
`• Unread: ${result.unread ?? 0}`,
|
|
1798
|
+
`• Read: ${result.read ?? 0}`,
|
|
1799
|
+
];
|
|
1800
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
catch (err) {
|
|
1805
|
+
return {
|
|
1806
|
+
content: [{ type: "text", text: `Error in mind_notify: ${err}` }],
|
|
1807
|
+
isError: true,
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
});
|
|
562
1811
|
return server;
|
|
563
1812
|
}
|
|
564
1813
|
//# sourceMappingURL=server.js.map
|