@j0hanz/memory-mcp 1.0.0 → 1.1.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 (131) hide show
  1. package/README.md +32 -25
  2. package/dist/completions/index.d.ts.map +1 -1
  3. package/dist/completions/index.js +11 -8
  4. package/dist/completions/index.js.map +1 -1
  5. package/dist/db/index.d.ts.map +1 -1
  6. package/dist/db/index.js +68 -8
  7. package/dist/db/index.js.map +1 -1
  8. package/dist/db/typed.d.ts +9 -3
  9. package/dist/db/typed.d.ts.map +1 -1
  10. package/dist/db/typed.js +33 -4
  11. package/dist/db/typed.js.map +1 -1
  12. package/dist/index.js +13 -8
  13. package/dist/index.js.map +1 -1
  14. package/dist/lib/errors.d.ts +4 -0
  15. package/dist/lib/errors.d.ts.map +1 -1
  16. package/dist/lib/errors.js +12 -4
  17. package/dist/lib/errors.js.map +1 -1
  18. package/dist/lib/hash.d.ts.map +1 -1
  19. package/dist/lib/hash.js +9 -2
  20. package/dist/lib/hash.js.map +1 -1
  21. package/dist/lib/instructions.d.ts +2 -0
  22. package/dist/lib/instructions.d.ts.map +1 -0
  23. package/dist/lib/instructions.js +96 -0
  24. package/dist/lib/instructions.js.map +1 -0
  25. package/dist/lib/mcp-utils.d.ts +6 -0
  26. package/dist/lib/mcp-utils.d.ts.map +1 -0
  27. package/dist/lib/mcp-utils.js +26 -0
  28. package/dist/lib/mcp-utils.js.map +1 -0
  29. package/dist/lib/pagination.d.ts.map +1 -1
  30. package/dist/lib/pagination.js +14 -7
  31. package/dist/lib/pagination.js.map +1 -1
  32. package/dist/lib/search-cursor.d.ts +13 -0
  33. package/dist/lib/search-cursor.d.ts.map +1 -0
  34. package/dist/lib/search-cursor.js +89 -0
  35. package/dist/lib/search-cursor.js.map +1 -0
  36. package/dist/lib/search.d.ts +16 -0
  37. package/dist/lib/search.d.ts.map +1 -1
  38. package/dist/lib/search.js +53 -12
  39. package/dist/lib/search.js.map +1 -1
  40. package/dist/lib/sql.d.ts +17 -0
  41. package/dist/lib/sql.d.ts.map +1 -0
  42. package/dist/lib/sql.js +18 -0
  43. package/dist/lib/sql.js.map +1 -0
  44. package/dist/lib/tool-contracts.d.ts +18 -0
  45. package/dist/lib/tool-contracts.d.ts.map +1 -0
  46. package/dist/lib/tool-contracts.js +120 -0
  47. package/dist/lib/tool-contracts.js.map +1 -0
  48. package/dist/lib/tool-response.d.ts +1 -5
  49. package/dist/lib/tool-response.d.ts.map +1 -1
  50. package/dist/lib/tool-response.js +9 -7
  51. package/dist/lib/tool-response.js.map +1 -1
  52. package/dist/lib/types.d.ts.map +1 -1
  53. package/dist/lib/types.js +10 -9
  54. package/dist/lib/types.js.map +1 -1
  55. package/dist/prompts/index.d.ts.map +1 -1
  56. package/dist/prompts/index.js +22 -36
  57. package/dist/prompts/index.js.map +1 -1
  58. package/dist/resources/index.d.ts.map +1 -1
  59. package/dist/resources/index.js +15 -36
  60. package/dist/resources/index.js.map +1 -1
  61. package/dist/schemas/index.d.ts.map +1 -1
  62. package/dist/schemas/index.js +1 -1
  63. package/dist/schemas/index.js.map +1 -1
  64. package/dist/schemas/inputs.d.ts +5 -5
  65. package/dist/schemas/inputs.d.ts.map +1 -1
  66. package/dist/schemas/inputs.js +21 -14
  67. package/dist/schemas/inputs.js.map +1 -1
  68. package/dist/schemas/outputs.d.ts +94 -148
  69. package/dist/schemas/outputs.d.ts.map +1 -1
  70. package/dist/schemas/outputs.js +59 -66
  71. package/dist/schemas/outputs.js.map +1 -1
  72. package/dist/server.d.ts.map +1 -1
  73. package/dist/server.js +20 -18
  74. package/dist/server.js.map +1 -1
  75. package/dist/tools/create-relationship.d.ts.map +1 -1
  76. package/dist/tools/create-relationship.js +38 -25
  77. package/dist/tools/create-relationship.js.map +1 -1
  78. package/dist/tools/delete-memories.d.ts.map +1 -1
  79. package/dist/tools/delete-memories.js +37 -30
  80. package/dist/tools/delete-memories.js.map +1 -1
  81. package/dist/tools/delete-memory.d.ts.map +1 -1
  82. package/dist/tools/delete-memory.js +24 -22
  83. package/dist/tools/delete-memory.js.map +1 -1
  84. package/dist/tools/delete-relationship.d.ts.map +1 -1
  85. package/dist/tools/delete-relationship.js +28 -20
  86. package/dist/tools/delete-relationship.js.map +1 -1
  87. package/dist/tools/get-memory.d.ts.map +1 -1
  88. package/dist/tools/get-memory.js +26 -16
  89. package/dist/tools/get-memory.js.map +1 -1
  90. package/dist/tools/get-relationships.d.ts.map +1 -1
  91. package/dist/tools/get-relationships.js +71 -40
  92. package/dist/tools/get-relationships.js.map +1 -1
  93. package/dist/tools/index.d.ts +6 -14
  94. package/dist/tools/index.d.ts.map +1 -1
  95. package/dist/tools/index.js +5 -0
  96. package/dist/tools/index.js.map +1 -1
  97. package/dist/tools/memory-stats.d.ts.map +1 -1
  98. package/dist/tools/memory-stats.js +29 -39
  99. package/dist/tools/memory-stats.js.map +1 -1
  100. package/dist/tools/progress.d.ts +34 -0
  101. package/dist/tools/progress.d.ts.map +1 -0
  102. package/dist/tools/progress.js +136 -0
  103. package/dist/tools/progress.js.map +1 -0
  104. package/dist/tools/recall.d.ts.map +1 -1
  105. package/dist/tools/recall.js +157 -105
  106. package/dist/tools/recall.js.map +1 -1
  107. package/dist/tools/result.d.ts +7 -0
  108. package/dist/tools/result.d.ts.map +1 -0
  109. package/dist/tools/result.js +19 -0
  110. package/dist/tools/result.js.map +1 -0
  111. package/dist/tools/retrieve-context.d.ts.map +1 -1
  112. package/dist/tools/retrieve-context.js +127 -40
  113. package/dist/tools/retrieve-context.js.map +1 -1
  114. package/dist/tools/search-memories.d.ts.map +1 -1
  115. package/dist/tools/search-memories.js +37 -47
  116. package/dist/tools/search-memories.js.map +1 -1
  117. package/dist/tools/store-memories.d.ts.map +1 -1
  118. package/dist/tools/store-memories.js +44 -28
  119. package/dist/tools/store-memories.js.map +1 -1
  120. package/dist/tools/store-memory.d.ts.map +1 -1
  121. package/dist/tools/store-memory.js +43 -23
  122. package/dist/tools/store-memory.js.map +1 -1
  123. package/dist/tools/update-memory.d.ts.map +1 -1
  124. package/dist/tools/update-memory.js +63 -29
  125. package/dist/tools/update-memory.js.map +1 -1
  126. package/package.json +1 -3
  127. package/dist/instructions.md +0 -123
  128. package/dist/tools/helpers.d.ts +0 -13
  129. package/dist/tools/helpers.d.ts.map +0 -1
  130. package/dist/tools/helpers.js +0 -49
  131. package/dist/tools/helpers.js.map +0 -1
