memento-mcp 0.3.6 → 0.3.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memento-mcp",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "mcpName": "io.github.myrakrusemark/memento-protocol",
5
5
  "description": "The Memento Protocol — persistent memory for AI agents",
6
6
  "type": "module",
@@ -143,9 +143,11 @@ if [ -z "$SAAS_COUNT" ] || [ "$SAAS_COUNT" = "0" ]; then
143
143
  "$TOAST" memento "✓ ${EXTRACTED_COUNT} memories stored" &>/dev/null
144
144
  else
145
145
  "$TOAST" memento "✓ No memories matched" &>/dev/null
146
- exit 0
147
146
  fi
148
- else
147
+ exit 0
148
+ fi
149
+
150
+ if [ "$SAAS_COUNT" != "0" ]; then
149
151
  if [ -n "$EXTRACTED_COUNT" ] && [ "$EXTRACTED_COUNT" != "0" ]; then
150
152
  "$TOAST" memento "✓ ${SAAS_COUNT} recalled, ${EXTRACTED_COUNT} stored" &>/dev/null
151
153
  else
@@ -159,11 +161,12 @@ if [ -n "$EXTRACTED_COUNT" ] && [ "$EXTRACTED_COUNT" != "0" ]; then
159
161
  SUMMARY="${SUMMARY}, ${EXTRACTED_COUNT} memories stored"
160
162
  fi
161
163
 
162
- # Block the Stop so Claude continues the reason becomes Claude's next instruction.
164
+ # Block the Stop so recalled memories are injected into context.
165
+ # If no memories are relevant, respond with <...> to signal active silence.
163
166
  REASON="${SUMMARY} surfaced from your last response.
164
167
  ${SAAS_DETAIL}
165
168
 
166
- You have absorbed these memories into context. If any recalled memory is stale, wrong, or overlaps with others — update, delete, or consolidate it now. Otherwise continue naturally."
169
+ You have absorbed these memories into context. If any recalled memory is stale, wrong, or overlaps with others — update, delete, or consolidate it now. Otherwise respond with <...> to continue naturally."
167
170
 
168
171
  python3 -c "
169
172
  import json, sys
package/src/index.js CHANGED
@@ -433,6 +433,72 @@ This is reconsolidation — like how the brain rebuilds memories on recall. Freq
433
433
  }
434
434
  );
435
435
 
436
+ // ---------------------------------------------------------------------------
437
+ // Tool: memento_extract
438
+ // ---------------------------------------------------------------------------
439
+
440
+ server.tool(
441
+ "memento_extract",
442
+ `Extract memories from a conversation transcript or the conversation buffer using LLM. Use this to manually trigger memory extraction — e.g., to flush the buffer before ending a session, or to extract from a pasted transcript.
443
+
444
+ Two modes:
445
+ - "distill" (default): Full extraction — facts, decisions, instructions, observations. Up to 20 memories.
446
+ - "seeds": Relational/experiential texture — preferences, emotions, sensory details. Up to 3 memories.
447
+
448
+ If no transcript is provided, reads from the conversation buffer (auto-populated by the context hook). Buffer is cleared after extraction unless keep_buffer is true.`,
449
+ {
450
+ transcript: z.string().optional().describe("Raw conversation text. If omitted, reads from the conversation buffer."),
451
+ mode: z.enum(["distill", "seeds"]).optional().describe("Extraction mode (default: distill)"),
452
+ max_memories: z.number().optional().describe("Override max memories to extract"),
453
+ keep_buffer: z.boolean().optional().describe("If true, don't clear the buffer after reading it"),
454
+ },
455
+ async ({ transcript, mode, max_memories, keep_buffer }) => {
456
+ const result = await storage.extractMemories(null, {
457
+ transcript,
458
+ mode,
459
+ max_memories,
460
+ keep_buffer,
461
+ });
462
+
463
+ if (result.error && !result.stored) {
464
+ return {
465
+ content: [{ type: "text", text: `Error: ${result.error}` }],
466
+ isError: true,
467
+ };
468
+ }
469
+
470
+ if (result.error) {
471
+ // Partial success — extraction ran but had issues
472
+ const summary = result.stored?.length > 0
473
+ ? result.stored.map((m) => `- **${m.id}** (${m.type}): ${m.content}`).join("\n")
474
+ : "No memories extracted.";
475
+ return {
476
+ content: [{
477
+ type: "text",
478
+ text: `Extraction completed with warning: ${result.error}\n\n${summary}`,
479
+ }],
480
+ };
481
+ }
482
+
483
+ if (!result.stored || result.stored.length === 0) {
484
+ return {
485
+ content: [{
486
+ type: "text",
487
+ text: `No novel memories found (mode: ${result.mode || mode || "distill"}, source: ${result.source || "unknown"}).`,
488
+ }],
489
+ };
490
+ }
491
+
492
+ const summary = result.stored.map((m) => `- **${m.id}** (${m.type}): ${m.content}`).join("\n");
493
+ return {
494
+ content: [{
495
+ type: "text",
496
+ text: `Extracted ${result.count} memor${result.count === 1 ? "y" : "ies"} (mode: ${result.mode}, source: ${result.source}):\n\n${summary}`,
497
+ }],
498
+ };
499
+ }
500
+ );
501
+
436
502
  // ---------------------------------------------------------------------------
437
503
  // Tool: memento_skip_add
438
504
  // ---------------------------------------------------------------------------
@@ -261,6 +261,19 @@ export class HostedStorageAdapter extends StorageInterface {
261
261
  return res;
262
262
  }
263
263
 
264
+ async extractMemories(_wsPath, { transcript, mode, max_memories, source_tag, keep_buffer }) {
265
+ const body = {};
266
+ if (transcript) body.transcript = transcript;
267
+ if (mode) body.mode = mode;
268
+ if (max_memories) body.max_memories = max_memories;
269
+ if (source_tag) body.source_tag = source_tag;
270
+ if (keep_buffer !== undefined) body.keep_buffer = keep_buffer;
271
+
272
+ const res = await this._fetchJson("POST", "/v1/extract", body);
273
+ if (res.error && !res.stored) return { error: res.error };
274
+ return res;
275
+ }
276
+
264
277
  async getIdentity(_wsPath) {
265
278
  const { text, isError } = await this._fetch("GET", "/v1/identity");
266
279
  if (isError) return { error: text };