@aeriondyseti/vector-memory-mcp 2.2.6 → 2.3.0-dev.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aeriondyseti/vector-memory-mcp",
3
- "version": "2.2.6",
3
+ "version": "2.3.0-dev.1",
4
4
  "description": "A zero-configuration RAG memory server for MCP clients",
5
5
  "type": "module",
6
6
  "main": "server/index.ts",
@@ -9,7 +9,6 @@
9
9
  },
10
10
  "files": [
11
11
  "server",
12
- "scripts",
13
12
  "README.md",
14
13
  "LICENSE"
15
14
  ],
@@ -47,18 +46,18 @@
47
46
  ],
48
47
  "license": "MIT",
49
48
  "dependencies": {
50
- "@huggingface/transformers": "^3.8.0",
49
+ "@huggingface/tokenizers": "^0.1.3",
51
50
  "@lancedb/lancedb": "^0.26.2",
52
51
  "@modelcontextprotocol/sdk": "^1.0.0",
53
52
  "arg": "^5.0.2",
54
- "hono": "^4.11.3"
53
+ "hono": "^4.11.3",
54
+ "onnxruntime-node": "^1.21.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@types/bun": "latest",
58
58
  "typescript": "^5.0.0"
59
59
  },
60
60
  "trustedDependencies": [
61
- "protobufjs",
62
- "sharp"
61
+ "protobufjs"
63
62
  ]
64
63
  }
@@ -1,9 +1,17 @@
1
- import { pipeline, type FeatureExtractionPipeline } from "@huggingface/transformers";
1
+ import * as ort from "onnxruntime-node";
2
+ import { Tokenizer } from "@huggingface/tokenizers";
3
+ import { join, dirname } from "path";
4
+ import { mkdir } from "fs/promises";
5
+ import { existsSync } from "fs";
6
+
7
+ const HF_CDN = "https://huggingface.co";
8
+ const MAX_SEQ_LENGTH = 512;
2
9
 