package/README.md CHANGED
@@ -22,7 +22,7 @@ Memory MCP provides a local, persistent memory layer for MCP-enabled assistants.
22
22
  - **Token-budget retrieval** (`retrieve_context`) selects memories that fit a caller-specified token budget — no manual pagination needed.
23
23
  - **Strict Zod input validation** with typed output envelopes and SHA-256 hash addressing.
24
24
  - **Resource support** with `internal://instructions` (Markdown guide) and `memory://memories/{hash}` URI template with hash auto-completion.
25
- - **stdio transport** with clean shutdown handling (`SIGINT`, `SIGTERM`) and no HTTP endpoints.
25
+ - **stdio transport** with clean shutdown handling (`SIGINT`, `SIGTERM`) and no HTTP endpoints. |
26
26
 
27
27
  ## Requirements
28
28
 
@@ -192,6 +192,16 @@ MCP client config:
192
192
 
193
193
  </details>
194
194
 
195
+ ## Documentation Maintenance
196
+
197
+ - **Owner**: maintainers updating MCP behavior in `src/` must update `README.md` and affected `mcp/` mirror pages in the same PR.
198
+ - **Link/version policy**: use pinned `https://modelcontextprotocol.io/specification/2025-11-25/...` links for protocol references; avoid `latest` and mixed legacy targets.
199
+ - **Drift-check checklist**:
200
+ - Re-verify capability declarations in `src/server.ts`.
201
+ - Reconcile tool/resource/prompt docs with `src/tools/index.ts`, `src/resources/index.ts`, and `src/prompts/index.ts`.
202
+ - Confirm limitations/gotchas in `src/instructions.md` match runtime behavior.
203
+ - **Validation commands**: `npm run type-check`, `npm run test:fast`, `npm run build`.
204
+
195
205
  ## MCP Surface
196
206
 
197
207
  ### Tools Summary
