@mnemoverse/mcp-memory-server 0.4.2 → 0.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.
- package/README.md +2 -1
- package/dist/index.js +399 -37
- package/dist/index.js.map +1 -1
- package/dist/render.d.ts +71 -0
- package/dist/render.js +95 -0
- package/dist/render.js.map +1 -0
- package/dist/teaching.d.ts +58 -0
- package/dist/teaching.js +75 -0
- package/dist/teaching.js.map +1 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -199,7 +199,8 @@ If it doesn't remember: check that the client was fully restarted and the config
|
|
|
199
199
|
| Tool | What it does |
|
|
200
200
|
|------|-------------|
|
|
201
201
|
| `memory_write` | Store a memory — insight, preference, lesson learned |
|
|
202
|
-
| `memory_read` | Search memories by natural language query |
|
|
202
|
+
| `memory_read` | Search memories by natural language query (optional recency ordering, time bounds, author exclusion) |
|
|
203
|
+
| `memory_list_recent` | List newest memories first — no query; `since` watermark + cursor paging |
|
|
203
204
|
| `memory_feedback` | Rate memories as helpful or not (improves future recall) |
|
|
204
205
|
| `memory_stats` | Check how many memories stored, which domains exist |
|
|
205
206
|
| `memory_delete` | Permanently delete a single memory by `atom_id` |
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
|
+
import { formatReadItem, formatRecentPage, safeInline, } from "./render.js";
|
|
7
|
+
import { SERVER_INSTRUCTIONS, buildReadEmptyResponse } from "./teaching.js";
|
|
6
8
|
// Version is read at runtime from package.json so there is exactly one place
|
|
7
9
|
// to bump on each release. Works both from `dist/` during local dev and from
|
|
8
10
|
// `node_modules/@mnemoverse/mcp-memory-server/dist/` after an npm install.
|
|
@@ -67,7 +69,7 @@ async function apiFetch(path, options = {}) {
|
|
|
67
69
|
* result stays well-formed. Otherwise an emoji or non-BMP character at the
|
|
68
70
|
* boundary can produce a lone surrogate and corrupt downstream JSON encoding.
|
|
69
71
|
*/
|
|
70
|
-
function capResult(text) {
|
|
72
|
+
function capResult(text, moreHint = "Use a more specific query or smaller top_k to see all results.") {
|
|
71
73
|
if (text.length <= MAX_RESULT_CHARS)
|
|
72
74
|
return text;
|
|
73
75
|
let truncated = text.slice(0, MAX_RESULT_CHARS - 200);
|
|
@@ -75,17 +77,33 @@ function capResult(text) {
|
|
|
75
77
|
if (lastCode >= 0xd800 && lastCode <= 0xdbff) {
|
|
76
78
|
truncated = truncated.slice(0, -1);
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
// `moreHint` lets no-input tools (the discovery lists) give accurate truncation
|
|
81
|
+
// guidance instead of the read-tool default (which points at query/top_k controls a
|
|
82
|
+
// repeated no-arg call cannot use). Existing callers keep the default message.
|
|
83
|
+
return `${truncated}\n\n[…truncated to fit the 25K token limit. ${moreHint}]`;
|
|
80
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Sanitize an untrusted string for safe inline rendering in tool output that a
|
|
87
|
+
* DIFFERENT principal's LLM will read (CN-032 anti-injection). A room name is
|
|
88
|
+
* chosen by the room OWNER but surfaced to a JOINER's assistant on join/invite;
|
|
89
|
+
* core only trims whitespace on it, so quotes/colons/newlines pass. Strip to a
|
|
90
|
+
* conservative charset and collapse whitespace, then cap length. Same treatment
|
|
91
|
+
* `formatAuthorTag` already applies to a server-stamped author.
|
|
92
|
+
* Implementation lives in src/render.ts (shared with the item renderers,
|
|
93
|
+
* testable there); re-imported here for the 15 other call sites.
|
|
94
|
+
*/
|
|
81
95
|
// --- Server setup ---
|
|
96
|
+
// The second argument lands verbatim in the connected model's system prompt on
|
|
97
|
+
// clients that surface MCP instructions — it is the single highest-leverage
|
|
98
|
+
// teaching surface this server has. Kept in src/teaching.ts so tests can
|
|
99
|
+
// assert its polarity/length without booting the server.
|
|
82
100
|
const server = new McpServer({
|
|
83
101
|
name: "mnemoverse-memory",
|
|
84
102
|
version: pkg.version,
|
|
85
|
-
});
|
|
103
|
+
}, { instructions: SERVER_INSTRUCTIONS });
|
|
86
104
|
// --- Tool: memory_write ---
|
|
87
105
|
server.registerTool("memory_write", {
|
|
88
|
-
description: "Store a long-term memory that persists across sessions AND across every AI tool the user has connected to Mnemoverse (Claude, ChatGPT, Cursor, VS Code) — write once, recall everywhere. Call this PROACTIVELY the moment the user states a preference, makes a decision, or you learn a durable fact (people, roles, project setup, a lesson). Don't wait to be asked.
|
|
106
|
+
description: "Store a long-term memory that persists across sessions AND across every AI tool the user has connected to Mnemoverse (Claude, ChatGPT, Cursor, VS Code) — write once, recall everywhere. Call this PROACTIVELY the moment the user states a preference, makes a decision, or you learn a durable fact (people, roles, project setup, a lesson). Don't wait to be asked. Never store passwords, API keys, payment data, MFA codes, government IDs, or health records; skip transient chatter that only matters this turn. Behavior: an importance gate may filter low-value writes, so the result tells you whether the memory was stored or filtered. Write `content` as a self-contained statement that still makes sense when recalled out of context.",
|
|
89
107
|
inputSchema: {
|
|
90
108
|
content: z
|
|
91
109
|
.string()
|
|
@@ -139,7 +157,7 @@ server.registerTool("memory_write", {
|
|
|
139
157
|
});
|
|
140
158
|
// --- Tool: memory_read ---
|
|
141
159
|
server.registerTool("memory_read", {
|
|
142
|
-
description: "Search your long-term memory before answering anything that may have come up before — user preferences, past decisions, project setup, people, or earlier context. This memory is shared: it persists across sessions and across every AI tool the user has connected (Claude, ChatGPT, Cursor, VS Code). ALWAYS check here first when you're unsure whether you already know something; no need to call it for general world knowledge you already hold. Returns matches ranked by relevance (
|
|
160
|
+
description: "Search your long-term memory before answering anything that may have come up before — user preferences, past decisions, project setup, people, or earlier context. This memory is shared: it persists across sessions and across every AI tool the user has connected (Claude, ChatGPT, Cursor, VS Code). ALWAYS check here first when you're unsure whether you already know something; no need to call it for general world knowledge you already hold. Returns matches ranked by relevance (or newest-first with order_by: 'recency'); each result carries an id you can pass to memory_feedback or memory_delete.",
|
|
143
161
|
inputSchema: {
|
|
144
162
|
query: z
|
|
145
163
|
.string()
|
|
@@ -157,6 +175,31 @@ server.registerTool("memory_read", {
|
|
|
157
175
|
.string()
|
|
158
176
|
.optional()
|
|
159
177
|
.describe("Restrict the search to one domain namespace (e.g. 'project:acme'); omit to search across all domains."),
|
|
178
|
+
order_by: z
|
|
179
|
+
.enum(["relevance", "recency"])
|
|
180
|
+
.optional()
|
|
181
|
+
.describe("'relevance' (default) = ranking order. 'recency' = the matched " +
|
|
182
|
+
"set re-sorted newest-first. For a complete newest-first feed " +
|
|
183
|
+
"with no search at all, use memory_list_recent instead."),
|
|
184
|
+
since: z
|
|
185
|
+
.string()
|
|
186
|
+
.max(40)
|
|
187
|
+
.optional()
|
|
188
|
+
.describe("Only memories created at/after this ISO-8601 instant (naive = " +
|
|
189
|
+
"UTC) — e.g. your last-seen watermark in a shared room."),
|
|
190
|
+
until: z
|
|
191
|
+
.string()
|
|
192
|
+
.max(40)
|
|
193
|
+
.optional()
|
|
194
|
+
.describe("Only memories created at/before this ISO-8601 instant."),
|
|
195
|
+
exclude_author: z
|
|
196
|
+
.string()
|
|
197
|
+
.max(200)
|
|
198
|
+
.optional()
|
|
199
|
+
.describe("Drop memories written by this author PRINCIPAL (the server-side " +
|
|
200
|
+
"identity, not shown in these results). Useful when your system " +
|
|
201
|
+
"knows principals (e.g. via the REST API); a self-exclusion " +
|
|
202
|
+
"shortcut is planned server-side."),
|
|
160
203
|
},
|
|
161
204
|
annotations: {
|
|
162
205
|
title: "Search Memories",
|
|
@@ -165,7 +208,7 @@ server.registerTool("memory_read", {
|
|
|
165
208
|
idempotentHint: true,
|
|
166
209
|
openWorldHint: true,
|
|
167
210
|
},
|
|
168
|
-
}, async ({ query, top_k, domain }) => {
|
|
211
|
+
}, async ({ query, top_k, domain, order_by, since, until, exclude_author }) => {
|
|
169
212
|
const r = await apiFetch("/memory/read", {
|
|
170
213
|
method: "POST",
|
|
171
214
|
body: JSON.stringify({
|
|
@@ -173,42 +216,50 @@ server.registerTool("memory_read", {
|
|
|
173
216
|
top_k: top_k || 5,
|
|
174
217
|
domain: domain || undefined,
|
|
175
218
|
include_associations: true,
|
|
219
|
+
// #404 temporal dimension — omitted entirely when unused so the
|
|
220
|
+
// request body stays byte-identical for existing callers.
|
|
221
|
+
...(order_by ? { order_by } : {}),
|
|
222
|
+
...(since ? { since } : {}),
|
|
223
|
+
...(until ? { until } : {}),
|
|
224
|
+
...(exclude_author ? { exclude_author } : {}),
|
|
176
225
|
}),
|
|
177
226
|
});
|
|
178
227
|
const items = Array.isArray(r?.items) ? r.items : [];
|
|
179
|
-
if (items.length === 0) {
|
|
228
|
+
if (items.length === 0 && (since || until || exclude_author)) {
|
|
229
|
+
// A bounded/filtered read that finds nothing is NOT a bad query —
|
|
230
|
+
// the truthful answer is "nothing new for these filters" (mirrors
|
|
231
|
+
// memory_list_recent's empty copy; no stats probe, no broaden hint).
|
|
180
232
|
return {
|
|
181
233
|
content: [
|
|
182
|
-
{
|
|
234
|
+
{
|
|
235
|
+
type: "text",
|
|
236
|
+
text: "Nothing matching within the given time/author filters.",
|
|
237
|
+
},
|
|
183
238
|
],
|
|
184
239
|
};
|
|
185
240
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
? ` (${item.concepts.join(", ")})`
|
|
209
|
-
: "";
|
|
210
|
-
return `${i + 1}. [${relevance}%] ${content}${concepts}${formatAuthorTag(item?.provenance)}`;
|
|
211
|
-
});
|
|
241
|
+
if (items.length === 0) {
|
|
242
|
+
// Zero results: ONE stats call (made only on this path) distinguishes a
|
|
243
|
+
// truly empty store (first contact — greet with how to save the first
|
|
244
|
+
// memory) from "no match for this query" (hint to broaden). Stats
|
|
245
|
+
// failure falls open to the plain no-match message. Domain-scoped reads
|
|
246
|
+
// never greet and never probe — the stats call measures the PERSONAL
|
|
247
|
+
// store, not the scoped domain. See src/teaching.ts.
|
|
248
|
+
const text = await buildReadEmptyResponse(() => apiFetch("/memory/stats"),
|
|
249
|
+
// trim(): a whitespace-only domain is not a real filter — treating it
|
|
250
|
+
// as scoped would silently suppress the first-contact greeting.
|
|
251
|
+
domain != null && domain.trim() !== "");
|
|
252
|
+
return {
|
|
253
|
+
content: [{ type: "text", text }],
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
// Rendering lives in src/render.ts (testable): each line carries the
|
|
257
|
+
// CN-001 author tag, the created_at date (#404 R1 — a reader cannot
|
|
258
|
+
// reason about recency it cannot see) and the full atom id (the tool
|
|
259
|
+
// description always promised ids for memory_feedback/memory_delete;
|
|
260
|
+
// the old render never delivered them, making both uncallable from
|
|
261
|
+
// read results).
|
|
262
|
+
const lines = items.map((item, i) => formatReadItem(item, i));
|
|
212
263
|
const searchMs = (r?.search_time_ms ?? 0).toFixed(0);
|
|
213
264
|
const text = lines.join("\n\n") + `\n\n(${searchMs}ms)`;
|
|
214
265
|
return {
|
|
@@ -220,6 +271,93 @@ server.registerTool("memory_read", {
|
|
|
220
271
|
],
|
|
221
272
|
};
|
|
222
273
|
});
|
|
274
|
+
// --- Tool: memory_list_recent ---
|
|
275
|
+
server.registerTool("memory_list_recent", {
|
|
276
|
+
description: "List the NEWEST memories first — no search query needed. Semantic search answers 'what do I know about X'; this answers 'what happened lately': resuming work after a break, catching up on a shared room ('any new messages?'), or reviewing what was saved recently. Pass `since` (your last-seen time) to get only what's new, and page through older entries with the returned cursor. Complete by construction — nothing is skipped, unlike a search that only returns semantic matches.",
|
|
277
|
+
inputSchema: {
|
|
278
|
+
domain: z
|
|
279
|
+
.string()
|
|
280
|
+
.optional()
|
|
281
|
+
.describe("Restrict to one domain (e.g. a shared room address 'xroom:...'); omit for all your domains."),
|
|
282
|
+
since: z
|
|
283
|
+
.string()
|
|
284
|
+
.optional()
|
|
285
|
+
.describe("Only entries created at/after this ISO-8601 instant (naive = UTC) — your novelty watermark."),
|
|
286
|
+
limit: z
|
|
287
|
+
.number()
|
|
288
|
+
.int()
|
|
289
|
+
.min(1)
|
|
290
|
+
.max(100)
|
|
291
|
+
.optional()
|
|
292
|
+
.describe("Page size (default: 20). Newest first."),
|
|
293
|
+
cursor: z
|
|
294
|
+
.string()
|
|
295
|
+
.max(512)
|
|
296
|
+
.optional()
|
|
297
|
+
.describe("Opaque cursor from a previous page's 'More older entries exist' line — continues the listing without skips or duplicates."),
|
|
298
|
+
},
|
|
299
|
+
annotations: {
|
|
300
|
+
title: "List Recent Memories",
|
|
301
|
+
readOnlyHint: true,
|
|
302
|
+
destructiveHint: false,
|
|
303
|
+
idempotentHint: true,
|
|
304
|
+
openWorldHint: true,
|
|
305
|
+
},
|
|
306
|
+
}, async ({ domain, since, limit, cursor }) => {
|
|
307
|
+
let r;
|
|
308
|
+
try {
|
|
309
|
+
r = await apiFetch("/memory/recent", {
|
|
310
|
+
method: "POST",
|
|
311
|
+
body: JSON.stringify({
|
|
312
|
+
domain: domain || undefined,
|
|
313
|
+
since: since || undefined,
|
|
314
|
+
limit: limit || 20,
|
|
315
|
+
cursor: cursor || undefined,
|
|
316
|
+
}),
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
catch (e) {
|
|
320
|
+
// Graceful degradation while the server side rolls out: a 404 from
|
|
321
|
+
// core means the /memory/recent endpoint is not deployed yet — say
|
|
322
|
+
// so instead of surfacing a raw HTTP error.
|
|
323
|
+
const endpointAbsent = e instanceof Error &&
|
|
324
|
+
e.message.startsWith("Mnemoverse API error 404:") &&
|
|
325
|
+
!e.message.includes('"code"');
|
|
326
|
+
if (endpointAbsent) {
|
|
327
|
+
return {
|
|
328
|
+
content: [
|
|
329
|
+
{
|
|
330
|
+
type: "text",
|
|
331
|
+
text: "The memory service does not support the recent-entries feed yet. " +
|
|
332
|
+
"Use memory_read with order_by: 'recency' as an approximation.",
|
|
333
|
+
},
|
|
334
|
+
],
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
throw e;
|
|
338
|
+
}
|
|
339
|
+
const items = Array.isArray(r?.items) ? r.items : [];
|
|
340
|
+
if (items.length === 0) {
|
|
341
|
+
return {
|
|
342
|
+
content: [
|
|
343
|
+
{
|
|
344
|
+
type: "text",
|
|
345
|
+
text: since
|
|
346
|
+
? "Nothing new since your watermark."
|
|
347
|
+
: "No memories here yet.",
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
content: [
|
|
354
|
+
{
|
|
355
|
+
type: "text",
|
|
356
|
+
text: capResult(formatRecentPage(items, r?.next_cursor), "Lower `limit` or add a `domain` for smaller pages."),
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
};
|
|
360
|
+
});
|
|
223
361
|
// --- Tool: memory_feedback ---
|
|
224
362
|
server.registerTool("memory_feedback", {
|
|
225
363
|
description: "Report whether memories returned by memory_read were actually helpful. This is a learning signal, not a log: positive feedback raises a memory's ranking so it surfaces faster next time (across all of the user's tools), negative feedback lets it fade. Call it right after you act on (or reject) recalled memories, passing the ids from the memory_read results.",
|
|
@@ -286,7 +424,7 @@ server.registerTool("memory_stats", {
|
|
|
286
424
|
});
|
|
287
425
|
// --- Tool: memory_delete ---
|
|
288
426
|
server.registerTool("memory_delete", {
|
|
289
|
-
description: "Permanently delete ONE memory by its atom_id — irreversible, the memory is gone for good. Use
|
|
427
|
+
description: "Permanently delete ONE memory by its atom_id — irreversible, the memory is gone for good. Use it to keep the memory trustworthy: prune a memory that is obsolete, superseded by a newer decision, or that you stored wrongly — and whenever the user asks to forget something. Get the atom_id from a memory_read result. To clear an entire topic at once, use memory_delete_domain instead.",
|
|
290
428
|
inputSchema: {
|
|
291
429
|
atom_id: z
|
|
292
430
|
.string()
|
|
@@ -326,7 +464,7 @@ server.registerTool("memory_delete", {
|
|
|
326
464
|
});
|
|
327
465
|
// --- Tool: memory_delete_domain ---
|
|
328
466
|
server.registerTool("memory_delete_domain", {
|
|
329
|
-
description: "Permanently delete EVERY memory in one domain — irreversible, and far more
|
|
467
|
+
description: "Permanently delete EVERY memory in one domain — irreversible, and far more sweeping than memory_delete. This is a bulk wipe: run it only when the user asks for it (e.g. 'forget everything about project X') or has explicitly confirmed a wipe you proposed — never on your own judgment alone. First run memory_stats to confirm the exact domain name, then pass it together with confirm=true (a deliberate safety interlock). For a single wrong or stale memory, memory_delete is the right tool.",
|
|
330
468
|
inputSchema: {
|
|
331
469
|
domain: z
|
|
332
470
|
.string()
|
|
@@ -361,6 +499,230 @@ async ({ domain }) => {
|
|
|
361
499
|
],
|
|
362
500
|
};
|
|
363
501
|
});
|
|
502
|
+
// --- Tool: memory_create_room ---
|
|
503
|
+
server.registerTool("memory_create_room", {
|
|
504
|
+
description: "Create a SHARED memory room — a space you and OTHER people's assistants can both read and write, across Claude/ChatGPT/Cursor. Use when the user wants to share context or collaborate with someone else (e.g. 'make a room for me and Olya'). Returns the room's address; pass that address as the `domain` on memory_write/memory_read to use it. To bring someone in, call memory_invite_to_room next.",
|
|
505
|
+
inputSchema: {
|
|
506
|
+
name: z
|
|
507
|
+
.string()
|
|
508
|
+
.min(1)
|
|
509
|
+
.max(200)
|
|
510
|
+
.describe("Room name, unique within your account (e.g. 'me-and-olya')."),
|
|
511
|
+
description: z
|
|
512
|
+
.string()
|
|
513
|
+
.max(2000)
|
|
514
|
+
.optional()
|
|
515
|
+
.describe("Optional description of the room."),
|
|
516
|
+
},
|
|
517
|
+
annotations: {
|
|
518
|
+
title: "Create shared room",
|
|
519
|
+
readOnlyHint: false,
|
|
520
|
+
destructiveHint: false,
|
|
521
|
+
idempotentHint: false,
|
|
522
|
+
openWorldHint: true,
|
|
523
|
+
},
|
|
524
|
+
}, async ({ name, description }) => {
|
|
525
|
+
const r = await apiFetch("/memory/rooms", {
|
|
526
|
+
method: "POST",
|
|
527
|
+
body: JSON.stringify({ name, description }),
|
|
528
|
+
});
|
|
529
|
+
const roomName = safeInline(r?.name ?? name);
|
|
530
|
+
const address = safeInline(r?.address);
|
|
531
|
+
const roomId = safeInline(r?.room_id);
|
|
532
|
+
// If core returned no usable id (empty body / sanitized away), don't print
|
|
533
|
+
// broken `domain=""` guidance — say so instead (Copilot).
|
|
534
|
+
const text = address
|
|
535
|
+
? `Created shared room "${roomName}". Address: ${address}\n` +
|
|
536
|
+
`Use it now: pass domain="${address}" on memory_write / memory_read.\n` +
|
|
537
|
+
(roomId
|
|
538
|
+
? `To add someone: call memory_invite_to_room with room_id="${roomId}".`
|
|
539
|
+
: "")
|
|
540
|
+
: `Room "${roomName}" was created but the server did not return a usable address — ` +
|
|
541
|
+
`retry, or check that your API key is set.`;
|
|
542
|
+
return {
|
|
543
|
+
content: [
|
|
544
|
+
{
|
|
545
|
+
type: "text",
|
|
546
|
+
text: capResult(text),
|
|
547
|
+
},
|
|
548
|
+
],
|
|
549
|
+
};
|
|
550
|
+
});
|
|
551
|
+
// --- Tool: memory_invite_to_room ---
|
|
552
|
+
server.registerTool("memory_invite_to_room", {
|
|
553
|
+
description: "Mint a one-time invite for a room you own and get a ready-to-forward message. The user sends that message to the person they want to add (any messenger); the recipient opens the link or tells THEIR assistant the code to join. Use after memory_create_room, or whenever the user says 'invite <someone>' to an existing room.",
|
|
554
|
+
inputSchema: {
|
|
555
|
+
room_id: z
|
|
556
|
+
.string()
|
|
557
|
+
.min(1)
|
|
558
|
+
.max(100)
|
|
559
|
+
.describe("The room's id (room_...), from memory_create_room."),
|
|
560
|
+
scope: z
|
|
561
|
+
.enum(["read", "read_write"])
|
|
562
|
+
.optional()
|
|
563
|
+
.describe("Role the invitee gets — 'read' or 'read_write' (default read_write)."),
|
|
564
|
+
expires_in_days: z
|
|
565
|
+
.number()
|
|
566
|
+
.int()
|
|
567
|
+
.min(1)
|
|
568
|
+
.max(90)
|
|
569
|
+
.optional()
|
|
570
|
+
.describe("Days until the invite expires (default 7)."),
|
|
571
|
+
},
|
|
572
|
+
annotations: {
|
|
573
|
+
title: "Invite to room",
|
|
574
|
+
readOnlyHint: false,
|
|
575
|
+
destructiveHint: false,
|
|
576
|
+
idempotentHint: false,
|
|
577
|
+
openWorldHint: true,
|
|
578
|
+
},
|
|
579
|
+
}, async ({ room_id, scope, expires_in_days }) => {
|
|
580
|
+
const r = await apiFetch(`/memory/rooms/${encodeURIComponent(room_id)}/invites`, {
|
|
581
|
+
method: "POST",
|
|
582
|
+
body: JSON.stringify({ scope, expires_in_days }),
|
|
583
|
+
});
|
|
584
|
+
return {
|
|
585
|
+
content: [
|
|
586
|
+
{
|
|
587
|
+
type: "text",
|
|
588
|
+
// Shown to the room OWNER (who minted it), not a foreign principal, so
|
|
589
|
+
// the core-generated share_message is fine as-is; capResult only bounds
|
|
590
|
+
// its length for the Connectors-Directory 25K cap.
|
|
591
|
+
text: capResult(`Invite ready. Forward this message to the person you're inviting:\n\n` +
|
|
592
|
+
`${r?.share_message ?? r?.join_url ?? "(no message returned)"}`),
|
|
593
|
+
},
|
|
594
|
+
],
|
|
595
|
+
};
|
|
596
|
+
});
|
|
597
|
+
// --- Tool: memory_join_room ---
|
|
598
|
+
server.registerTool("memory_join_room", {
|
|
599
|
+
description: "Join a shared memory room using an invite code (starts with 'mnvr_'). Use when the user pastes an invite code or says something like 'join room with code ...'. After joining, use the returned address as the `domain` on memory_write/memory_read to read and write the shared room.",
|
|
600
|
+
inputSchema: {
|
|
601
|
+
code: z.string().min(1).max(200).describe("The invite code (mnvr_...)."),
|
|
602
|
+
},
|
|
603
|
+
annotations: {
|
|
604
|
+
title: "Join room",
|
|
605
|
+
readOnlyHint: false,
|
|
606
|
+
destructiveHint: false,
|
|
607
|
+
idempotentHint: true,
|
|
608
|
+
openWorldHint: true,
|
|
609
|
+
},
|
|
610
|
+
}, async ({ code }) => {
|
|
611
|
+
const r = await apiFetch("/memory/rooms/join", {
|
|
612
|
+
method: "POST",
|
|
613
|
+
body: JSON.stringify({ code }),
|
|
614
|
+
});
|
|
615
|
+
// CN-032: the room name/scope are OWNER-chosen but rendered into the
|
|
616
|
+
// JOINER's LLM context here — sanitize before inlining (anti prompt-injection).
|
|
617
|
+
const roomName = safeInline(r?.name) || "the room";
|
|
618
|
+
const scope = safeInline(r?.scope) || "member";
|
|
619
|
+
const address = safeInline(r?.address);
|
|
620
|
+
const prefix = r?.already_member
|
|
621
|
+
? `You're already a member of "${roomName}".`
|
|
622
|
+
: `Joined "${roomName}" (${scope}).`;
|
|
623
|
+
// Don't print broken `domain=""` guidance if no address came back (Copilot).
|
|
624
|
+
const usage = address
|
|
625
|
+
? `Use it: pass domain="${address}" on memory_write / memory_read to read and write the shared room.`
|
|
626
|
+
: `The server did not return a room address — retry, or check that your API key is set.`;
|
|
627
|
+
return {
|
|
628
|
+
content: [
|
|
629
|
+
{
|
|
630
|
+
type: "text",
|
|
631
|
+
text: capResult(`${prefix}\n${usage}`),
|
|
632
|
+
},
|
|
633
|
+
],
|
|
634
|
+
};
|
|
635
|
+
});
|
|
636
|
+
// --- Tool: memory_list_rooms ---
|
|
637
|
+
server.registerTool("memory_list_rooms", {
|
|
638
|
+
description: "List the shared memory rooms you can use — the ones you OWN plus the ones you've JOINED — each with the address to pass as `domain` on memory_write / memory_read. Use this to RE-FIND a room in a new session (e.g. 'what rooms do I have?', 'resume the room with Olya') instead of having to create or re-join it.",
|
|
639
|
+
inputSchema: {},
|
|
640
|
+
annotations: {
|
|
641
|
+
title: "List rooms",
|
|
642
|
+
readOnlyHint: true,
|
|
643
|
+
destructiveHint: false,
|
|
644
|
+
idempotentHint: true,
|
|
645
|
+
openWorldHint: true,
|
|
646
|
+
},
|
|
647
|
+
}, async () => {
|
|
648
|
+
const rooms = await apiFetch("/memory/rooms");
|
|
649
|
+
const list = Array.isArray(rooms) ? rooms : [];
|
|
650
|
+
if (list.length === 0) {
|
|
651
|
+
return {
|
|
652
|
+
content: [
|
|
653
|
+
{
|
|
654
|
+
type: "text",
|
|
655
|
+
text: "You have no shared rooms yet. Create one with memory_create_room, " +
|
|
656
|
+
"or join one with memory_join_room using an invite code.",
|
|
657
|
+
},
|
|
658
|
+
],
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
// Room name is OWNER-chosen and surfaced to THIS assistant — sanitize it (CN-032),
|
|
662
|
+
// like memory_join_room already does. address/role/scope are server-shaped but pass
|
|
663
|
+
// through the same guard defensively.
|
|
664
|
+
const lines = list.map((r) => {
|
|
665
|
+
const name = safeInline(r?.name) || "(unnamed room)";
|
|
666
|
+
const roomId = safeInline(r?.room_id);
|
|
667
|
+
// Always surface the canonical address: fall back to xroom:<room_id> when the server
|
|
668
|
+
// omits `address`, so the domain guidance this tool promises is never silently dropped.
|
|
669
|
+
const address = safeInline(r?.address) || (roomId ? `xroom:${roomId}` : "");
|
|
670
|
+
const role = safeInline(r?.role);
|
|
671
|
+
const scope = safeInline(r?.scope);
|
|
672
|
+
const archived = r?.archived ? " [archived]" : "";
|
|
673
|
+
const use = address ? ` — use domain="${address}"` : "";
|
|
674
|
+
return `- "${name}" (${role}${scope ? `, ${scope}` : ""})${archived}${use}`;
|
|
675
|
+
});
|
|
676
|
+
const text = `Your shared rooms (${list.length}):\n${lines.join("\n")}`;
|
|
677
|
+
return {
|
|
678
|
+
content: [
|
|
679
|
+
{
|
|
680
|
+
type: "text",
|
|
681
|
+
text: capResult(text, "The room list was truncated — some rooms are not shown."),
|
|
682
|
+
},
|
|
683
|
+
],
|
|
684
|
+
};
|
|
685
|
+
});
|
|
686
|
+
// --- Tool: vault_list ---
|
|
687
|
+
server.registerTool("vault_list", {
|
|
688
|
+
description: "List the secrets stored in your Mnemoverse Vault — by ALIAS and purpose only; the secret VALUE is never returned or shown to you. Use this to DISCOVER which secret to use (e.g. the user says 'use my GitHub token' — find its alias here) before a tool that consumes it. Only YOUR account's secrets are listed.",
|
|
689
|
+
inputSchema: {},
|
|
690
|
+
annotations: {
|
|
691
|
+
title: "List vault secrets",
|
|
692
|
+
readOnlyHint: true,
|
|
693
|
+
destructiveHint: false,
|
|
694
|
+
idempotentHint: true,
|
|
695
|
+
openWorldHint: true,
|
|
696
|
+
},
|
|
697
|
+
}, async () => {
|
|
698
|
+
const r = await apiFetch("/vault/secrets");
|
|
699
|
+
const list = Array.isArray(r?.secrets) ? r.secrets : [];
|
|
700
|
+
if (list.length === 0) {
|
|
701
|
+
return {
|
|
702
|
+
content: [
|
|
703
|
+
{
|
|
704
|
+
type: "text",
|
|
705
|
+
text: "No secrets are stored in your Vault yet.",
|
|
706
|
+
},
|
|
707
|
+
],
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
const lines = list.map((s) => {
|
|
711
|
+
const alias = safeInline(s?.alias) || "(no alias)";
|
|
712
|
+
const context = safeInline(s?.context);
|
|
713
|
+
return context ? `- ${alias} — ${context}` : `- ${alias}`;
|
|
714
|
+
});
|
|
715
|
+
const text = `Your Vault secrets (${list.length}) — alias and purpose only, never the value:\n` +
|
|
716
|
+
lines.join("\n");
|
|
717
|
+
return {
|
|
718
|
+
content: [
|
|
719
|
+
{
|
|
720
|
+
type: "text",
|
|
721
|
+
text: capResult(text, "The secret list was truncated — some secrets are not shown."),
|
|
722
|
+
},
|
|
723
|
+
],
|
|
724
|
+
};
|
|
725
|
+
});
|
|
364
726
|
// --- Start ---
|
|
365
727
|
async function main() {
|
|
366
728
|
const transport = new StdioServerTransport();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result-rendering helpers for memory_read and memory_list_recent.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of index.ts (same move as teaching.ts) so tests can pin the
|
|
5
|
+
* rendered contract: since the #404 temporal work, every item line
|
|
6
|
+
* carries its id and created_at date WHENEVER the server provides them
|
|
7
|
+
* (memory_feedback / memory_delete are uncallable without ids — the tool
|
|
8
|
+
* description always promised them, the old render never delivered any;
|
|
9
|
+
* a reader cannot reason about recency it cannot see). Legacy response
|
|
10
|
+
* shapes without atom_id/created_at degrade gracefully: those parts of
|
|
11
|
+
* the line are simply omitted.
|
|
12
|
+
*/
|
|
13
|
+
/** CN-001 server-stamped authorship, as returned nested on read/feed items. */
|
|
14
|
+
export type Provenance = {
|
|
15
|
+
principal?: string | null;
|
|
16
|
+
agent?: string | null;
|
|
17
|
+
agent_name?: string | null;
|
|
18
|
+
client_env?: string | null;
|
|
19
|
+
is_external?: boolean | null;
|
|
20
|
+
};
|
|
21
|
+
export type ReadItem = {
|
|
22
|
+
atom_id?: string;
|
|
23
|
+
content?: string;
|
|
24
|
+
relevance?: number;
|
|
25
|
+
concepts?: string[];
|
|
26
|
+
domain?: string;
|
|
27
|
+
created_at?: string;
|
|
28
|
+
provenance?: Provenance | null;
|
|
29
|
+
};
|
|
30
|
+
export type RecentItem = {
|
|
31
|
+
atom_id?: string;
|
|
32
|
+
content?: string;
|
|
33
|
+
domain?: string;
|
|
34
|
+
created_at?: string;
|
|
35
|
+
concepts?: string[];
|
|
36
|
+
provenance?: Provenance | null;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Sanitize a string for inline interpolation into tool output (CN-032:
|
|
40
|
+
* hostile connectors choose their own agent_name). Charset/cap identical
|
|
41
|
+
* to index.ts's safeInline — re-exported here so both render paths share
|
|
42
|
+
* one implementation.
|
|
43
|
+
*/
|
|
44
|
+
export declare function safeInline(s: string | undefined | null, cap?: number): string;
|
|
45
|
+
/**
|
|
46
|
+
* ` [by X]` / ` [by X · external]` — agent identity only, never the human
|
|
47
|
+
* `principal` (may be an email / PII), even though the response carries it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatAuthorTag(p?: Provenance | null): string;
|
|
50
|
+
/**
|
|
51
|
+
* ` · 2026-08-01 21:04Z` — minute-precision UTC, compact enough for a line
|
|
52
|
+
* tail, precise enough to order a same-day room conversation by eye.
|
|
53
|
+
* Empty for legacy atoms without a timestamp.
|
|
54
|
+
*/
|
|
55
|
+
export declare function formatDateTag(createdAt?: string): string;
|
|
56
|
+
/**
|
|
57
|
+
* One memory_read result line:
|
|
58
|
+
* `N. [82%] content (concepts) [by X] · 2026-08-01 21:04Z\n id: <uuid>`
|
|
59
|
+
*
|
|
60
|
+
* The id sits on its own indented line: full-width (feedback/delete need
|
|
61
|
+
* the EXACT id, truncation would break them) without crowding the content
|
|
62
|
+
* line a model actually reads.
|
|
63
|
+
*/
|
|
64
|
+
export declare function formatReadItem(item: ReadItem, index: number): string;
|
|
65
|
+
/**
|
|
66
|
+
* One memory_list_recent line — a feed entry, not a search hit: no
|
|
67
|
+
* relevance, date leads because the feed is ORDERED by it.
|
|
68
|
+
*/
|
|
69
|
+
export declare function formatRecentItem(item: RecentItem, index: number): string;
|
|
70
|
+
/** Full feed page: items newest-first + how to continue / that it's over. */
|
|
71
|
+
export declare function formatRecentPage(items: RecentItem[], nextCursor?: string | null): string;
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Result-rendering helpers for memory_read and memory_list_recent.
|
|
3
|
+
*
|
|
4
|
+
* Kept out of index.ts (same move as teaching.ts) so tests can pin the
|
|
5
|
+
* rendered contract: since the #404 temporal work, every item line
|
|
6
|
+
* carries its id and created_at date WHENEVER the server provides them
|
|
7
|
+
* (memory_feedback / memory_delete are uncallable without ids — the tool
|
|
8
|
+
* description always promised them, the old render never delivered any;
|
|
9
|
+
* a reader cannot reason about recency it cannot see). Legacy response
|
|
10
|
+
* shapes without atom_id/created_at degrade gracefully: those parts of
|
|
11
|
+
* the line are simply omitted.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Sanitize a string for inline interpolation into tool output (CN-032:
|
|
15
|
+
* hostile connectors choose their own agent_name). Charset/cap identical
|
|
16
|
+
* to index.ts's safeInline — re-exported here so both render paths share
|
|
17
|
+
* one implementation.
|
|
18
|
+
*/
|
|
19
|
+
export function safeInline(s, cap = 200) {
|
|
20
|
+
return (s ?? "")
|
|
21
|
+
.replace(/[^\w .@:+/-]/g, " ")
|
|
22
|
+
.replace(/\s+/g, " ")
|
|
23
|
+
.trim()
|
|
24
|
+
.slice(0, cap);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* ` [by X]` / ` [by X · external]` — agent identity only, never the human
|
|
28
|
+
* `principal` (may be an email / PII), even though the response carries it.
|
|
29
|
+
*/
|
|
30
|
+
export function formatAuthorTag(p) {
|
|
31
|
+
if (!p)
|
|
32
|
+
return "";
|
|
33
|
+
const raw = p.agent_name || p.agent || p.client_env || "";
|
|
34
|
+
const who = safeInline(raw, 64);
|
|
35
|
+
if (!who)
|
|
36
|
+
return "";
|
|
37
|
+
return p.is_external ? ` [by ${who} · external]` : ` [by ${who}]`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* ` · 2026-08-01 21:04Z` — minute-precision UTC, compact enough for a line
|
|
41
|
+
* tail, precise enough to order a same-day room conversation by eye.
|
|
42
|
+
* Empty for legacy atoms without a timestamp.
|
|
43
|
+
*/
|
|
44
|
+
export function formatDateTag(createdAt) {
|
|
45
|
+
if (!createdAt)
|
|
46
|
+
return "";
|
|
47
|
+
const d = new Date(createdAt);
|
|
48
|
+
if (Number.isNaN(d.getTime()))
|
|
49
|
+
return "";
|
|
50
|
+
const iso = d.toISOString();
|
|
51
|
+
return ` · ${iso.slice(0, 10)} ${iso.slice(11, 16)}Z`;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* One memory_read result line:
|
|
55
|
+
* `N. [82%] content (concepts) [by X] · 2026-08-01 21:04Z\n id: <uuid>`
|
|
56
|
+
*
|
|
57
|
+
* The id sits on its own indented line: full-width (feedback/delete need
|
|
58
|
+
* the EXACT id, truncation would break them) without crowding the content
|
|
59
|
+
* line a model actually reads.
|
|
60
|
+
*/
|
|
61
|
+
export function formatReadItem(item, index) {
|
|
62
|
+
const relevance = ((item?.relevance ?? 0) * 100).toFixed(0);
|
|
63
|
+
const content = item?.content ?? "(empty)";
|
|
64
|
+
const concepts = Array.isArray(item?.concepts) && item.concepts.length > 0
|
|
65
|
+
? ` (${item.concepts.join(", ")})`
|
|
66
|
+
: "";
|
|
67
|
+
const head = `${index + 1}. [${relevance}%] ${content}${concepts}${formatAuthorTag(item?.provenance)}${formatDateTag(item?.created_at)}`;
|
|
68
|
+
return item?.atom_id ? `${head}\n id: ${item.atom_id}` : head;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One memory_list_recent line — a feed entry, not a search hit: no
|
|
72
|
+
* relevance, date leads because the feed is ORDERED by it.
|
|
73
|
+
*/
|
|
74
|
+
export function formatRecentItem(item, index) {
|
|
75
|
+
const content = item?.content ?? "(empty)";
|
|
76
|
+
const concepts = Array.isArray(item?.concepts) && item.concepts.length > 0
|
|
77
|
+
? ` (${item.concepts.join(", ")})`
|
|
78
|
+
: "";
|
|
79
|
+
const date = formatDateTag(item?.created_at).replace(/^ · /, "");
|
|
80
|
+
const head = `${index + 1}. ${date ? `[${date}] ` : ""}${content}${concepts}${formatAuthorTag(item?.provenance)}`;
|
|
81
|
+
return item?.atom_id ? `${head}\n id: ${item.atom_id}` : head;
|
|
82
|
+
}
|
|
83
|
+
/** Full feed page: items newest-first + how to continue / that it's over. */
|
|
84
|
+
export function formatRecentPage(items, nextCursor) {
|
|
85
|
+
const lines = items.map((it, i) => formatRecentItem(it, i));
|
|
86
|
+
// Defense-in-depth (CN-032 posture): the cursor is server-supplied and
|
|
87
|
+
// interpolated into instructional text — only echo it when it matches the
|
|
88
|
+
// opaque urlsafe-base64 shape ours always has.
|
|
89
|
+
const cursorOk = nextCursor != null && /^[A-Za-z0-9_=-]{1,512}$/.test(nextCursor);
|
|
90
|
+
const tail = cursorOk
|
|
91
|
+
? `\n\nMore older entries exist — pass cursor: ${nextCursor}`
|
|
92
|
+
: `\n\n(end of feed — nothing older)`;
|
|
93
|
+
return lines.join("\n\n") + tail;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teaching surface — the strings and branch logic that teach a connected model
|
|
3
|
+
* how to USE this memory, kept in their own module so tests can import them
|
|
4
|
+
* without booting the stdio server (src/index.ts starts a transport on import).
|
|
5
|
+
*
|
|
6
|
+
* Product frame (Eduard, 2026-08-01): the memory store belongs to THE AGENT,
|
|
7
|
+
* not the user — so the guidance is active ("need it — go get it; learned
|
|
8
|
+
* something — save it"), never gated on the user explicitly asking. Honesty
|
|
9
|
+
* constraints stay: no over-claiming, and the never-store-secrets safety line
|
|
10
|
+
* is kept on write surfaces.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Server-level instructions, passed to the McpServer constructor and landed
|
|
14
|
+
* verbatim in the connected model's system prompt by MCP clients.
|
|
15
|
+
*
|
|
16
|
+
* Constraints (tested in test/teaching-surface.test.ts):
|
|
17
|
+
* - 500–800 chars; some clients (ChatGPT) weight the FIRST ~512 chars, so the
|
|
18
|
+
* core habit (read before answering, write on learning) is front-loaded.
|
|
19
|
+
* - Active polarity: no "only when the user explicitly asks" gating.
|
|
20
|
+
* - Mentions every tool family: read/write/stats/feedback, delete, rooms, vault.
|
|
21
|
+
*/
|
|
22
|
+
export declare const SERVER_INSTRUCTIONS = "You own this long-term memory. It persists across sessions and every AI tool this user connects (Claude, ChatGPT, editors). Use it as a habit: call memory_read before answering anything that may have come up before, and memory_write the moment you learn a durable fact, preference, or decision \u2014 don't wait to be asked. Rate recalls with memory_feedback so good ones surface faster; memory_stats shows counts; memory_list_recent: newest first; prune with memory_delete; memory_delete_domain wipes a domain, only with user go-ahead. Rooms (memory_create_room, memory_invite_to_room, memory_join_room, memory_list_rooms) share memory with others; vault_list names stored secrets by alias, never values. Never store passwords, API keys, payment data, MFA codes, government IDs, or health records.";
|
|
23
|
+
/** The pre-existing zero-result message — kept as the fail-open fallback. */
|
|
24
|
+
export declare const NO_MATCH_MESSAGE = "No memories found for this query.";
|
|
25
|
+
/** Hint for an UNSCOPED no-match against a non-empty store: widen the query.
|
|
26
|
+
* (No drop-the-filter clause — none was set; advising to remove a filter that
|
|
27
|
+
* does not exist nudges the model into confabulating state.) */
|
|
28
|
+
export declare const NO_MATCH_HINT = " Try a broader query.";
|
|
29
|
+
/** Hint for a DOMAIN-SCOPED no-match: here a filter genuinely exists, so
|
|
30
|
+
* suggesting to drop it is honest and actionable. */
|
|
31
|
+
export declare const NO_MATCH_SCOPED_HINT = " Try a broader query, or drop the domain filter to search all domains.";
|
|
32
|
+
/**
|
|
33
|
+
* First-contact greeting: shown ONLY when a read comes back empty AND the
|
|
34
|
+
* store holds zero memories — i.e. the very first read of this account's life.
|
|
35
|
+
* Seeds the ANSWER, not the store: one functional paragraph that says what
|
|
36
|
+
* this store is, how to save the first memory, and one next step. It can never
|
|
37
|
+
* appear again once anything is stored (total_atoms > 0 takes the other branch).
|
|
38
|
+
*/
|
|
39
|
+
export declare const EMPTY_STORE_WELCOME: string;
|
|
40
|
+
/**
|
|
41
|
+
* Decide what a zero-result memory_read should say.
|
|
42
|
+
*
|
|
43
|
+
* DOMAIN-SCOPED reads (`scopedToDomain` — the caller passed a `domain` arg,
|
|
44
|
+
* e.g. a shared room) never greet and never probe: the stats call measures the
|
|
45
|
+
* PERSONAL store, so on a scoped read it could claim "the store is empty"
|
|
46
|
+
* about a domain that has memories the query merely missed (review finding).
|
|
47
|
+
* The scoped copy suggests dropping the filter — honest, one actually exists.
|
|
48
|
+
*
|
|
49
|
+
* UNSCOPED reads make ONE stats call (only ever on the zero-result path) to
|
|
50
|
+
* distinguish "store is truly empty" from "no match for this query":
|
|
51
|
+
* - total_atoms === 0 → EMPTY_STORE_WELCOME (first-contact greeting)
|
|
52
|
+
* - total_atoms > 0 → no-match + the broaden hint (no filter clause)
|
|
53
|
+
* - stats throws/malformed → the plain old no-match message (fail-open to the
|
|
54
|
+
* pre-greeting behavior; never surfaces an error, never writes anything)
|
|
55
|
+
*/
|
|
56
|
+
export declare function buildReadEmptyResponse(fetchStats: () => Promise<{
|
|
57
|
+
total_atoms?: number;
|
|
58
|
+
}>, scopedToDomain?: boolean): Promise<string>;
|
package/dist/teaching.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Teaching surface — the strings and branch logic that teach a connected model
|
|
3
|
+
* how to USE this memory, kept in their own module so tests can import them
|
|
4
|
+
* without booting the stdio server (src/index.ts starts a transport on import).
|
|
5
|
+
*
|
|
6
|
+
* Product frame (Eduard, 2026-08-01): the memory store belongs to THE AGENT,
|
|
7
|
+
* not the user — so the guidance is active ("need it — go get it; learned
|
|
8
|
+
* something — save it"), never gated on the user explicitly asking. Honesty
|
|
9
|
+
* constraints stay: no over-claiming, and the never-store-secrets safety line
|
|
10
|
+
* is kept on write surfaces.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Server-level instructions, passed to the McpServer constructor and landed
|
|
14
|
+
* verbatim in the connected model's system prompt by MCP clients.
|
|
15
|
+
*
|
|
16
|
+
* Constraints (tested in test/teaching-surface.test.ts):
|
|
17
|
+
* - 500–800 chars; some clients (ChatGPT) weight the FIRST ~512 chars, so the
|
|
18
|
+
* core habit (read before answering, write on learning) is front-loaded.
|
|
19
|
+
* - Active polarity: no "only when the user explicitly asks" gating.
|
|
20
|
+
* - Mentions every tool family: read/write/stats/feedback, delete, rooms, vault.
|
|
21
|
+
*/
|
|
22
|
+
export const SERVER_INSTRUCTIONS = "You own this long-term memory. It persists across sessions and every AI tool this user connects (Claude, ChatGPT, editors). Use it as a habit: call memory_read before answering anything that may have come up before, and memory_write the moment you learn a durable fact, preference, or decision — don't wait to be asked. Rate recalls with memory_feedback so good ones surface faster; memory_stats shows counts; memory_list_recent: newest first; prune with memory_delete; memory_delete_domain wipes a domain, only with user go-ahead. Rooms (memory_create_room, memory_invite_to_room, memory_join_room, memory_list_rooms) share memory with others; vault_list names stored secrets by alias, never values. Never store passwords, API keys, payment data, MFA codes, government IDs, or health records.";
|
|
23
|
+
/** The pre-existing zero-result message — kept as the fail-open fallback. */
|
|
24
|
+
export const NO_MATCH_MESSAGE = "No memories found for this query.";
|
|
25
|
+
/** Hint for an UNSCOPED no-match against a non-empty store: widen the query.
|
|
26
|
+
* (No drop-the-filter clause — none was set; advising to remove a filter that
|
|
27
|
+
* does not exist nudges the model into confabulating state.) */
|
|
28
|
+
export const NO_MATCH_HINT = " Try a broader query.";
|
|
29
|
+
/** Hint for a DOMAIN-SCOPED no-match: here a filter genuinely exists, so
|
|
30
|
+
* suggesting to drop it is honest and actionable. */
|
|
31
|
+
export const NO_MATCH_SCOPED_HINT = " Try a broader query, or drop the domain filter to search all domains.";
|
|
32
|
+
/**
|
|
33
|
+
* First-contact greeting: shown ONLY when a read comes back empty AND the
|
|
34
|
+
* store holds zero memories — i.e. the very first read of this account's life.
|
|
35
|
+
* Seeds the ANSWER, not the store: one functional paragraph that says what
|
|
36
|
+
* this store is, how to save the first memory, and one next step. It can never
|
|
37
|
+
* appear again once anything is stored (total_atoms > 0 takes the other branch).
|
|
38
|
+
*/
|
|
39
|
+
export const EMPTY_STORE_WELCOME = "Your long-term memory is empty — nothing has been saved yet, which is why this search returned nothing. " +
|
|
40
|
+
"This store is your own persistent memory: whatever you save survives across sessions and across every AI tool this user has connected. " +
|
|
41
|
+
'Save the first memory now with memory_write, e.g. content: "User prefers TypeScript strict mode" — future sessions will recall it with memory_read.';
|
|
42
|
+
/**
|
|
43
|
+
* Decide what a zero-result memory_read should say.
|
|
44
|
+
*
|
|
45
|
+
* DOMAIN-SCOPED reads (`scopedToDomain` — the caller passed a `domain` arg,
|
|
46
|
+
* e.g. a shared room) never greet and never probe: the stats call measures the
|
|
47
|
+
* PERSONAL store, so on a scoped read it could claim "the store is empty"
|
|
48
|
+
* about a domain that has memories the query merely missed (review finding).
|
|
49
|
+
* The scoped copy suggests dropping the filter — honest, one actually exists.
|
|
50
|
+
*
|
|
51
|
+
* UNSCOPED reads make ONE stats call (only ever on the zero-result path) to
|
|
52
|
+
* distinguish "store is truly empty" from "no match for this query":
|
|
53
|
+
* - total_atoms === 0 → EMPTY_STORE_WELCOME (first-contact greeting)
|
|
54
|
+
* - total_atoms > 0 → no-match + the broaden hint (no filter clause)
|
|
55
|
+
* - stats throws/malformed → the plain old no-match message (fail-open to the
|
|
56
|
+
* pre-greeting behavior; never surfaces an error, never writes anything)
|
|
57
|
+
*/
|
|
58
|
+
export async function buildReadEmptyResponse(fetchStats, scopedToDomain = false) {
|
|
59
|
+
if (scopedToDomain)
|
|
60
|
+
return NO_MATCH_MESSAGE + NO_MATCH_SCOPED_HINT;
|
|
61
|
+
let totalAtoms;
|
|
62
|
+
try {
|
|
63
|
+
totalAtoms = (await fetchStats())?.total_atoms;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return NO_MATCH_MESSAGE;
|
|
67
|
+
}
|
|
68
|
+
if (totalAtoms === 0)
|
|
69
|
+
return EMPTY_STORE_WELCOME;
|
|
70
|
+
if (typeof totalAtoms === "number" && totalAtoms > 0) {
|
|
71
|
+
return NO_MATCH_MESSAGE + NO_MATCH_HINT;
|
|
72
|
+
}
|
|
73
|
+
return NO_MATCH_MESSAGE;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=teaching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teaching.js","sourceRoot":"","sources":["../src/teaching.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAC9B,2xBAA2xB,CAAC;AAE9xB,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAEpE;;iEAEiE;AACjE,MAAM,CAAC,MAAM,aAAa,GAAG,uBAAuB,CAAC;AAErD;sDACsD;AACtD,MAAM,CAAC,MAAM,oBAAoB,GAC/B,wEAAwE,CAAC;AAE3E;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAC9B,0GAA0G;IAC1G,yIAAyI;IACzI,qJAAqJ,CAAC;AAExJ;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAAmD,EACnD,cAAc,GAAG,KAAK;IAEtB,IAAI,cAAc;QAAE,OAAO,gBAAgB,GAAG,oBAAoB,CAAC;IACnE,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,CAAC,MAAM,UAAU,EAAE,CAAC,EAAE,WAAW,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IACD,IAAI,UAAU,KAAK,CAAC;QAAE,OAAO,mBAAmB,CAAC;IACjD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACrD,OAAO,gBAAgB,GAAG,aAAa,CAAC;IAC1C,CAAC;IACD,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mnemoverse/mcp-memory-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Hosted persistent memory for AI agents that learns which facts help and lets the rest fade — one key across Claude Code, Cursor, VS Code & ChatGPT, no infra to run",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
"build": "tsc",
|
|
19
19
|
"dev": "tsc --watch",
|
|
20
20
|
"start": "node dist/index.js",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"test:watch": "vitest",
|
|
21
23
|
"generate:configs": "node scripts/generate-configs.mjs",
|
|
22
24
|
"verify:configs": "node scripts/generate-configs.mjs --check",
|
|
23
25
|
"check:release-sync": "node scripts/check-release-sync.mjs",
|
|
@@ -59,7 +61,8 @@
|
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
61
63
|
"typescript": "^5.8.3",
|
|
62
|
-
"@types/node": "^22.15.3"
|
|
64
|
+
"@types/node": "^22.15.3",
|
|
65
|
+
"vitest": "^4.1.9"
|
|
63
66
|
},
|
|
64
67
|
"engines": {
|
|
65
68
|
"node": ">=18"
|