@j0hanz/memory-mcp 1.3.0 → 1.4.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 (174) hide show
  1. package/README.md +8 -8
  2. package/dist/completions/index.d.ts +0 -1
  3. package/dist/completions/index.js +4 -3
  4. package/dist/db/index.d.ts +0 -1
  5. package/dist/db/index.js +14 -9
  6. package/dist/db/typed.d.ts +0 -1
  7. package/dist/db/typed.js +3 -7
  8. package/dist/index.d.ts +0 -1
  9. package/dist/index.js +29 -2
  10. package/dist/lib/errors.d.ts +2 -1
  11. package/dist/lib/errors.js +4 -2
  12. package/dist/lib/hash.d.ts +0 -1
  13. package/dist/lib/hash.js +2 -2
  14. package/dist/lib/instructions.d.ts +0 -1
  15. package/dist/lib/instructions.js +1 -5
  16. package/dist/lib/json-schema.d.ts +3 -0
  17. package/dist/lib/json-schema.js +9 -0
  18. package/dist/lib/mcp-utils.d.ts +0 -1
  19. package/dist/lib/mcp-utils.js +5 -3
  20. package/dist/lib/pagination.d.ts +0 -1
  21. package/dist/lib/pagination.js +4 -2
  22. package/dist/lib/search-cursor.d.ts +0 -1
  23. package/dist/lib/search-cursor.js +2 -2
  24. package/dist/lib/search.d.ts +0 -1
  25. package/dist/lib/search.js +12 -11
  26. package/dist/lib/sql.d.ts +1 -2
  27. package/dist/lib/sql.js +5 -2
  28. package/dist/lib/tool-contracts.d.ts +0 -1
  29. package/dist/lib/tool-contracts.js +15 -15
  30. package/dist/lib/tool-response.d.ts +0 -1
  31. package/dist/lib/tool-response.js +4 -3
  32. package/dist/lib/types.d.ts +0 -1
  33. package/dist/lib/types.js +2 -2
  34. package/dist/prompts/index.d.ts +0 -1
  35. package/dist/prompts/index.js +1 -2
  36. package/dist/resources/index.d.ts +0 -1
  37. package/dist/resources/index.js +59 -61
  38. package/dist/resources/instructions.d.ts +0 -1
  39. package/dist/resources/instructions.js +58 -60
  40. package/dist/resources/server-config.d.ts +0 -1
  41. package/dist/resources/server-config.js +11 -7
  42. package/dist/resources/tool-catalog.d.ts +0 -1
  43. package/dist/resources/tool-catalog.js +7 -18
  44. package/dist/resources/tool-info.d.ts +0 -1
  45. package/dist/resources/tool-info.js +12 -20
  46. package/dist/resources/workflows.d.ts +0 -1
  47. package/dist/resources/workflows.js +6 -4
  48. package/dist/schemas/index.d.ts +0 -1
  49. package/dist/schemas/index.js +1 -2
  50. package/dist/schemas/inputs.d.ts +17 -25
  51. package/dist/schemas/inputs.js +19 -7
  52. package/dist/schemas/outputs.d.ts +0 -1
  53. package/dist/schemas/outputs.js +3 -3
  54. package/dist/server.d.ts +0 -1
  55. package/dist/server.js +16 -13
  56. package/dist/tools/create-relationship.d.ts +0 -1
  57. package/dist/tools/create-relationship.js +26 -22
  58. package/dist/tools/delete-memories.d.ts +0 -1
  59. package/dist/tools/delete-memories.js +4 -12
  60. package/dist/tools/delete-memory.d.ts +0 -1
  61. package/dist/tools/delete-memory.js +4 -12
  62. package/dist/tools/delete-relationship.d.ts +0 -1
  63. package/dist/tools/delete-relationship.js +4 -12
  64. package/dist/tools/get-memory.d.ts +0 -1
  65. package/dist/tools/get-memory.js +4 -12
  66. package/dist/tools/get-relationships.d.ts +0 -1
  67. package/dist/tools/get-relationships.js +7 -13
  68. package/dist/tools/index.d.ts +0 -1
  69. package/dist/tools/index.js +2 -3
  70. package/dist/tools/memory-stats.d.ts +0 -1
  71. package/dist/tools/memory-stats.js +4 -12
  72. package/dist/tools/progress.d.ts +2 -2
  73. package/dist/tools/progress.js +2 -2
  74. package/dist/tools/recall.d.ts +0 -1
  75. package/dist/tools/recall.js +47 -49
  76. package/dist/tools/register-contract.d.ts +3 -0
  77. package/dist/tools/register-contract.js +11 -0
  78. package/dist/tools/result.d.ts +1 -1
  79. package/dist/tools/result.js +4 -1
  80. package/dist/tools/retrieve-context.d.ts +0 -1
  81. package/dist/tools/retrieve-context.js +6 -14
  82. package/dist/tools/search-memories.d.ts +0 -1
  83. package/dist/tools/search-memories.js +4 -12
  84. package/dist/tools/store-memories.d.ts +0 -1
  85. package/dist/tools/store-memories.js +4 -12
  86. package/dist/tools/store-memory.d.ts +0 -1
  87. package/dist/tools/store-memory.js +4 -12
  88. package/dist/tools/update-memory.d.ts +0 -1
  89. package/dist/tools/update-memory.js +4 -12
  90. package/package.json +9 -6
  91. package/dist/completions/index.d.ts.map +0 -1
  92. package/dist/completions/index.js.map +0 -1
  93. package/dist/db/index.d.ts.map +0 -1
  94. package/dist/db/index.js.map +0 -1
  95. package/dist/db/typed.d.ts.map +0 -1
  96. package/dist/db/typed.js.map +0 -1
  97. package/dist/index.d.ts.map +0 -1
  98. package/dist/index.js.map +0 -1
  99. package/dist/lib/errors.d.ts.map +0 -1
  100. package/dist/lib/errors.js.map +0 -1
  101. package/dist/lib/hash.d.ts.map +0 -1
  102. package/dist/lib/hash.js.map +0 -1
  103. package/dist/lib/instructions.d.ts.map +0 -1
  104. package/dist/lib/instructions.js.map +0 -1
  105. package/dist/lib/mcp-utils.d.ts.map +0 -1
  106. package/dist/lib/mcp-utils.js.map +0 -1
  107. package/dist/lib/pagination.d.ts.map +0 -1
  108. package/dist/lib/pagination.js.map +0 -1
  109. package/dist/lib/search-cursor.d.ts.map +0 -1
  110. package/dist/lib/search-cursor.js.map +0 -1
  111. package/dist/lib/search.d.ts.map +0 -1
  112. package/dist/lib/search.js.map +0 -1
  113. package/dist/lib/sql.d.ts.map +0 -1
  114. package/dist/lib/sql.js.map +0 -1
  115. package/dist/lib/tool-contracts.d.ts.map +0 -1
  116. package/dist/lib/tool-contracts.js.map +0 -1
  117. package/dist/lib/tool-response.d.ts.map +0 -1
  118. package/dist/lib/tool-response.js.map +0 -1
  119. package/dist/lib/types.d.ts.map +0 -1
  120. package/dist/lib/types.js.map +0 -1
  121. package/dist/prompts/index.d.ts.map +0 -1
  122. package/dist/prompts/index.js.map +0 -1
  123. package/dist/resources/index.d.ts.map +0 -1
  124. package/dist/resources/index.js.map +0 -1
  125. package/dist/resources/instructions.d.ts.map +0 -1
  126. package/dist/resources/instructions.js.map +0 -1
  127. package/dist/resources/server-config.d.ts.map +0 -1
  128. package/dist/resources/server-config.js.map +0 -1
  129. package/dist/resources/tool-catalog.d.ts.map +0 -1
  130. package/dist/resources/tool-catalog.js.map +0 -1
  131. package/dist/resources/tool-info.d.ts.map +0 -1
  132. package/dist/resources/tool-info.js.map +0 -1
  133. package/dist/resources/workflows.d.ts.map +0 -1
  134. package/dist/resources/workflows.js.map +0 -1
  135. package/dist/schemas/index.d.ts.map +0 -1
  136. package/dist/schemas/index.js.map +0 -1
  137. package/dist/schemas/inputs.d.ts.map +0 -1
  138. package/dist/schemas/inputs.js.map +0 -1
  139. package/dist/schemas/outputs.d.ts.map +0 -1
  140. package/dist/schemas/outputs.js.map +0 -1
  141. package/dist/server.d.ts.map +0 -1
  142. package/dist/server.js.map +0 -1
  143. package/dist/tools/create-relationship.d.ts.map +0 -1
  144. package/dist/tools/create-relationship.js.map +0 -1
  145. package/dist/tools/delete-memories.d.ts.map +0 -1
  146. package/dist/tools/delete-memories.js.map +0 -1
  147. package/dist/tools/delete-memory.d.ts.map +0 -1
  148. package/dist/tools/delete-memory.js.map +0 -1
  149. package/dist/tools/delete-relationship.d.ts.map +0 -1
  150. package/dist/tools/delete-relationship.js.map +0 -1
  151. package/dist/tools/get-memory.d.ts.map +0 -1
  152. package/dist/tools/get-memory.js.map +0 -1
  153. package/dist/tools/get-relationships.d.ts.map +0 -1
  154. package/dist/tools/get-relationships.js.map +0 -1
  155. package/dist/tools/index.d.ts.map +0 -1
  156. package/dist/tools/index.js.map +0 -1
  157. package/dist/tools/memory-stats.d.ts.map +0 -1
  158. package/dist/tools/memory-stats.js.map +0 -1
  159. package/dist/tools/progress.d.ts.map +0 -1
  160. package/dist/tools/progress.js.map +0 -1
  161. package/dist/tools/recall.d.ts.map +0 -1
  162. package/dist/tools/recall.js.map +0 -1
  163. package/dist/tools/result.d.ts.map +0 -1
  164. package/dist/tools/result.js.map +0 -1
  165. package/dist/tools/retrieve-context.d.ts.map +0 -1
  166. package/dist/tools/retrieve-context.js.map +0 -1
  167. package/dist/tools/search-memories.d.ts.map +0 -1
  168. package/dist/tools/search-memories.js.map +0 -1
  169. package/dist/tools/store-memories.d.ts.map +0 -1
  170. package/dist/tools/store-memories.js.map +0 -1
  171. package/dist/tools/store-memory.d.ts.map +0 -1
  172. package/dist/tools/store-memory.js.map +0 -1
  173. package/dist/tools/update-memory.d.ts.map +0 -1
  174. package/dist/tools/update-memory.js.map +0 -1