@@ -225,7 +235,7 @@ Store a new memory with content, tags, and optional type/importance. Idempotent
225
235
  | `memory_type` | enum | No | `general` | `general`, `fact`, `plan`, `decision`, `reflection`, `lesson`, `error`, `gradient` |
226
236
  | `importance` | `integer` | No | `0` | Priority 0–10 |
227
237
 
228
- Returns: `{ ok, result: { hash, created } }`
238
+ Returns: `{ hash, created }`
229
239
 
230
240
  ---
231
241
 
@@ -237,7 +247,7 @@ Store multiple memories in one transaction (max 50 items).
237
247
  | ------- | ------------------------ | -------- | -------------------------------------------------------------------------------------- |
238
248
  | `items` | `Array<StoreMemoryItem>` | Yes | 1–50 items, each with `content`, `tags`, optional `memory_type`, optional `importance` |
239
249
 
240
- Returns: `{ ok, result: { items, succeeded, failed } }`
250
+ Returns: `{ items, succeeded, failed }`
241
251
 
242
252
  ---
243
253
 
@@ -249,7 +259,7 @@ Retrieve one memory by its SHA-256 hash.
249
259
  | ------ | -------- | -------- | ----------------------------- |
250
260
  | `hash` | `string` | Yes | 64-char lowercase SHA-256 hex |
251
261
 
252
- Returns: `{ ok, result: Memory }` or `{ ok: false, error }` on `E_NOT_FOUND`.
262
+ Returns: `Memory` or `{ ok: false, error }` on `E_NOT_FOUND`.
253
263
 
254
264
  ---
255
265
 
@@ -263,7 +273,7 @@ Update content and optionally tags for an existing memory. Returns both hashes.
263
273
  | `content` | `string` | Yes | — | Replacement content |
264
274
  | `tags` | `string[]` | No | Existing tags | Replacement tags |
265
275
 
266
- Returns: `{ ok, result: { old_hash, new_hash } }`
276
+ Returns: `{ old_hash, new_hash }`
267
277
 
268
278
  ---
269
279
 
@@ -275,7 +285,7 @@ Delete one memory by hash. Cascades to related relationship rows.
275
285
  | ------ | -------- | -------- | ----------- |
276
286
  | `hash` | `string` | Yes | Memory hash |
277
287
 
278
- Returns: `{ ok, result: { hash, deleted } }`
288
+ Returns: `{ hash, deleted }`
279
289
 
280
290
  ---
281
291
 
@@ -287,7 +297,7 @@ Delete multiple memories by hash in one transaction.
287
297
  | -------- | ---------- | -------- | ------------------ |
288
298
  | `hashes` | `string[]` | Yes | 1–50 memory hashes |
289
299
 
290
- Returns: `{ ok, result: { items, succeeded, failed } }`
300
+ Returns: `{ items, succeeded, failed }`
291
301
 
292
302
  ---
293
303
 
@@ -304,7 +314,7 @@ Full-text search over memory content and tags using FTS5. Supports importance an
304
314
  | `max_importance` | `integer` | No | — | Only return memories with importance <= this value (0–10) |
305
315
  | `memory_type` | enum | No | — | Filter by memory type |
306
316
 
307
- Returns: `{ ok, result: { memories, total_returned, nextCursor? } }`
317
+ Returns: `{ memories, total_returned, nextCursor? }`
308
318
 
309
319
  ---
310
320
 
@@ -320,7 +330,7 @@ Suggested `relation_type` values: `related_to`, `causes`, `depends_on`, `parent_
320
330
  | `to_hash` | `string` | Yes | Target memory hash |
321
331
  | `relation_type` | `string` | Yes | Edge label (1–50 chars, no whitespace, free-form) |
322
332
 
323
- Returns: `{ ok, result: { created } }`
333
+ Returns: `{ created }`
324
334
 
325
335
  ---
326
336
 
@@ -334,7 +344,7 @@ Delete one directed relationship edge.
334
344
  | `to_hash` | `string` | Yes | Target hash |
335
345
  | `relation_type` | `string` | Yes | Relationship type |
336
346
 
337
- Returns: `{ ok, result: { deleted } }` or `{ ok: false, error }` on `E_NOT_FOUND`.
347
+ Returns: `{ deleted }` or `{ ok: false, error }` on `E_NOT_FOUND`.
338
348
 
339
349
  ---
340
350
 
@@ -347,7 +357,7 @@ Retrieve relationships for a memory, with optional direction filter.
347
357
  | `hash` | `string` | Yes | — | Memory hash |
348
358
  | `direction` | enum | No | `both` | `outgoing`, `incoming`, or `both` |
349
359
 
350
- Returns: `{ ok, result: { relationships, count } }`
360
+ Returns: `{ relationships, count }`
351
361
 
352
362
  Each relationship includes `from_hash`, `to_hash`, `relation_type`, `created_at`, `linked_hash`, `linked_content`, and `linked_tags`.
353
363
 
@@ -367,7 +377,7 @@ Search memories by full-text query, then traverse the relationship graph up to `
367
377
  | `max_importance` | `integer` | No | — | Seed filter: only memories with importance <= value (0–10) |
