@cartisien/engram-mcp 0.3.3 → 0.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.
package/dist/client.js CHANGED
@@ -18,7 +18,10 @@ export async function getEngram() {
18
18
  maxContextLength: config.maxContextLength,
19
19
  dedupThreshold: config.dedupThreshold,
20
20
  enableWAL: config.enableWAL,
21
- graphMemory: true,
21
+ // T-P3-06 — honor the config (which honors ENGRAM_GRAPH_MEMORY env, default false).
22
+ // Previous code forced `true` regardless of env, so graph extraction ran in every
23
+ // MCP session and wrote inferred entities into graph_edges.
24
+ graphMemory: config.graphMemory,
22
25
  enableFTS5: true,
23
26
  semanticSearch: config.semanticSearch,
24
27
  });
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,IAAI,QAAQ,GAAkB,IAAI,CAAC;AAEnC,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,6BAA6B;IAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,QAAQ,GAAG,IAAI,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,WAAW,EAAE,IAAI;QACjB,UAAU,EAAE,IAAI;QAChB,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,EAAE,CAAC,SAAS,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,IAAI,QAAQ,GAAkB,IAAI,CAAC;AAEnC,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,6BAA6B;IAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,QAAQ,GAAG,IAAI,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,oFAAoF;QACpF,kFAAkF;QAClF,4DAA4D;QAC5D,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,UAAU,EAAE,IAAI;QAChB,cAAc,EAAE,MAAM,CAAC,cAAc;KACtC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,EAAE,CAAC,SAAS,CAAC;AAChC,CAAC"}
package/dist/config.js CHANGED
@@ -3,6 +3,14 @@ import { join } from 'path';
3
3
  function env(key, fallback) {
4
4
  return process.env[key] ?? fallback;
5
5
  }
