@melandlabs/memory-store 0.2.0 → 0.2.2

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.
@@ -1,13 +1,23 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { z } from 'zod';
5
2
  import { buildMemoryRecordEmbeddingDocument } from '@melandlabs/ai/memory';
6
3
  import { ChromaVectorStore } from '@melandlabs/rag';
7
4
  import { mkdirSync } from 'fs';
8
5
  import { homedir } from 'os';
9
- import { join, dirname } from 'path';
6
+ import { dirname, join } from 'path';
10
7
  import { SQLiteRawMessageManager } from '@melandlabs/sqlite';
8
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import { z } from 'zod';
11
+
12
+ var __defProp = Object.defineProperty;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __esm = (fn, res) => function __init() {
15
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
+ };
17
+ var __export = (target, all) => {
18
+ for (var name in all)
19
+ __defProp(target, name, { get: all[name], enumerable: true });
20
+ };
11
21
 
12
22
  // src/contracts.ts
13
23
  function normalizeTimestampToMs(value) {
@@ -31,14 +41,10 @@ function rawMessageToMemoryRecord(message) {
31
41
  embeddingContentHash: message.embeddingContentHash
32
42
  };
33
43
  }
34
-
35
- // src/storage/chroma-memory-index.ts
36
- var DEFAULT_RAW_MESSAGES_COLLECTION = "opencontext_raw_messages";
37
- var RAW_VECTOR_BACKEND_ENV_KEYS = [
38
- "RAW_MESSAGE_VECTOR_STORE_BACKEND",
39
- "MEMORY_VECTOR_STORE_BACKEND",
40
- "VECTOR_STORE_BACKEND"
41
- ];
44
+ var init_contracts = __esm({
45
+ "src/contracts.ts"() {
46
+ }
47
+ });
42
48
  function getBackend(keys) {
43
49
  for (const key of keys) {
44
50
  const value = process.env[key]?.trim().toLowerCase();
@@ -141,21 +147,51 @@ async function searchRawMessagesWithChroma(input) {
141
147
  metadata: result.metadata ?? {}
142
148
  })).slice(0, input.limit);
143
149
  }
150
+ var DEFAULT_RAW_MESSAGES_COLLECTION, RAW_VECTOR_BACKEND_ENV_KEYS;
151
+ var init_chroma_memory_index = __esm({
152
+ "src/storage/chroma-memory-index.ts"() {
153
+ init_contracts();
154
+ DEFAULT_RAW_MESSAGES_COLLECTION = "opencontext_raw_messages";
155
+ RAW_VECTOR_BACKEND_ENV_KEYS = [
156
+ "RAW_MESSAGE_VECTOR_STORE_BACKEND",
157
+ "MEMORY_VECTOR_STORE_BACKEND",
158
+ "VECTOR_STORE_BACKEND"
159
+ ];
160
+ }
161
+ });
144
162
 
145
163
  // src/storage/postgres-raw-message-factory.ts
146
- var factory = null;
147
164
  async function resolvePostgresFactory(env) {
148
- return null;
165
+ if (!factory) return null;
166
+ return await factory(env);
149
167
  }
150
168
  function hasPostgresFactory() {
151
169
  return factory !== null;
152
170
  }
153
- var manager = null;
154
- var DEFAULT_SQLITE_PATH = join(homedir(), ".opencontext", "memory", "store.db");
171
+ var factory;
172
+ var init_postgres_raw_message_factory = __esm({
173
+ "src/storage/postgres-raw-message-factory.ts"() {
174
+ factory = null;
175
+ }
176
+ });
177
+
178
+ // src/storage/sqlite-raw-message-store.ts
179
+ var sqlite_raw_message_store_exports = {};
180
+ __export(sqlite_raw_message_store_exports, {
181
+ __resetSQLiteRawMessageManagerForTests: () => __resetSQLiteRawMessageManagerForTests,
182
+ closeSQLiteRawMessageManager: () => closeSQLiteRawMessageManager,
183
+ getSQLiteRawMessageManager: () => getSQLiteRawMessageManager,
184
+ isSQLiteRawMessageStorageAvailable: () => isSQLiteRawMessageStorageAvailable,
185
+ lexicalSearchRawMessages: () => lexicalSearchRawMessages,
186
+ resolveSQLiteRawMessageDbPath: () => resolveSQLiteRawMessageDbPath
187
+ });
155
188
  function resolveSQLiteRawMessageDbPath() {
156
189
  const fromEnv = process.env.MEMORY_STORE_DB_PATH?.trim();
157
190
  return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_SQLITE_PATH;
158
191
  }
