@lanonasis/mem-intel-sdk 1.0.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +490 -0
  4. package/dist/core/client.d.ts +43 -0
  5. package/dist/core/client.d.ts.map +1 -0
  6. package/dist/core/errors.d.ts +24 -0
  7. package/dist/core/errors.d.ts.map +1 -0
  8. package/dist/core/index.cjs +310 -0
  9. package/dist/core/index.cjs.map +1 -0
  10. package/dist/core/index.d.ts +7 -0
  11. package/dist/core/index.d.ts.map +1 -0
  12. package/dist/core/index.js +300 -0
  13. package/dist/core/index.js.map +1 -0
  14. package/dist/core/types.d.ts +171 -0
  15. package/dist/core/types.d.ts.map +1 -0
  16. package/dist/index-sdk.d.ts +8 -0
  17. package/dist/index-sdk.d.ts.map +1 -0
  18. package/dist/index.cjs +310 -0
  19. package/dist/index.cjs.map +1 -0
  20. package/dist/index.js +300 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/node/client.d.ts +22 -0
  23. package/dist/node/client.d.ts.map +1 -0
  24. package/dist/node/index.cjs +331 -0
  25. package/dist/node/index.cjs.map +1 -0
  26. package/dist/node/index.d.ts +7 -0
  27. package/dist/node/index.d.ts.map +1 -0
  28. package/dist/node/index.js +321 -0
  29. package/dist/node/index.js.map +1 -0
  30. package/dist/react/context/MemoryIntelligenceProvider.d.ts +18 -0
  31. package/dist/react/context/MemoryIntelligenceProvider.d.ts.map +1 -0
  32. package/dist/react/hooks/useMemoryIntelligence.d.ts +115 -0
  33. package/dist/react/hooks/useMemoryIntelligence.d.ts.map +1 -0
  34. package/dist/react/index.cjs +399 -0
  35. package/dist/react/index.cjs.map +1 -0
  36. package/dist/react/index.d.ts +8 -0
  37. package/dist/react/index.d.ts.map +1 -0
  38. package/dist/react/index.js +377 -0
  39. package/dist/react/index.js.map +1 -0
  40. package/dist/server/index.cjs +802 -0
  41. package/dist/server/index.cjs.map +1 -0
  42. package/dist/server/index.d.ts +7 -0
  43. package/dist/server/index.d.ts.map +1 -0
  44. package/dist/server/index.js +792 -0
  45. package/dist/server/index.js.map +1 -0
  46. package/dist/server/mcp-server.d.ts +7 -0
  47. package/dist/server/mcp-server.d.ts.map +1 -0
  48. package/dist/utils/embeddings.d.ts +13 -0
  49. package/dist/utils/embeddings.d.ts.map +1 -0
  50. package/dist/utils/formatting.d.ts +13 -0
  51. package/dist/utils/formatting.d.ts.map +1 -0
  52. package/dist/utils/http-client.d.ts +31 -0
  53. package/dist/utils/http-client.d.ts.map +1 -0
  54. package/dist/utils/index.d.ts +9 -0
  55. package/dist/utils/index.d.ts.map +1 -0
  56. package/dist/utils/similarity.d.ts +8 -0
  57. package/dist/utils/similarity.d.ts.map +1 -0
  58. package/dist/vue/composables/useMemoryIntelligence.d.ts +24 -0
  59. package/dist/vue/composables/useMemoryIntelligence.d.ts.map +1 -0
  60. package/dist/vue/index.cjs +132 -0
  61. package/dist/vue/index.cjs.map +1 -0
  62. package/dist/vue/index.d.ts +7 -0
  63. package/dist/vue/index.d.ts.map +1 -0
  64. package/dist/vue/index.js +115 -0
  65. package/dist/vue/index.js.map +1 -0
  66. package/package.json +144 -0