368
378
  | `memory_type` | enum | No | — | Seed filter: only memories of this type |
369
379
 
370
- Returns: `{ ok, result: { memories, graph, depth_reached, aborted?, nextCursor? } }`
380
+ Returns: `{ memories, graph, depth_reached, aborted?, nextCursor? }`
371
381
 
372
382
  Each item in `graph` uses the shape:
373
383
 
@@ -390,7 +400,7 @@ Search memories and return relevance-ranked results that fit within a caller-spe
390
400
  | `token_budget` | `integer` | No | `4000` | Maximum estimated tokens to return (100–200000) |
391
401
  | `strategy` | enum | No | `relevance` | Sort order: `relevance` (FTS rank), `importance` (highest first), `recency` (newest first) |
392
402
 
393
- Returns: `{ ok, result: { memories, estimated_tokens, truncated } }`
403
+ Returns: `{ memories, estimated_tokens, truncated }`
394
404
 
395
405
  > [!TIP]
396
406
  > Token estimation is approximate (content length ÷ 4). `truncated: true` means the budget was reached before all candidates were included.
@@ -405,17 +415,14 @@ Returns:
405
415
 
406
416
  ```json
407
417
  {
408
- "ok": true,
409
- "result": {
410
- "memories": {
411
- "total": 0,
412
- "oldest": null,
413
- "newest": null,
414
- "avg_importance": null
415
- },
416
- "relationships": { "total": 0 },
417
- "by_type": {}
418
- }
418
+ "memories": {
419
+ "total": 0,
420
+ "oldest": null,
421
+ "newest": null,
422
+ "avg_importance": null
423
+ },
424
+ "relationships": { "total": 0 },
425
+ "by_type": {}
419
426
  }
420
427
  ```
421
428
 
@@ -469,7 +476,7 @@ Returns:
469
476
  | SQLite busy timeout | 5000 ms |
470
477
 
471
478
  > [!NOTE]
472
- > Cursor values are base64url-encoded offsets. Treat them as opaque tokens.
479
+ > Cursor values are opaque base64url-encoded tokens. Treat them as opaque and do not parse them.
473
480
 
474
481
  ## Security
475
482
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAQ9C,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,OAAO,GACV,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAQ7B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAgB9C,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,OAAO,GACV,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAQ7B"}
@@ -1,17 +1,20 @@
1
1
  const HASH_MAX_LENGTH = 64;
2
2
  const HASH_COMPLETION_LIMIT = 101;
3
3
  const HASH_COMPLETION_SQL = `SELECT hash FROM memories WHERE hash LIKE ? ESCAPE '\\' ORDER BY hash LIMIT ${HASH_COMPLETION_LIMIT}`;
4
+ function escapeLikePattern(value) {
5
+ return value.replace(/[%_\\]/g, '\\$&');
6
+ }
7
+ function normalizeHashPrefix(value) {
8
+ return escapeLikePattern(value.slice(0, HASH_MAX_LENGTH));
9
+ }
4
10
  // Returns a completion callback for the `hash` URI variable.
5
11
  export function createHashCompletionCallback(db) {
6
12
  return (value) => {
7
- const escapedPrefix = escapeLikePattern(value.slice(0, HASH_MAX_LENGTH));
8
- const rows = db
9
- .prepare(HASH_COMPLETION_SQL)
10
- .all(`${escapedPrefix}%`);
11
- return rows.map((r) => r.hash);
13
+ const escapedPrefix = normalizeHashPrefix(value);
14
+ return db
15
+ .prepareOnce(HASH_COMPLETION_SQL)
16
+ .all(`${escapedPrefix}%`)
17
+ .map((row) => row.hash);
12
18
  };
13
19
  }
14
- function escapeLikePattern(value) {
15
- return value.replace(/[%_\\]/g, '\\$&');
16
- }
17
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,mBAAmB,GAAG,+EAA+E,qBAAqB,EAAE,CAAC;AAEnI,6DAA6D;AAC7D,MAAM,UAAU,4BAA4B,CAC1C,EAAW;IAEX,OAAO,CAAC,KAAa,EAAY,EAAE;QACjC,MAAM,aAAa,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,EAAE;aACZ,OAAO,CAAU,mBAAmB,CAAC;aACrC,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,mBAAmB,GAAG,+EAA+E,qBAAqB,EAAE,CAAC;AAEnI,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,4BAA4B,CAC1C,EAAW;IAEX,OAAO,CAAC,KAAa,EAAY,EAAE;QACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACjD,OAAO,EAAE;aACN,WAAW,CAAU,mBAAmB,CAAC;aACzC,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC;aACxB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AA2FzD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAWvD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAElE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAiLzD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAWvD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAElE"}
package/dist/db/index.js CHANGED
@@ -4,8 +4,17 @@ import { DatabaseSync } from 'node:sqlite';
4
4
  import { createTypedDb } from './typed.js';