6
+ /** Parse a boolean-ish env var. Returns the default unless the value is "true". */
7
+ function envBool(key, fallback) {
8
+ const raw = process.env[key];
9
+ if (raw === undefined)
10
+ return fallback;
11
+ const v = raw.trim().toLowerCase();
12
+ return v === 'true' || v === '1' || v === 'yes';
13
+ }
6
14
  export function loadConfig() {
7
15
  return {
8
16
  dbPath: env('ENGRAM_DB_PATH', join(homedir(), '.engram', 'memory.db')),
@@ -12,9 +20,13 @@ export function loadConfig() {
12
20
  embeddingProvider: env('ENGRAM_EMBEDDING_PROVIDER', 'ollama'),
13
21
  maxContextLength: parseInt(env('ENGRAM_MAX_CONTEXT', '4000'), 10),
14
22
  dedupThreshold: parseFloat(env('ENGRAM_DEDUP_THRESHOLD', '0.95')),
15
- enableWAL: env('ENGRAM_ENABLE_WAL', 'true') === 'true',
16
- semanticSearch: env('ENGRAM_SEMANTIC_SEARCH', 'true') === 'true',
17
- graphMemory: true, // always enabled in MCP server
23
+ enableWAL: envBool('ENGRAM_ENABLE_WAL', true),
24
+ semanticSearch: envBool('ENGRAM_SEMANTIC_SEARCH', true),
25
+ // T-P3-06 graph memory is OFF by default. The regex-based extractor
26
+ // writes inferred entities (which may include PII pulled from chat
27
+ // content) into the graph_edges table. Privacy-by-default requires
28
+ // explicit opt-in. Enable via ENGRAM_GRAPH_MEMORY=true.
29
+ graphMemory: envBool('ENGRAM_GRAPH_MEMORY', false),
18
30
  };
19
31
  }
20
32
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAe5B,SAAS,GAAG,CAAC,GAAW,EAAE,QAAgB;IACxC,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACtE,SAAS,EAAE,GAAG,CAAC,mBAAmB,EAAE,SAAS,CAAC;QAC9C,YAAY,EAAE,GAAG,CAAC,sBAAsB,EAAE,wBAAwB,CAAC;QACnE,cAAc,EAAE,GAAG,CAAC,wBAAwB,EAAE,kBAAkB,CAAC;QACjE,iBAAiB,EAAE,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC;QAC7D,gBAAgB,EAAE,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QACjE,cAAc,EAAE,UAAU,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;QACjE,SAAS,EAAE,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,KAAK,MAAM;QACtD,cAAc,EAAE,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,KAAK,MAAM;QAChE,WAAW,EAAE,IAAI,EAAE,+BAA+B;KACnD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAe5B,SAAS,GAAG,CAAC,GAAW,EAAE,QAAgB;IACxC,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC;AACtC,CAAC;AAED,mFAAmF;AACnF,SAAS,OAAO,CAAC,GAAW,EAAE,QAAiB;IAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACvC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnC,OAAO,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;QACL,MAAM,EAAE,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QACtE,SAAS,EAAE,GAAG,CAAC,mBAAmB,EAAE,SAAS,CAAC;QAC9C,YAAY,EAAE,GAAG,CAAC,sBAAsB,EAAE,wBAAwB,CAAC;QACnE,cAAc,EAAE,GAAG,CAAC,wBAAwB,EAAE,kBAAkB,CAAC;QACjE,iBAAiB,EAAE,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC;QAC7D,gBAAgB,EAAE,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QACjE,cAAc,EAAE,UAAU,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;QACjE,SAAS,EAAE,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC;QAC7C,cAAc,EAAE,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC;QACvD,sEAAsE;QACtE,mEAAmE;QACnE,mEAAmE;QACnE,wDAAwD;QACxD,WAAW,EAAE,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC;KACnD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,402 @@
1
+ import type { Engram } from '@cartisien/engram';
2
+ /**
3
+ * Single source of truth for the tool registry and dispatch.
4
+ *
5
+ * Both transports consume this: the stdio bin (`server.ts`) and the in-process
6
+ * `McpServer` (`mcp-server.ts`) used by the hosted API. Previously the switch
7
+ * lived only inside `server.ts`'s stdio `main()`, so the hosted path had no way
8
+ * to reach the tools and returned 501.
9
+ */
10
+ export declare const ALL_TOOLS: ({
11
+ readonly name: "remember";
12
+ readonly description: "Store a new memory with automatic entity extraction, theme detection, and relationship mapping.";
13
+ readonly inputSchema: {
14
+ readonly type: "object";
15
+ readonly properties: {
16
+ readonly content: {
17
+ readonly type: "string";
18
+ readonly description: "The memory text to store";
19
+ };
20
+ readonly role: {
21
+ readonly type: "string";
22
+ readonly enum: readonly ["user", "assistant", "system"];
23
+ readonly default: "user";
24
+ };
25
+ readonly session_id: {
26
+ readonly type: "string";
27
+ readonly description: "Session identifier (defaults to ENGRAM_SESSION_ID)";
28
+ };
29
+ readonly timestamp: {
30
+ readonly type: "string";
31
+ readonly description: "ISO8601 timestamp (defaults to now)";
32
+ };
33
+ readonly metadata: {
34
+ readonly type: "object";
35
+ readonly description: "Arbitrary key-value metadata";
36
+ };
37
+ readonly extract_entities: {
38
+ readonly type: "boolean";
39
+ readonly default: true;
40
+ readonly description: "Auto-extract entities and store in graph";
41
+ };
42
+ };
43
+ readonly required: readonly ["content"];
44
+ };
45
+ } | {
46
+ readonly name: "recall";
47
+ readonly description: "Retrieve relevant memories with entity, theme, and emotional context. Returns 360° relational intelligence around the query.";
48
+ readonly inputSchema: {
49
+ readonly type: "object";
50
+ readonly properties: {
51
+ readonly query: {
52
+ readonly type: "string";
53
+ readonly description: "What to search for";
54
+ };
55
+ readonly session_id: {
56
+ readonly type: "string";
57
+ };
58
+ readonly limit: {
59
+ readonly type: "number";
60
+ readonly default: 5;
61
+ readonly description: "Max results (default: 5, max: 50)";
62
+ };
63
+ readonly min_relevance: {
64
+ readonly type: "number";
65
+ readonly default: 0.7;
66
+ readonly description: "Minimum relevance score 0-1";
67
+ };
68
+ readonly include_context: {
69
+ readonly type: "boolean";
70
+ readonly default: true;
71
+ };
72
+ readonly time_range: {
73
+ readonly type: "object";
74
+ readonly properties: {
75
+ readonly start: {
76
+ readonly type: "string";
77
+ readonly description: "ISO8601 start date";
78
+ };
79
+ readonly end: {
80
+ readonly type: "string";
81
+ readonly description: "ISO8601 end date";
82
+ };
83
+ };
84
+ };
85
+ readonly entity_filter: {
86
+ readonly type: "array";
87
+ readonly items: {
88
+ readonly type: "string";
89
+ };
90
+ readonly description: "Only return memories mentioning these entities";
91
+ };
92
+ readonly theme_filter: {
93
+ readonly type: "array";
94
+ readonly items: {
95
+ readonly type: "string";
96
+ };
97
+ readonly description: "Only return memories matching these themes";
98
+ };
99
+ readonly tiers: {
100
+ readonly type: "array";
101
+ readonly items: {
102
+ readonly type: "string";
103
+ };
104
+ readonly description: "Memory tiers to search: working, long_term, archived";
105
+ };
106
+ };
107
+ readonly required: readonly ["query"];
108
+ };
109
+ } | {
110
+ readonly name: "search";
111
+ readonly description: "Raw hybrid search with pagination and filtering. Use for precise control over results.";
112
+ readonly inputSchema: {
113
+ readonly type: "object";
114
+ readonly properties: {
115
+ readonly query: {
116
+ readonly type: "string";
117
+ };
118
+ readonly session_id: {
119
+ readonly type: "string";
120
+ };
121
+ readonly search_type: {
122
+ readonly type: "string";
123
+ readonly enum: readonly ["hybrid", "semantic", "fts", "graph"];
124
+ readonly default: "hybrid";
125
+ };
126
+ readonly limit: {
127
+ readonly type: "number";
128
+ readonly default: 10;
129
+ };
130
+ readonly offset: {
131
+ readonly type: "number";
132
+ readonly default: 0;
133
+ };
134
+ readonly semantic_weight: {
135
+ readonly type: "number";
136
+ readonly description: "0-1, weight for semantic vs BM25 (not yet configurable in v0.7)";
137
+ };
138
+ readonly filters: {
139
+ readonly type: "object";
140
+ readonly properties: {
141
+ readonly role: {
142
+ readonly type: "array";
143
+ readonly items: {
144
+ readonly type: "string";
145
+ };
146
+ };
147
+ readonly tier: {
148
+ readonly type: "array";
149
+ readonly items: {
150
+ readonly type: "string";
151
+ };
152
+ };
153
+ readonly date_after: {
154
+ readonly type: "string";
155
+ };
156
+ readonly date_before: {
157
+ readonly type: "string";
158
+ };
159
+ };
160
+ };
161
+ };
162
+ readonly required: readonly ["query"];
163
+ };
164
+ } | {
165
+ readonly name: "context";
166
+ readonly description: "Get 360° context around a specific entity, theme, or memory. Returns timeline, relationships, emotional arc, and key memories.";
167
+ readonly inputSchema: {
168
+ readonly type: "object";
169
+ readonly properties: {
170
+ readonly target: {
171
+ readonly type: "string";
172
+ readonly description: "Entity name, theme name, or memory_id";
173
+ };
174
+ readonly target_type: {
175
+ readonly type: "string";
176
+ readonly enum: readonly ["entity", "theme", "memory"];
177
+ };
178
+ readonly session_id: {
179
+ readonly type: "string";
180
+ };
181
+ readonly depth: {
182
+ readonly type: "number";
183
+ readonly default: 2;
184
+ readonly description: "Relationship depth (1-3)";
185
+ };
186
+ readonly include_memories: {
187
+ readonly type: "boolean";
188
+ readonly default: true;
189
+ };
190
+ readonly include_metrics: {
191
+ readonly type: "boolean";
192
+ readonly default: true;
193
+ };
194
+ };
195
+ readonly required: readonly ["target", "target_type"];
196
+ };
197
+ } | {
198
+ readonly name: "impact";
199
+ readonly description: "Analyze how a new piece of information would affect existing memory structure. Detects conflicts, affected entities, and themes before storing.";
200
+ readonly inputSchema: {
201
+ readonly type: "object";
202
+ readonly properties: {
203
+ readonly hypothetical: {
204
+ readonly type: "string";
205
+ readonly description: "The new information to analyze";
206
+ };
207
+ readonly analysis_type: {
208
+ readonly type: "string";
209
+ readonly enum: readonly ["add", "update", "remove"];
210
+ };
211
+ readonly session_id: {
212
+ readonly type: "string";
213
+ };
214
+ readonly target_entity: {
215
+ readonly type: "string";
216
+ readonly description: "Focus analysis on a specific entity";
217
+ };
218
+ readonly min_confidence: {
219
+ readonly type: "number";
220
+ readonly default: 0.5;
221
+ readonly description: "Minimum entity confidence threshold";
222
+ };
223
+ };
224
+ readonly required: readonly ["hypothetical", "analysis_type"];
225
+ };
226
+ } | {
227
+ readonly name: "detect_changes";
228
+ readonly description: "Compare recent memory activity against a baseline period to identify new entities, theme shifts, emotional changes, and anomalies.";
229
+ readonly inputSchema: {
230
+ readonly type: "object";
231
+ readonly properties: {
232
+ readonly baseline: {
233
+ readonly type: "string";
234
+ readonly enum: readonly ["session", "day", "week", "month"];
235
+ readonly description: "Time window to compare against";
236
+ };
237
+ readonly session_id: {
238
+ readonly type: "string";
239
+ };
240
+ readonly scope: {
241
+ readonly type: "string";
242
+ readonly enum: readonly ["entities", "themes", "emotions", "all"];
243
+ readonly default: "all";
244
+ };
245
+ readonly compare_session_id: {
246
+ readonly type: "string";
247
+ readonly description: "Compare against a specific session instead";
248
+ };
249
+ };
250
+ readonly required: readonly ["baseline"];
251
+ };
252
+ } | {
253
+ readonly name: "consolidate";
254
+ readonly description: "Consolidate working memories into long-term storage. Archives old memories beyond the keep threshold.";
255
+ readonly inputSchema: {
256
+ readonly type: "object";
257
+ readonly properties: {
258
+ readonly trigger: {
259
+ readonly type: "string";
260
+ readonly enum: readonly ["manual", "scheduled", "threshold"];
261
+ readonly default: "manual";
262
+ };
263
+ readonly session_id: {
264
+ readonly type: "string";
265
+ };
266
+ readonly keep: {
267
+ readonly type: "number";
268
+ readonly description: "Number of working memories to keep (overrides aggressiveness)";
269
+ };
270
+ readonly aggressiveness: {
271
+ readonly type: "string";
272
+ readonly enum: readonly ["conservative", "normal", "aggressive"];
273
+ readonly default: "normal";
274
+ readonly description: "conservative=keep 50, normal=keep 20, aggressive=keep 10";
275
+ };
276
+ readonly dry_run: {
277
+ readonly type: "boolean";
278
+ readonly default: false;
279
+ readonly description: "Preview consolidation without making changes";
280
+ };
281
+ };
282
+ };
283
+ } | {
284
+ readonly name: "process_detect";
285
+ readonly description: "Identify recurring conversation and behavior patterns: decision loops, planning sessions, learning moments, and conflict patterns.";
286
+ readonly inputSchema: {
287
+ readonly type: "object";
288
+ readonly properties: {
289
+ readonly process_type: {
290
+ readonly type: "string";
291
+ readonly enum: readonly ["decision", "learning", "conflict", "planning", "all"];
292
+ readonly default: "all";
293
+ };
294
+ readonly session_id: {
295
+ readonly type: "string";
296
+ };
297
+ readonly entity_focus: {
298
+ readonly type: "string";
299
+ readonly description: "Focus pattern detection on a specific entity";
300
+ };
301
+ readonly min_occurrences: {
302
+ readonly type: "number";
303
+ readonly default: 2;
304
+ readonly description: "Minimum occurrences to consider a pattern";
305
+ };
306
+ readonly time_range: {
307
+ readonly type: "object";
308
+ readonly properties: {
309
+ readonly start: {
310
+ readonly type: "string";
311
+ };
312
+ readonly end: {
313
+ readonly type: "string";
314
+ };
315
+ };
316
+ };
317
+ };
318
+ };
319
+ } | {
320
+ readonly name: "forget";
321
+ readonly description: "Delete memories matching criteria. Requires confirm: true. This is irreversible.";
322
+ readonly inputSchema: {
323
+ readonly type: "object";
324
+ readonly properties: {
325
+ readonly session_id: {
326
+ readonly type: "string";
327
+ };
328
+ readonly before: {
329
+ readonly type: "string";
330
+ readonly description: "Delete memories before this ISO8601 date";
331
+ };
332
+ readonly memory_id: {
333
+ readonly type: "string";
334
+ readonly description: "Delete a specific memory by ID";
335
+ };
336
+ readonly include_long_term: {
337
+ readonly type: "boolean";
338
+ readonly description: "Also delete long_term memories (default: working only)";
339
+ };
340
+ readonly confirm: {
341
+ readonly type: "boolean";
342
+ readonly description: "Must be true to execute deletion";
343
+ };
344
+ };
345
+ readonly required: readonly ["confirm"];
346
+ };
347
+ } | {
348
+ readonly name: "stats";
349
+ readonly description: "Get memory statistics for a session: counts by role/tier, embeddings coverage, importance scores, and graph metrics.";
350
+ readonly inputSchema: {
351
+ readonly type: "object";
352
+ readonly properties: {
353
+ readonly session_id: {
354
+ readonly type: "string";
355
+ };
356
+ readonly include_graph: {
357
+ readonly type: "boolean";
358
+ readonly default: true;
359
+ readonly description: "Include entity graph node/edge counts";
360
+ };
361
+ };
362
+ };
363
+ } | {
364
+ readonly name: "graph";
365
+ readonly description: "Query the entity relationship graph. Find connections, relationships, and paths between entities.";
366
+ readonly inputSchema: {
367
+ readonly type: "object";
368
+ readonly properties: {
369
+ readonly entity: {
370
+ readonly type: "string";
371
+ readonly description: "Entity name to query";
372
+ };
373
+ readonly session_id: {
374
+ readonly type: "string";
375
+ };
376
+ readonly include_memories: {
377
+ readonly type: "boolean";
378
+ readonly default: true;
379
+ readonly description: "Include related memory snippets";
380
+ };
381
+ readonly find_path_to: {
382
+ readonly type: "string";
383
+ readonly description: "Find relationship path to this entity";
384
+ };
385
+ readonly max_depth: {
386
+ readonly type: "number";
387
+ readonly default: 3;
388
+ readonly description: "Max hops for path finding (1-3)";
389
+ };
390
+ };
391
+ readonly required: readonly ["entity"];
392
+ };
393
+ })[];
394
+ /**
395
+ * Dispatch a single tool call against a given Engram instance and return the
396
+ * raw tool result (an `McpResponse`). Transport layers are responsible for
397
+ * wrapping this into their own envelope (MCP `content` blocks, HTTP JSON, ...).
398
+ *
399
+ * Runtime validation lives in each tool handler; the `unknown` cast mirrors the
400
+ * original stdio dispatcher.
401
+ */
402
+ export declare function callTool(engram: Engram, name: string, args?: Record<string, unknown>): Promise<unknown>;
@@ -0,0 +1,75 @@
1
+ import { VERSION } from './response.js';
2
+ import { toolRemember, REMEMBER_SCHEMA } from './tools/remember.js';
3
+ import { toolRecall, RECALL_SCHEMA } from './tools/recall.js';
4
+ import { toolSearch, SEARCH_SCHEMA } from './tools/search.js';
5
+ import { toolContext, CONTEXT_SCHEMA } from './tools/context.js';
6
+ import { toolImpact, IMPACT_SCHEMA } from './tools/impact.js';
7
+ import { toolDetectChanges, DETECT_CHANGES_SCHEMA } from './tools/detect_changes.js';
8
+ import { toolConsolidate, CONSOLIDATE_SCHEMA } from './tools/consolidate.js';
9
+ import { toolProcessDetect, PROCESS_DETECT_SCHEMA } from './tools/process_detect.js';
10
+ import { toolForget, FORGET_SCHEMA } from './tools/forget.js';
11
+ import { toolStats, STATS_SCHEMA } from './tools/stats.js';
12
+ import { toolGraph, GRAPH_SCHEMA } from './tools/graph.js';
13
+ /**
14
+ * Single source of truth for the tool registry and dispatch.
15
+ *
16
+ * Both transports consume this: the stdio bin (`server.ts`) and the in-process
17
+ * `McpServer` (`mcp-server.ts`) used by the hosted API. Previously the switch
18
+ * lived only inside `server.ts`'s stdio `main()`, so the hosted path had no way
19
+ * to reach the tools and returned 501.
20
+ */
21
+ export const ALL_TOOLS = [
22
+ REMEMBER_SCHEMA,
23
+ RECALL_SCHEMA,
24
+ SEARCH_SCHEMA,
25
+ CONTEXT_SCHEMA,
26
+ IMPACT_SCHEMA,
27
+ DETECT_CHANGES_SCHEMA,
28
+ CONSOLIDATE_SCHEMA,
29
+ PROCESS_DETECT_SCHEMA,
30
+ FORGET_SCHEMA,
31
+ STATS_SCHEMA,
32
+ GRAPH_SCHEMA,
33
+ ];
34
+ /**
35
+ * Dispatch a single tool call against a given Engram instance and return the
36
+ * raw tool result (an `McpResponse`). Transport layers are responsible for
37
+ * wrapping this into their own envelope (MCP `content` blocks, HTTP JSON, ...).
38
+ *
39
+ * Runtime validation lives in each tool handler; the `unknown` cast mirrors the
40
+ * original stdio dispatcher.
41
+ */
42
+ export async function callTool(engram, name, args = {}) {
43
+ const a = args;
44
+ switch (name) {
45
+ case 'remember':
46
+ return toolRemember(engram, a);
47
+ case 'recall':
48
+ return toolRecall(engram, a);
49
+ case 'search':
50
+ return toolSearch(engram, a);
51
+ case 'context':
52
+ return toolContext(engram, a);
53
+ case 'impact':
54
+ return toolImpact(engram, a);
55
+ case 'detect_changes':
56
+ return toolDetectChanges(engram, a);
57
+ case 'consolidate':
58
+ return toolConsolidate(engram, a);
59
+ case 'process_detect':
60
+ return toolProcessDetect(engram, a);
61
+ case 'forget':
62
+ return toolForget(engram, a);
63
+ case 'stats':
64
+ return toolStats(engram, a);
65
+ case 'graph':
66
+ return toolGraph(engram, a);
67
+ default:
68
+ return {
69
+ success: false,
70
+ error: { code: 'UNKNOWN_TOOL', message: `Unknown tool: ${name}` },
71
+ meta: { query_time_ms: 0, version: VERSION, session_id: 'unknown' },
72
+ };
73
+ }
74
+ }
75
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,eAAe;IACf,aAAa;IACb,aAAa;IACb,cAAc;IACd,aAAa;IACb,qBAAqB;IACrB,kBAAkB;IAClB,qBAAqB;IACrB,aAAa;IACb,YAAY;IACZ,YAAY;CACb,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAc,EACd,IAAY,EACZ,OAAgC,EAAE;IAElC,MAAM,CAAC,GAAG,IAAe,CAAC;IAC1B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,UAAU;YACb,OAAO,YAAY,CAAC,MAAM,EAAE,CAAuC,CAAC,CAAC;QACvE,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC,MAAM,EAAE,CAAqC,CAAC,CAAC;QACnE,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC,MAAM,EAAE,CAAqC,CAAC,CAAC;QACnE,KAAK,SAAS;YACZ,OAAO,WAAW,CAAC,MAAM,EAAE,CAAsC,CAAC,CAAC;QACrE,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC,MAAM,EAAE,CAAqC,CAAC,CAAC;QACnE,KAAK,gBAAgB;YACnB,OAAO,iBAAiB,CAAC,MAAM,EAAE,CAA4C,CAAC,CAAC;QACjF,KAAK,aAAa;YAChB,OAAO,eAAe,CAAC,MAAM,EAAE,CAA0C,CAAC,CAAC;QAC7E,KAAK,gBAAgB;YACnB,OAAO,iBAAiB,CAAC,MAAM,EAAE,CAA4C,CAAC,CAAC;QACjF,KAAK,QAAQ;YACX,OAAO,UAAU,CAAC,MAAM,EAAE,CAAqC,CAAC,CAAC;QACnE,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,MAAM,EAAE,CAAoC,CAAC,CAAC;QACjE,KAAK,OAAO;YACV,OAAO,SAAS,CAAC,MAAM,EAAE,CAAoC,CAAC,CAAC;QACjE;YACE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,IAAI,EAAE,EAAE;gBACjE,IAAI,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE;aACpE,CAAC;IACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Library entry for @cartisien/engram-mcp.
3
+ *
4
+ * Side-effect free: importing this module must NOT start a stdio server (the
5
+ * bin, `server.ts`, does that). The hosted API imports `McpServer` from here to
6
+ * run the tools in-process, per workspace.
7
+ */
8
+ export { McpServer } from './mcp-server.js';
9
+ export type { McpServerOptions, JsonRpcResponse } from './mcp-server.js';
10
+ export { ALL_TOOLS, callTool } from './dispatch.js';
11
+ export { extractEntities, entityRelation } from './analysis/entities.js';
12
+ export type { ExtractedEntity, EntityType } from './analysis/entities.js';
13
+ export { VERSION } from './response.js';
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Library entry for @cartisien/engram-mcp.
3
+ *
4
+ * Side-effect free: importing this module must NOT start a stdio server (the
5
+ * bin, `server.ts`, does that). The hosted API imports `McpServer` from here to
6
+ * run the tools in-process, per workspace.
7
+ */
8
+ export { McpServer } from './mcp-server.js';
9
+ export { ALL_TOOLS, callTool } from './dispatch.js';
10
+ export { extractEntities, entityRelation } from './analysis/entities.js';
11
+ export { VERSION } from './response.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEzE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,40 @@
1
+ import type { Engram } from '@cartisien/engram';
2
+ export interface McpServerOptions {
3
+ /** Workspace-scoped Engram instance the tools operate against. */
4
+ engram: Engram;
5
+ /** SSE sink for the GET stream: `(event, data) => void`. */
6
+ onEvent?: (event: string, data: unknown) => void;
7
+ }
8
+ export interface JsonRpcResponse {
9
+ jsonrpc: '2.0';
10
+ id: string | number | null;
11
+ result?: unknown;
12
+ error?: {
13
+ code: number;
14
+ message: string;
15
+ data?: unknown;
16
+ };
17
+ }
18
+ export declare class McpServer {
19
+ private readonly engram;
20
+ private readonly onEvent?;
21
+ private keepAlive?;
22
+ constructor(opts: McpServerOptions);
23
+ /**
24
+ * Open the server→client SSE channel. The Engram tools are request/response
25
+ * only and never push server-initiated notifications, so the stream simply
26
+ * announces readiness and emits periodic keepalives to keep proxies from
27
+ * closing an idle connection. Actual tool calls flow through `handle()`.
28
+ */
29
+ start(): Promise<void>;
30
+ stop(): Promise<void>;
31
+ /**
32
+ * Handle one JSON-RPC message, or a batch array. Returns the response(s), or
33
+ * `null` for notifications (messages without an `id`), which per JSON-RPC
34
+ * receive no reply — the caller should answer 202 with no body.
35
+ */
36
+ handle(message: unknown): Promise<JsonRpcResponse | JsonRpcResponse[] | null>;
37
+ private handleOne;
38
+ private ok;
39
+ private err;
40
+ }
@@ -0,0 +1,127 @@
1
+ import { ALL_TOOLS, callTool } from './dispatch.js';
2
+ import { VERSION } from './response.js';
3
+ /**
4
+ * In-process, transport-agnostic MCP server.
5
+ *
6
+ * The stdio bin (`server.ts`) wires the tools to a `StdioServerTransport`. The
7
+ * hosted API instead needs to drive the same tools per-workspace over HTTP, so
8
+ * it constructs one of these with an injected, workspace-scoped Engram instance
9
+ * and calls `handle()` (Streamable-HTTP POST) or `start()`/`stop()` (the SSE
10
+ * GET channel). This is what the API's `import('@cartisien/engram-mcp')` looks
11
+ * for; before it existed the hosted endpoint returned 501.
12
+ *
13
+ * `handle()` implements the JSON-RPC 2.0 subset the MCP protocol requires
14
+ * (`initialize`, `tools/list`, `tools/call`, `ping`, and notifications). It is
15
+ * stateless: each call is self-contained, which matches the API POST handler
16
+ * creating a fresh server per request.
17
+ */
18
+ const PROTOCOL_VERSION = '2024-11-05';
19
+ const SERVER_INFO = { name: 'engram', version: VERSION };
20
+ export class McpServer {
21
+ engram;
22
+ onEvent;
23
+ keepAlive;
24
+ constructor(opts) {
25
+ this.engram = opts.engram;
26
+ this.onEvent = opts.onEvent;
27
+ }
28
+ /**
29
+ * Open the server→client SSE channel. The Engram tools are request/response
30
+ * only and never push server-initiated notifications, so the stream simply
31
+ * announces readiness and emits periodic keepalives to keep proxies from
32
+ * closing an idle connection. Actual tool calls flow through `handle()`.
33
+ */
34
+ async start() {
35
+ this.onEvent?.('ready', { serverInfo: SERVER_INFO, protocolVersion: PROTOCOL_VERSION });
36
+ this.keepAlive = setInterval(() => {
37
+ try {
38
+ this.onEvent?.('ping', {});
39
+ }
40
+ catch {
41
+ /* stream already closed — stop() will clear the timer */
42
+ }
43
+ }, 25_000);
44
+ // Don't let keepalives alone hold the event loop open.
45
+ this.keepAlive.unref?.();
46
+ }
47
+ async stop() {
48
+ if (this.keepAlive) {
49
+ clearInterval(this.keepAlive);
50
+ this.keepAlive = undefined;
51
+ }
52
+ }
53
+ /**
54
+ * Handle one JSON-RPC message, or a batch array. Returns the response(s), or
55
+ * `null` for notifications (messages without an `id`), which per JSON-RPC
56
+ * receive no reply — the caller should answer 202 with no body.
57
+ */
58
+ async handle(message) {
59
+ if (Array.isArray(message)) {
60
+ const out = [];
61
+ for (const m of message) {
62
+ const r = await this.handleOne(m);
63
+ if (r)
64
+ out.push(r);
65
+ }
66
+ return out.length ? out : null;
67
+ }
68
+ return this.handleOne(message);
69
+ }
70
+ async handleOne(req) {
71
+ const id = req?.id ?? null;
72
+ // JSON-RPC notifications omit `id` entirely (undefined). `id: null` or
73
+ // `id: 0` are valid request ids and still expect a response.
74
+ if (!req || req.id === undefined) {
75
+ // e.g. notifications/initialized, notifications/cancelled — no-op, no reply.
76
+ return null;
77
+ }
78
+ const method = req.method;
79
+ try {
80
+ switch (method) {
81
+ case 'initialize':
82
+ return this.ok(id, {
83
+ protocolVersion: req.params?.protocolVersion ?? PROTOCOL_VERSION,
84
+ capabilities: { tools: {} },
85
+ serverInfo: SERVER_INFO,
86
+ });
87
+ case 'ping':
88
+ return this.ok(id, {});
89
+ case 'tools/list':
90
+ return this.ok(id, {
91
+ tools: ALL_TOOLS.map((t) => ({
92
+ name: t.name,
93
+ description: t.description,
94
+ inputSchema: t.inputSchema,
95
+ })),
96
+ });
97
+ case 'tools/call': {
98
+ const name = req.params?.name;
99
+ const args = (req.params?.arguments ?? {});
100
+ if (!name) {
101
+ return this.err(id, -32602, 'Invalid params: tool name is required');
102
+ }
103
+ const result = await callTool(this.engram, name, args);
104
+ const isError = !!(result &&
105
+ typeof result === 'object' &&
106
+ result.success === false);
107
+ return this.ok(id, {
108
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
109
+ isError,
110
+ });
111
+ }
112
+ default:
113
+ return this.err(id, -32601, `Method not found: ${method ?? '(none)'}`);
114
+ }
115
+ }
116
+ catch (err) {
117
+ return this.err(id, -32603, `Internal error: ${err instanceof Error ? err.message : String(err)}`);
118
+ }
119
+ }
120
+ ok(id, result) {
121
+ return { jsonrpc: '2.0', id, result };
122
+ }
123
+ err(id, code, message) {
124
+ return { jsonrpc: '2.0', id, error: { code, message } };
125
+ }
126
+ }
127
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,gBAAgB,GAAG,YAAY,CAAC;AACtC,MAAM,WAAW,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAuBzD,MAAM,OAAO,SAAS;IACH,MAAM,CAAS;IACf,OAAO,CAA0C;IAC1D,SAAS,CAAkC;IAEnD,YAAY,IAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC9B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACxF,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC;gBACH,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,yDAAyD;YAC3D,CAAC;QACH,CAAC,EAAE,MAAM,CAAC,CAAC;QACX,uDAAuD;QACtD,IAAI,CAAC,SAAoC,CAAC,KAAK,EAAE,EAAE,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,aAAa,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CACV,OAAgB;QAEhB,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAsB,EAAE,CAAC;YAClC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,CAAmB,CAAC,CAAC;gBACpD,IAAI,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACrB,CAAC;YACD,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAyB,CAAC,CAAC;IACnD,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,GAAmB;QACzC,MAAM,EAAE,GAAG,GAAG,EAAE,EAAE,IAAI,IAAI,CAAC;QAC3B,uEAAuE;QACvE,6DAA6D;QAC7D,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YACjC,6EAA6E;YAC7E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC;YACH,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,YAAY;oBACf,OAAO,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;wBACjB,eAAe,EACZ,GAAG,CAAC,MAAM,EAAE,eAAsC,IAAI,gBAAgB;wBACzE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;wBAC3B,UAAU,EAAE,WAAW;qBACxB,CAAC,CAAC;gBACL,KAAK,MAAM;oBACT,OAAO,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACzB,KAAK,YAAY;oBACf,OAAO,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;wBACjB,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BAC3B,IAAI,EAAE,CAAC,CAAC,IAAI;4BACZ,WAAW,EAAE,CAAC,CAAC,WAAW;4BAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;yBAC3B,CAAC,CAAC;qBACJ,CAAC,CAAC;gBACL,KAAK,YAAY,CAAC,CAAC,CAAC;oBAClB,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,EAAE,IAA0B,CAAC;oBACpD,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,IAAI,EAAE,CAA4B,CAAC;oBACtE,IAAI,CAAC,IAAI,EAAE,CAAC;wBACV,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,uCAAuC,CAAC,CAAC;oBACvE,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;oBACvD,MAAM,OAAO,GAAG,CAAC,CAAC,CAChB,MAAM;wBACN,OAAO,MAAM,KAAK,QAAQ;wBACzB,MAAgC,CAAC,OAAO,KAAK,KAAK,CACpD,CAAC;oBACF,OAAO,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;wBACjB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;wBAClE,OAAO;qBACR,CAAC,CAAC;gBACL,CAAC;gBACD;oBACE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,qBAAqB,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,GAAG,CACb,EAAE,EACF,CAAC,KAAK,EACN,mBAAmB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACtE,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,EAAE,CAAC,EAA0B,EAAE,MAAe;QACpD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC;IACxC,CAAC;IAEO,GAAG,CAAC,EAA0B,EAAE,IAAY,EAAE,OAAe;QACnE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;IAC1D,CAAC;CACF"}
@@ -13,5 +13,6 @@ export interface McpResponse<T = unknown> {
13
13
  };
14
14
  suggestions?: string[];
15
15
  }