@@ -70,6 +70,23 @@ const RECALL_MEMORY_TYPE_DESCRIPTION = 'Memory type filter';
70
70
  function describeImportanceFilter(description) {
71
71
  return IMPORTANCE_FILTER_SCHEMA.clone().describe(description);
72
72
  }
73
+ function createSearchFilterFields(descriptions) {
74
+ return {
75
+ min_importance: describeImportanceFilter(descriptions.min),
76
+ max_importance: describeImportanceFilter(descriptions.max),
77
+ memory_type: MEMORY_TYPE_SCHEMA.optional().describe(descriptions.type),
78
+ };
79
+ }
80
+ const SEARCH_FILTER_FIELDS = createSearchFilterFields({
81
+ min: SEARCH_MIN_IMPORTANCE_DESCRIPTION,
82
+ max: SEARCH_MAX_IMPORTANCE_DESCRIPTION,
83
+ type: SEARCH_MEMORY_TYPE_DESCRIPTION,
84
+ });
85
+ const RECALL_FILTER_FIELDS = createSearchFilterFields({
86
+ min: RECALL_MIN_IMPORTANCE_DESCRIPTION,
87
+ max: RECALL_MAX_IMPORTANCE_DESCRIPTION,
88
+ type: RECALL_MEMORY_TYPE_DESCRIPTION,
89
+ });
73
90
  const STORE_MEMORY_SHAPE = {
74
91
  content: CONTENT_SCHEMA,
75
92
  tags: TAGS_ARRAY_SCHEMA,
@@ -132,9 +149,7 @@ export const SearchMemoriesInputSchema = z
132
149
  .prefault(20)
133
150
  .describe('Max results (default 20)'),
134
151
  cursor: CURSOR_SCHEMA.optional().describe(CURSOR_DESCRIPTION),
135
- min_importance: describeImportanceFilter(SEARCH_MIN_IMPORTANCE_DESCRIPTION),
136
- max_importance: describeImportanceFilter(SEARCH_MAX_IMPORTANCE_DESCRIPTION),
137
- memory_type: MEMORY_TYPE_SCHEMA.optional().describe(SEARCH_MEMORY_TYPE_DESCRIPTION),
152
+ ...SEARCH_FILTER_FIELDS,
138
153
  })
