@j0hanz/memory-mcp 1.6.0 → 1.7.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 (120) hide show
  1. package/dist/completions/index.d.ts +0 -1
  2. package/dist/db/index.d.ts +0 -1
  3. package/dist/db/index.js +8 -7
  4. package/dist/db/typed.d.ts +0 -1
  5. package/dist/index.d.ts +0 -1
  6. package/dist/lib/errors.d.ts +4 -1
  7. package/dist/lib/errors.js +11 -0
  8. package/dist/lib/graph-traversal.d.ts +12 -0
  9. package/dist/lib/graph-traversal.js +145 -0
  10. package/dist/lib/hash.d.ts +0 -1
  11. package/dist/lib/instructions.d.ts +0 -1
  12. package/dist/lib/json-schema.d.ts +5 -1
  13. package/dist/lib/json-schema.js +19 -1
  14. package/dist/lib/mcp-utils.d.ts +0 -1
  15. package/dist/lib/pagination.d.ts +0 -3
  16. package/dist/lib/pagination.js +0 -43
  17. package/dist/lib/search-cursor.d.ts +0 -1
  18. package/dist/lib/search.d.ts +0 -1
  19. package/dist/lib/search.js +26 -13
  20. package/dist/lib/sql.d.ts +0 -1
  21. package/dist/lib/tool-contracts.d.ts +0 -1
  22. package/dist/lib/tool-contracts.js +40 -35
  23. package/dist/lib/tool-execution.d.ts +1 -1
  24. package/dist/lib/tool-execution.js +24 -1
  25. package/dist/lib/tool-response.d.ts +0 -1
  26. package/dist/lib/types.d.ts +0 -1
  27. package/dist/prompts/index.d.ts +0 -1
  28. package/dist/resources/index.d.ts +0 -1
  29. package/dist/resources/index.js +24 -27
  30. package/dist/resources/instructions.d.ts +0 -1
  31. package/dist/resources/server-config.d.ts +0 -1
  32. package/dist/resources/tool-catalog.d.ts +0 -1
  33. package/dist/resources/tool-catalog.js +1 -10
  34. package/dist/resources/tool-info.d.ts +0 -1
  35. package/dist/resources/tool-info.js +1 -10
  36. package/dist/resources/workflows.d.ts +0 -1
  37. package/dist/schemas/index.d.ts +0 -1
  38. package/dist/schemas/inputs.d.ts +8 -6
  39. package/dist/schemas/inputs.js +43 -30
  40. package/dist/schemas/outputs.d.ts +0 -1
  41. package/dist/server.d.ts +0 -1
  42. package/dist/tools/create-relationship.d.ts +0 -1
  43. package/dist/tools/create-relationship.js +4 -4
  44. package/dist/tools/delete-memories.d.ts +0 -1
  45. package/dist/tools/delete-memories.js +4 -3
  46. package/dist/tools/delete-memory.d.ts +0 -1
  47. package/dist/tools/delete-memory.js +6 -4
  48. package/dist/tools/delete-relationship.d.ts +0 -1
  49. package/dist/tools/delete-relationship.js +7 -17
  50. package/dist/tools/get-memory.d.ts +0 -1
  51. package/dist/tools/get-memory.js +4 -4
  52. package/dist/tools/get-relationships.d.ts +0 -1
  53. package/dist/tools/get-relationships.js +16 -12
  54. package/dist/tools/index.d.ts +0 -1
  55. package/dist/tools/memory-stats.d.ts +0 -1
  56. package/dist/tools/memory-stats.js +1 -3
  57. package/dist/tools/progress.d.ts +6 -1
  58. package/dist/tools/progress.js +38 -2
  59. package/dist/tools/recall.d.ts +0 -1
  60. package/dist/tools/recall.js +28 -166
  61. package/dist/tools/register-contract.d.ts +1 -3
  62. package/dist/tools/register-contract.js +4 -2
  63. package/dist/tools/result.d.ts +4 -1
  64. package/dist/tools/result.js +27 -0
  65. package/dist/tools/retrieve-context.d.ts +0 -1
  66. package/dist/tools/retrieve-context.js +42 -74
  67. package/dist/tools/search-memories.d.ts +0 -1
  68. package/dist/tools/search-memories.js +14 -11
  69. package/dist/tools/store-memories.d.ts +0 -1
  70. package/dist/tools/store-memories.js +2 -3
  71. package/dist/tools/store-memory.d.ts +0 -1
  72. package/dist/tools/store-memory.js +2 -3
  73. package/dist/tools/update-memory.d.ts +0 -1
  74. package/dist/tools/update-memory.js +7 -6
  75. package/package.json +1 -1
  76. package/dist/completions/index.d.ts.map +0 -1
  77. package/dist/db/index.d.ts.map +0 -1
  78. package/dist/db/typed.d.ts.map +0 -1
  79. package/dist/index.d.ts.map +0 -1
  80. package/dist/lib/errors.d.ts.map +0 -1
  81. package/dist/lib/hash.d.ts.map +0 -1
  82. package/dist/lib/instructions.d.ts.map +0 -1
  83. package/dist/lib/json-schema.d.ts.map +0 -1
  84. package/dist/lib/mcp-utils.d.ts.map +0 -1
  85. package/dist/lib/pagination.d.ts.map +0 -1
  86. package/dist/lib/search-cursor.d.ts.map +0 -1
  87. package/dist/lib/search.d.ts.map +0 -1
  88. package/dist/lib/sql.d.ts.map +0 -1
  89. package/dist/lib/tool-contracts.d.ts.map +0 -1
  90. package/dist/lib/tool-execution.d.ts.map +0 -1
  91. package/dist/lib/tool-response.d.ts.map +0 -1
  92. package/dist/lib/types.d.ts.map +0 -1
  93. package/dist/prompts/index.d.ts.map +0 -1
  94. package/dist/resources/index.d.ts.map +0 -1
  95. package/dist/resources/instructions.d.ts.map +0 -1
  96. package/dist/resources/server-config.d.ts.map +0 -1
  97. package/dist/resources/tool-catalog.d.ts.map +0 -1
  98. package/dist/resources/tool-info.d.ts.map +0 -1
  99. package/dist/resources/workflows.d.ts.map +0 -1
  100. package/dist/schemas/index.d.ts.map +0 -1
  101. package/dist/schemas/inputs.d.ts.map +0 -1
  102. package/dist/schemas/outputs.d.ts.map +0 -1
  103. package/dist/server.d.ts.map +0 -1
  104. package/dist/tools/create-relationship.d.ts.map +0 -1
  105. package/dist/tools/delete-memories.d.ts.map +0 -1
  106. package/dist/tools/delete-memory.d.ts.map +0 -1
  107. package/dist/tools/delete-relationship.d.ts.map +0 -1
  108. package/dist/tools/get-memory.d.ts.map +0 -1
  109. package/dist/tools/get-relationships.d.ts.map +0 -1
  110. package/dist/tools/index.d.ts.map +0 -1
  111. package/dist/tools/memory-stats.d.ts.map +0 -1
  112. package/dist/tools/progress.d.ts.map +0 -1
  113. package/dist/tools/recall.d.ts.map +0 -1
  114. package/dist/tools/register-contract.d.ts.map +0 -1
  115. package/dist/tools/result.d.ts.map +0 -1
  116. package/dist/tools/retrieve-context.d.ts.map +0 -1
  117. package/dist/tools/search-memories.d.ts.map +0 -1
  118. package/dist/tools/store-memories.d.ts.map +0 -1
  119. package/dist/tools/store-memory.d.ts.map +0 -1
  120. package/dist/tools/update-memory.d.ts.map +0 -1