192
+ function isSQLiteRawMessageStorageAvailable(_env) {
193
+ return true;
194
+ }
159
195
  async function getSQLiteRawMessageManager(_env) {
160
196
  if (!manager) {
161
197
  const dbPath = resolveSQLiteRawMessageDbPath();
@@ -175,8 +211,35 @@ async function closeSQLiteRawMessageManager() {
175
211
  await manager.close();
176
212
  manager = null;
177
213
  }
214
+ function __resetSQLiteRawMessageManagerForTests() {
215
+ manager = null;
216
+ }
217
+ async function lexicalSearchRawMessages(input) {
218
+ const mgr = await getSQLiteRawMessageManager();
219
+ if (typeof mgr.lexicalSearchMessages !== "function") {
220
+ return [];
221
+ }
222
+ return mgr.lexicalSearchMessages(input);
223
+ }
224
+ var manager, DEFAULT_SQLITE_PATH;
225
+ var init_sqlite_raw_message_store = __esm({
226
+ "src/storage/sqlite-raw-message-store.ts"() {
227
+ init_chroma_memory_index();
228
+ manager = null;
229
+ DEFAULT_SQLITE_PATH = join(homedir(), ".opencontext", "memory", "store.db");
230
+ }
231
+ });
178
232
 
179
233
  // src/storage/raw-message-store.ts
234
+ var raw_message_store_exports = {};
235
+ __export(raw_message_store_exports, {
236
+ closeRawMessageStore: () => closeRawMessageStore,
237
+ configureRawMessageStore: () => configureRawMessageStore,
238
+ createRawMessageStore: () => createRawMessageStore,
239
+ getRawMessageManager: () => getRawMessageManager,
240
+ getRawMessageStorageBackend: () => getRawMessageStorageBackend,
241
+ isRawMessageStorageAvailable: () => isRawMessageStorageAvailable
242
+ });
180
243
  function resolveBackend(env) {
181
244
  const explicit = process.env.OPENCONTEXT_MEMORY_STORE_BACKEND?.trim().toLowerCase();
182
245
  if (explicit === "postgres") return "postgres";
@@ -186,7 +249,7 @@ function resolveEnv(_env) {
186
249
  return {};
187
250
  }
188
251
  function createRawMessageStore(options = {}) {
189
- resolveEnv(options.env);
252
+ const env = resolveEnv(options.env);
190
253
  return {
191
254
  getBackend() {
192
255
  return resolveBackend();
@@ -196,7 +259,7 @@ function createRawMessageStore(options = {}) {
196
259
  },
197
260
  async getManager() {
198
261
  if (resolveBackend() === "postgres") {
199
- const pg = await resolvePostgresFactory();
262
+ const pg = await resolvePostgresFactory(env);
200
263
  if (!pg) {
201
264
  throw new Error(
202
265
  "OPENCONTEXT_MEMORY_STORE_BACKEND=postgres but no Postgres factory is registered. Call registerPostgresFactory() at startup, or unset the env var to use the default SQLite backend."
@@ -211,14 +274,47 @@ function createRawMessageStore(options = {}) {
211
274
  }
212
275
  };
213
276
  }
214
- var moduleStore = null;
215
- var moduleConfig = null;
277
+ function configureRawMessageStore(config) {
278
+ moduleConfig = config;
279
+ moduleStore = createRawMessageStore({ env: config.env });
280
+ return moduleStore;
281
+ }
282
+ function getRawMessageStorageBackend() {
283
+ if (!moduleStore) {
284
+ moduleStore = createRawMessageStore({ env: moduleConfig?.env });
285
+ }
286
+ return moduleStore.getBackend();
287
+ }
216
288
  function isRawMessageStorageAvailable() {
217
289
  if (!moduleStore) {
218
290
  moduleStore = createRawMessageStore({ env: moduleConfig?.env });
219
291
  }
220
292
  return moduleStore.isAvailable();
221
293
  }
294
+ async function getRawMessageManager() {
295
+ if (!moduleStore) {
296
+ moduleStore = createRawMessageStore({ env: moduleConfig?.env });
297
+ }
298
+ return moduleStore.getManager();
299
+ }
300
+ async function closeRawMessageStore() {
301
+ if (!moduleStore) return;
302
+ await moduleStore.close();
303
+ moduleStore = null;
304
+ }
305
+ var moduleStore, moduleConfig;
306
+ var init_raw_message_store = __esm({
307
+ "src/storage/raw-message-store.ts"() {
308
+ init_postgres_raw_message_factory();
309
+ init_sqlite_raw_message_store();
310
+ moduleStore = null;
311
+ moduleConfig = null;
312
+ }
313
+ });
314
+
315
+ // src/search/unified-search.ts
316
+ init_chroma_memory_index();
317
+ init_raw_message_store();
222
318
 
223
319
  // src/search/utilities.ts
224
320
  var DEFAULT_LIMIT = 10;
@@ -362,7 +458,7 @@ function createUnifiedSearch(deps = {}) {
362
458
  warnings.push({
363
459
  source: "memory",
364
460
  code: "memory_search_failed",
365
- message: error.message ?? "memory_search_failed"
461
+ message: `Memory search failed: ${error.message ?? "Unknown error"}. Using keyword search fallback.`
366
462
  });
367
463
  }
368
464
  } else {
@@ -402,13 +498,7 @@ function createUnifiedSearch(deps = {}) {
402
498
  message: error.message ?? "insights_search_failed"
403
499
  });
404
500
  }
405
- } else if (sources.includes("insights")) {
406
- warnings.push({
407
- source: "insights",
408
- code: "insights_search_not_configured",
409
- message: "Insights search is not configured for this host."
410
- });
411
- }
501
+ } else if (sources.includes("insights")) ;
412
502
  const knowledgeHits = [];
413
503
  if (sources.includes("knowledge") && typeof deps.searchKnowledge === "function") {
414
504
  try {
@@ -433,13 +523,7 @@ function createUnifiedSearch(deps = {}) {
433
523
  message: error.message ?? "knowledge_search_failed"
434
524
  });
435
525
  }
436
- } else if (sources.includes("knowledge")) {
437
- warnings.push({
438
- source: "knowledge",
439
- code: "knowledge_search_not_configured",
440
- message: "Knowledge search is not configured for this host."
441
- });
442
- }
526
+ } else if (sources.includes("knowledge")) ;
443
527
  const merged = mergeAcrossSources({
444
528
  memorySubs,
445
529
  insightHits,
@@ -457,7 +541,33 @@ function createUnifiedSearch(deps = {}) {
457
541
  }
458
542
  async function runMemorySource(input, limit, threshold, warnings) {
459
543
  if (typeof deps.embedQuery !== "function") {
460
- throw new Error("embedQuery is not configured");
544
+ warnings.push({
545
+ source: "memory",
546
+ code: "memory_lexical_search_fallback",
547
+ message: "Semantic search not configured, using keyword search as fallback"
548
+ });
549
+ const { lexicalSearchRawMessages: lexicalSearchRawMessages2 } = await Promise.resolve().then(() => (init_sqlite_raw_message_store(), sqlite_raw_message_store_exports));
550
+ const keywords = deriveLexicalKeywords(input.query);
551
+ let lexical2 = [];
552
+ if (keywords.length > 0) {
553
+ try {
554
+ const filters2 = input.botIds && input.botIds.length > 0 ? input.botIds : [void 0];
555
+ const results = await Promise.all(
556
+ filters2.map(
557
+ (botId) => lexicalSearchRawMessages2({
558
+ userId: input.userId,
559
+ keywords,
560
+ limit: Math.ceil(limit / filters2.length),
561
+ botId
562
+ })
563
+ )
564
+ );
565
+ lexical2 = results.flat().filter(Boolean).map(toMemoryResult);
566
+ } catch (error) {
567
+ logger.warn?.("[memory-store] Default lexical search failed:", error);
568
+ }
569
+ }
570
+ return { semantic: [], lexical: lexical2 };
461
571
  }
462
572
  const queryEmbedding = await deps.embedQuery({
463
573
  userId: input.userId,
@@ -504,6 +614,28 @@ function createUnifiedSearch(deps = {}) {
504
614
  )
505
615
  )).flat().filter(isRawMemorySemanticResult).map(toMemoryResult);
506
616
  }
617
+ if (semantic.length === 0) {
618
+ try {
619
+ const { getRawMessageManager: getRawMessageManager2 } = await Promise.resolve().then(() => (init_raw_message_store(), raw_message_store_exports));
620
+ const manager2 = await getRawMessageManager2();
621
+ if (typeof manager2.searchMessagesSemantically === "function") {
622
+ const results = await manager2.searchMessagesSemantically({
623
+ userId: input.userId,
624
+ queryEmbedding,
625
+ limit
626
+ });
627
+ semantic = results.map((r) => ({
628
+ type: "memory",
629
+ id: r.id,
630
+ content: r.content,
631
+ similarity: r.similarity,
632
+ metadata: r.metadata ?? {}
633
+ }));
634
+ }
635
+ } catch (error) {
636
+ logger.warn?.("[memory-store] SQLite semantic search failed:", error);
637
+ }
638
+ }
507
639
  let lexical = [];
508
640
  if (typeof deps.searchRawMessagesLexical === "function") {
509
641
  const keywords = deriveLexicalKeywords(input.query);
@@ -586,6 +718,8 @@ function mergeAcrossSources(input) {
586
718
  }
587
719
 
588
720
  // src/mcp.ts
721
+ init_chroma_memory_index();
722
+ init_raw_message_store();
589
723
  var DEFAULT_NAME = "@melandlabs/memory-store";
590
724
  var DEFAULT_VERSION = "0.1.0";
591
725
  async function embedMissingMessages(messages, deps) {
@@ -744,7 +878,11 @@ async function startMcpServer(options = {}) {
744
878
  return server;
745
879
  }
746
880
 
881
+ // src/server/cli-shared.ts
882
+ init_raw_message_store();
883
+
747
884
  // src/storage/sqlite-vector-index.ts
885
+ init_sqlite_raw_message_store();
748
886
  function getMemoryVectorStoreBackend() {
749
887
  const backend = (process.env.INSIGHT_VECTOR_STORE_BACKEND || process.env.MEMORY_VECTOR_STORE_BACKEND || process.env.VECTOR_STORE_BACKEND || "sqlite-vec").toLowerCase();
750
888
  return backend === "chroma" ? "chroma" : "sqlite-vec";
@@ -858,11 +996,26 @@ async function buildUnified(args) {
858
996
  const wantsAiRag = args.embeddingProvider === "local" || args.memoryBackend === "chroma" || args.insightsBackend === "chroma" || args.knowledgeBackend === "chroma";
859
997
  const aiRag = wantsAiRag ? await loadAiRag() : null;
860
998
  if (args.embeddingProvider === "local") {
861
- const provider = new aiRag.LocalTransformersEmbeddingProvider({ modelName: args.embeddingModel });
862
- unified.embedQuery = async ({ query }) => provider.embedQuery(query);
863
- log(
864
- `embedQuery wired via LocalTransformersEmbeddingProvider (model=${args.embeddingModel ?? "Xenova/all-MiniLM-L6-v2"})`
865
- );
999
+ try {
1000
+ if (!aiRag) {
1001
+ throw new Error("ai-rag modules not loaded");
1002
+ }
1003
+ const provider = new aiRag.LocalTransformersEmbeddingProvider({ modelName: args.embeddingModel });
1004
+ unified.embedQuery = async ({ query }) => provider.embedQuery(query);
1005
+ log(
1006
+ `embedQuery wired via LocalTransformersEmbeddingProvider (model=${args.embeddingModel ?? "Xenova/all-MiniLM-L6-v2"})`
1007
+ );
1008
+ } catch (error) {
1009
+ log(
1010
+ `Warning: Failed to initialize LocalTransformersEmbeddingProvider: ${error.message}`
1011
+ );
1012
+ log(
1013
+ "Semantic search will be disabled. The server will continue with keyword-only search."
1014
+ );
1015
+ log(
1016
+ "To fix: Ensure the model is downloaded or check your network connection to huggingface.co"
1017
+ );
1018
+ }
866
1019
  } else if (args.embeddingProvider === "openrouter") {
867
1020
  const apiKey = process.env.OPENROUTER_API_KEY;
868
1021
  if (!apiKey) {
@@ -209,11 +209,26 @@ async function buildUnified(args) {
209
209
  const wantsAiRag = args.embeddingProvider === "local" || args.memoryBackend === "chroma" || args.insightsBackend === "chroma" || args.knowledgeBackend === "chroma";
210
210
  const aiRag = wantsAiRag ? await loadAiRag() : null;
211
211
  if (args.embeddingProvider === "local") {
212
- const provider = new aiRag.LocalTransformersEmbeddingProvider({ modelName: args.embeddingModel });
213
- unified.embedQuery = async ({ query }) => provider.embedQuery(query);
214
- log(
215
- `embedQuery wired via LocalTransformersEmbeddingProvider (model=${args.embeddingModel ?? "Xenova/all-MiniLM-L6-v2"})`
216
- );
212
+ try {
213
+ if (!aiRag) {
214
+ throw new Error("ai-rag modules not loaded");
215
+ }
216
+ const provider = new aiRag.LocalTransformersEmbeddingProvider({ modelName: args.embeddingModel });
217
+ unified.embedQuery = async ({ query }) => provider.embedQuery(query);
218
+ log(
219
+ `embedQuery wired via LocalTransformersEmbeddingProvider (model=${args.embeddingModel ?? "Xenova/all-MiniLM-L6-v2"})`
220
+ );
221
+ } catch (error) {
222
+ log(
223
+ `Warning: Failed to initialize LocalTransformersEmbeddingProvider: ${error.message}`
224
+ );
225
+ log(
226
+ "Semantic search will be disabled. The server will continue with keyword-only search."
227
+ );
228
+ log(
229
+ "To fix: Ensure the model is downloaded or check your network connection to huggingface.co"
230
+ );
231
+ }
217
232
  } else if (args.embeddingProvider === "openrouter") {
218
233
  const apiKey = process.env.OPENROUTER_API_KEY;
219
234
  if (!apiKey) {
package/package.json CHANGED
@@ -1,94 +1,82 @@
1
1
  {
2
- "name": "@melandlabs/memory-store",
3
- "version": "0.2.0",
4
- "type": "module",
5
- "files": [
6
- "dist",
7
- "README.md",
8
- "LICENSE"
9
- ],
10
- "main": "./dist/index.js",
11
- "types": "./dist/index.d.ts",
12
- "exports": {
13
- ".": {
14
- "types": "./dist/index.d.ts",
15
- "import": "./dist/index.js"
16
- },
17
- "./contracts": "./dist/contracts.js",
18
- "./http": {
19
- "types": "./dist/http.d.ts",
20
- "import": "./dist/http.js"
21
- },
22
- "./mcp": {
23
- "types": "./dist/mcp.d.ts",
24
- "import": "./dist/mcp.js"
25
- },
26
- "./raw-message-store": "./dist/storage/raw-message-store.js",
27
- "./sqlite-raw-message-store": "./dist/storage/sqlite-raw-message-store.js",
28
- "./postgres-raw-message-factory": "./dist/storage/postgres-raw-message-factory.js",
29
- "./sqlite-vector-index": "./dist/storage/sqlite-vector-index.js",
30
- "./chroma-memory-index": "./dist/storage/chroma-memory-index.js",
31
- "./unified-search": "./dist/search/unified-search.js",
32
- "./memory-graph-write-policy": "./dist/policies/memory-graph-write-policy.js",
33
- "./memory-graph-correction-policy": "./dist/policies/memory-graph-correction-policy.js"
34
- },
35
- "bin": {
36
- "opencontext-memory-http": "./dist/server/cli-http.js",
37
- "opencontext-memory-mcp": "./dist/server/cli-mcp.js"
38
- },
39
- "repository": {
40
- "type": "git",
41
- "url": "git+https://github.com/melandlabs/opencontext.git",
42
- "directory": "packages/memory-store"
43
- },
44
- "license": "Apache-2.0",
45
- "description": "OpenContext memory storage + search SDK with HTTP and MCP server entry points.",
46
- "keywords": [
47
- "opencontext",
48
- "memory",
49
- "storage",
50
- "search",
51
- "sdk",
52
- "mcp",
53
- "http"
54
- ],
55
- "publishConfig": {
56
- "access": "public"
57
- },
58
- "dependencies": {
59
- "@hono/node-server": "^1.13.7",
60
- "@modelcontextprotocol/sdk": "^1.25.3",
61
- "hono": "^4.6.14",
62
- "zod": "^4.3.6",
63
- "@melandlabs/ai": "0.2.0",
64
- "@melandlabs/rag": "0.2.0",
65
- "@melandlabs/shared": "0.2.0",
66
- "@melandlabs/sqlite": "0.2.0"
67
- },
68
- "peerDependencies": {
69
- "@melandlabs/ai-rag": "0.2.0",
70
- "@melandlabs/indexeddb": "0.2.0"
71
- },
72
- "peerDependenciesMeta": {
73
- "@melandlabs/ai-rag": {
74
- "optional": true
75
- },
76
- "@melandlabs/indexeddb": {
77
- "optional": true
78
- }
79
- },
80
- "devDependencies": {
81
- "@types/node": "^22.13.10",
82
- "typescript": "^5.6.3",
83
- "@melandlabs/config": "0.2.0",
84
- "@melandlabs/ai-rag": "0.2.0"
85
- },
86
- "scripts": {
87
- "build": "tsup",
88
- "typecheck": "tsc --noEmit",
89
- "lint": "biome check .",
90
- "lint:fix": "biome check --write .",
91
- "test": "vitest run",
92
- "test:watch": "vitest"
93
- }
94
- }
2
+ "name": "@melandlabs/memory-store",
3
+ "version": "0.2.2",
4
+ "type": "module",
5
+ "files": ["dist", "README.md", "LICENSE"],
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./contracts": "./dist/contracts.js",
14
+ "./http": {
15
+ "types": "./dist/http.d.ts",
16
+ "import": "./dist/http.js"
17
+ },
18
+ "./mcp": {
19
+ "types": "./dist/mcp.d.ts",
20
+ "import": "./dist/mcp.js"
21
+ },
22
+ "./raw-message-store": "./dist/storage/raw-message-store.js",
23
+ "./sqlite-raw-message-store": "./dist/storage/sqlite-raw-message-store.js",
24
+ "./postgres-raw-message-factory": "./dist/storage/postgres-raw-message-factory.js",
25
+ "./sqlite-vector-index": "./dist/storage/sqlite-vector-index.js",
26
+ "./chroma-memory-index": "./dist/storage/chroma-memory-index.js",
27
+ "./unified-search": "./dist/search/unified-search.js",
28
+ "./memory-graph-write-policy": "./dist/policies/memory-graph-write-policy.js",
29
+ "./memory-graph-correction-policy": "./dist/policies/memory-graph-correction-policy.js"
30
+ },
31
+ "bin": {
32
+ "opencontext-memory-http": "./dist/server/cli-http.js",
33
+ "opencontext-memory-mcp": "./dist/server/cli-mcp.js"
34
+ },
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "git+https://github.com/melandlabs/opencontext.git",
38
+ "directory": "packages/memory-store"
39
+ },
40
+ "license": "Apache-2.0",
41
+ "description": "OpenContext memory storage + search SDK with HTTP and MCP server entry points.",
42
+ "keywords": ["opencontext", "memory", "storage", "search", "sdk", "mcp", "http"],
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "dependencies": {
47
+ "@hono/node-server": "^1.13.7",
48
+ "@modelcontextprotocol/sdk": "^1.25.3",
49
+ "@melandlabs/ai": "workspace:*",
50
+ "@melandlabs/rag": "workspace:*",
51
+ "@melandlabs/shared": "workspace:*",
52
+ "@melandlabs/sqlite": "workspace:*",
53
+ "hono": "^4.6.14",
54
+ "zod": "^4.3.6"
55
+ },
56
+ "peerDependencies": {
57
+ "@melandlabs/ai-rag": "workspace:*",
58
+ "@melandlabs/indexeddb": "workspace:*"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "@melandlabs/ai-rag": {
62
+ "optional": true
63
+ },
64
+ "@melandlabs/indexeddb": {
65
+ "optional": true
66
+ }
67
+ },
68
+ "devDependencies": {
69
+ "@melandlabs/ai-rag": "workspace:*",
70
+ "@melandlabs/config": "workspace:*",
71
+ "@types/node": "^22.13.10",
72
+ "typescript": "^5.6.3"
73
+ },
74
+ "scripts": {
75
+ "build": "tsup",
76
+ "typecheck": "tsc --noEmit",
77
+ "lint": "biome check .",
78
+ "lint:fix": "biome check --write .",
79
+ "test": "vitest run",
80
+ "test:watch": "vitest"
81
+ }
82
+ }