139
154
  .describe('Search memories');
140
155
  export const RecallInputSchema = z
@@ -155,9 +170,7 @@ export const RecallInputSchema = z
155
170
  .prefault(10)
156
171
  .describe('Max seed memories (default 10)'),
157
172
  cursor: CURSOR_SCHEMA.optional().describe(CURSOR_DESCRIPTION),
158
- min_importance: describeImportanceFilter(RECALL_MIN_IMPORTANCE_DESCRIPTION),
159
- max_importance: describeImportanceFilter(RECALL_MAX_IMPORTANCE_DESCRIPTION),
160
- memory_type: MEMORY_TYPE_SCHEMA.optional().describe(RECALL_MEMORY_TYPE_DESCRIPTION),
173
+ ...RECALL_FILTER_FIELDS,
161
174
  })
162
175
  .describe('Recall memories via graph traversal');
163
176
  export const RetrieveContextInputSchema = z
@@ -204,4 +217,3 @@ export const DeleteRelationshipInputSchema = z
204
217
  export const MemoryStatsInputSchema = z
205
218
  .strictObject({})
206
219
  .describe('Get memory stats');
207
- //# sourceMappingURL=inputs.js.map
@@ -145,4 +145,3 @@ export declare const RetrieveContextResultSchema: z.ZodObject<{
145
145
  estimated_tokens: z.ZodNumber;
146
146
  truncated: z.ZodBoolean;
147
147
  }, z.core.$strict>;
148
- //# sourceMappingURL=outputs.d.ts.map
@@ -2,6 +2,7 @@ import { z } from 'zod/v4';
2
2
  const STRING_SCHEMA = z.string();
3
3
  const NUMBER_SCHEMA = z.number();
4
4
  const BOOLEAN_SCHEMA = z.boolean();
5
+ const STRING_ARRAY_SCHEMA = z.array(STRING_SCHEMA);
5
6
  export const ErrorResultSchema = z