16
+ export declare const VERSION: string;
16
17
  export declare function ok<T>(data: T, sessionId: string, startMs: number, suggestions?: string[]): McpResponse<T>;
17
18
  export declare function fail(code: string, message: string, sessionId: string, startMs: number, suggestions?: string[]): McpResponse;
package/dist/response.js CHANGED
@@ -1,4 +1,8 @@
1
- const VERSION = '0.2.0';
1
+ import { createRequire } from 'node:module';
2
+ // Single-source the version from package.json — hardcoded copies drifted
3
+ // (package.json was bumped to 0.3.0 while '0.2.0' lingered in three files).
4
+ // '../package.json' resolves to the package root from both src/ and dist/.
5
+ export const VERSION = createRequire(import.meta.url)('../package.json').version;
2
6
  export function ok(data, sessionId, startMs, suggestions) {
3
7
  return {
4
8
  success: true,
@@ -1 +1 @@
1
- {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,UAAU,EAAE,CAChB,IAAO,EACP,SAAiB,EACjB,OAAe,EACf,WAAsB;IAEtB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI;QACJ,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE;QACtF,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,IAAY,EACZ,OAAe,EACf,SAAiB,EACjB,OAAe,EACf,WAAsB;IAEtB,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;QACzE,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE;KACvF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAU5C,yEAAyE;AACzE,4EAA4E;AAC5E,2EAA2E;AAC3E,MAAM,CAAC,MAAM,OAAO,GAAW,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC;AAEzF,MAAM,UAAU,EAAE,CAChB,IAAO,EACP,SAAiB,EACjB,OAAe,EACf,WAAsB;IAEtB,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI;QACJ,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE;QACtF,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI,CAClB,IAAY,EACZ,OAAe,EACf,SAAiB,EACjB,OAAe,EACf,WAAsB;IAEtB,OAAO;QACL,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;QACzE,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE;KACvF,CAAC;AACJ,CAAC"}
package/dist/server.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Engram MCP Server v0.2.0
3
+ * Engram MCP Server (version: see package.json)
4
4
  * Exposes agent memory as structured relational intelligence.
5
- * Transport: stdio
5
+ * Transport: stdio (this is the `engram-mcp` bin).
6
+ *
7
+ * The tool registry and dispatch live in ./dispatch.js so the hosted API's
8
+ * in-process McpServer (./mcp-server.js) drives exactly the same tools.
6
9
  */
7
10
  export {};
package/dist/server.js CHANGED
@@ -1,39 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Engram MCP Server v0.2.0
3
+ * Engram MCP Server (version: see package.json)
4
4
  * Exposes agent memory as structured relational intelligence.
5
- * Transport: stdio
5
+ * Transport: stdio (this is the `engram-mcp` bin).
6
+ *
7
+ * The tool registry and dispatch live in ./dispatch.js so the hosted API's
8
+ * in-process McpServer (./mcp-server.js) drives exactly the same tools.
6
9
  */
7
10
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
11
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
12
  import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
10
13
  import { getEngram } from './client.js';
11
- import { toolRemember, REMEMBER_SCHEMA } from './tools/remember.js';
12
- import { toolRecall, RECALL_SCHEMA } from './tools/recall.js';
13
- import { toolSearch, SEARCH_SCHEMA } from './tools/search.js';
14
- import { toolContext, CONTEXT_SCHEMA } from './tools/context.js';
15
- import { toolImpact, IMPACT_SCHEMA } from './tools/impact.js';
16
- import { toolDetectChanges, DETECT_CHANGES_SCHEMA } from './tools/detect_changes.js';
17
- import { toolConsolidate, CONSOLIDATE_SCHEMA } from './tools/consolidate.js';
18
- import { toolProcessDetect, PROCESS_DETECT_SCHEMA } from './tools/process_detect.js';
19
- import { toolForget, FORGET_SCHEMA } from './tools/forget.js';
20
- import { toolStats, STATS_SCHEMA } from './tools/stats.js';
21
- import { toolGraph, GRAPH_SCHEMA } from './tools/graph.js';
22
- const ALL_TOOLS = [
23
- REMEMBER_SCHEMA,
24
- RECALL_SCHEMA,
25
- SEARCH_SCHEMA,
26
- CONTEXT_SCHEMA,
27
- IMPACT_SCHEMA,
28
- DETECT_CHANGES_SCHEMA,
29
- CONSOLIDATE_SCHEMA,
30
- PROCESS_DETECT_SCHEMA,
31
- FORGET_SCHEMA,
32
- STATS_SCHEMA,
33
- GRAPH_SCHEMA,
34
- ];
14
+ import { VERSION } from './response.js';
15
+ import { ALL_TOOLS, callTool } from './dispatch.js';
35
16
  async function main() {
36
- const server = new Server({ name: 'engram', version: '0.2.0' }, { capabilities: { tools: {} } });
17
+ const server = new Server({ name: 'engram', version: VERSION }, { capabilities: { tools: {} } });
37
18
  // List available tools
38
19
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
39
20
  tools: ALL_TOOLS.map(t => ({
@@ -42,54 +23,11 @@ async function main() {
42
23
  inputSchema: t.inputSchema,
43
24
  })),
44
25
  }));
45
- // Handle tool calls
26
+ // Handle tool calls — stdio uses the process-global (config-driven) Engram.
46
27
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
47
28
  const { name, arguments: args = {} } = request.params;
48
29
  const engram = await getEngram();
49
- let result;
50
- // Cast via unknown to satisfy TypeScript — runtime validation is in each tool handler
51
- const a = args;
52
- switch (name) {
53
- case 'remember':
54
- result = await toolRemember(engram, a);
55
- break;
56
- case 'recall':
57
- result = await toolRecall(engram, a);
58
- break;
59
- case 'search':
60
- result = await toolSearch(engram, a);
61
- break;
62
- case 'context':
63
- result = await toolContext(engram, a);
64
- break;
65
- case 'impact':
66
- result = await toolImpact(engram, a);
67
- break;
68
- case 'detect_changes':
69
- result = await toolDetectChanges(engram, a);
70
- break;
71
- case 'consolidate':
72
- result = await toolConsolidate(engram, a);
73
- break;
74
- case 'process_detect':
75
- result = await toolProcessDetect(engram, a);
76
- break;
77
- case 'forget':
78
- result = await toolForget(engram, a);
79
- break;
80
- case 'stats':
81
- result = await toolStats(engram, a);
82
- break;
83
- case 'graph':
84
- result = await toolGraph(engram, a);
85
- break;
86
- default:
87
- result = {
88
- success: false,
89
- error: { code: 'UNKNOWN_TOOL', message: `Unknown tool: ${name}` },
90
- meta: { query_time_ms: 0, version: '0.2.0', session_id: 'unknown' },
91
- };
92
- }
30
+ const result = await callTool(engram, name, args);
93
31
  return {
94
32
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
95
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EACpC,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IAEF,uBAAuB;IACvB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;IAEJ,4EAA4E;IAC5E,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,IAA+B,CAAC,CAAC;QAC7E,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,GAAG,IAAI,CAAC,CAAC;IACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@cartisien/engram-mcp",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "MCP server for Engram — structured agent memory as relational intelligence",
5
5
  "type": "module",
6
- "main": "dist/server.js",
6
+ "main": "dist/index.js",
7
7
  "bin": {
8
8
  "engram-mcp": "dist/server.js"
9
9
  },
@@ -31,6 +31,14 @@
31
31
  "engines": {
32
32
  "node": ">=18.0.0"
33
33
  },
34
+ "types": "dist/index.d.ts",
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "import": "./dist/index.js"
39
+ },
40
+ "./package.json": "./package.json"
41
+ },
34
42
  "scripts": {
35
43
  "build": "tsc",
36
44
  "dev": "tsc --watch",