@@ -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 registerAllResources(server: McpServer, db: TypedDb): void;
4
- //# sourceMappingURL=index.d.ts.map
@@ -104,6 +104,12 @@ const INSTRUCTIONS_CONTENT = loadInstructions();
104
104
  const TOOL_CATALOG_CONTENT = buildToolCatalog();
105
105
  const WORKFLOW_GUIDE_CONTENT = buildWorkflowGuide();
106
106
  const SERVER_CONFIG_CONTENT = buildServerConfig();
107
+ const STATIC_CONTENT_BY_KEY = {
108
+ instructions: INSTRUCTIONS_CONTENT,
109
+ toolCatalog: TOOL_CATALOG_CONTENT,
110
+ workflows: WORKFLOW_GUIDE_CONTENT,
111
+ serverConfig: SERVER_CONFIG_CONTENT,
112
+ };
107
113
  const STATIC_RESOURCE_SEEDS = [
108
114
  {
109
115
  name: 'instructions',
@@ -142,35 +148,19 @@ const STATIC_RESOURCE_SEEDS = [
142
148
  contentKey: 'serverConfig',
143
149
  },
144
150
  ];
145
- function resolveStaticResourceContent(contentKey) {
146
- switch (contentKey) {
147
- case 'instructions':
148
- return INSTRUCTIONS_CONTENT;
149
- case 'toolCatalog':
150
- return TOOL_CATALOG_CONTENT;
151
- case 'workflows':
152
- return WORKFLOW_GUIDE_CONTENT;
153
- case 'serverConfig':
154
- return SERVER_CONFIG_CONTENT;
155
- }
156
- }
157
151
  function getStaticMarkdownResources() {
158
152
  return STATIC_RESOURCE_SEEDS.map((seed) => ({
159
153
  ...seed,
160
- content: resolveStaticResourceContent(seed.contentKey),
154
+ content: STATIC_CONTENT_BY_KEY[seed.contentKey],
161
155
  }));
162
156
  }
163
- // --- Registration ---
164
- export function registerAllResources(server, db) {
165
- for (const config of getStaticMarkdownResources()) {
166
- registerStaticMarkdownResource(server, config);
167
- }
168
- // internal://tool-info/{toolName}
157
+ function completeToolName(value) {
158
+ return TOOL_NAMES.filter((toolName) => toolName.startsWith(value));
159
+ }
160
+ function registerToolInfoResource(server) {
169
161
  server.registerResource('tool-info', new ResourceTemplate(TOOL_INFO_URI_TEMPLATE, {
170
- list: () => listToolInfoResources(),
171
- complete: {
172
- toolName: (value) => TOOL_NAMES.filter((n) => n.startsWith(value)),
173
- },
162
+ list: listToolInfoResources,
163
+ complete: { toolName: completeToolName },
174
164
  }), {
175
165
  title: 'Tool Info',
176
166
  description: 'Per-tool detail: parameters, behavior, and output shape. Supports toolName auto-completion.',
@@ -179,11 +169,10 @@ export function registerAllResources(server, db) {
179
169
  }, (uri, variables) => {
180
170
  const toolName = requireSingleVariable(variables, 'toolName', 'Missing toolName parameter');
181
171
  const info = requireKnownToolInfo(toolName);
182
- return {
183
- contents: [createMarkdownContent(uri.href, info)],
184
- };
172
+ return { contents: [createMarkdownContent(uri.href, info)] };
185
173
  });
186
- // memory://memories/{hash}
174
+ }
175
+ function registerMemoryResource(server, db) {
187
176
  const hashCompletion = createHashCompletionCallback(db);
188
177
  server.registerResource('memory', new ResourceTemplate(MEMORY_RESOURCE_URI_TEMPLATE, {
189
178
  list: () => listMemoryResources(db),
@@ -204,3 +193,11 @@ export function registerAllResources(server, db) {
204
193
  };
205
194
  });
206
195
  }
196
+ // --- Registration ---
197
+ export function registerAllResources(server, db) {
198
+ for (const config of getStaticMarkdownResources()) {
199
+ registerStaticMarkdownResource(server, config);
200
+ }
201
+ registerToolInfoResource(server);
202
+ registerMemoryResource(server, db);
203
+ }
@@ -1,2 +1 @@
1
1
  export declare function buildServerInstructions(): string;
2
- //# sourceMappingURL=instructions.d.ts.map
@@ -1,2 +1 @@
1
1
  export declare function buildServerConfig(): string;
2
- //# sourceMappingURL=server-config.d.ts.map
@@ -1,2 +1 @@
1
1
  export declare function buildToolCatalog(): string;
2
- //# sourceMappingURL=tool-catalog.d.ts.map
@@ -1,15 +1,6 @@
1
- import { extractJsonSchema, } from '../lib/json-schema.js';
1
+ import { getSchemaMeta } from '../lib/json-schema.js';
2
2
  import { getToolContracts } from '../lib/tool-contracts.js';
3
3
  import { buildCoreContextPack } from './tool-info.js';
4
- function getSchemaMeta(schema) {
5
- const jsonSchema = extractJsonSchema(schema);
6
- return {
7
- properties: (jsonSchema['properties'] ?? {}),
8
- requiredFields: new Set(Array.isArray(jsonSchema['required'])
9
- ? jsonSchema['required']
10
- : []),
11
- };
12
- }
13
4
  function extractOptionalParams(toolName, schema) {
14
5
  const { properties, requiredFields } = getSchemaMeta(schema);
15
6
  const rows = [];
@@ -2,4 +2,3 @@ export declare function getSharedConstraints(): readonly string[];
2
2
  export declare function buildCoreContextPack(): string;
3
3
  export declare function getToolInfo(name: string): string | undefined;
4
4
  export declare function getToolNames(): string[];
5
- //# sourceMappingURL=tool-info.d.ts.map
@@ -1,4 +1,4 @@
1
- import { extractJsonSchema, } from '../lib/json-schema.js';
1
+ import { extractJsonSchema, getSchemaMeta, } from '../lib/json-schema.js';
2
2
  import { getToolContracts } from '../lib/tool-contracts.js';
3
3
  // --- Shared Constraints (Single Source of Truth) ---
4
4
  const SHARED_CONSTRAINTS = [
@@ -61,15 +61,6 @@ function formatParamConstraints(prop) {
61
61
  parts.push(`enum: ${prop['enum'].join(' | ')}`);
62
62
  return parts.length > 0 ? `; ${parts.join(', ')}` : '';
63
63
  }
64
- function getSchemaMeta(schema) {
65
- const jsonSchema = extractJsonSchema(schema);
66
- return {
67
- properties: (jsonSchema['properties'] ?? {}),
68
- requiredFields: new Set(Array.isArray(jsonSchema['required'])
69
- ? jsonSchema['required']
70
- : []),
71
- };
72
- }
73
64
  function getSortedSchemaProperties(properties) {
74
65
  return Object.entries(properties).sort(([a], [b]) => a.localeCompare(b));
75
66
  }
@@ -1,2 +1 @@
1
1
  export declare function buildWorkflowGuide(): string;
2
- //# sourceMappingURL=workflows.d.ts.map
@@ -1,3 +1,2 @@
1
1
  export * from './inputs.js';
2
2
  export * from './outputs.js';
3
- //# sourceMappingURL=index.d.ts.map
@@ -63,7 +63,7 @@ export declare const GetMemoryInputSchema: z.ZodObject<{
63
63
  }, z.core.$strict>;
64
64
  export declare const UpdateMemoryInputSchema: z.ZodObject<{
65
65
  hash: z.ZodString;
66
- content: z.ZodString;
66
+ content: z.ZodOptional<z.ZodString>;
67
67
  tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
68
  }, z.core.$strict>;
69
69
  export declare const DeleteMemoryInputSchema: z.ZodObject<{
@@ -77,7 +77,7 @@ export declare const SearchMemoriesInputSchema: z.ZodObject<{
77
77
  max_importance: z.ZodOptional<z.ZodNumber>;
78
78
  memory_type: z.ZodOptional<typeof MEMORY_TYPE_SCHEMA>;
79
79
  query: z.ZodString;
80
- limit: z.ZodPrefault<z.ZodOptional<z.ZodInt>>;
80
+ limit: z.ZodPrefault<z.ZodOptional<z.ZodNumber>>;
81
81
  cursor: z.ZodOptional<z.ZodString>;
82
82
  }, z.core.$strict>;
83
83
  export declare const RecallInputSchema: z.ZodObject<{
@@ -85,13 +85,16 @@ export declare const RecallInputSchema: z.ZodObject<{
85
85
  max_importance: z.ZodOptional<z.ZodNumber>;
86
86
  memory_type: z.ZodOptional<typeof MEMORY_TYPE_SCHEMA>;
87
87
  query: z.ZodString;
88
- depth: z.ZodPrefault<z.ZodOptional<z.ZodInt>>;
89
- limit: z.ZodPrefault<z.ZodOptional<z.ZodInt>>;
88
+ depth: z.ZodPrefault<z.ZodOptional<z.ZodNumber>>;
89
+ limit: z.ZodPrefault<z.ZodOptional<z.ZodNumber>>;
90
90
  cursor: z.ZodOptional<z.ZodString>;
91
91
  }, z.core.$strict>;
92
92
  export declare const RetrieveContextInputSchema: z.ZodObject<{
93
+ min_importance: z.ZodOptional<z.ZodNumber>;
94
+ max_importance: z.ZodOptional<z.ZodNumber>;
95
+ memory_type: z.ZodOptional<typeof MEMORY_TYPE_SCHEMA>;
93
96
  query: z.ZodString;
94
- token_budget: z.ZodPrefault<z.ZodOptional<z.ZodInt>>;
97
+ token_budget: z.ZodPrefault<z.ZodOptional<z.ZodNumber>>;
95
98
  strategy: z.ZodPrefault<z.ZodOptional<z.ZodEnum<{
96
99
  importance: "importance";
97
100
  recency: "recency";
@@ -118,4 +121,3 @@ export declare const DeleteRelationshipInputSchema: z.ZodObject<{
118
121
  }, z.core.$strict>;
119
122
  export declare const MemoryStatsInputSchema: z.ZodObject<{}, z.core.$strict>;
120
123
  export {};
121
- //# sourceMappingURL=inputs.d.ts.map
@@ -14,7 +14,6 @@ const TAG_SCHEMA = z
14
14
  .describe('Tag (no whitespace, max 50 chars)');
15
15
  const TAGS_ARRAY_SCHEMA = z
16
16
  .array(TAG_SCHEMA)
17
- .min(1, { error: 'At least one tag is required' })
18
17
  .max(100, { error: 'Maximum 100 tags allowed' })
19
18
  .describe('Memory tags');
20
19
  const MEMORY_TYPE_SCHEMA = z
@@ -70,6 +69,15 @@ const RECALL_MEMORY_TYPE_DESCRIPTION = 'Memory type filter';
70
69
  function describeHash(label) {
71
70
  return HASH_SCHEMA.describe(label);
72
71
  }
72
+ function createPrefaultIntField(config) {
73
+ return z
74
+ .int()
75
+ .min(config.min)
76
+ .max(config.max)
77
+ .optional()
78
+ .prefault(config.prefault)
79
+ .describe(config.description);
80
+ }
73
81
  function describeImportanceFilter(description) {
74
82
  return IMPORTANCE_FILTER_SCHEMA.clone().describe(description);
75
83
  }
@@ -123,8 +131,11 @@ export const GetMemoryInputSchema = z
123
131
  export const UpdateMemoryInputSchema = z
124
132
  .strictObject({
125
133
  hash: describeHash('SHA-256 hash'),
126
- content: CONTENT_SCHEMA,
134
+ content: CONTENT_SCHEMA.optional(),
127
135
  tags: TAGS_ARRAY_SCHEMA.optional(),
136
+ })
137
+ .refine((data) => data.content !== undefined || data.tags !== undefined, {
138
+ error: 'At least one of content or tags must be provided',
128
139
  })
129
140
  .describe('Update memory');
130
141
  export const DeleteMemoryInputSchema = z
@@ -149,13 +160,12 @@ const RELATIONSHIP_ENDPOINT_FIELDS = {
149
160
  export const SearchMemoriesInputSchema = z
150
161
  .strictObject({
151
162
  query: SEARCH_QUERY_SCHEMA.describe('Search query'),
152
- limit: z
153
- .int()
154
- .min(1)
155
- .max(100)
156
- .optional()
157
- .prefault(20)
158
- .describe('Max results (default 20)'),
163
+ limit: createPrefaultIntField({
164
+ min: 1,
165
+ max: 100,
166
+ prefault: 20,
167
+ description: 'Max results (default 20)',
168
+ }),
159
169
  cursor: CURSOR_SCHEMA.optional().describe(CURSOR_DESCRIPTION),
160
170
  ...SEARCH_FILTER_FIELDS,
161
171
  })
@@ -163,39 +173,42 @@ export const SearchMemoriesInputSchema = z
163
173
  export const RecallInputSchema = z
164
174
  .strictObject({
165
175
  query: SEARCH_QUERY_SCHEMA.describe('Search query'),
166
- depth: z
167
- .int()
168
- .min(0)
169
- .max(3)
170
- .optional()
171
- .prefault(1)
172
- .describe('Relationship hops (0-3)'),
173
- limit: z
174
- .int()
175
- .min(1)
176
- .max(50)
177
- .optional()
178
- .prefault(10)
179
- .describe('Max seed memories (default 10)'),
176
+ depth: createPrefaultIntField({
177
+ min: 0,
178
+ max: 3,
179
+ prefault: 1,
180
+ description: 'Relationship hops (0-3)',
181
+ }),
182
+ limit: createPrefaultIntField({
183
+ min: 1,
184
+ max: 50,
185
+ prefault: 10,
186
+ description: 'Max seed memories (default 10)',
187
+ }),
180
188
  cursor: CURSOR_SCHEMA.optional().describe(CURSOR_DESCRIPTION),
181
189
  ...RECALL_FILTER_FIELDS,
182
190
  })
183
191
  .describe('Recall memories via graph traversal');
192
+ const RETRIEVE_CONTEXT_FILTER_FIELDS = createSearchFilterFields({
193
+ min: 'Min importance filter',
194
+ max: 'Max importance filter',
195
+ type: 'Memory type filter',
196
+ });
184
197
  export const RetrieveContextInputSchema = z
185
198
  .strictObject({
186
199
  query: SEARCH_QUERY_SCHEMA.describe('Search query'),
187
- token_budget: z
188
- .int()
189
- .min(100)
190
- .max(200000)
191
- .optional()
192
- .prefault(4000)
193
- .describe('Max tokens (default 4000)'),
200
+ token_budget: createPrefaultIntField({
201
+ min: 100,
202
+ max: 200000,
203
+ prefault: 4000,
204
+ description: 'Max tokens (default 4000)',
205
+ }),
194
206
  strategy: z
195
207
  .enum(['importance', 'recency', 'relevance'])
196
208
  .optional()
197
209
  .prefault('relevance')
198
210
  .describe('Sort strategy'),
211
+ ...RETRIEVE_CONTEXT_FILTER_FIELDS,
199
212
  })
200
213
  .describe('Retrieve context within token budget');
201
214
  export const GetRelationshipsInputSchema = z
@@ -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
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
@@ -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
@@ -2,10 +2,10 @@ import { E_NOT_FOUND } from '../lib/errors.js';
2
2
  import { logToolEvent } from '../lib/mcp-utils.js';
3
3
  import { executeToolSafely } from '../lib/tool-execution.js';
4
4
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
- import { CreateRelationshipInputSchema } from '../schemas/inputs.js';
6
- import { CreateRelationshipResultSchema } from '../schemas/outputs.js';
5
+ import {} from '../schemas/inputs.js';
7
6
  import { wrapToolHandler } from './progress.js';
8
7
  import { registerToolWithContract } from './register-contract.js';
8
+ import { formatRelationshipPreview } from './result.js';
9
9
  const INSERT_RELATIONSHIP_SQL = `INSERT OR IGNORE INTO relationships (from_hash, to_hash, relation_type, created_at)
10
10
  VALUES (?, ?, ?, ?)`;
11
11
  const SELECT_HASHES_SQL = 'SELECT hash FROM memories WHERE hash IN (?, ?) LIMIT 2';
@@ -43,7 +43,7 @@ function createRelationshipTx(db, params) {
43
43
  });
44
44
  }
45
45
  export function registerCreateRelationship(server, db) {
46
- registerToolWithContract(server, 'create_relationship', CreateRelationshipInputSchema, CreateRelationshipResultSchema, wrapToolHandler(async (params) => executeToolSafely(async () => {
46
+ registerToolWithContract(server, 'create_relationship', wrapToolHandler(async (params) => executeToolSafely(async () => {
47
47
  const txResult = createRelationshipTx(db, params);
48
48
  if (!txResult.ok) {
49
49
  return createErrorResponse(txResult.code, txResult.message);
@@ -56,6 +56,6 @@ export function registerCreateRelationship(server, db) {
56
56
  });
57
57
  return createToolResponse({ created: txResult.created });
58
58
  }), {
59
- progressMessage: (params) => `⊕ create_relationship: ${params.from_hash.slice(0, 8)}... -> ${params.to_hash.slice(0, 8)}... [${params.relation_type}]`,
59
+ progressMessage: (params) => `⊕ create_relationship: ${formatRelationshipPreview(params.from_hash, params.to_hash)} [${params.relation_type}]`,
60
60
  }));
61
61
  }
@@ -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
@@ -2,18 +2,19 @@ import { logToolEvent, notifyMemoryResourceUpdated } from '../lib/mcp-utils.js';
2
2
  import { DELETE_MEMORY_SQL } from '../lib/sql.js';
3
3
  import { executeToolSafely, summarizeBatch } from '../lib/tool-execution.js';
4
4
  import { createToolResponse } from '../lib/tool-response.js';
5
- import { DeleteMemoriesInputSchema } from '../schemas/inputs.js';
6
- import { BatchResultSchema } from '../schemas/outputs.js';
5
+ import {} from '../schemas/inputs.js';
7
6
  import { wrapToolHandler } from './progress.js';
8
7
  import { registerToolWithContract } from './register-contract.js';
9
8
  async function notifyDeletedResources(server, items) {
9
+ // MCP spec (v2025-11-25) has no 'deleted' resource notification;
10
+ // 'updated' is the closest available signal to inform clients.
10
11
  const notifications = items
11
12
  .filter((item) => item.deleted)
12
13
  .map((item) => notifyMemoryResourceUpdated(server, item.hash));
13
14
  await Promise.allSettled(notifications);
14
15
  }
15
16
  export function registerDeleteMemories(server, db) {
16
- registerToolWithContract(server, 'delete_memories', DeleteMemoriesInputSchema, BatchResultSchema, wrapToolHandler(async (params) => executeToolSafely(async () => {
17
+ registerToolWithContract(server, 'delete_memories', wrapToolHandler(async (params) => executeToolSafely(async () => {
17
18
  const results = db.transaction(() => {
18
19
  const items = [];
19
20
  const stmt = db.prepareOnce(DELETE_MEMORY_SQL);
@@ -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
@@ -2,22 +2,24 @@ import { logToolEvent, notifyMemoryResourceUpdated } from '../lib/mcp-utils.js';
2
2
  import { DELETE_MEMORY_SQL } from '../lib/sql.js';
3
3
  import { executeToolSafely } from '../lib/tool-execution.js';
4
4
  import { createToolResponse } from '../lib/tool-response.js';
5
- import { DeleteMemoryInputSchema } from '../schemas/inputs.js';
6
- import { DeleteResultSchema } from '../schemas/outputs.js';
5
+ import {} from '../schemas/inputs.js';
7
6
  import { wrapToolHandler } from './progress.js';
8
7
  import { registerToolWithContract } from './register-contract.js';
8
+ import { formatHashPreview } from './result.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
- registerToolWithContract(server, 'delete_memory', DeleteMemoryInputSchema, DeleteResultSchema, wrapToolHandler(async (params) => executeToolSafely(async () => {
13
+ registerToolWithContract(server, 'delete_memory', wrapToolHandler(async (params) => executeToolSafely(async () => {
14
14
  const deleted = deleteByHash(db, params.hash);
15
15
  if (deleted) {
16
16
  await logToolEvent(server, 'delete', { hash: params.hash });
17
+ // MCP spec (v2025-11-25) has no 'deleted' resource notification;
18
+ // 'updated' is the closest available signal to inform clients.
17
19
  await notifyMemoryResourceUpdated(server, params.hash);
18
20
  }
19
21
  return createToolResponse({ deleted, hash: params.hash });
20
22
  }), {
21
- progressMessage: (params) => `⊖ delete_memory: ${params.hash.slice(0, 12)}... [single]`,
23
+ progressMessage: (params) => `⊖ delete_memory: ${formatHashPreview(params.hash)} [single]`,
22
24
  }));
23
25
  }
@@ -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,30 +1,20 @@
1
- import { E_NOT_FOUND } from '../lib/errors.js';
2
1
  import { executeToolSafely } from '../lib/tool-execution.js';
3
- import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
4
- import { DeleteRelationshipInputSchema } from '../schemas/inputs.js';
5
- import { DeleteRelationshipResultSchema } from '../schemas/outputs.js';
2
+ import { createToolResponse } from '../lib/tool-response.js';
3
+ import {} from '../schemas/inputs.js';
6
4
  import { wrapToolHandler } from './progress.js';
7
5
  import { registerToolWithContract } from './register-contract.js';
6
+ import { formatRelationshipPreview } from './result.js';
8
7
  const DELETE_RELATIONSHIP_SQL = 'DELETE FROM relationships WHERE from_hash = ? AND to_hash = ? AND relation_type = ?';
9
- const DELETE_RELATIONSHIP_RESULT = { deleted: true };
10
- function formatRelationship(params) {
11
- return `${params.from_hash} -[${params.relation_type}]-> ${params.to_hash}`;
12
- }
13
- function createNotFoundRelationshipMessage(params) {
14
- return `Relationship not found: ${formatRelationship(params)}`;
15
- }
16
8
  function deleteRelationship(db, params) {
17
9
  return (db
18
10
  .prepareOnce(DELETE_RELATIONSHIP_SQL)
19
11
  .run(params.from_hash, params.to_hash, params.relation_type).changes > 0);
20
12
  }
21
13
  export function registerDeleteRelationship(server, db) {
22
- registerToolWithContract(server, 'delete_relationship', DeleteRelationshipInputSchema, DeleteRelationshipResultSchema, wrapToolHandler((params) => executeToolSafely(() => {
23
- if (!deleteRelationship(db, params)) {
24
- return createErrorResponse(E_NOT_FOUND, createNotFoundRelationshipMessage(params));
25
- }
26
- return createToolResponse(DELETE_RELATIONSHIP_RESULT);
14
+ registerToolWithContract(server, 'delete_relationship', wrapToolHandler((params) => executeToolSafely(() => {
15
+ const deleted = deleteRelationship(db, params);
16
+ return createToolResponse({ deleted });
27
17
  }), {
28
- progressMessage: (params) => `⊖ delete_relationship: ${params.from_hash.slice(0, 8)}... -> ${params.to_hash.slice(0, 8)}... [${params.relation_type}]`,
18
+ progressMessage: (params) => `⊖ delete_relationship: ${formatRelationshipPreview(params.from_hash, params.to_hash)} [${params.relation_type}]`,
29
19
  }));
30
20
  }
@@ -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
@@ -3,10 +3,10 @@ import { SELECT_MEMORY_BY_HASH_SQL } from '../lib/sql.js';
3
3
  import { executeToolSafely } from '../lib/tool-execution.js';
4
4
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
5
  import { parseMemoryRow } from '../lib/types.js';
6
- import { GetMemoryInputSchema } from '../schemas/inputs.js';
7
- import { MemoryResultSchema } from '../schemas/outputs.js';
6
+ import {} from '../schemas/inputs.js';
8
7
  import { wrapToolHandler } from './progress.js';
9
8
  import { registerToolWithContract } from './register-contract.js';
9
+ import { formatHashPreview } from './result.js';
10
10
  function getMemoryRow(db, hash) {
11
11
  return db.prepareOnce(SELECT_MEMORY_BY_HASH_SQL).get(hash);
12
12
  }
@@ -14,7 +14,7 @@ function notFound(hash) {
14
14
  return createErrorResponse(E_NOT_FOUND, `Memory not found: ${hash}`);
15
15
  }
16
16
  export function registerGetMemory(server, db) {
17
- registerToolWithContract(server, 'get_memory', GetMemoryInputSchema, MemoryResultSchema, wrapToolHandler((params) => executeToolSafely(() => {
17
+ registerToolWithContract(server, 'get_memory', wrapToolHandler((params) => executeToolSafely(() => {
18
18
  const row = getMemoryRow(db, params.hash);
19
19
  if (!row) {
20
20
  return notFound(params.hash);
@@ -22,6 +22,6 @@ export function registerGetMemory(server, db) {
22
22
  const memory = parseMemoryRow(row);
23
23
  return createToolResponse({ ...memory });
24
24
  }), {
25
- progressMessage: (params) => `⊙ get_memory: ${params.hash.slice(0, 12)}... [single]`,
25
+ progressMessage: (params) => `⊙ get_memory: ${formatHashPreview(params.hash)} [single]`,
26
26
  }));
27
27
  }
@@ -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
@@ -3,10 +3,10 @@ import { SELECT_MEMORY_HASH_SQL } from '../lib/sql.js';
3
3
  import { executeToolSafely } from '../lib/tool-execution.js';
4
4
  import { createErrorResponse, createToolResponse, } from '../lib/tool-response.js';
5
5
  import { parseTags } from '../lib/types.js';
6
- import { GetRelationshipsInputSchema } from '../schemas/inputs.js';
7
- import { RelationshipResultSchema } from '../schemas/outputs.js';
6
+ import {} from '../schemas/inputs.js';
8
7
  import { wrapToolHandler } from './progress.js';
9
8
  import { registerToolWithContract } from './register-contract.js';
9
+ import { formatHashPreview } from './result.js';
10
10
  // Pre-defined SQL for each direction mode to maximise prepareOnce cache hits.
11
11
  const OUTGOING_SQL = `
12
12
  SELECT r.from_hash, r.to_hash, r.relation_type, r.created_at,
@@ -61,17 +61,21 @@ function toRelationshipWithMemory(row) {
61
61
  };
62
62
  }
63
63
  export function registerGetRelationships(server, db) {
64
- registerToolWithContract(server, 'get_relationships', GetRelationshipsInputSchema, RelationshipResultSchema, wrapToolHandler((params) => executeToolSafely(() => {
65
- if (!memoryExists(db, params.hash)) {
66
- return createErrorResponse(E_NOT_FOUND, `Memory not found: ${params.hash}`);
67
- }
68
- const rows = loadRelationships(db, params.hash, params.direction);
69
- const relationships = rows.map(toRelationshipWithMemory);
70
- return createToolResponse({
71
- relationships,
72
- count: relationships.length,
64
+ registerToolWithContract(server, 'get_relationships', wrapToolHandler((params) => executeToolSafely(() => {
65
+ // Transaction eliminates TOCTOU: memory cannot be deleted
66
+ // between the existence check and the relationship query.
67
+ return db.transaction(() => {
68
+ if (!memoryExists(db, params.hash)) {
69
+ return createErrorResponse(E_NOT_FOUND, `Memory not found: ${params.hash}`);
70
+ }
71
+ const rows = loadRelationships(db, params.hash, params.direction);
72
+ const relationships = rows.map(toRelationshipWithMemory);
73
+ return createToolResponse({
74
+ relationships,
75
+ count: relationships.length,
76
+ });
73
77
  });
74
78
  }), {
75
- progressMessage: (params) => `⊙ get_relationships: ${params.hash.slice(0, 12)}... [${params.direction}]`,
79
+ progressMessage: (params) => `⊙ get_relationships: ${formatHashPreview(params.hash)} [${params.direction}]`,
76
80
  }));
77
81
  }
@@ -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
@@ -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,8 +1,6 @@
1
1
  import { MEMORY_AGGREGATE_SQL, RELATIONSHIP_COUNT_SQL, TYPE_COUNTS_SQL, } from '../lib/sql.js';
2
2
  import { executeToolSafely } from '../lib/tool-execution.js';
3
3
  import { createToolResponse } from '../lib/tool-response.js';
4
- import { MemoryStatsInputSchema } from '../schemas/inputs.js';
5
- import { StatsResultSchema } from '../schemas/outputs.js';
6
4
  import { wrapToolHandler } from './progress.js';
7
5
  import { registerToolWithContract } from './register-contract.js';
8
6
  function toTypeCounts(rows) {
@@ -13,7 +11,7 @@ function toTypeCounts(rows) {
13
11
  return byType;
14
12
  }
15
13
  export function registerMemoryStats(server, db) {
16
- registerToolWithContract(server, 'memory_stats', MemoryStatsInputSchema, StatsResultSchema, wrapToolHandler(() => executeToolSafely(() => {
14
+ registerToolWithContract(server, 'memory_stats', wrapToolHandler(() => executeToolSafely(() => {
17
15
  const aggregate = db
18
16
  .prepareOnce(MEMORY_AGGREGATE_SQL)
19
17
  .get();
@@ -26,10 +26,15 @@ interface WrappedHandlerOptions<TArgs> {
26
26
  completionMessage?: (args: TArgs, result: CallToolResult) => string;
27
27
  progressMessage: (args: TArgs) => string;
28
28
  }
29
+ interface CompletionRunOptions {
30
+ reporter: Pick<ProgressReporter, 'flush'>;
31
+ completionCurrent: number | (() => number);
32
+ completionMessage: (result: CallToolResult) => string;
33
+ }
29
34
  type ToolHandler<TArgs> = (args: TArgs, extra: ProgressContext) => Promise<CallToolResult> | CallToolResult;
30
35
  export declare function notifyProgress(extra: ProgressContext, progress: ProgressUpdate): Promise<void>;
31
36
  export declare function createProgressReporter(extra: ProgressContext, options?: ProgressReporterOptions): ProgressReporter;
32
37
  export declare function progressWithMessage(reporter: ProgressReporter, getMessage: (progress: ProgressSnapshot) => string): ProgressReporter<ProgressSnapshot>;
33
38
  export declare function wrapToolHandler<TArgs>(handler: ToolHandler<TArgs>, options: WrappedHandlerOptions<TArgs>): ToolHandler<TArgs>;
39
+ export declare function runWithProgressCompletion(extra: ProgressContext, run: () => CallToolResult | Promise<CallToolResult>, options: CompletionRunOptions): Promise<CallToolResult>;
34
40
  export {};
35
- //# sourceMappingURL=progress.d.ts.map