6
7
  .strictObject({
7
8
  code: STRING_SCHEMA.describe('Error code'),
@@ -12,7 +13,7 @@ export const MemorySchema = z
12
13
  .strictObject({
13
14
  hash: STRING_SCHEMA.describe('SHA-256 hash'),
14
15
  content: STRING_SCHEMA.describe('Memory content'),
15
- tags: z.array(STRING_SCHEMA).describe('Memory tags'),
16
+ tags: STRING_ARRAY_SCHEMA.describe('Memory tags'),
16
17
  memory_type: STRING_SCHEMA.describe('Memory type'),
17
18
  importance: NUMBER_SCHEMA.describe('Importance (0-10)'),
18
19
  created_at: STRING_SCHEMA.describe('Created at'),
@@ -77,7 +78,7 @@ export const RelationshipWithMemorySchema = z
77
78
  created_at: z.string().describe('Created at'),
78
79
  linked_hash: z.string().describe('Linked memory hash'),
79
80
  linked_content: z.string().describe('Linked memory content'),
80
- linked_tags: z.array(z.string()).describe('Linked memory tags'),
81
+ linked_tags: STRING_ARRAY_SCHEMA.describe('Linked memory tags'),
81
82
  })
82
83
  .describe('Relationship edge with linked memory');
83
84
  export const RelationshipResultSchema = z
@@ -132,4 +133,3 @@ export const RetrieveContextResultSchema = z
132
133
  truncated: BOOLEAN_SCHEMA.describe('True if truncated by budget'),
133
134
  })
134
135
  .describe('Retrieve context result');
135
- //# sourceMappingURL=outputs.js.map
package/dist/server.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from './db/typed.js';
3
3
  export declare function createServer(db: TypedDb): McpServer;
4
- //# sourceMappingURL=server.d.ts.map
package/dist/server.js CHANGED
@@ -14,14 +14,22 @@ const SERVER_NAME = 'memory-mcp';
14
14
  const SERVER_CAPABILITIES = {
15
15
  logging: {},
16
16
  completions: {},
17
- resources: { subscribe: true },
17
+ resources: {},
18
18
  prompts: {},
19
19
  tools: {},
20
- tasks: {
21
- list: {},
22
- cancel: {},
23
- },
24
20
  };
21
+ function getIconAssetCandidates() {
22
+ return [
23
+ new URL(`../assets/${ICON_ASSET}`, import.meta.url),
24
+ new URL(`./assets/${ICON_ASSET}`, import.meta.url),
25
+ ];
26
+ }
27
+ function isOversizedIcon(byteLength) {
28
+ return byteLength >= MAX_ICON_BYTES;
29
+ }
30
+ function toIconDataUri(bytes) {
31
+ return `data:${ICON_MIME};base64,${bytes.toString('base64')}`;
32
+ }
25
33
  function parsePackageManifest(contents) {
26
34
  return JSON.parse(contents);
27
35
  }
@@ -33,19 +41,15 @@ function loadPackageManifest() {
33
41
  return parsePackageManifest(readFileSync(pkgPath, 'utf-8'));
34
42
  }