@@ -0,0 +1,792 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+
4
+ // src/server/mcp-server.ts
5
+
6
+ // src/core/errors.ts
7
+ var MemoryIntelligenceError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "MemoryIntelligenceError";
11
+ }
12
+ };
13
+ var ConfigurationError = class extends MemoryIntelligenceError {
14
+ constructor(message) {
15
+ super(message);
16
+ this.name = "ConfigurationError";
17
+ }
18
+ };
19
+ var MemoryNotFoundError = class extends MemoryIntelligenceError {
20
+ constructor(memoryId) {
21
+ super(`Memory not found: ${memoryId}`);
22
+ this.name = "MemoryNotFoundError";
23
+ }
24
+ };
25
+ var DatabaseError = class extends MemoryIntelligenceError {
26
+ constructor(message, originalError) {
27
+ super(message);
28
+ this.originalError = originalError;
29
+ this.name = "DatabaseError";
30
+ }
31
+ };
32
+ var EmbeddingError = class extends MemoryIntelligenceError {
33
+ constructor(message, originalError) {
34
+ super(message);
35
+ this.originalError = originalError;
36
+ this.name = "EmbeddingError";
37
+ }
38
+ };
39
+ var ValidationError = class extends MemoryIntelligenceError {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = "ValidationError";
43
+ }
44
+ };
45
+
46
+ // src/utils/http-client.ts
47
+ var HttpClient = class {
48
+ apiUrl;
49
+ apiKey;
50
+ timeout;
51
+ headers;
52
+ constructor(config) {
53
+ if (!config.apiKey) {
54
+ throw new ConfigurationError("API key is required");
55
+ }
56
+ if (!config.apiKey.startsWith("lano_")) {
57
+ throw new ConfigurationError(
58
+ "Invalid API key format. API key should start with 'lano_'"
59
+ );
60
+ }
61
+ this.apiUrl = config.apiUrl.replace(/\/$/, "");
62
+ this.apiKey = config.apiKey;
63
+ this.timeout = config.timeout || 3e4;
64
+ this.headers = {
65
+ "Content-Type": "application/json",
66
+ "X-API-Key": this.apiKey,
67
+ ...config.headers
68
+ };
69
+ }
70
+ async request(method, endpoint, data) {
71
+ const url = `${this.apiUrl}${endpoint}`;
72
+ const controller = new AbortController();
73
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
74
+ try {
75
+ const options = {
76
+ method,
77
+ headers: this.headers,
78
+ signal: controller.signal
79
+ };
80
+ if (data && (method === "POST" || method === "PUT" || method === "PATCH")) {
81
+ options.body = JSON.stringify(data);
82
+ }
83
+ const response = await fetch(url, options);
84
+ clearTimeout(timeoutId);
85
+ const responseData = await response.json();
86
+ if (!response.ok) {
87
+ return {
88
+ status: response.status,
89
+ error: {
90
+ message: responseData?.message || responseData?.error || "Request failed",
91
+ code: responseData?.code
92
+ }
93
+ };
94
+ }
95
+ return {
96
+ status: response.status,
97
+ data: responseData
98
+ };
99
+ } catch (error) {
100
+ clearTimeout(timeoutId);
101
+ if (error instanceof Error) {
102
+ if (error.name === "AbortError") {
103
+ return {
104
+ status: 408,
105
+ error: {
106
+ message: `Request timeout after ${this.timeout}ms`,
107
+ code: "TIMEOUT"
108
+ }
109
+ };
110
+ }
111
+ return {
112
+ status: 0,
113
+ error: {
114
+ message: error.message,
115
+ code: "NETWORK_ERROR"
116
+ }
117
+ };
118
+ }
119
+ return {
120
+ status: 0,
121
+ error: {
122
+ message: "Unknown error occurred",
123
+ code: "UNKNOWN_ERROR"
124
+ }
125
+ };
126
+ }
127
+ }
128
+ async get(endpoint) {
129
+ return this.request("GET", endpoint);
130
+ }
131
+ async post(endpoint, data) {
132
+ return this.request("POST", endpoint, data);
133
+ }
134
+ async put(endpoint, data) {
135
+ return this.request("PUT", endpoint, data);
136
+ }
137
+ async patch(endpoint, data) {
138
+ return this.request("PATCH", endpoint, data);
139
+ }
140
+ async delete(endpoint) {
141
+ return this.request("DELETE", endpoint);
142
+ }
143
+ };
144
+
145
+ // src/core/client.ts
146
+ var DEFAULT_API_URL = "https://api.lanonasis.com/api/v1";
147
+ var MemoryIntelligenceClient = class {
148
+ httpClient;
149
+ defaultResponseFormat;
150
+ constructor(config) {
151
+ if (!config.apiKey) {
152
+ throw new ConfigurationError(
153
+ "Missing required configuration: apiKey is required (format: lano_xxxxxxxxxx)"
154
+ );
155
+ }
156
+ this.httpClient = new HttpClient({
157
+ apiUrl: config.apiUrl || DEFAULT_API_URL,
158
+ apiKey: config.apiKey,
159
+ timeout: config.timeout,
160
+ headers: config.headers
161
+ });
162
+ this.defaultResponseFormat = config.responseFormat || "markdown";
163
+ }
164
+ /**
165
+ * Get HTTP client for direct API access
166
+ */
167
+ getHttpClient() {
168
+ return this.httpClient;
169
+ }
170
+ /**
171
+ * Query memories from the API
172
+ */
173
+ async queryMemories(userId, options = {}) {
174
+ const { type, limit = 100, offset = 0 } = options;
175
+ const params = new URLSearchParams({
176
+ user_id: userId,
177
+ limit: limit.toString(),
178
+ offset: offset.toString()
179
+ });
180
+ if (type) {
181
+ params.append("type", type);
182
+ }
183
+ const response = await this.httpClient.get(
184
+ `/intelligence/memories?${params.toString()}`
185
+ );
186
+ if (response.error) {
187
+ throw new DatabaseError(`Failed to query memories: ${response.error.message}`);
188
+ }
189
+ return response.data?.memories || [];
190
+ }
191
+ /**
192
+ * Analyze usage patterns and trends in memory collection
193
+ */
194
+ async analyzePatterns(params) {
195
+ const response = await this.httpClient.post(
196
+ "/intelligence/analyze-patterns",
197
+ {
198
+ ...params,
199
+ responseFormat: params.responseFormat || this.defaultResponseFormat
200
+ }
201
+ );
202
+ if (response.error) {
203
+ throw new DatabaseError(`Failed to analyze patterns: ${response.error.message}`);
204
+ }
205
+ return response.data;
206
+ }
207
+ /**
208
+ * Get AI-powered tag suggestions for a memory
209
+ */
210
+ async suggestTags(params) {
211
+ const response = await this.httpClient.post(
212
+ "/intelligence/suggest-tags",
213
+ {
214
+ ...params,
215
+ responseFormat: params.responseFormat || this.defaultResponseFormat
216
+ }
217
+ );
218
+ if (response.error) {
219
+ throw new DatabaseError(`Failed to suggest tags: ${response.error.message}`);
220
+ }
221
+ return response.data;
222
+ }
223
+ /**
224
+ * Find semantically related memories using vector similarity
225
+ */
226
+ async findRelated(params) {
227
+ const response = await this.httpClient.post(
228
+ "/intelligence/find-related",
229
+ {
230
+ ...params,
231
+ responseFormat: params.responseFormat || this.defaultResponseFormat
232
+ }
233
+ );
234
+ if (response.error) {
235
+ throw new DatabaseError(`Failed to find related memories: ${response.error.message}`);
236
+ }
237
+ return response.data;
238
+ }
239
+ /**
240
+ * Detect potential duplicate memories
241
+ */
242
+ async detectDuplicates(params) {
243
+ const response = await this.httpClient.post(
244
+ "/intelligence/detect-duplicates",
245
+ {
246
+ ...params,
247
+ responseFormat: params.responseFormat || this.defaultResponseFormat
248
+ }
249
+ );
250
+ if (response.error) {
251
+ throw new DatabaseError(`Failed to detect duplicates: ${response.error.message}`);
252
+ }
253
+ return response.data;
254
+ }
255
+ /**
256
+ * Extract insights and patterns from memories
257
+ */
258
+ async extractInsights(params) {
259
+ const response = await this.httpClient.post(
260
+ "/intelligence/extract-insights",
261
+ {
262
+ ...params,
263
+ responseFormat: params.responseFormat || this.defaultResponseFormat
264
+ }
265
+ );
266
+ if (response.error) {
267
+ throw new DatabaseError(`Failed to extract insights: ${response.error.message}`);
268
+ }
269
+ return response.data;
270
+ }
271
+ /**
272
+ * Check the health and organization quality of memories
273
+ */
274
+ async healthCheck(params) {
275
+ const response = await this.httpClient.post(
276
+ "/intelligence/health-check",
277
+ {
278
+ ...params,
279
+ responseFormat: params.responseFormat || this.defaultResponseFormat
280
+ }
281
+ );
282
+ if (response.error) {
283
+ throw new DatabaseError(`Failed to check health: ${response.error.message}`);
284
+ }
285
+ return response.data;
286
+ }
287
+ };
288
+ var ResponseFormat = {
289
+ JSON: "json",
290
+ MARKDOWN: "markdown"
291
+ };
292
+ var MemoryType = z.enum([
293
+ "context",
294
+ "project",
295
+ "knowledge",
296
+ "reference",
297
+ "personal",
298
+ "workflow"
299
+ ]);
300
+
301
+ // src/utils/formatting.ts
302
+ var CHARACTER_LIMIT = 5e4;
303
+ function formatResponse(data, format, markdownFormatter) {
304
+ if (format === ResponseFormat.JSON) {
305
+ return JSON.stringify(data, null, 2);
306
+ }
307
+ return markdownFormatter(data);
308
+ }
309
+ function truncateIfNeeded(text) {
310
+ if (text.length > CHARACTER_LIMIT) {
311
+ return text.substring(0, CHARACTER_LIMIT) + `
312
+
313
+ ... (truncated, ${text.length - CHARACTER_LIMIT} characters omitted)`;
314
+ }
315
+ return text;
316
+ }
317
+
318
+ // src/server/mcp-server.ts
319
+ function createMCPServer(config) {
320
+ const client = new MemoryIntelligenceClient(config);
321
+ const server = new McpServer({
322
+ name: "memory-intelligence-mcp-server",
323
+ version: "1.0.0"
324
+ });
325
+ server.registerTool(
326
+ "memory_analyze_patterns",
327
+ {
328
+ title: "Analyze Memory Patterns",
329
+ description: `Analyze usage patterns and trends in the user's memory collection.`,
330
+ inputSchema: z.object({
331
+ user_id: z.string().uuid(),
332
+ time_range_days: z.number().int().min(1).max(365).default(30),
333
+ response_format: z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
334
+ }).strict(),
335
+ annotations: {
336
+ readOnlyHint: true,
337
+ destructiveHint: false,
338
+ idempotentHint: true,
339
+ openWorldHint: true
340
+ }
341
+ },
342
+ async (rawParams) => {
343
+ try {
344
+ const params = {
345
+ userId: rawParams.user_id,
346
+ timeRangeDays: rawParams.time_range_days,
347
+ responseFormat: rawParams.response_format
348
+ };
349
+ const analysis = await client.analyzePatterns(params);
350
+ const responseText = formatResponse(
351
+ analysis,
352
+ params.responseFormat || "markdown",
353
+ (data) => {
354
+ let md = `# Memory Pattern Analysis
355
+
356
+ `;
357
+ md += `**Time Range:** Last ${params.timeRangeDays || 30} days
358
+ `;
359
+ md += `**Total Memories:** ${data.total_memories}
360
+
361
+ `;
362
+ md += `## Distribution by Type
363
+ `;
364
+ for (const [type, count] of Object.entries(data.memories_by_type)) {
365
+ const percentage = (count / data.total_memories * 100).toFixed(1);
366
+ md += `- **${type}**: ${count} (${percentage}%)
367
+ `;
368
+ }
369
+ md += `
370
+ ## Activity Patterns
371
+ `;
372
+ md += `- **Peak Hours (UTC):** ${data.peak_creation_hours.join(", ")}
373
+ `;
374
+ md += `- **Daily Average:** ${data.creation_velocity.daily_average} memories/day
375
+ `;
376
+ md += `- **Trend:** ${data.creation_velocity.trend}
377
+ `;
378
+ md += `
379
+ ## Top Tags
380
+ `;
381
+ for (const { tag, count } of data.most_common_tags.slice(0, 5)) {
382
+ md += `- **${tag}**: ${count} uses
383
+ `;
384
+ }
385
+ md += `
386
+ ## AI Insights
387
+ `;
388
+ for (const insight of data.insights) {
389
+ md += `${insight}
390
+ `;
391
+ }
392
+ return md;
393
+ }
394
+ );
395
+ return {
396
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
397
+ };
398
+ } catch (error) {
399
+ return {
400
+ isError: true,
401
+ content: [
402
+ {
403
+ type: "text",
404
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
405
+ }
406
+ ]
407
+ };
408
+ }
409
+ }
410
+ );
411
+ server.registerTool(
412
+ "memory_suggest_tags",
413
+ {
414
+ title: "Suggest Tags for Memory",
415
+ description: `AI-powered tag suggestions for a memory.`,
416
+ inputSchema: z.object({
417
+ memory_id: z.string().uuid(),
418
+ user_id: z.string().uuid(),
419
+ max_suggestions: z.number().int().min(1).max(20).default(5),
420
+ include_existing_tags: z.boolean().default(true),
421
+ response_format: z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
422
+ }).strict(),
423
+ annotations: {
424
+ readOnlyHint: true,
425
+ destructiveHint: false,
426
+ idempotentHint: false,
427
+ openWorldHint: true
428
+ }
429
+ },
430
+ async (rawParams) => {
431
+ try {
432
+ const params = {
433
+ memoryId: rawParams.memory_id,
434
+ userId: rawParams.user_id,
435
+ maxSuggestions: rawParams.max_suggestions,
436
+ includeExistingTags: rawParams.include_existing_tags,
437
+ responseFormat: rawParams.response_format
438
+ };
439
+ const result = await client.suggestTags(params);
440
+ const responseText = formatResponse(
441
+ result,
442
+ params.responseFormat || "markdown",
443
+ (data) => {
444
+ let md = `# Tag Suggestions
445
+
446
+ `;
447
+ md += `**Existing Tags:** ${data.existing_tags.join(", ") || "none"}
448
+
449
+ `;
450
+ md += `## Suggested Tags
451
+ `;
452
+ for (const suggestion of data.suggestions) {
453
+ md += `
454
+ ### \`${suggestion.tag}\`
455
+ `;
456
+ md += `**Confidence:** ${(suggestion.confidence * 100).toFixed(0)}%
457
+ `;
458
+ md += `**Reason:** ${suggestion.reasoning}
459
+ `;
460
+ }
461
+ return md;
462
+ }
463
+ );
464
+ return {
465
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
466
+ };
467
+ } catch (error) {
468
+ return {
469
+ isError: true,
470
+ content: [
471
+ {
472
+ type: "text",
473
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
474
+ }
475
+ ]
476
+ };
477
+ }
478
+ }
479
+ );
480
+ server.registerTool(
481
+ "memory_find_related",
482
+ {
483
+ title: "Find Related Memories",
484
+ description: `Find semantically related memories using vector similarity.`,
485
+ inputSchema: z.object({
486
+ memory_id: z.string().uuid(),
487
+ user_id: z.string().uuid(),
488
+ limit: z.number().int().min(1).max(50).default(10),
489
+ similarity_threshold: z.number().min(0).max(1).default(0.7),
490
+ response_format: z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
491
+ }).strict(),
492
+ annotations: {
493
+ readOnlyHint: true,
494
+ destructiveHint: false,
495
+ idempotentHint: true,
496
+ openWorldHint: true
497
+ }
498
+ },
499
+ async (rawParams) => {
500
+ try {
501
+ const params = {
502
+ memoryId: rawParams.memory_id,
503
+ userId: rawParams.user_id,
504
+ limit: rawParams.limit,
505
+ similarityThreshold: rawParams.similarity_threshold,
506
+ responseFormat: rawParams.response_format
507
+ };
508
+ const result = await client.findRelated(params);
509
+ const responseText = formatResponse(
510
+ result,
511
+ params.responseFormat || "markdown",
512
+ (data) => {
513
+ let md = `# Related Memories
514
+
515
+ `;
516
+ md += `**Source:** ${data.source_memory.title}
517
+ `;
518
+ md += `**Found:** ${data.total_found} related memories
519
+
520
+ `;
521
+ for (const mem of data.related_memories) {
522
+ md += `## ${mem.title}
523
+ `;
524
+ md += `**Similarity:** ${(mem.similarity_score * 100).toFixed(1)}%
525
+ `;
526
+ if (mem.shared_tags.length > 0) {
527
+ md += `**Shared Tags:** ${mem.shared_tags.join(", ")}
528
+ `;
529
+ }
530
+ md += `**Preview:** ${mem.content_preview}
531
+
532
+ `;
533
+ }
534
+ return md;
535
+ }
536
+ );
537
+ return {
538
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
539
+ };
540
+ } catch (error) {
541
+ return {
542
+ isError: true,
543
+ content: [
544
+ {
545
+ type: "text",
546
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
547
+ }
548
+ ]
549
+ };
550
+ }
551
+ }
552
+ );
553
+ server.registerTool(
554
+ "memory_detect_duplicates",
555
+ {
556
+ title: "Detect Duplicate Memories",
557
+ description: `Find potential duplicate memories.`,
558
+ inputSchema: z.object({
559
+ user_id: z.string().uuid(),
560
+ similarity_threshold: z.number().min(0.8).max(0.99).default(0.9),
561
+ max_pairs: z.number().int().min(1).max(100).default(20),
562
+ response_format: z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
563
+ }).strict(),
564
+ annotations: {
565
+ readOnlyHint: true,
566
+ destructiveHint: false,
567
+ idempotentHint: true,
568
+ openWorldHint: true
569
+ }
570
+ },
571
+ async (rawParams) => {
572
+ try {
573
+ const params = {
574
+ userId: rawParams.user_id,
575
+ similarityThreshold: rawParams.similarity_threshold,
576
+ maxPairs: rawParams.max_pairs,
577
+ responseFormat: rawParams.response_format
578
+ };
579
+ const result = await client.detectDuplicates(params);
580
+ const responseText = formatResponse(
581
+ result,
582
+ params.responseFormat || "markdown",
583
+ (data) => {
584
+ let md = `# Duplicate Detection
585
+
586
+ `;
587
+ md += `**Memories Analyzed:** ${data.total_memories_analyzed}
588
+ `;
589
+ md += `**Duplicate Pairs Found:** ${data.duplicate_pairs_found}
590
+ `;
591
+ md += `**Storage Savings:** ${data.estimated_storage_savings}
592
+
593
+ `;
594
+ for (const pair of data.duplicate_pairs) {
595
+ md += `### Similarity: ${(pair.similarity_score * 100).toFixed(1)}%
596
+ `;
597
+ md += `**Memory 1:** ${pair.memory_1.title}
598
+ `;
599
+ md += `**Memory 2:** ${pair.memory_2.title}
600
+ `;
601
+ md += `**Recommendation:** ${pair.recommendation}
602
+
603
+ `;
604
+ }
605
+ return md;
606
+ }
607
+ );
608
+ return {
609
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
610
+ };
611
+ } catch (error) {
612
+ return {
613
+ isError: true,
614
+ content: [
615
+ {
616
+ type: "text",
617
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
618
+ }
619
+ ]
620
+ };
621
+ }
622
+ }
623
+ );
624
+ server.registerTool(
625
+ "memory_extract_insights",
626
+ {
627
+ title: "Extract Insights from Memories",
628
+ description: `Extract key insights and patterns from memories.`,
629
+ inputSchema: z.object({
630
+ user_id: z.string().uuid(),
631
+ topic: z.string().optional(),
632
+ memory_type: z.string().optional(),
633
+ max_memories: z.number().int().min(5).max(100).default(20),
634
+ response_format: z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
635
+ }).strict(),
636
+ annotations: {
637
+ readOnlyHint: true,
638
+ destructiveHint: false,
639
+ idempotentHint: false,
640
+ openWorldHint: true
641
+ }
642
+ },
643
+ async (rawParams) => {
644
+ try {
645
+ const params = {
646
+ userId: rawParams.user_id,
647
+ topic: rawParams.topic,
648
+ memoryType: rawParams.memory_type,
649
+ maxMemories: rawParams.max_memories,
650
+ responseFormat: rawParams.response_format
651
+ };
652
+ const result = await client.extractInsights(params);
653
+ const responseText = formatResponse(
654
+ result,
655
+ params.responseFormat || "markdown",
656
+ (data) => {
657
+ let md = `# Memory Insights
658
+
659
+ `;
660
+ md += `**Memories Analyzed:** ${data.total_memories_analyzed}
661
+ `;
662
+ if (data.topic_filter) {
663
+ md += `**Topic:** ${data.topic_filter}
664
+ `;
665
+ }
666
+ md += `
667
+ ## Summary
668
+ ${data.summary}
669
+
670
+ `;
671
+ md += `## Insights
672
+ `;
673
+ for (const insight of data.insights) {
674
+ const icon = {
675
+ pattern: "\u{1F504}",
676
+ learning: "\u{1F4A1}",
677
+ opportunity: "\u{1F680}",
678
+ risk: "\u26A0\uFE0F",
679
+ action_item: "\u2705"
680
+ }[insight.category] || "\u{1F4CC}";
681
+ md += `
682
+ ### ${icon} ${insight.title}
683
+ `;
684
+ md += `${insight.description}
685
+ `;
686
+ md += `**Confidence:** ${(insight.confidence * 100).toFixed(0)}%
687
+ `;
688
+ }
689
+ return md;
690
+ }
691
+ );
692
+ return {
693
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
694
+ };
695
+ } catch (error) {
696
+ return {
697
+ isError: true,
698
+ content: [
699
+ {
700
+ type: "text",
701
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
702
+ }
703
+ ]
704
+ };
705
+ }
706
+ }
707
+ );
708
+ server.registerTool(
709
+ "memory_health_check",
710
+ {
711
+ title: "Memory Health Check",
712
+ description: `Analyze the health and organization quality of memories.`,
713
+ inputSchema: z.object({
714
+ user_id: z.string().uuid(),
715
+ response_format: z.enum([ResponseFormat.JSON, ResponseFormat.MARKDOWN]).default(ResponseFormat.MARKDOWN)
716
+ }).strict(),
717
+ annotations: {
718
+ readOnlyHint: true,
719
+ destructiveHint: false,
720
+ idempotentHint: true,
721
+ openWorldHint: true
722
+ }
723
+ },
724
+ async (rawParams) => {
725
+ try {
726
+ const params = {
727
+ userId: rawParams.user_id,
728
+ responseFormat: rawParams.response_format
729
+ };
730
+ const result = await client.healthCheck(params);
731
+ const responseText = formatResponse(
732
+ result,
733
+ params.responseFormat || "markdown",
734
+ (data) => {
735
+ let md = `# Memory Health Check
736
+
737
+ `;
738
+ md += `**Health Score:** ${data.health_score}/100
739
+
740
+ `;
741
+ md += `## Metrics
742
+ `;
743
+ md += `- **Total Memories:** ${data.metrics.total_memories}
744
+ `;
745
+ md += `- **Embedding Coverage:** ${data.metrics.embedding_coverage_percentage}%
746
+ `;
747
+ md += `- **Tagging Rate:** ${data.metrics.tagging_percentage}%
748
+ `;
749
+ md += `- **Avg Tags/Memory:** ${data.metrics.average_tags_per_memory}
750
+
751
+ `;
752
+ if (data.issues.length > 0) {
753
+ md += `## Issues
754
+ `;
755
+ for (const issue of data.issues) {
756
+ md += `- ${issue}
757
+ `;
758
+ }
759
+ md += `
760
+ `;
761
+ }
762
+ md += `## Recommendations
763
+ `;
764
+ for (const rec of data.recommendations) {
765
+ md += `- ${rec}
766
+ `;
767
+ }
768
+ return md;
769
+ }
770
+ );
771
+ return {
772
+ content: [{ type: "text", text: truncateIfNeeded(responseText) }]
773
+ };
774
+ } catch (error) {
775
+ return {
776
+ isError: true,
777
+ content: [
778
+ {
779
+ type: "text",
780
+ text: `Error: ${error instanceof Error ? error.message : "Unknown error"}`
781
+ }
782
+ ]
783
+ };
784
+ }
785
+ }
786
+ );
787
+ return server;
788
+ }
789
+
790
+ export { ConfigurationError, DatabaseError, EmbeddingError, MemoryIntelligenceError, MemoryNotFoundError, MemoryType, ResponseFormat, ValidationError, createMCPServer };
791
+ //# sourceMappingURL=index.js.map
792
+ //# sourceMappingURL=index.js.map