5
5
  const SQLITE_TIMEOUT_MS = 5000;
6
6
  const STATEMENT_CACHE_SIZE = 1000;
7
+ const TARGET_SCHEMA_VERSION = 2;
7
8
  const FTS5_CHECK_SQL = 'CREATE VIRTUAL TABLE IF NOT EXISTS __fts5_check USING fts5(x); DROP TABLE __fts5_check;';
8
9
  const FTS5_REQUIRED_MESSAGE = 'SQLite FTS5 extension is not available. memory-mcp requires a SQLite build with FTS5 support.';
10
+ const DEFENSIVE_PRAGMA_SQL = 'PRAGMA defensive = ON';
11
+ const RELATIONSHIPS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS relationships (
12
+ from_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE ON UPDATE CASCADE,
13
+ to_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE ON UPDATE CASCADE,
14
+ relation_type TEXT NOT NULL,
15
+ created_at TEXT NOT NULL,
16
+ PRIMARY KEY (from_hash, to_hash, relation_type)
17
+ ) STRICT;`;
9
18
  const SCHEMA_SQL = `
10
19
  CREATE TABLE IF NOT EXISTS memories (
11
20
  hash TEXT PRIMARY KEY NOT NULL,
@@ -41,13 +50,7 @@ const SCHEMA_SQL = `
41
50
  VALUES ('delete', old.rowid, old.content, old.tags);
42
51
  END;
43
52
 
44
- CREATE TABLE IF NOT EXISTS relationships (
45
- from_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE,
46
- to_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE,
47
- relation_type TEXT NOT NULL,
48
- created_at TEXT NOT NULL,
49
- PRIMARY KEY (from_hash, to_hash, relation_type)
50
- ) STRICT;
53
+ ${RELATIONSHIPS_TABLE_SQL}
51
54
 
52
55
  CREATE INDEX IF NOT EXISTS idx_memories_importance
53
56
  ON memories(importance DESC);
@@ -76,12 +79,69 @@ function ensureParentDir(path) {
76
79
  }
77
80
  mkdirSync(dirname(path), { recursive: true });
78
81
  }
82
+ function readUserVersion(db) {
83
+ const row = db.prepare('PRAGMA user_version').get();
84
+ return row?.user_version ?? 0;
85
+ }
86
+ function writeUserVersion(db, version) {
87
+ db.exec(`PRAGMA user_version = ${version}`);
88
+ }
89
+ function needsRelationshipsCascadeUpdateMigration(db) {
90
+ const rows = db
91
+ .prepare("PRAGMA foreign_key_list('relationships')")
92
+ .all();
93
+ if (rows.length === 0) {
94
+ return false;
95
+ }
96
+ for (const row of rows) {
97
+ const isMemoryEdge = row.table === 'memories' &&
98
+ (row.from === 'from_hash' || row.from === 'to_hash');
99
+ if (!isMemoryEdge) {
100
+ continue;
101
+ }
102
+ if (row.on_update.toUpperCase() !== 'CASCADE') {
103
+ return true;
104
+ }
105
+ }
106
+ return false;
107
+ }
108
+ function migrateRelationshipsCascadeUpdate(db) {
109
+ db.exec('BEGIN IMMEDIATE');
110
+ try {
111
+ db.exec('ALTER TABLE relationships RENAME TO relationships_old');
112
+ db.exec(RELATIONSHIPS_TABLE_SQL.replace(' IF NOT EXISTS', ''));
113
+ db.exec(`
114
+ INSERT INTO relationships (from_hash, to_hash, relation_type, created_at)
115
+ SELECT from_hash, to_hash, relation_type, created_at
116
+ FROM relationships_old
117
+ `);
118
+ db.exec('DROP TABLE relationships_old');
119
+ db.exec('CREATE INDEX IF NOT EXISTS idx_relationships_from ON relationships(from_hash)');
120
+ db.exec('CREATE INDEX IF NOT EXISTS idx_relationships_to ON relationships(to_hash)');
121
+ db.exec('COMMIT');
122
+ }
123
+ catch (err) {
124
+ db.exec('ROLLBACK');
125
+ throw err;
126
+ }
127
+ }
128
+ function applyMigrations(db) {
129
+ const currentVersion = readUserVersion(db);
130
+ const needsCascadeMigration = needsRelationshipsCascadeUpdateMigration(db);
131
+ if (needsCascadeMigration) {
132
+ migrateRelationshipsCascadeUpdate(db);
133
+ }
134
+ if (currentVersion < TARGET_SCHEMA_VERSION || needsCascadeMigration) {
135
+ writeUserVersion(db, TARGET_SCHEMA_VERSION);
136
+ }
137
+ }
79
138
  function configureDatabase(db) {
80
139
  // Enable defensive mode (SQLite v3.39+ / Node 24.12+: prevents deliberate DB corruption)
81
- db.exec('PRAGMA defensive = ON');
140
+ db.exec(DEFENSIVE_PRAGMA_SQL);
82
141
  // Verify FTS5 support
83
142
  assertFts5Available(db);
84
143
  db.exec(SCHEMA_SQL);
144
+ applyMigrations(db);
85
145
  }
86
146
  export function initDatabase(path) {
87
147
  ensureParentDir(path);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAoB,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAEzD,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,cAAc,GAClB,yFAAyF,CAAC;AAC5F,MAAM,qBAAqB,GACzB,+FAA+F,CAAC;AAElG,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsDlB,CAAC;AAEF,SAAS,mBAAmB,CAAC,EAAgB;IAC3C,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,cAAc,GAAG,IAAI,KAAK,UAAU,CAAC;IAC3C,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO;IACT,CAAC;IACD,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,iBAAiB,CAAC,EAAgB;IACzC,yFAAyF;IACzF,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAEjC,sBAAsB;IACtB,mBAAmB,CAAC,EAAE,CAAC,CAAC;IAExB,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,eAAe,CAAC,IAAI,CAAC,CAAC;IAEtB,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE;QAChC,2BAA2B,EAAE,IAAI;QACjC,OAAO,EAAE,iBAAiB;KAC3B,CAAC,CAAC;IAEH,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAEtB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,aAAa,CAAC,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAgB;IACnD,OAAO,EAAE,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,21 @@
1
1
  import type { DatabaseSync, SQLInputValue, StatementResultingChanges } from 'node:sqlite';
2
+ type SqlParams = readonly SQLInputValue[];
2
3
  export interface TypedStatement<T> {
3
- all(...params: SQLInputValue[]): T[];
4
- get(...params: SQLInputValue[]): T | undefined;
5
- run(...params: SQLInputValue[]): StatementResultingChanges;
4
+ all(...params: SqlParams): T[];
5
+ get(...params: SqlParams): T | undefined;
6
+ run(...params: SqlParams): StatementResultingChanges;
6
7
  }
7
8
  export declare class TypedDb {
8
9
  private readonly db;
10
+ private readonly cache;
9
11
  constructor(db: DatabaseSync);
12
+ private makeStatement;
10
13
  prepare<T>(sql: string): TypedStatement<T>;
14
+ prepareOnce<T>(sql: string): TypedStatement<T>;
15
+ transaction<T>(action: () => T): T;
11
16
  exec(sql: string): void;
12
17
  close(): void;
13
18
  }
14
19
  export declare function createTypedDb(db: DatabaseSync): TypedDb;
20
+ export {};
15
21
  //# sourceMappingURL=typed.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typed.d.ts","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,GAAG,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC;IACrC,GAAG,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC;IAC/C,GAAG,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,GAAG,yBAAyB,CAAC;CAC5D;AAED,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,YAAY;IAE7C,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;IAS1C,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,KAAK,IAAI,IAAI;CAGd;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAEvD"}
1
+ {"version":3,"file":"typed.d.ts","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAErB,KAAK,SAAS,GAAG,SAAS,aAAa,EAAE,CAAC;AAE1C,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC;IAC/B,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,GAAG,yBAAyB,CAAC;CACtD;AAED,qBAAa,OAAO;IAGN,OAAO,CAAC,QAAQ,CAAC,EAAE;IAF/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;gBAEvC,EAAE,EAAE,YAAY;IAE7C,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;IAI1C,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;IAU9C,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;IAYlC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,KAAK,IAAI,IAAI;CAId;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAEvD"}
package/dist/db/typed.js CHANGED
@@ -1,20 +1,49 @@
1
1
  export class TypedDb {
2
2
  db;
3
+ cache = new Map();
3
4
  constructor(db) {
4
5
  this.db = db;
5
6
  }
6
- prepare(sql) {
7
+ makeStatement(sql) {
7
8
  const stmt = this.db.prepare(sql);
9
+ const materializeParams = (...params) => [
10
+ ...params,
11
+ ];
8
12
  return {
9
- all: (...params) => stmt.all(...params),
10
- get: (...params) => stmt.get(...params),
11
- run: (...params) => stmt.run(...params),
13
+ all: (...params) => stmt.all(...materializeParams(...params)),
14
+ get: (...params) => stmt.get(...materializeParams(...params)),
15
+ run: (...params) => stmt.run(...materializeParams(...params)),
12
16
  };
13
17
  }
18
+ prepare(sql) {
19
+ return this.makeStatement(sql);
20
+ }
21
+ prepareOnce(sql) {
22
+ const cached = this.cache.get(sql);
23
+ if (cached !== undefined) {
24
+ return cached;
25
+ }
26
+ const stmt = this.makeStatement(sql);
27
+ this.cache.set(sql, stmt);
28
+ return stmt;
29
+ }
30
+ transaction(action) {
31
+ this.db.exec('BEGIN IMMEDIATE');
32
+ try {
33
+ const result = action();
34
+ this.db.exec('COMMIT');
35
+ return result;
36
+ }
37
+ catch (err) {
38
+ this.db.exec('ROLLBACK');
39
+ throw err;
40
+ }
41
+ }
14
42
  exec(sql) {
15
43
  this.db.exec(sql);
16
44
  }
17
45
  close() {
46
+ this.cache.clear();
18
47
  this.db.close();
19
48
  }
20
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"typed.js","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAYA,MAAM,OAAO,OAAO;IACW;IAA7B,YAA6B,EAAgB;QAAhB,OAAE,GAAF,EAAE,CAAc;IAAG,CAAC;IAEjD,OAAO,CAAI,GAAW;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO;YACL,GAAG,EAAE,CAAC,GAAG,MAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAQ;YAC/D,GAAG,EAAE,CAAC,GAAG,MAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAkB;YACzE,GAAG,EAAE,CAAC,GAAG,MAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAC,EAAgB;IAC5C,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"typed.js","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,OAAO;IAGW;IAFZ,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;IAEpE,YAA6B,EAAgB;QAAhB,OAAE,GAAF,EAAE,CAAc;IAAG,CAAC;IAEzC,aAAa,CAAI,GAAW;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,iBAAiB,GAAG,CAAC,GAAG,MAAiB,EAAmB,EAAE,CAAC;YACnE,GAAG,MAAM;SACV,CAAC;QACF,OAAO;YACL,GAAG,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE,CAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAQ;YAClD,GAAG,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE,CAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAkB;YAC5D,GAAG,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAC;SACzE,CAAC;IACJ,CAAC;IAED,OAAO,CAAI,GAAW;QACpB,OAAO,IAAI,CAAC,aAAa,CAAI,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,WAAW,CAAI,GAAW;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAA2B,CAAC;QACrC,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAI,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW,CAAI,MAAe;QAC5B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAC,EAAgB;IAC5C,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
package/dist/index.js CHANGED
@@ -2,15 +2,13 @@
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
3
  import process from 'node:process';
4
4
  import { initTypedDatabase } from './db/index.js';
5
+ import { getErrorMessage } from './lib/errors.js';
5
6
  import { createServer } from './server.js';
6
7
  const MEMORY_DB_PATH = process.env['MEMORY_DB_PATH'] ?? 'memory.db';
7
8
  const SHUTDOWN_SIGNALS = ['SIGINT', 'SIGTERM'];
8
9
  const SHUTDOWN_TIMEOUT_MS = 3000;
9
10
  const FORCED_EXIT_CODE = 1;
10
11
  const CLEAN_EXIT_CODE = 0;
11
- function formatFatalError(err) {
12
- return err instanceof Error ? err.message : String(err);
13
- }
14
12
  function registerShutdownHandlers(shutdown) {
15
13
  for (const signal of SHUTDOWN_SIGNALS) {
16
14
  process.on(signal, shutdown);
@@ -24,16 +22,23 @@ function scheduleForcedShutdown() {
24
22
  timer.unref();
25
23
  return timer;
26
24
  }
27
- async function runShutdown(server, db) {
28
- const timer = scheduleForcedShutdown();
25
+ async function closeServer(server) {
29
26
  try {
30
27
  await server.close();
31
28
  }
32
29
  catch {
33
30
  // ignore close errors
34
31
  }
35
- db.close();
36
- clearTimeout(timer);
32
+ }
33
+ async function runShutdown(server, db) {
34
+ const timer = scheduleForcedShutdown();
35
+ try {
36
+ await closeServer(server);
37
+ db.close();
38
+ }
39
+ finally {
40
+ clearTimeout(timer);
41
+ }
37
42
  process.exit(CLEAN_EXIT_CODE);
38
43
  }
39
44
  function createShutdownHandler(server, db) {
@@ -54,7 +59,7 @@ async function main() {
54
59
  await server.connect(transport);
55
60
  }
56
61
  main().catch((err) => {
57
- process.stderr.write(`Fatal error: ${formatFatalError(err)}\n`);
62
+ process.stderr.write(`Fatal error: ${getErrorMessage(err)}\n`);
58
63
  process.exit(FORCED_EXIT_CODE);
59
64
  });
60
65
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,WAAW,CAAC;AACpE,MAAM,gBAAgB,GAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACjE,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,SAAS,gBAAgB,CAAC,GAAY;IACpC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,wBAAwB,CAAC,QAAoB;IACpD,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACjC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACxB,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAuC,EACvC,EAAwC;IAExC,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;IACD,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,YAAY,CAAC,KAAK,CAAC,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAAuC,EACvC,EAAwC;IAExC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,OAAO,GAAG,EAAE;QACV,IAAI,cAAc;YAAE,OAAO;QAC3B,cAAc,GAAG,IAAI,CAAC;QACtB,KAAK,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnD,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAEnC,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,WAAW,CAAC;AACpE,MAAM,gBAAgB,GAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACjE,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,SAAS,wBAAwB,CAAC,QAAoB;IACpD,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACjC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACxB,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAuC;IAEvC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAuC,EACvC,EAAwC;IAExC,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1B,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAAuC,EACvC,EAAwC;IAExC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,OAAO,GAAG,EAAE;QACV,IAAI,cAAc;YAAE,OAAO;QAC3B,cAAc,GAAG,IAAI,CAAC;QACtB,KAAK,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnD,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAEnC,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC"}
@@ -1,5 +1,9 @@
1
1
  export declare const E_NOT_FOUND = "E_NOT_FOUND";
2
2
  export declare const E_INVALID_CURSOR = "E_INVALID_CURSOR";
3
+ export declare const E_DB_ERROR = "E_DB_ERROR";
4
+ export declare const E_CONFLICT = "E_CONFLICT";
5
+ export declare const E_CANCELLED = "E_CANCELLED";
3
6
  export declare const E_UNKNOWN = "E_UNKNOWN";
4
7
  export declare function getErrorMessage(err: unknown): string;
8
+ export declare function rethrowMcpError(err: unknown): void;
5
9
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAKpD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,UAAU,eAAe,CAAC;AACvC,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,SAAS,cAAc,CAAC;AAGrC,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAIpD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAElD"}
@@ -1,12 +1,20 @@
1
+ import { McpError } from '@modelcontextprotocol/sdk/types.js';
1
2
  export const E_NOT_FOUND = 'E_NOT_FOUND';
2
3
  export const E_INVALID_CURSOR = 'E_INVALID_CURSOR';
4
+ export const E_DB_ERROR = 'E_DB_ERROR';
5
+ export const E_CONFLICT = 'E_CONFLICT';
6
+ export const E_CANCELLED = 'E_CANCELLED';
3
7
  export const E_UNKNOWN = 'E_UNKNOWN';
8
+ const UNKNOWN_ERROR_MESSAGE = 'Unknown error occurred';
4
9
  export function getErrorMessage(err) {
5
10
  if (err instanceof Error)
6
11
  return err.message;
7
- const errorAsString = typeof err === 'string' ? err : undefined;
8
- if (errorAsString != null)
9
- return errorAsString;
10
- return 'Unknown error occurred';
12
+ if (typeof err === 'string')
13
+ return err;
14
+ return UNKNOWN_ERROR_MESSAGE;
15
+ }
16
+ export function rethrowMcpError(err) {
17
+ if (err instanceof McpError)
18
+ throw err;
11
19
  }
12
20
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AAErC,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC7C,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;IAChE,IAAI,aAAa,IAAI,IAAI;QAAE,OAAO,aAAa,CAAC;IAChD,OAAO,wBAAwB,CAAC;AAClC,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAE9D,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC;AACvC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AACrC,MAAM,qBAAqB,GAAG,wBAAwB,CAAC;AAEvD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAC;IAC7C,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,QAAQ;QAAE,MAAM,GAAG,CAAC;AACzC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/lib/hash.ts"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,MAAM,CAKR"}
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/lib/hash.ts"],"names":[],"mappings":"AAgBA,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,MAAM,CAKR"}
package/dist/lib/hash.js CHANGED
@@ -1,11 +1,18 @@
1
1
  import { createHash } from 'node:crypto';
2
+ const MEMORY_HASH_ALGORITHM = 'sha256';
2
3
  function normalizeTags(tags) {
4
+ if (tags.length < 2) {
5
+ return tags;
6
+ }
3
7
  return [...tags].sort();
4
8
  }
9
+ function stableTagsJson(tags) {
10
+ return JSON.stringify(normalizeTags(tags));
11
+ }
5
12
  export function computeMemoryHash(content, tags) {
6
- return createHash('sha256')
13
+ return createHash(MEMORY_HASH_ALGORITHM)
7
14
  .update(content)
8
- .update(JSON.stringify(normalizeTags(tags)))
15
+ .update(stableTagsJson(tags))
9
16
  .digest('hex');
10
17
  }
11
18
  //# sourceMappingURL=hash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/lib/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,SAAS,aAAa,CAAC,IAAuB;IAC5C,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,IAAuB;IAEvB,OAAO,UAAU,CAAC,QAAQ,CAAC;SACxB,MAAM,CAAC,OAAO,CAAC;SACf,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;SAC3C,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/lib/hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,qBAAqB,GAAG,QAAQ,CAAC;AAEvC,SAAS,aAAa,CAAC,IAAuB;IAC5C,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,IAAuB;IAC7C,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,IAAuB;IAEvB,OAAO,UAAU,CAAC,qBAAqB,CAAC;SACrC,MAAM,CAAC,OAAO,CAAC;SACf,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;SAC5B,MAAM,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function loadInstructions(): string;
2
+ //# sourceMappingURL=instructions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/lib/instructions.ts"],"names":[],"mappings":"AAwEA,wBAAgB,gBAAgB,IAAI,MAAM,CA+BzC"}