@aeriondyseti/vector-memory-mcp 2.0.0-rc.3 → 2.0.0-rc.4
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/package.json +1 -1
- package/src/config/index.ts +5 -0
- package/src/mcp/handlers.ts +63 -4
package/package.json
CHANGED
package/src/config/index.ts
CHANGED
|
@@ -5,6 +5,11 @@ import packageJson from "../../package.json" with { type: "json" };
|
|
|
5
5
|
|
|
6
6
|
export const VERSION = packageJson.version;
|
|
7
7
|
|
|
8
|
+
/** Debug mode: auto-enabled for pre-release versions (dev/rc), or via VECTOR_MEMORY_DEBUG env var */
|
|
9
|
+
export const DEBUG = process.env.VECTOR_MEMORY_DEBUG === "1"
|
|
10
|
+
|| VERSION.includes("-dev.")
|
|
11
|
+
|| VERSION.includes("-rc.");
|
|
12
|
+
|
|
8
13
|
export type TransportMode = "stdio" | "http" | "both";
|
|
9
14
|
|
|
10
15
|
export interface ConversationHistoryConfig {
|
package/src/mcp/handlers.ts
CHANGED
|
@@ -3,16 +3,55 @@ import type { MemoryService } from "../services/memory.service.js";
|
|
|
3
3
|
import type { ConversationHistoryService } from "../services/conversation.service.js";
|
|
4
4
|
import type { SearchIntent } from "../types/memory.js";
|
|
5
5
|
import type { HistoryFilters, SearchResult } from "../types/conversation.js";
|
|
6
|
+
import { DEBUG } from "../config/index.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Safely coerce a tool argument to an array. Handles the case where the MCP
|
|
10
|
+
* transport delivers a JSON-serialized string instead of a parsed array.
|
|
11
|
+
*/
|
|
12
|
+
function asArray<T>(value: unknown, fieldName: string): T[] {
|
|
13
|
+
if (Array.isArray(value)) return value;
|
|
14
|
+
if (typeof value === "string") {
|
|
15
|
+
if (DEBUG) {
|
|
16
|
+
console.error(
|
|
17
|
+
`[vector-memory-mcp] DEBUG: ${fieldName} received as string (${value.length} chars) instead of array — parsing`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(value);
|
|
22
|
+
if (Array.isArray(parsed)) return parsed;
|
|
23
|
+
if (DEBUG) {
|
|
24
|
+
console.error(
|
|
25
|
+
`[vector-memory-mcp] DEBUG: ${fieldName} parsed as ${typeof parsed}, not array`
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
} catch { /* fall through */ }
|
|
29
|
+
} else if (DEBUG) {
|
|
30
|
+
console.error(
|
|
31
|
+
`[vector-memory-mcp] DEBUG: ${fieldName} has unexpected type: ${typeof value}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`${fieldName} must be an array`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function errorText(e: unknown): string {
|
|
38
|
+
return e instanceof Error ? e.message : String(e);
|
|
39
|
+
}
|
|
6
40
|
|
|
7
41
|
export async function handleStoreMemories(
|
|
8
42
|
args: Record<string, unknown> | undefined,
|
|
9
43
|
service: MemoryService
|
|
10
44
|
): Promise<CallToolResult> {
|
|
11
|
-
|
|
45
|
+
let memories: Array<{
|
|
12
46
|
content: string;
|
|
13
47
|
embedding_text?: string;
|
|
14
48
|
metadata?: Record<string, unknown>;
|
|
15
49
|
}>;
|
|
50
|
+
try {
|
|
51
|
+
memories = asArray(args?.memories, "memories");
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return { isError: true, content: [{ type: "text", text: errorText(e) }] };
|
|
54
|
+
}
|
|
16
55
|
|
|
17
56
|
const ids: string[] = [];
|
|
18
57
|
for (const item of memories) {
|
|
@@ -41,7 +80,12 @@ export async function handleDeleteMemories(
|
|
|
41
80
|
args: Record<string, unknown> | undefined,
|
|
42
81
|
service: MemoryService
|
|
43
82
|
): Promise<CallToolResult> {
|
|
44
|
-
|
|
83
|
+
let ids: string[];
|
|
84
|
+
try {
|
|
85
|
+
ids = asArray(args?.ids, "ids");
|
|
86
|
+
} catch (e) {
|
|
87
|
+
return { isError: true, content: [{ type: "text", text: errorText(e) }] };
|
|
88
|
+
}
|
|
45
89
|
const results: string[] = [];
|
|
46
90
|
|
|
47
91
|
for (const id of ids) {
|
|
@@ -66,16 +110,26 @@ export async function handleUpdateMemories(
|
|
|
66
110
|
args: Record<string, unknown> | undefined,
|
|
67
111
|
service: MemoryService
|
|
68
112
|
): Promise<CallToolResult> {
|
|
69
|
-
|
|
113
|
+
let updates: Array<{
|
|
70
114
|
id: string;
|
|
71
115
|
content?: string;
|
|
72
116
|
embedding_text?: string;
|
|
73
117
|
metadata?: Record<string, unknown>;
|
|
74
118
|
}>;
|
|
119
|
+
try {
|
|
120
|
+
updates = asArray(args?.updates, "updates");
|
|
121
|
+
} catch (e) {
|
|
122
|
+
return { isError: true, content: [{ type: "text", text: errorText(e) }] };
|
|
123
|
+
}
|
|
75
124
|
|
|
76
125
|
const results: string[] = [];
|
|
77
126
|
|
|
78
127
|
for (const update of updates) {
|
|
128
|
+
if (!update.id || typeof update.id !== "string") {
|
|
129
|
+
results.push("Skipped update: missing required id field");
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
79
133
|
const memory = await service.update(update.id, {
|
|
80
134
|
content: update.content,
|
|
81
135
|
embeddingText: update.embedding_text,
|
|
@@ -166,7 +220,12 @@ export async function handleGetMemories(
|
|
|
166
220
|
args: Record<string, unknown> | undefined,
|
|
167
221
|
service: MemoryService
|
|
168
222
|
): Promise<CallToolResult> {
|
|
169
|
-
|
|
223
|
+
let ids: string[];
|
|
224
|
+
try {
|
|
225
|
+
ids = asArray(args?.ids, "ids");
|
|
226
|
+
} catch (e) {
|
|
227
|
+
return { isError: true, content: [{ type: "text", text: errorText(e) }] };
|
|
228
|
+
}
|
|
170
229
|
|
|
171
230
|
const memories = await service.getMultiple(ids);
|
|
172
231
|
const memoryMap = new Map(memories.map((m) => [m.id, m]));
|