35
43
  function getLocalIconData() {
36
- const candidates = [
37
- new URL(`../assets/${ICON_ASSET}`, import.meta.url),
38
- new URL(`./assets/${ICON_ASSET}`, import.meta.url),
39
- ];
40
- for (const candidate of candidates) {
44
+ for (const candidate of getIconAssetCandidates()) {
41
45
  try {
42
46
  const filePath = fileURLToPath(candidate);
43
47
  const buf = readFileSync(filePath);
44
- if (buf.byteLength >= MAX_ICON_BYTES) {
48
+ if (isOversizedIcon(buf.byteLength)) {
45
49
  console.warn(`Icon asset exceeds 2 MB (${buf.byteLength} bytes), skipping.`);
46
50
  return undefined;
47
51
  }
48
- return `data:${ICON_MIME};base64,${buf.toString('base64')}`;
52
+ return toIconDataUri(buf);
49
53
  }
50
54
  catch {
51
55
  // try next candidate
@@ -76,4 +80,3 @@ export function createServer(db) {
76
80
  registerAllPrompts(server);
77
81
  return server;
78
82
  }
79
- //# sourceMappingURL=server.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerCreateRelationship(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=create-relationship.d.ts.map
@@ -1,10 +1,10 @@
1
1
  import { E_NOT_FOUND, E_UNKNOWN, getErrorMessage, rethrowMcpError, } from '../lib/errors.js';
2
2
  import { logToolEvent } from '../lib/mcp-utils.js';
3
- import { getToolContract } from '../lib/tool-contracts.js';
4
3
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
- import {} from '../schemas/inputs.js';
6
- import {} from '../schemas/outputs.js';
4
+ import { CreateRelationshipInputSchema } from '../schemas/inputs.js';
5
+ import { CreateRelationshipResultSchema } from '../schemas/outputs.js';
7
6
  import { wrapToolHandler } from './progress.js';
7
+ import { registerToolWithContract } from './register-contract.js';
8
8
  const INSERT_RELATIONSHIP_SQL = `INSERT OR IGNORE INTO relationships (from_hash, to_hash, relation_type, created_at)
9
9
  VALUES (?, ?, ?, ?)`;
10
10
  const SELECT_HASHES_SQL = 'SELECT hash FROM memories WHERE hash IN (?, ?) LIMIT 2';
@@ -24,32 +24,37 @@ function getMissingEndpoint(db, params) {
24
24
  }
25
25
  return undefined;
26
26
  }
27
+ function createRelationshipTx(db, params) {
28
+ return db.transaction(() => {
29
+ const missing = getMissingEndpoint(db, params);
30
+ if (missing) {
31
+ return {
32
+ ok: false,
33
+ code: E_NOT_FOUND,
34
+ message: formatMemoryNotFound(missing.kind, missing.hash),
35
+ };
36
+ }
37
+ const now = new Date().toISOString();
38
+ const result = db
39
+ .prepareOnce(INSERT_RELATIONSHIP_SQL)
40
+ .run(params.from_hash, params.to_hash, params.relation_type, now);
41
+ return { ok: true, created: result.changes > 0 };
42
+ });
43
+ }
27
44
  export function registerCreateRelationship(server, db) {
28
- const contract = getToolContract('create_relationship');
29
- server.registerTool(contract.name, {
30
- title: contract.title,
31
- description: contract.description,
32
- inputSchema: contract.inputSchema,
33
- outputSchema: contract.outputSchema,
34
- annotations: contract.annotations,
35
- }, wrapToolHandler(async (params) => {
45
+ registerToolWithContract(server, 'create_relationship', CreateRelationshipInputSchema, CreateRelationshipResultSchema, wrapToolHandler(async (params) => {
36
46
  try {
37
- const missing = getMissingEndpoint(db, params);
38
- if (missing) {
39
- return createErrorResponse(E_NOT_FOUND, formatMemoryNotFound(missing.kind, missing.hash));
47
+ const txResult = createRelationshipTx(db, params);
48
+ if (!txResult.ok) {
49
+ return createErrorResponse(txResult.code, txResult.message);
40
50
  }
41
- const now = new Date().toISOString();
42
- const result = db
43
- .prepareOnce(INSERT_RELATIONSHIP_SQL)
44
- .run(params.from_hash, params.to_hash, params.relation_type, now);
45
- const created = result.changes > 0;
46
51
  await logToolEvent(server, 'create_relationship', {
47
52
  fromHash: params.from_hash,
48
53
  toHash: params.to_hash,
49
54
  relationType: params.relation_type,
50
- created,
55
+ created: txResult.created,
51
56
  });
52
- return createToolResponse({ created });
57
+ return createToolResponse({ created: txResult.created });
53
58
  }
54
59
  catch (err) {
55
60
  rethrowMcpError(err);
@@ -59,4 +64,3 @@ export function registerCreateRelationship(server, db) {
59
64
  progressMessage: (params) => `⊕ create_relationship: ${params.from_hash.slice(0, 8)}... -> ${params.to_hash.slice(0, 8)}... [${params.relation_type}]`,
60
65
  }));
61
66
  }
62
- //# sourceMappingURL=create-relationship.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerDeleteMemories(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=delete-memories.d.ts.map
@@ -1,11 +1,11 @@
1
1
  import { E_UNKNOWN, getErrorMessage, rethrowMcpError } from '../lib/errors.js';
2
2
  import { logToolEvent, notifyMemoryResourceUpdated } from '../lib/mcp-utils.js';
3
3
  import { DELETE_MEMORY_SQL } from '../lib/sql.js';
4
- import { getToolContract } from '../lib/tool-contracts.js';
5
4
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
6
- import {} from '../schemas/inputs.js';
7
- import {} from '../schemas/outputs.js';
5
+ import { DeleteMemoriesInputSchema } from '../schemas/inputs.js';
6
+ import { BatchResultSchema } from '../schemas/outputs.js';
8
7
  import { wrapToolHandler } from './progress.js';
8
+ import { registerToolWithContract } from './register-contract.js';
9
9
  async function notifyDeletedResources(server, items) {
10
10
  const notifications = items
11
11
  .filter((item) => item.deleted)
@@ -13,14 +13,7 @@ async function notifyDeletedResources(server, items) {
13
13
  await Promise.allSettled(notifications);
14
14
  }
15
15
  export function registerDeleteMemories(server, db) {
16
- const contract = getToolContract('delete_memories');
17
- server.registerTool(contract.name, {
18
- title: contract.title,
19
- description: contract.description,
20
- inputSchema: contract.inputSchema,
21
- outputSchema: contract.outputSchema,
22
- annotations: contract.annotations,
23
- }, wrapToolHandler(async (params) => {
16
+ registerToolWithContract(server, 'delete_memories', DeleteMemoriesInputSchema, BatchResultSchema, wrapToolHandler(async (params) => {
24
17
  try {
25
18
  const results = db.transaction(() => {
26
19
  const items = [];
@@ -59,4 +52,3 @@ export function registerDeleteMemories(server, db) {
59
52
  progressMessage: (params) => `⊖ delete_memories: ${params.hashes.length} hashes [batch]`,
60
53
  }));
61
54
  }
62
- //# sourceMappingURL=delete-memories.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerDeleteMemory(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=delete-memory.d.ts.map
@@ -1,23 +1,16 @@
1
1
  import { E_UNKNOWN, getErrorMessage, rethrowMcpError } from '../lib/errors.js';
2
2
  import { logToolEvent, notifyMemoryResourceUpdated } from '../lib/mcp-utils.js';
3
3
  import { DELETE_MEMORY_SQL } from '../lib/sql.js';
4
- import { getToolContract } from '../lib/tool-contracts.js';
5
4
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
6
- import {} from '../schemas/inputs.js';
7
- import {} from '../schemas/outputs.js';
5
+ import { DeleteMemoryInputSchema } from '../schemas/inputs.js';
6
+ import { DeleteResultSchema } from '../schemas/outputs.js';
8
7
  import { wrapToolHandler } from './progress.js';
8
+ import { registerToolWithContract } from './register-contract.js';
9
9
  function deleteByHash(db, hash) {
10
10
  return db.prepareOnce(DELETE_MEMORY_SQL).run(hash).changes > 0;
11
11
  }
12
12
  export function registerDeleteMemory(server, db) {
13
- const contract = getToolContract('delete_memory');
14
- server.registerTool(contract.name, {
15
- title: contract.title,
16
- description: contract.description,
17
- inputSchema: contract.inputSchema,
18
- outputSchema: contract.outputSchema,
19
- annotations: contract.annotations,
20
- }, wrapToolHandler(async (params) => {
13
+ registerToolWithContract(server, 'delete_memory', DeleteMemoryInputSchema, DeleteResultSchema, wrapToolHandler(async (params) => {
21
14
  try {
22
15
  const deleted = deleteByHash(db, params.hash);
23
16
  if (deleted) {
@@ -34,4 +27,3 @@ export function registerDeleteMemory(server, db) {
34
27
  progressMessage: (params) => `⊖ delete_memory: ${params.hash.slice(0, 12)}... [single]`,
35
28
  }));
36
29
  }
37
- //# sourceMappingURL=delete-memory.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerDeleteRelationship(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=delete-relationship.d.ts.map
@@ -1,9 +1,9 @@
1
1
  import { E_NOT_FOUND, E_UNKNOWN, getErrorMessage, rethrowMcpError, } from '../lib/errors.js';
2
- import { getToolContract } from '../lib/tool-contracts.js';
3
2
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
4
- import {} from '../schemas/inputs.js';
5
- import {} from '../schemas/outputs.js';
3
+ import { DeleteRelationshipInputSchema } from '../schemas/inputs.js';
4
+ import { DeleteRelationshipResultSchema } from '../schemas/outputs.js';
6
5
  import { wrapToolHandler } from './progress.js';
6
+ import { registerToolWithContract } from './register-contract.js';
7
7
  const DELETE_RELATIONSHIP_SQL = 'DELETE FROM relationships WHERE from_hash = ? AND to_hash = ? AND relation_type = ?';
8
8
  const DELETE_RELATIONSHIP_RESULT = { deleted: true };
9
9
  function formatRelationship(params) {
@@ -18,14 +18,7 @@ function deleteRelationship(db, params) {
18
18
  .run(params.from_hash, params.to_hash, params.relation_type).changes > 0);
19
19
  }
20
20
  export function registerDeleteRelationship(server, db) {
21
- const contract = getToolContract('delete_relationship');
22
- server.registerTool(contract.name, {
23
- title: contract.title,
24
- description: contract.description,
25
- inputSchema: contract.inputSchema,
26
- outputSchema: contract.outputSchema,
27
- annotations: contract.annotations,
28
- }, wrapToolHandler((params) => {
21
+ registerToolWithContract(server, 'delete_relationship', DeleteRelationshipInputSchema, DeleteRelationshipResultSchema, wrapToolHandler((params) => {
29
22
  try {
30
23
  if (!deleteRelationship(db, params)) {
31
24
  return createErrorResponse(E_NOT_FOUND, createNotFoundRelationshipMessage(params));
@@ -40,4 +33,3 @@ export function registerDeleteRelationship(server, db) {
40
33
  progressMessage: (params) => `⊖ delete_relationship: ${params.from_hash.slice(0, 8)}... -> ${params.to_hash.slice(0, 8)}... [${params.relation_type}]`,
41
34
  }));
42
35
  }
43
- //# sourceMappingURL=delete-relationship.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerGetMemory(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=get-memory.d.ts.map
@@ -1,11 +1,11 @@
1
1
  import { E_NOT_FOUND, E_UNKNOWN, getErrorMessage, rethrowMcpError, } from '../lib/errors.js';
2
2
  import { SELECT_MEMORY_BY_HASH_SQL } from '../lib/sql.js';
3
- import { getToolContract } from '../lib/tool-contracts.js';
4
3
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
4
  import { parseMemoryRow } from '../lib/types.js';
6
- import {} from '../schemas/inputs.js';
7
- import {} from '../schemas/outputs.js';
5
+ import { GetMemoryInputSchema } from '../schemas/inputs.js';
6
+ import { MemoryResultSchema } from '../schemas/outputs.js';
8
7
  import { wrapToolHandler } from './progress.js';
8
+ import { registerToolWithContract } from './register-contract.js';
9
9
  function getMemoryRow(db, hash) {
10
10
  return db.prepareOnce(SELECT_MEMORY_BY_HASH_SQL).get(hash);
11
11
  }
@@ -13,14 +13,7 @@ function notFound(hash) {
13
13
  return createErrorResponse(E_NOT_FOUND, `Memory not found: ${hash}`);
14
14
  }
15
15
  export function registerGetMemory(server, db) {
16
- const contract = getToolContract('get_memory');
17
- server.registerTool(contract.name, {
18
- title: contract.title,
19
- description: contract.description,
20
- inputSchema: contract.inputSchema,
21
- outputSchema: contract.outputSchema,
22
- annotations: contract.annotations,
23
- }, wrapToolHandler((params) => {
16
+ registerToolWithContract(server, 'get_memory', GetMemoryInputSchema, MemoryResultSchema, wrapToolHandler((params) => {
24
17
  try {
25
18
  const row = getMemoryRow(db, params.hash);
26
19
  if (!row) {
@@ -37,4 +30,3 @@ export function registerGetMemory(server, db) {
37
30
  progressMessage: (params) => `⊙ get_memory: ${params.hash.slice(0, 12)}... [single]`,
38
31
  }));
39
32
  }
40
- //# sourceMappingURL=get-memory.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerGetRelationships(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=get-relationships.d.ts.map
@@ -1,11 +1,11 @@
1
1
  import { E_NOT_FOUND, E_UNKNOWN, getErrorMessage, rethrowMcpError, } from '../lib/errors.js';
2
2
  import { SELECT_MEMORY_HASH_SQL } from '../lib/sql.js';
3
- import { getToolContract } from '../lib/tool-contracts.js';
4
3
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
4
  import { parseTags } from '../lib/types.js';
6
- import {} from '../schemas/inputs.js';
7
- import {} from '../schemas/outputs.js';
5
+ import { GetRelationshipsInputSchema } from '../schemas/inputs.js';
6
+ import { RelationshipResultSchema } from '../schemas/outputs.js';
8
7
  import { wrapToolHandler } from './progress.js';
8
+ import { registerToolWithContract } from './register-contract.js';
9
9
  // Pre-defined SQL for each direction mode to maximise prepareOnce cache hits.
10
10
  const OUTGOING_SQL = `
11
11
  SELECT r.from_hash, r.to_hash, r.relation_type, r.created_at,
@@ -22,6 +22,7 @@ const INCOMING_SQL = `
22
22
  WHERE r.to_hash = ?
23
23
  ORDER BY r.created_at DESC`;
24
24
  // UNION ALL for 'both': single round-trip instead of two separate queries.
25
+ // Exclude self-loops from the second branch to avoid duplicate rows.
25
26
  const BOTH_SQL = `
26
27
  SELECT r.from_hash, r.to_hash, r.relation_type, r.created_at,
27
28
  m.hash AS linked_hash, m.content AS linked_content, m.tags AS linked_tags
@@ -34,6 +35,7 @@ const BOTH_SQL = `
34
35
  FROM relationships r
35
36
  JOIN memories m ON r.from_hash = m.hash
36
37
  WHERE r.to_hash = ?
38
+ AND r.from_hash != ?
37
39
  ORDER BY 4 DESC`;
38
40
  function memoryExists(db, hash) {
39
41
  return (db.prepareOnce(SELECT_MEMORY_HASH_SQL).get(hash) !==
@@ -41,7 +43,7 @@ function memoryExists(db, hash) {
41
43
  }
42
44
  function loadRelationships(db, hash, direction) {
43
45
  if (direction === 'both') {
44
- return db.prepareOnce(BOTH_SQL).all(hash, hash);
46
+ return db.prepareOnce(BOTH_SQL).all(hash, hash, hash);
45
47
  }
46
48
  const sql = direction === 'outgoing' ? OUTGOING_SQL : INCOMING_SQL;
47
49
  return db.prepareOnce(sql).all(hash);
@@ -58,14 +60,7 @@ function toRelationshipWithMemory(row) {
58
60
  };
59
61
  }
60
62
  export function registerGetRelationships(server, db) {
61
- const contract = getToolContract('get_relationships');
62
- server.registerTool(contract.name, {
63
- title: contract.title,
64
- description: contract.description,
65
- inputSchema: contract.inputSchema,
66
- outputSchema: contract.outputSchema,
67
- annotations: contract.annotations,
68
- }, wrapToolHandler((params) => {
63
+ registerToolWithContract(server, 'get_relationships', GetRelationshipsInputSchema, RelationshipResultSchema, wrapToolHandler((params) => {
69
64
  try {
70
65
  if (!memoryExists(db, params.hash)) {
71
66
  return createErrorResponse(E_NOT_FOUND, `Memory not found: ${params.hash}`);
@@ -85,4 +80,3 @@ export function registerGetRelationships(server, db) {
85
80
  progressMessage: (params) => `⊙ get_relationships: ${params.hash.slice(0, 12)}... [${params.direction}]`,
86
81
  }));
87
82
  }
88
- //# sourceMappingURL=get-relationships.js.map
@@ -4,4 +4,3 @@ type ToolRegistrar = (server: McpServer, db: TypedDb) => void;
4
4
  export declare const TOOL_REGISTRARS: readonly ToolRegistrar[];
5
5
  export declare function registerAllTools(server: McpServer, db: TypedDb): void;
6
6
  export {};
7
- //# sourceMappingURL=index.d.ts.map
@@ -27,8 +27,7 @@ export const TOOL_REGISTRARS = [
27
27
  registerRetrieveContext,
28
28
  ];
29
29
  export function registerAllTools(server, db) {
30
- for (const registerTool of TOOL_REGISTRARS) {
31
- registerTool(server, db);
30
+ for (const register of TOOL_REGISTRARS) {
31
+ register(server, db);
32
32
  }
33
33
  }
34
- //# sourceMappingURL=index.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerMemoryStats(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=memory-stats.d.ts.map
@@ -1,10 +1,10 @@
1
1
  import { E_UNKNOWN, getErrorMessage, rethrowMcpError } from '../lib/errors.js';
2
2
  import { MEMORY_AGGREGATE_SQL, RELATIONSHIP_COUNT_SQL, TYPE_COUNTS_SQL, } from '../lib/sql.js';
3
- import { getToolContract } from '../lib/tool-contracts.js';
4
3
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
- import {} from '../schemas/inputs.js';
6
- import {} from '../schemas/outputs.js';
4
+ import { MemoryStatsInputSchema } from '../schemas/inputs.js';
5
+ import { StatsResultSchema } from '../schemas/outputs.js';
7
6
  import { wrapToolHandler } from './progress.js';
7
+ import { registerToolWithContract } from './register-contract.js';
8
8
  function toTypeCounts(rows) {
9
9
  const byType = {};
10
10
  for (const row of rows) {
@@ -13,14 +13,7 @@ function toTypeCounts(rows) {
13
13
  return byType;
14
14
  }
15
15
  export function registerMemoryStats(server, db) {
16
- const contract = getToolContract('memory_stats');
17
- server.registerTool(contract.name, {
18
- title: contract.title,
19
- description: contract.description,
20
- inputSchema: contract.inputSchema,
21
- outputSchema: contract.outputSchema,
22
- annotations: contract.annotations,
23
- }, wrapToolHandler(() => {
16
+ registerToolWithContract(server, 'memory_stats', MemoryStatsInputSchema, StatsResultSchema, wrapToolHandler(() => {
24
17
  try {
25
18
  const aggregate = db
26
19
  .prepareOnce(MEMORY_AGGREGATE_SQL)
@@ -47,4 +40,3 @@ export function registerMemoryStats(server, db) {
47
40
  }
48
41
  }, { progressMessage: () => '⊙ memory_stats: [aggregate]' }));
49
42
  }
50
- //# sourceMappingURL=memory-stats.js.map
@@ -2,8 +2,9 @@ import type { CallToolResult, ProgressNotification } from '@modelcontextprotocol
2
2
  interface ProgressMeta {
3
3
  progressToken?: unknown;
4
4
  }
5
- interface ProgressContext {
5
+ export interface ProgressContext {
6
6
  _meta?: ProgressMeta;
7
+ signal?: AbortSignal;
7
8
  sendNotification?: (notification: ProgressNotification) => Promise<void>;
8
9
  }
9
10
  interface ProgressUpdate {
@@ -31,4 +32,3 @@ export declare function createProgressReporter(extra: ProgressContext, options?:
31
32
  export declare function progressWithMessage(reporter: ProgressReporter, getMessage: (progress: ProgressSnapshot) => string): ProgressReporter<ProgressSnapshot>;
32
33
  export declare function wrapToolHandler<TArgs>(handler: ToolHandler<TArgs>, options: WrappedHandlerOptions<TArgs>): ToolHandler<TArgs>;
33
34
  export {};
34
- //# sourceMappingURL=progress.d.ts.map
@@ -1,4 +1,5 @@
1
1
  import { E_CANCELLED } from '../lib/errors.js';
2
+ import { getToolResultText } from './result.js';
2
3
  const DEFAULT_PROGRESS_INTERVAL_MS = 250;
3
4
  function toProgressToken(value) {
4
5
  if (typeof value === 'string' || typeof value === 'number') {
@@ -21,7 +22,7 @@ function toNotificationParams(progressToken, progress) {
21
22
  }
22
23
  function getResultOutcome(result) {
23
24
  if (result.isError) {
24
- const text = result.content[0]?.type === 'text' ? result.content[0].text : '';
25
+ const text = getToolResultText(result);
25
26
  if (text.includes(E_CANCELLED)) {
26
27
  return 'cancelled';
27
28
  }
@@ -131,4 +132,3 @@ export function wrapToolHandler(handler, options) {
131
132
  return result;
132
133
  };
133
134
  }
134
- //# sourceMappingURL=progress.js.map
@@ -1,4 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { TypedDb } from '../db/typed.js';
3
3
  export declare function registerRecall(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=recall.d.ts.map