3
10
  export class EmbeddingsService {
4
11
  private modelName: string;
5
- private extractor: FeatureExtractionPipeline | null = null;
6
- private initPromise: Promise<FeatureExtractionPipeline> | null = null;
12
+ private session: ort.InferenceSession | null = null;
13
+ private tokenizer: Tokenizer | null = null;
14
+ private initPromise: Promise<void> | null = null;
7
15
  private _dimension: number;
8
16
 
9
17
  constructor(modelName: string, dimension: number) {
@@ -15,27 +23,71 @@ export class EmbeddingsService {
15
23
  return this._dimension;
16
24
  }
17
25
 
18
- private async getExtractor(): Promise<FeatureExtractionPipeline> {
19
- if (this.extractor) {
20
- return this.extractor;
21
- }
22
-
26
+ private async initialize(): Promise<void> {
27
+ if (this.session) return;
23
28
  if (!this.initPromise) {
24
- this.initPromise = pipeline(
25
- "feature-extraction",
26
- this.modelName,
27
- { dtype: "fp32" } as any
28
- ) as Promise<FeatureExtractionPipeline>;
29
+ this.initPromise = this._init();
29
30
  }
31
+ await this.initPromise;
32
+ }
33
+
34
+ private get cacheDir(): string {
35
+ const packageRoot = join(dirname(Bun.main), "..");
36
+ return join(packageRoot, ".cache", "models", this.modelName);
37
+ }
30
38
 
31
- this.extractor = await this.initPromise;
32
- return this.extractor;
39
+ private async downloadIfMissing(fileName: string): Promise<string> {
40
+ const filePath = join(this.cacheDir, fileName);
41
+ if (existsSync(filePath)) return filePath;
42
+
43
+ const url = `${HF_CDN}/${this.modelName}/resolve/main/${fileName}`;
44
+ await mkdir(dirname(filePath), { recursive: true });
45
+ const response = await fetch(url);
46
+ if (!response.ok) throw new Error(`Failed to download ${url}: ${response.status}`);
47
+ const buffer = await response.arrayBuffer();
48
+ await Bun.write(filePath, buffer);
49
+ return filePath;
50
+ }
51
+
52
+ private async _init(): Promise<void> {
53
+ const modelPath = await this.downloadIfMissing("onnx/model.onnx");
54
+ const tokenizerJsonPath = await this.downloadIfMissing("tokenizer.json");
55
+ const tokenizerConfigPath = await this.downloadIfMissing("tokenizer_config.json");
56
+
57
+ this.session = await ort.InferenceSession.create(modelPath, {
58
+ executionProviders: ["cpu"],
59
+ });
60
+
61
+ const tokenizerJson = await Bun.file(tokenizerJsonPath).json();
62
+ const tokenizerConfig = await Bun.file(tokenizerConfigPath).json();
63
+ this.tokenizer = new Tokenizer(tokenizerJson, tokenizerConfig);
33
64
  }
34
65
 
35
66
  async embed(text: string): Promise<number[]> {
36
- const extractor = await this.getExtractor();
37
- const output = await extractor(text, { pooling: "mean", normalize: true });
38
- return Array.from(output.data as Float32Array);
67
+ await this.initialize();
68
+
69
+ const encoded = this.tokenizer!.encode(text);
70
+
71
+ // Truncate to model's max sequence length
72
+ const seqLen = Math.min(encoded.ids.length, MAX_SEQ_LENGTH);
73
+ const ids = encoded.ids.slice(0, seqLen);
74
+ const mask = encoded.attention_mask.slice(0, seqLen);
75
+
76
+ const inputIds = BigInt64Array.from(ids.map(BigInt));
77
+ const attentionMask = BigInt64Array.from(mask.map(BigInt));
78
+ const tokenTypeIds = new BigInt64Array(seqLen); // zeros for single-sequence input
79
+
80
+ const feeds: Record<string, ort.Tensor> = {
81
+ input_ids: new ort.Tensor("int64", inputIds, [1, seqLen]),
82
+ attention_mask: new ort.Tensor("int64", attentionMask, [1, seqLen]),
83
+ token_type_ids: new ort.Tensor("int64", tokenTypeIds, [1, seqLen]),
84
+ };
85
+
86
+ const output = await this.session!.run(feeds);
87
+ const lastHidden = output["last_hidden_state"];
88
+
89
+ const pooled = this.meanPool(lastHidden.data as Float32Array, mask, seqLen);
90
+ return this.normalize(pooled);
39
91
  }
40
92
 
41
93
  async embedBatch(texts: string[]): Promise<number[][]> {
@@ -45,4 +97,29 @@ export class EmbeddingsService {
45
97
  }
46
98
  return results;
47
99
  }
100
+
101
+ private meanPool(data: Float32Array, mask: number[], seqLen: number): number[] {
102
+ const dim = this._dimension;
103
+ const pooled = new Array(dim).fill(0);
104
+ let maskSum = 0;
105
+ for (let t = 0; t < seqLen; t++) {
106
+ if (mask[t]) {
107
+ maskSum += 1;
108
+ for (let d = 0; d < dim; d++) {
109
+ pooled[d] += data[t * dim + d];
110
+ }
111
+ }
112
+ }
113
+ for (let d = 0; d < dim; d++) {
114
+ pooled[d] /= maskSum;
115
+ }
116
+ return pooled;
117
+ }
118
+
119
+ private normalize(vec: number[]): number[] {
120
+ let norm = 0;
121
+ for (const v of vec) norm += v * v;
122
+ norm = Math.sqrt(norm);
123
+ return vec.map(v => v / norm);
124
+ }
48
125
  }
@@ -1,4 +1,6 @@
1
1
  import type { Database } from "bun:sqlite";
2
+ import type { EmbeddingsService } from "./embeddings.service.js";
3
+ import { serializeVector } from "./sqlite-utils.js";
2
4
 
3
5
  /**
4
6
  * Pre-migration step: remove vec0 virtual table entries from sqlite_master
@@ -113,3 +115,149 @@ export function runMigrations(db: Database): void {
113
115
  db.exec(`CREATE INDEX IF NOT EXISTS idx_conversation_role ON conversation_history(role)`);
114
116
  db.exec(`CREATE INDEX IF NOT EXISTS idx_conversation_created_at ON conversation_history(created_at)`);
115
117
  }
118
+
119
+ /**
120
+ * Backfill missing vectors in memories_vec and conversation_history_vec.
121
+ *
122
+ * After the vec0-to-BLOB migration, existing rows may lack vector embeddings.
123
+ * This re-embeds their content and inserts into the _vec tables.
124
+ * Idempotent: skips rows that already have vectors. Fast no-op when fully backfilled.
125
+ */
126
+ export async function backfillVectors(
127
+ db: Database,
128
+ embeddings: EmbeddingsService,
129
+ ): Promise<void> {
130
+ // Fast sentinel check: skip the LEFT JOIN queries entirely when backfill is done
131
+ const sentinel = db
132
+ .prepare("SELECT 1 FROM memories_vec LIMIT 1")
133
+ .get();
134
+ const memoriesExist = db.prepare("SELECT 1 FROM memories LIMIT 1").get();
135
+ const convosExist = db.prepare("SELECT 1 FROM conversation_history LIMIT 1").get();
136
+
137
+ // If vec tables have data and source tables have data, backfill is likely complete.
138
+ // Only run the expensive LEFT JOIN when there's reason to suspect gaps.
139
+ const convoSentinel = db
140
+ .prepare("SELECT 1 FROM conversation_history_vec LIMIT 1")
141
+ .get();
142
+ const mayNeedMemoryBackfill = memoriesExist && !sentinel;
143
+ const mayNeedConvoBackfill = convosExist && !convoSentinel;
144
+
145
+ // If both vec tables are populated, do a quick count check to confirm
146
+ if (!mayNeedMemoryBackfill && !mayNeedConvoBackfill) {
147
+ if (memoriesExist) {
148
+ const gap = db.prepare(
149
+ `SELECT 1 FROM memories m LEFT JOIN memories_vec v ON m.id = v.id
150
+ WHERE v.id IS NULL OR length(v.vector) = 0 LIMIT 1`,
151
+ ).get();
152
+ if (!gap && convosExist) {
153
+ const convoGap = db.prepare(
154
+ `SELECT 1 FROM conversation_history c LEFT JOIN conversation_history_vec v ON c.id = v.id
155
+ WHERE v.id IS NULL OR length(v.vector) = 0 LIMIT 1`,
156
+ ).get();
157
+ if (!convoGap) return;
158
+ } else if (!gap && !convosExist) {
159
+ return;
160
+ }
161
+ } else {
162
+ return; // No data at all
163
+ }
164
+ }
165
+
166
+ // ── Memories ──────────────────────────────────────────────────────
167
+ const missingMemories = db
168
+ .prepare(
169
+ `SELECT m.id, m.content, json_extract(m.metadata, '$.type') AS type
170
+ FROM memories m
171
+ LEFT JOIN memories_vec v ON m.id = v.id
172
+ WHERE v.id IS NULL OR length(v.vector) = 0`,
173
+ )
174
+ .all() as Array<{ id: string; content: string; type: string | null }>;
175
+
176
+ if (missingMemories.length > 0) {
177
+ console.error(
178
+ `[vector-memory-mcp] Backfilling vectors for ${missingMemories.length} memories...`,
179
+ );
180
+
181
+ const insertVec = db.prepare(
182
+ "INSERT OR REPLACE INTO memories_vec (id, vector) VALUES (?, ?)",
183
+ );
184
+
185
+ const zeroVector = serializeVector(
186
+ new Array(embeddings.dimension).fill(0),
187
+ );
188
+
189
+ // Separate waypoints from content that needs embedding
190
+ const toEmbed = missingMemories.filter((r) => r.type !== "waypoint");
191
+ const waypoints = missingMemories.filter((r) => r.type === "waypoint");
192
+
193
+ // Batch embed all non-waypoint content
194
+ const vectors = toEmbed.length > 0
195
+ ? await embeddings.embedBatch(toEmbed.map((r) => r.content))
196
+ : [];
197
+
198
+ db.exec("BEGIN");
199
+ try {
200
+ for (const row of waypoints) {
201
+ insertVec.run(row.id, zeroVector);
202
+ }
203
+ for (let i = 0; i < toEmbed.length; i++) {
204
+ insertVec.run(toEmbed[i].id, serializeVector(vectors[i]));
205
+ }
206
+ db.exec("COMMIT");
207
+ } catch (e) {
208
+ db.exec("ROLLBACK");
209
+ throw e;
210
+ }
211
+
212
+ console.error(
213
+ `[vector-memory-mcp] Backfilled ${missingMemories.length} memory vectors`,
214
+ );
215
+ }
216
+
217
+ // ── Conversation history ──────────────────────────────────────────
218
+ const missingConvos = db
219
+ .prepare(
220
+ `SELECT c.id, c.content
221
+ FROM conversation_history c
222
+ LEFT JOIN conversation_history_vec v ON c.id = v.id
223
+ WHERE v.id IS NULL OR length(v.vector) = 0`,
224
+ )
225
+ .all() as Array<{ id: string; content: string }>;
226
+
227
+ if (missingConvos.length > 0) {
228
+ console.error(
229
+ `[vector-memory-mcp] Backfilling vectors for ${missingConvos.length} conversation chunks...`,
230
+ );
231
+
232
+ const insertConvoVec = db.prepare(
233
+ "INSERT OR REPLACE INTO conversation_history_vec (id, vector) VALUES (?, ?)",
234
+ );
235
+
236
+ // Batch embed in chunks of 32
237
+ const BATCH_SIZE = 32;
238
+ db.exec("BEGIN");
239
+ try {
240
+ for (let i = 0; i < missingConvos.length; i += BATCH_SIZE) {
241
+ const batch = missingConvos.slice(i, i + BATCH_SIZE);
242
+ const vecs = await embeddings.embedBatch(batch.map((r) => r.content));
243
+ for (let j = 0; j < batch.length; j++) {
244
+ insertConvoVec.run(batch[j].id, serializeVector(vecs[j]));
245
+ }
246
+
247
+ if ((i + BATCH_SIZE) % 100 < BATCH_SIZE) {
248
+ console.error(
249
+ `[vector-memory-mcp] ...${Math.min(i + BATCH_SIZE, missingConvos.length)}/${missingConvos.length} conversation chunks`,
250
+ );
251
+ }
252
+ }
253
+ db.exec("COMMIT");
254
+ } catch (e) {
255
+ db.exec("ROLLBACK");
256
+ throw e;
257
+ }
258
+
259
+ console.error(
260
+ `[vector-memory-mcp] Backfilled ${missingConvos.length} conversation vectors`,
261
+ );
262
+ }
263
+ }
package/server/index.ts CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { loadConfig, parseCliArgs } from "./config/index.js";
4
4
  import { connectToDatabase } from "./core/connection.js";
5
+ import { backfillVectors } from "./core/migrations.js";
5
6
  import { MemoryRepository } from "./core/memory.repository.js";
6
7
  import { ConversationRepository } from "./core/conversation.repository.js";
7
8
  import { EmbeddingsService } from "./core/embeddings.service.js";
@@ -9,26 +10,6 @@ import { MemoryService } from "./core/memory.service.js";
9
10
  import { ConversationHistoryService } from "./core/conversation.service.js";
10
11
  import { startServer } from "./transports/mcp/server.js";
11
12
  import { startHttpServer } from "./transports/http/server.js";
12
- import { isLanceDbDirectory, migrate, formatMigrationSummary } from "./migration.js";
13
-
14
- async function runMigrate(args: string[]): Promise<void> {
15
- const overrides = parseCliArgs(args.slice(1)); // skip "migrate"
16
- const config = loadConfig(overrides);
17
-
18
- const source = config.dbPath;
19
- const target = source.endsWith(".sqlite") ? source.replace(/\.sqlite$/, "-migrated.sqlite") : source + ".sqlite";
20
-
21
- if (!isLanceDbDirectory(source)) {
22
- console.error(
23
- `[vector-memory-mcp] No LanceDB data found at ${source}\n` +
24
- ` Nothing to migrate. The server will create a fresh SQLite database on startup.`
25
- );
26
- return;
27
- }
28
-
29
- const result = await migrate({ source, target });
30
- console.error(formatMigrationSummary(source, target, result));
31
- }
32
13
 
33
14
  async function main(): Promise<void> {
34
15
  const args = process.argv.slice(2);
@@ -40,33 +21,17 @@ async function main(): Promise<void> {
40
21
  return;
41
22
  }
42
23
 
43
- // Check for migrate command
44
- if (args[0] === "migrate") {
45
- await runMigrate(args);
46
- return;
47
- }
48
-
49
24
  // Parse CLI args and load config
50
25
  const overrides = parseCliArgs(args);
51
26
  const config = loadConfig(overrides);
52
27
 
53
- // Detect legacy LanceDB data and warn
54
- if (isLanceDbDirectory(config.dbPath)) {
55
- console.error(
56
- `[vector-memory-mcp] ⚠️ Legacy LanceDB data detected at ${config.dbPath}\n` +
57
- ` Your data must be migrated to the new SQLite format.\n` +
58
- ` Run: vector-memory-mcp migrate\n` +
59
- ` Or: bun run server/index.ts migrate\n`
60
- );
61
- process.exit(1);
62
- }
63
-
64
- // Initialize database
28
+ // Initialize database and backfill any missing vectors before services start
65
29
  const db = connectToDatabase(config.dbPath);
30
+ const embeddings = new EmbeddingsService(config.embeddingModel, config.embeddingDimension);
31
+ await backfillVectors(db, embeddings);
66
32
 
67
33
  // Initialize layers
68
34
  const repository = new MemoryRepository(db);
69
- const embeddings = new EmbeddingsService(config.embeddingModel, config.embeddingDimension);
70
35
  const memoryService = new MemoryService(repository, embeddings);
71
36
 
72
37
  if (config.pluginMode) {
@@ -8,7 +8,7 @@ import type { Config } from "../../config/index.js";
8
8
  import { isDeleted } from "../../core/memory.js";
9
9
  import { createMcpRoutes } from "./mcp-transport.js";
10
10
  import type { Memory, SearchIntent } from "../../core/memory.js";
11
- import { MigrationService } from "../../core/migration.service.js";
11
+
12
12
 
13
13
  /**
14
14
  * Check if a port is available by attempting to bind to it
@@ -245,34 +245,6 @@ export function createHttpApp(memoryService: MemoryService, config: Config): Hon
245
245
  }
246
246
  });
247
247
 
248
- // Migrate from external memory database
249
- app.post("/migrate", async (c) => {
250
- try {
251
- const body = await c.req.json().catch(() => null);
252
- if (!body || typeof body !== "object") {
253
- return c.json({ error: "Invalid or missing JSON body" }, 400);
254
- }
255
- const source = body.source;
256
-
257
- if (!source || typeof source !== "string") {
258
- return c.json({ error: "Missing or invalid 'source' field" }, 400);
259
- }
260
-
261
- const repository = memoryService.getRepository();
262
- const migrationService = new MigrationService(
263
- repository,
264
- memoryService.getEmbeddings(),
265
- repository.getDb(),
266
- );
267
-
268
- const result = await migrationService.migrate(source);
269
- return c.json(result);
270
- } catch (error) {
271
- const message = error instanceof Error ? error.message : "Unknown error";
272
- return c.json({ error: message }, 500);
273
- }
274
- });
275
-
276
248
  // Get single memory
277
249
  app.get("/memories/:id", async (c) => {
278
250
  try {
@@ -1,152 +1,11 @@
1
- const MIGRATE_GUIDE = `# Migrating External Memory Databases
2
-
3
- The vector-memory-mcp server exposes a \`POST /migrate\` HTTP endpoint that imports
4
- memories from other database formats into the running instance. All imported
5
- content is re-embedded with the server's current embedding model to guarantee
6
- consistency.
7
-
8
- ## Endpoint
9
-
10
- \`\`\`
11
- POST http://<host>:<port>/migrate
12
- Content-Type: application/json
13
-
14
- { "source": "/absolute/path/to/source/database" }
15
- \`\`\`
16
-
17
- ## Discovering the Server Port
18
-
19
- The HTTP server writes a lockfile at \`.vector-memory/server.lock\` in the
20
- project's working directory. Read it to discover the current port:
21
-
22
- \`\`\`json
23
- { "port": 3271, "pid": 12345 }
24
- \`\`\`
25
-
26
- ## Supported Source Formats
27
-
28
- The endpoint auto-detects the source format from the path provided.
29
-
30
- ### 1. LanceDB Directory
31
- Provide the path to a LanceDB data directory (contains \`.lance\` files or
32
- \`_versions\`/\`_indices\` subdirectories). Both memories and conversation
33
- history are imported.
34
-
35
- \`\`\`json
36
- { "source": "/path/to/project/.vector-memory" }
37
- \`\`\`
38
-
39
- ### 2. Own SQLite (Current or Older Schema)
40
- Provide the path to a \`.db\` file that was created by any version of
41
- vector-memory-mcp. The migrator handles missing columns (e.g. \`usefulness\`,
42
- \`access_count\`) by using sensible defaults. Both memories and conversation
43
- history are imported.
44
-
45
- \`\`\`json
46
- { "source": "/path/to/old-project/.vector-memory/memories.db" }
47
- \`\`\`
48
-
49
- ### 3. CCCMemory SQLite
50
- Provide the path to a CCCMemory database. The migrator extracts from the
51
- \`decisions\`, \`mistakes\`, \`methodologies\`, \`research_findings\`,
52
- \`solution_patterns\`, and \`working_memory\` tables. Each record is tagged
53
- with \`source_type: "cccmemory"\` and the appropriate \`memory_type\` in
54
- metadata.
55
-
56
- \`\`\`json
57
- { "source": "/path/to/cccmemory.db" }
58
- \`\`\`
59
-
60
- ### 4. MCP Memory Service SQLite
61
- Provide the path to an mcp-memory-service database. Memories with
62
- \`deleted_at IS NULL\` are imported. Tags and memory type are preserved in
63
- metadata.
64
-
65
- \`\`\`json
66
- { "source": "/path/to/mcp-memory-service.db" }
67
- \`\`\`
68
-
69
- ### 5. MIF JSON (Shodh Memory Interchange Format)
70
- Provide the path to a \`.json\` file exported from Shodh Memory. The file must
71
- contain a top-level \`memories\` array. Memory type, tags, entities, and source
72
- metadata are preserved.
73
-
74
- \`\`\`json
75
- { "source": "/path/to/export.mif.json" }
76
- \`\`\`
77
-
78
- ## Response
79
-
80
- The endpoint returns a JSON summary upon completion:
81
-
82
- \`\`\`json
83
- {
84
- "source": "/path/to/source",
85
- "format": "own-sqlite",
86
- "memoriesImported": 142,
87
- "memoriesSkipped": 3,
88
- "conversationsImported": 0,
89
- "conversationsSkipped": 0,
90
- "errors": [],
91
- "durationMs": 8320
92
- }
93
- \`\`\`
94
-
95
- - **memoriesImported**: Number of new memories written to the database.
96
- - **memoriesSkipped**: Records skipped because a memory with the same ID
97
- already exists (safe for idempotent re-runs).
98
- - **conversationsImported / conversationsSkipped**: Same, for conversation
99
- history chunks (LanceDB and own-sqlite formats only).
100
- - **errors**: Per-record errors that did not abort the migration.
101
- - **durationMs**: Wall-clock time for the entire operation.
102
-
103
- ## Important Notes
104
-
105
- - **Re-embedding**: All content is re-embedded regardless of the source format.
106
- This ensures vector consistency with the server's current model but means the
107
- operation can take time for large databases (~50ms per record).
108
- - **Idempotent**: Running the same migration twice is safe. Duplicate IDs are
109
- skipped.
110
- - **Non-destructive**: The source database is opened read-only and is never
111
- modified.
112
- - **Batched writes**: Records are inserted in batches of 100 within
113
- transactions. If the process is interrupted, already-committed batches are
114
- durable.
115
- - **Error isolation**: A single bad record does not abort the migration. Check
116
- the \`errors\` array in the response for any per-record failures.
117
-
118
- ## Workflow Example
119
-
120
- 1. Locate the source database file or directory.
121
- 2. Read \`.vector-memory/server.lock\` to get the port.
122
- 3. Send the migrate request:
123
- \`\`\`bash
124
- curl -X POST http://127.0.0.1:3271/migrate \\
125
- -H "Content-Type: application/json" \\
126
- -d '{"source": "/path/to/old/memories.db"}'
127
- \`\`\`
128
- 4. Inspect the response summary.
129
- 5. Verify imported memories with a search:
130
- \`\`\`bash
131
- curl -X POST http://127.0.0.1:3271/search \\
132
- -H "Content-Type: application/json" \\
133
- -d '{"query": "test query", "limit": 5}'
134
- \`\`\`
135
- `;
136
-
137
- export const resources = [
138
- {
139
- uri: "vector-memory://guides/migrate",
140
- name: "Migration Guide",
141
- description:
142
- "How to use the POST /migrate HTTP endpoint to import memories from external database formats (LanceDB, older SQLite, CCCMemory, MCP Memory Service, MIF JSON) into the running vector-memory instance.",
143
- mimeType: "text/markdown",
144
- },
145
- ];
146
-
147
- const RESOURCE_CONTENT: Record<string, string> = {
148
- "vector-memory://guides/migrate": MIGRATE_GUIDE,
149
- };
1
+ export const resources: Array<{
2
+ uri: string;
3
+ name: string;
4
+ description: string;
5
+ mimeType: string;
6
+ }> = [];
7
+
8
+ const RESOURCE_CONTENT: Record<string, string> = {};
150
9
 
151
10
  export function readResource(uri: string): {
152
11
  contents: Array<{ uri: string; mimeType: string; text: string }>;