@frontmcp/plugin-remember 1.8.6 → 1.9.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/esm/index.mjs +321 -243
- package/esm/package.json +4 -4
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +327 -251
- package/package.json +4 -4
- package/providers/remember-accessor.provider.d.ts +8 -3
- package/providers/remember-accessor.provider.d.ts.map +1 -1
- package/remember.errors.d.ts +9 -0
- package/remember.errors.d.ts.map +1 -1
- package/remember.plugin.d.ts +6 -1
- package/remember.plugin.d.ts.map +1 -1
- package/tools/forget.tool.d.ts +24 -0
- package/tools/forget.tool.d.ts.map +1 -1
- package/tools/index.d.ts +2 -0
- package/tools/index.d.ts.map +1 -1
- package/tools/list-memories.tool.d.ts +25 -0
- package/tools/list-memories.tool.d.ts.map +1 -1
- package/tools/recall.tool.d.ts +26 -0
- package/tools/recall.tool.d.ts.map +1 -1
- package/tools/remember-this.tool.d.ts +33 -0
- package/tools/remember-this.tool.d.ts.map +1 -1
- package/tools/remember-tool-names.d.ts +9 -0
- package/tools/remember-tool-names.d.ts.map +1 -0
- package/tools/remember-tools.factory.d.ts +8 -0
- package/tools/remember-tools.factory.d.ts.map +1 -0
package/esm/index.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
var __frontmcpModule = typeof process !== "undefined" && typeof process.getBuiltinModule === "function" ? process.getBuiltinModule("module") : undefined;
|
|
2
|
+
const require = __frontmcpModule ? __frontmcpModule.createRequire(import.meta.url || 'file:///') : undefined;
|
|
3
|
+
// __frontmcpCreateRequire
|
|
1
4
|
var __defProp = Object.defineProperty;
|
|
2
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
6
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -289,6 +292,16 @@ var RememberIdentityError = class extends PublicMcpError {
|
|
|
289
292
|
super(message, "REMEMBER_IDENTITY_REQUIRED", 403);
|
|
290
293
|
}
|
|
291
294
|
};
|
|
295
|
+
var RememberScopeNotAllowedError = class extends PublicMcpError {
|
|
296
|
+
name = "RememberScopeNotAllowedError";
|
|
297
|
+
constructor(scope, allowedScopes) {
|
|
298
|
+
super(
|
|
299
|
+
`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`,
|
|
300
|
+
"REMEMBER_SCOPE_NOT_ALLOWED",
|
|
301
|
+
400
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
292
305
|
|
|
293
306
|
// plugins/plugin-remember/src/remember.legacy-purge.ts
|
|
294
307
|
var LEGACY_SCOPES = ["session", "tool", "user"];
|
|
@@ -395,6 +408,9 @@ var STORAGE_LAYOUT_VERSION = "v2";
|
|
|
395
408
|
function encodeKeyPart(value) {
|
|
396
409
|
return encodeURIComponent(value);
|
|
397
410
|
}
|
|
411
|
+
function remainingSeconds(expiresAt, now) {
|
|
412
|
+
return Math.max(1, Math.ceil((expiresAt - now) / 1e3));
|
|
413
|
+
}
|
|
398
414
|
var RememberAccessor = class {
|
|
399
415
|
store;
|
|
400
416
|
ctx;
|
|
@@ -444,16 +460,8 @@ var RememberAccessor = class {
|
|
|
444
460
|
*/
|
|
445
461
|
async get(key, options = {}) {
|
|
446
462
|
const scope = options.scope ?? "session";
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
if (!raw) return options.defaultValue;
|
|
450
|
-
const entry = this.encryptionEnabled ? await deserializeAndDecrypt(raw, this.getKeySource(scope)) : this.parseEntry(raw);
|
|
451
|
-
if (!entry) return options.defaultValue;
|
|
452
|
-
if (entry.expiresAt && Date.now() > entry.expiresAt) {
|
|
453
|
-
await this.forget(key, { scope });
|
|
454
|
-
return options.defaultValue;
|
|
455
|
-
}
|
|
456
|
-
return entry.value;
|
|
463
|
+
const entry = await this.readEntry(this.buildStorageKey(key, scope), scope);
|
|
464
|
+
return entry ? entry.value : options.defaultValue;
|
|
457
465
|
}
|
|
458
466
|
/**
|
|
459
467
|
* Get the full entry including metadata.
|
|
@@ -464,16 +472,7 @@ var RememberAccessor = class {
|
|
|
464
472
|
*/
|
|
465
473
|
async getEntry(key, options = {}) {
|
|
466
474
|
const scope = options.scope ?? "session";
|
|
467
|
-
|
|
468
|
-
const raw = await this.store.getValue(storageKey);
|
|
469
|
-
if (!raw) return void 0;
|
|
470
|
-
const entry = this.encryptionEnabled ? await deserializeAndDecrypt(raw, this.getKeySource(scope)) : this.parseEntry(raw);
|
|
471
|
-
if (!entry) return void 0;
|
|
472
|
-
if (entry.expiresAt && Date.now() > entry.expiresAt) {
|
|
473
|
-
await this.forget(key, { scope });
|
|
474
|
-
return void 0;
|
|
475
|
-
}
|
|
476
|
-
return entry;
|
|
475
|
+
return this.readEntry(this.buildStorageKey(key, scope), scope);
|
|
477
476
|
}
|
|
478
477
|
/**
|
|
479
478
|
* Forget (delete) a value from memory.
|
|
@@ -487,19 +486,18 @@ var RememberAccessor = class {
|
|
|
487
486
|
await this.store.delete(storageKey);
|
|
488
487
|
}
|
|
489
488
|
/**
|
|
490
|
-
* Check if a key is remembered (
|
|
489
|
+
* Check if a key is remembered: true exactly when `get()` would return its value.
|
|
491
490
|
*
|
|
492
491
|
* @param key - The key to check
|
|
493
492
|
* @param options - Options (scope)
|
|
494
|
-
* @returns true if the key exists
|
|
493
|
+
* @returns true if the key exists and has not expired
|
|
495
494
|
*/
|
|
496
495
|
async knows(key, options = {}) {
|
|
497
496
|
const scope = options.scope ?? "session";
|
|
498
|
-
|
|
499
|
-
return this.store.exists(storageKey);
|
|
497
|
+
return await this.readEntry(this.buildStorageKey(key, scope), scope) !== void 0;
|
|
500
498
|
}
|
|
501
499
|
/**
|
|
502
|
-
* List all remembered keys for a scope.
|
|
500
|
+
* List all remembered keys for a scope: the keys `get()` would return a value for.
|
|
503
501
|
*
|
|
504
502
|
* @param options - Options (scope, pattern)
|
|
505
503
|
* @returns Array of keys (without the scope prefix)
|
|
@@ -507,13 +505,16 @@ var RememberAccessor = class {
|
|
|
507
505
|
async list(options = {}) {
|
|
508
506
|
const scope = options.scope ?? "session";
|
|
509
507
|
const scopePrefix = this.buildScopePrefix(scope);
|
|
510
|
-
const
|
|
511
|
-
const
|
|
512
|
-
return
|
|
508
|
+
const storageKeys = await this.store.keys(scopePrefix + (options.pattern ?? "*"));
|
|
509
|
+
const entries = await Promise.all(storageKeys.map((storageKey) => this.readEntry(storageKey, scope)));
|
|
510
|
+
return storageKeys.filter((_storageKey, index) => entries[index] !== void 0).map((storageKey) => storageKey.slice(scopePrefix.length));
|
|
513
511
|
}
|
|
514
512
|
/**
|
|
515
513
|
* Update an existing entry's value while preserving metadata.
|
|
516
514
|
*
|
|
515
|
+
* With a `ttl` the entry expires that many seconds from now; without one it keeps its current
|
|
516
|
+
* expiry, in the store as well, so the store does not keep it past that (rounded up to a second).
|
|
517
|
+
*
|
|
517
518
|
* @param key - The key to update
|
|
518
519
|
* @param value - The new value
|
|
519
520
|
* @param options - Options (scope, ttl)
|
|
@@ -522,15 +523,18 @@ var RememberAccessor = class {
|
|
|
522
523
|
const scope = options.scope ?? "session";
|
|
523
524
|
const existing = await this.getEntry(key, { scope });
|
|
524
525
|
if (!existing) return false;
|
|
526
|
+
const now = Date.now();
|
|
527
|
+
const expiresAt = options.ttl ? now + options.ttl * 1e3 : existing.expiresAt;
|
|
525
528
|
const entry = {
|
|
526
529
|
...existing,
|
|
527
530
|
value,
|
|
528
|
-
updatedAt:
|
|
529
|
-
expiresAt
|
|
531
|
+
updatedAt: now,
|
|
532
|
+
expiresAt
|
|
530
533
|
};
|
|
531
534
|
const storageKey = this.buildStorageKey(key, scope);
|
|
532
535
|
const serialized = this.encryptionEnabled ? await encryptAndSerialize(entry, this.getKeySource(scope)) : JSON.stringify(entry);
|
|
533
|
-
|
|
536
|
+
const storageTtl = options.ttl ?? (expiresAt !== void 0 ? remainingSeconds(expiresAt, now) : void 0);
|
|
537
|
+
await this.store.setValue(storageKey, serialized, storageTtl);
|
|
534
538
|
return true;
|
|
535
539
|
}
|
|
536
540
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -648,6 +652,18 @@ var RememberAccessor = class {
|
|
|
648
652
|
toolName: scope === "tool" ? this.toolName : void 0
|
|
649
653
|
});
|
|
650
654
|
}
|
|
655
|
+
/** The entry stored under `storageKey`, if readable and unexpired; an expired one is deleted. */
|
|
656
|
+
async readEntry(storageKey, scope) {
|
|
657
|
+
const raw = await this.store.getValue(storageKey);
|
|
658
|
+
if (!raw) return void 0;
|
|
659
|
+
const entry = this.encryptionEnabled ? await deserializeAndDecrypt(raw, this.getKeySource(scope)) : this.parseEntry(raw);
|
|
660
|
+
if (!entry) return void 0;
|
|
661
|
+
if (entry.expiresAt && Date.now() > entry.expiresAt) {
|
|
662
|
+
await this.store.delete(storageKey);
|
|
663
|
+
return void 0;
|
|
664
|
+
}
|
|
665
|
+
return entry;
|
|
666
|
+
}
|
|
651
667
|
/**
|
|
652
668
|
* Parse a JSON entry (when encryption is disabled).
|
|
653
669
|
*/
|
|
@@ -1129,6 +1145,265 @@ var RememberAccessorToken = /* @__PURE__ */ Symbol(
|
|
|
1129
1145
|
"plugin:remember:accessor"
|
|
1130
1146
|
);
|
|
1131
1147
|
|
|
1148
|
+
// plugins/plugin-remember/src/tools/remember-tools.factory.ts
|
|
1149
|
+
import { Tool as Tool5 } from "@frontmcp/sdk";
|
|
1150
|
+
|
|
1151
|
+
// plugins/plugin-remember/src/tools/forget.tool.ts
|
|
1152
|
+
import { z as z2 } from "@frontmcp/lazy-zod";
|
|
1153
|
+
import { Tool, ToolContext } from "@frontmcp/sdk";
|
|
1154
|
+
|
|
1155
|
+
// plugins/plugin-remember/src/tools/remember-scope.description.ts
|
|
1156
|
+
var REMEMBER_SCOPE_DESCRIPTION = "Whose memory to use (default: session). session: this session; without one (stateless HTTP, MCP 2026-07-28), the signed-in caller across its requests. user: the signed-in caller, across all of its sessions. tool: the tool running the call, for the same caller as session; each memory tool has its own, so the other memory tools do not see what one of them stores in tool scope. global: shared by every caller. An anonymous caller cannot use user scope, nor session or tool scope without a session.";
|
|
1157
|
+
|
|
1158
|
+
// plugins/plugin-remember/src/tools/remember-tool-names.ts
|
|
1159
|
+
function rememberToolNames(prefix = "") {
|
|
1160
|
+
return {
|
|
1161
|
+
rememberThis: `${prefix}remember_this`,
|
|
1162
|
+
recall: `${prefix}recall`,
|
|
1163
|
+
forget: `${prefix}forget`,
|
|
1164
|
+
listMemories: `${prefix}list_memories`
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
// plugins/plugin-remember/src/tools/forget.tool.ts
|
|
1169
|
+
var forgetInputSchema = {
|
|
1170
|
+
key: z2.string().min(1).describe("What memory to forget"),
|
|
1171
|
+
scope: z2.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
|
|
1172
|
+
};
|
|
1173
|
+
var forgetOutputSchema = z2.object({
|
|
1174
|
+
success: z2.boolean(),
|
|
1175
|
+
key: z2.string(),
|
|
1176
|
+
scope: z2.string(),
|
|
1177
|
+
existed: z2.boolean()
|
|
1178
|
+
});
|
|
1179
|
+
function forgetDescription() {
|
|
1180
|
+
return "Forget a previously remembered value. Use this when the user wants to delete stored preferences or information.";
|
|
1181
|
+
}
|
|
1182
|
+
function forgetToolMetadata(names = rememberToolNames()) {
|
|
1183
|
+
return {
|
|
1184
|
+
name: names.forget,
|
|
1185
|
+
description: forgetDescription(),
|
|
1186
|
+
inputSchema: forgetInputSchema,
|
|
1187
|
+
outputSchema: forgetOutputSchema,
|
|
1188
|
+
annotations: { readOnlyHint: false }
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
var ForgetTool = class extends ToolContext {
|
|
1192
|
+
async execute(input) {
|
|
1193
|
+
const remember = this.get(RememberAccessorToken);
|
|
1194
|
+
const config = this.get(RememberConfigToken);
|
|
1195
|
+
const scope = input.scope ?? "session";
|
|
1196
|
+
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1197
|
+
if (!allowedScopes.includes(scope)) {
|
|
1198
|
+
throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
|
|
1199
|
+
}
|
|
1200
|
+
const existed = await remember.knows(input.key, { scope });
|
|
1201
|
+
await remember.forget(input.key, { scope });
|
|
1202
|
+
return {
|
|
1203
|
+
success: true,
|
|
1204
|
+
key: input.key,
|
|
1205
|
+
scope,
|
|
1206
|
+
existed
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
ForgetTool = __decorateClass([
|
|
1211
|
+
Tool(forgetToolMetadata())
|
|
1212
|
+
], ForgetTool);
|
|
1213
|
+
|
|
1214
|
+
// plugins/plugin-remember/src/tools/list-memories.tool.ts
|
|
1215
|
+
import { z as z3 } from "@frontmcp/lazy-zod";
|
|
1216
|
+
import { Tool as Tool2, ToolContext as ToolContext2 } from "@frontmcp/sdk";
|
|
1217
|
+
var listMemoriesInputSchema = {
|
|
1218
|
+
scope: z3.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
|
|
1219
|
+
pattern: z3.string().optional().describe('Pattern to filter keys (e.g., "user_*")'),
|
|
1220
|
+
limit: z3.number().positive().max(100).optional().describe("Maximum number of keys to return (default: 50)")
|
|
1221
|
+
};
|
|
1222
|
+
var listMemoriesOutputSchema = z3.object({
|
|
1223
|
+
keys: z3.array(z3.string()),
|
|
1224
|
+
scope: z3.string(),
|
|
1225
|
+
count: z3.number(),
|
|
1226
|
+
truncated: z3.boolean()
|
|
1227
|
+
});
|
|
1228
|
+
function listMemoriesDescription(names = rememberToolNames()) {
|
|
1229
|
+
return `List the remembered keys in one scope (default: session). Use this to see what memories are stored before you ${names.recall} or ${names.forget} one.`;
|
|
1230
|
+
}
|
|
1231
|
+
function listMemoriesToolMetadata(names = rememberToolNames()) {
|
|
1232
|
+
return {
|
|
1233
|
+
name: names.listMemories,
|
|
1234
|
+
description: listMemoriesDescription(names),
|
|
1235
|
+
inputSchema: listMemoriesInputSchema,
|
|
1236
|
+
outputSchema: listMemoriesOutputSchema,
|
|
1237
|
+
annotations: { readOnlyHint: true }
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
var ListMemoriesTool = class extends ToolContext2 {
|
|
1241
|
+
async execute(input) {
|
|
1242
|
+
const remember = this.get(RememberAccessorToken);
|
|
1243
|
+
const config = this.get(RememberConfigToken);
|
|
1244
|
+
const scope = input.scope ?? "session";
|
|
1245
|
+
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1246
|
+
if (!allowedScopes.includes(scope)) {
|
|
1247
|
+
throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
|
|
1248
|
+
}
|
|
1249
|
+
const limit = input.limit ?? 50;
|
|
1250
|
+
let keys = await remember.list({ scope, pattern: input.pattern });
|
|
1251
|
+
const truncated = keys.length > limit;
|
|
1252
|
+
if (truncated) {
|
|
1253
|
+
keys = keys.slice(0, limit);
|
|
1254
|
+
}
|
|
1255
|
+
return {
|
|
1256
|
+
keys,
|
|
1257
|
+
scope,
|
|
1258
|
+
count: keys.length,
|
|
1259
|
+
truncated
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
ListMemoriesTool = __decorateClass([
|
|
1264
|
+
Tool2(listMemoriesToolMetadata())
|
|
1265
|
+
], ListMemoriesTool);
|
|
1266
|
+
|
|
1267
|
+
// plugins/plugin-remember/src/tools/recall.tool.ts
|
|
1268
|
+
import { z as z4 } from "@frontmcp/lazy-zod";
|
|
1269
|
+
import { Tool as Tool3, ToolContext as ToolContext3 } from "@frontmcp/sdk";
|
|
1270
|
+
var recallInputSchema = {
|
|
1271
|
+
key: z4.string().min(1).describe("What memory to recall"),
|
|
1272
|
+
scope: z4.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
|
|
1273
|
+
};
|
|
1274
|
+
var recallOutputSchema = z4.object({
|
|
1275
|
+
found: z4.boolean(),
|
|
1276
|
+
key: z4.string(),
|
|
1277
|
+
value: z4.unknown().optional(),
|
|
1278
|
+
scope: z4.string(),
|
|
1279
|
+
createdAt: z4.number().optional(),
|
|
1280
|
+
expiresAt: z4.number().optional()
|
|
1281
|
+
});
|
|
1282
|
+
function recallDescription(names = rememberToolNames()) {
|
|
1283
|
+
return `Recall something that was previously remembered. Use this to retrieve stored preferences, settings, or any information that was saved with ${names.rememberThis}.`;
|
|
1284
|
+
}
|
|
1285
|
+
function recallToolMetadata(names = rememberToolNames()) {
|
|
1286
|
+
return {
|
|
1287
|
+
name: names.recall,
|
|
1288
|
+
description: recallDescription(names),
|
|
1289
|
+
inputSchema: recallInputSchema,
|
|
1290
|
+
outputSchema: recallOutputSchema,
|
|
1291
|
+
annotations: { readOnlyHint: true }
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
var RecallTool = class extends ToolContext3 {
|
|
1295
|
+
async execute(input) {
|
|
1296
|
+
const remember = this.get(RememberAccessorToken);
|
|
1297
|
+
const config = this.get(RememberConfigToken);
|
|
1298
|
+
const scope = input.scope ?? "session";
|
|
1299
|
+
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1300
|
+
if (!allowedScopes.includes(scope)) {
|
|
1301
|
+
throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
|
|
1302
|
+
}
|
|
1303
|
+
const entry = await remember.getEntry(input.key, { scope });
|
|
1304
|
+
if (!entry) {
|
|
1305
|
+
return {
|
|
1306
|
+
found: false,
|
|
1307
|
+
key: input.key,
|
|
1308
|
+
scope
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
return {
|
|
1312
|
+
found: true,
|
|
1313
|
+
key: input.key,
|
|
1314
|
+
value: entry.value,
|
|
1315
|
+
scope,
|
|
1316
|
+
createdAt: entry.createdAt,
|
|
1317
|
+
expiresAt: entry.expiresAt
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
};
|
|
1321
|
+
RecallTool = __decorateClass([
|
|
1322
|
+
Tool3(recallToolMetadata())
|
|
1323
|
+
], RecallTool);
|
|
1324
|
+
|
|
1325
|
+
// plugins/plugin-remember/src/tools/remember-this.tool.ts
|
|
1326
|
+
import { z as z5 } from "@frontmcp/lazy-zod";
|
|
1327
|
+
import { Tool as Tool4, ToolContext as ToolContext4 } from "@frontmcp/sdk";
|
|
1328
|
+
var rememberThisInputSchema = {
|
|
1329
|
+
key: z5.string().min(1).describe('What to call this memory (e.g., "user_preference", "last_action")'),
|
|
1330
|
+
value: z5.unknown().describe("The value to remember (any JSON-serializable data)"),
|
|
1331
|
+
scope: z5.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
|
|
1332
|
+
ttl: z5.number().positive().optional().describe("Forget after this many seconds"),
|
|
1333
|
+
brand: z5.enum(["preference", "cache", "state", "conversation", "custom"]).optional().describe("Type hint for the stored value")
|
|
1334
|
+
};
|
|
1335
|
+
var rememberThisOutputSchema = z5.object({
|
|
1336
|
+
success: z5.boolean(),
|
|
1337
|
+
key: z5.string(),
|
|
1338
|
+
scope: z5.string(),
|
|
1339
|
+
expiresAt: z5.number().optional()
|
|
1340
|
+
});
|
|
1341
|
+
function rememberThisDescription(names = rememberToolNames()) {
|
|
1342
|
+
return `Remember something for later: store a value under a key that ${names.recall} can read back, in the scope you choose (this session by default; user scope for the signed-in user across sessions). It lasts until it is forgotten or its ttl runs out. Use this when the user asks you to remember preferences, settings, or any information they want to persist.`;
|
|
1343
|
+
}
|
|
1344
|
+
function rememberThisToolMetadata(names = rememberToolNames()) {
|
|
1345
|
+
return {
|
|
1346
|
+
name: names.rememberThis,
|
|
1347
|
+
description: rememberThisDescription(names),
|
|
1348
|
+
inputSchema: rememberThisInputSchema,
|
|
1349
|
+
outputSchema: rememberThisOutputSchema,
|
|
1350
|
+
annotations: { readOnlyHint: false }
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
var RememberThisTool = class extends ToolContext4 {
|
|
1354
|
+
async execute(input) {
|
|
1355
|
+
const remember = this.get(RememberAccessorToken);
|
|
1356
|
+
const config = this.get(RememberConfigToken);
|
|
1357
|
+
const scope = input.scope ?? "session";
|
|
1358
|
+
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1359
|
+
if (!allowedScopes.includes(scope)) {
|
|
1360
|
+
throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
|
|
1361
|
+
}
|
|
1362
|
+
await remember.set(input.key, input.value, {
|
|
1363
|
+
scope,
|
|
1364
|
+
ttl: input.ttl,
|
|
1365
|
+
brand: input.brand
|
|
1366
|
+
});
|
|
1367
|
+
const expiresAt = input.ttl ? Date.now() + input.ttl * 1e3 : void 0;
|
|
1368
|
+
return {
|
|
1369
|
+
success: true,
|
|
1370
|
+
key: input.key,
|
|
1371
|
+
scope,
|
|
1372
|
+
expiresAt
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
RememberThisTool = __decorateClass([
|
|
1377
|
+
Tool4(rememberThisToolMetadata())
|
|
1378
|
+
], RememberThisTool);
|
|
1379
|
+
|
|
1380
|
+
// plugins/plugin-remember/src/tools/remember-tools.factory.ts
|
|
1381
|
+
function createRememberTools(prefix = "") {
|
|
1382
|
+
if (!prefix) return [RememberThisTool, RecallTool, ForgetTool, ListMemoriesTool];
|
|
1383
|
+
const names = rememberToolNames(prefix);
|
|
1384
|
+
let PrefixedRememberThisTool = class extends RememberThisTool {
|
|
1385
|
+
};
|
|
1386
|
+
PrefixedRememberThisTool = __decorateClass([
|
|
1387
|
+
Tool5(rememberThisToolMetadata(names))
|
|
1388
|
+
], PrefixedRememberThisTool);
|
|
1389
|
+
let PrefixedRecallTool = class extends RecallTool {
|
|
1390
|
+
};
|
|
1391
|
+
PrefixedRecallTool = __decorateClass([
|
|
1392
|
+
Tool5(recallToolMetadata(names))
|
|
1393
|
+
], PrefixedRecallTool);
|
|
1394
|
+
let PrefixedForgetTool = class extends ForgetTool {
|
|
1395
|
+
};
|
|
1396
|
+
PrefixedForgetTool = __decorateClass([
|
|
1397
|
+
Tool5(forgetToolMetadata(names))
|
|
1398
|
+
], PrefixedForgetTool);
|
|
1399
|
+
let PrefixedListMemoriesTool = class extends ListMemoriesTool {
|
|
1400
|
+
};
|
|
1401
|
+
PrefixedListMemoriesTool = __decorateClass([
|
|
1402
|
+
Tool5(listMemoriesToolMetadata(names))
|
|
1403
|
+
], PrefixedListMemoriesTool);
|
|
1404
|
+
return [PrefixedRememberThisTool, PrefixedRecallTool, PrefixedForgetTool, PrefixedListMemoriesTool];
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1132
1407
|
// plugins/plugin-remember/src/remember.plugin.ts
|
|
1133
1408
|
var RememberPlugin = class extends DynamicPlugin {
|
|
1134
1409
|
options;
|
|
@@ -1145,6 +1420,11 @@ __publicField(RememberPlugin, "defaultOptions", {
|
|
|
1145
1420
|
keyPrefix: "remember:",
|
|
1146
1421
|
encryption: { enabled: true }
|
|
1147
1422
|
});
|
|
1423
|
+
/**
|
|
1424
|
+
* The memory tools, when `tools.enabled` is set: `remember_this`, `recall`, `forget` and
|
|
1425
|
+
* `list_memories`, under `tools.prefix`.
|
|
1426
|
+
*/
|
|
1427
|
+
__publicField(RememberPlugin, "dynamicTools", (options) => options.tools?.enabled ? createRememberTools(options.tools.prefix) : []);
|
|
1148
1428
|
/**
|
|
1149
1429
|
* Dynamic providers based on plugin options.
|
|
1150
1430
|
*/
|
|
@@ -1276,222 +1556,19 @@ RememberPlugin = __decorateClass([
|
|
|
1276
1556
|
], RememberPlugin);
|
|
1277
1557
|
|
|
1278
1558
|
// plugins/plugin-remember/src/remember.types.ts
|
|
1279
|
-
import { z as
|
|
1280
|
-
var rememberScopeSchema =
|
|
1559
|
+
import { z as z6 } from "@frontmcp/lazy-zod";
|
|
1560
|
+
var rememberScopeSchema = z6.enum(["session", "user", "tool", "global"]);
|
|
1281
1561
|
function brand(data, _brand) {
|
|
1282
1562
|
return data;
|
|
1283
1563
|
}
|
|
1284
|
-
var rememberEntrySchema =
|
|
1285
|
-
value:
|
|
1286
|
-
brand:
|
|
1287
|
-
createdAt:
|
|
1288
|
-
updatedAt:
|
|
1289
|
-
expiresAt:
|
|
1290
|
-
metadata:
|
|
1291
|
-
});
|
|
1292
|
-
|
|
1293
|
-
// plugins/plugin-remember/src/tools/remember-this.tool.ts
|
|
1294
|
-
import { z as z3 } from "@frontmcp/lazy-zod";
|
|
1295
|
-
import { Tool, ToolContext } from "@frontmcp/sdk";
|
|
1296
|
-
|
|
1297
|
-
// plugins/plugin-remember/src/tools/remember-scope.description.ts
|
|
1298
|
-
var REMEMBER_SCOPE_DESCRIPTION = "Whose memory to use (default: session). session: this session; without one (stateless HTTP, MCP 2026-07-28), the signed-in caller across its requests. user: the signed-in caller, across all of its sessions. tool: the tool running the call, for the same caller as session; each memory tool has its own, so the other memory tools do not see what one of them stores in tool scope. global: shared by every caller. An anonymous caller cannot use user scope, nor session or tool scope without a session.";
|
|
1299
|
-
|
|
1300
|
-
// plugins/plugin-remember/src/tools/remember-this.tool.ts
|
|
1301
|
-
var rememberThisInputSchema = {
|
|
1302
|
-
key: z3.string().min(1).describe('What to call this memory (e.g., "user_preference", "last_action")'),
|
|
1303
|
-
value: z3.unknown().describe("The value to remember (any JSON-serializable data)"),
|
|
1304
|
-
scope: z3.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
|
|
1305
|
-
ttl: z3.number().positive().optional().describe("Forget after this many seconds"),
|
|
1306
|
-
brand: z3.enum(["preference", "cache", "state", "conversation", "custom"]).optional().describe("Type hint for the stored value")
|
|
1307
|
-
};
|
|
1308
|
-
var rememberThisOutputSchema = z3.object({
|
|
1309
|
-
success: z3.boolean(),
|
|
1310
|
-
key: z3.string(),
|
|
1311
|
-
scope: z3.string(),
|
|
1312
|
-
expiresAt: z3.number().optional()
|
|
1313
|
-
});
|
|
1314
|
-
var RememberThisTool = class extends ToolContext {
|
|
1315
|
-
async execute(input) {
|
|
1316
|
-
const remember = this.get(RememberAccessorToken);
|
|
1317
|
-
const config = this.get(RememberConfigToken);
|
|
1318
|
-
const scope = input.scope ?? "session";
|
|
1319
|
-
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1320
|
-
if (!allowedScopes.includes(scope)) {
|
|
1321
|
-
throw this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
|
|
1322
|
-
}
|
|
1323
|
-
await remember.set(input.key, input.value, {
|
|
1324
|
-
scope,
|
|
1325
|
-
ttl: input.ttl,
|
|
1326
|
-
brand: input.brand
|
|
1327
|
-
});
|
|
1328
|
-
const expiresAt = input.ttl ? Date.now() + input.ttl * 1e3 : void 0;
|
|
1329
|
-
return {
|
|
1330
|
-
success: true,
|
|
1331
|
-
key: input.key,
|
|
1332
|
-
scope,
|
|
1333
|
-
expiresAt
|
|
1334
|
-
};
|
|
1335
|
-
}
|
|
1336
|
-
};
|
|
1337
|
-
RememberThisTool = __decorateClass([
|
|
1338
|
-
Tool({
|
|
1339
|
-
name: "remember_this",
|
|
1340
|
-
description: "Remember something for later: store a value under a key that recall can read back, in the scope you choose (this session by default; user scope for the signed-in user across sessions). It lasts until it is forgotten or its ttl runs out. Use this when the user asks you to remember preferences, settings, or any information they want to persist.",
|
|
1341
|
-
inputSchema: rememberThisInputSchema,
|
|
1342
|
-
outputSchema: rememberThisOutputSchema,
|
|
1343
|
-
annotations: {
|
|
1344
|
-
readOnlyHint: false
|
|
1345
|
-
}
|
|
1346
|
-
})
|
|
1347
|
-
], RememberThisTool);
|
|
1348
|
-
|
|
1349
|
-
// plugins/plugin-remember/src/tools/recall.tool.ts
|
|
1350
|
-
import { z as z4 } from "@frontmcp/lazy-zod";
|
|
1351
|
-
import { Tool as Tool2, ToolContext as ToolContext2 } from "@frontmcp/sdk";
|
|
1352
|
-
var recallInputSchema = {
|
|
1353
|
-
key: z4.string().min(1).describe("What memory to recall"),
|
|
1354
|
-
scope: z4.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
|
|
1355
|
-
};
|
|
1356
|
-
var recallOutputSchema = z4.object({
|
|
1357
|
-
found: z4.boolean(),
|
|
1358
|
-
key: z4.string(),
|
|
1359
|
-
value: z4.unknown().optional(),
|
|
1360
|
-
scope: z4.string(),
|
|
1361
|
-
createdAt: z4.number().optional(),
|
|
1362
|
-
expiresAt: z4.number().optional()
|
|
1564
|
+
var rememberEntrySchema = z6.object({
|
|
1565
|
+
value: z6.unknown(),
|
|
1566
|
+
brand: z6.enum(["approval", "preference", "cache", "state", "conversation", "custom"]).optional(),
|
|
1567
|
+
createdAt: z6.number(),
|
|
1568
|
+
updatedAt: z6.number(),
|
|
1569
|
+
expiresAt: z6.number().optional(),
|
|
1570
|
+
metadata: z6.record(z6.string(), z6.unknown()).optional()
|
|
1363
1571
|
});
|
|
1364
|
-
var RecallTool = class extends ToolContext2 {
|
|
1365
|
-
async execute(input) {
|
|
1366
|
-
const remember = this.get(RememberAccessorToken);
|
|
1367
|
-
const config = this.get(RememberConfigToken);
|
|
1368
|
-
const scope = input.scope ?? "session";
|
|
1369
|
-
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1370
|
-
if (!allowedScopes.includes(scope)) {
|
|
1371
|
-
this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
|
|
1372
|
-
}
|
|
1373
|
-
const entry = await remember.getEntry(input.key, { scope });
|
|
1374
|
-
if (!entry) {
|
|
1375
|
-
return {
|
|
1376
|
-
found: false,
|
|
1377
|
-
key: input.key,
|
|
1378
|
-
scope
|
|
1379
|
-
};
|
|
1380
|
-
}
|
|
1381
|
-
return {
|
|
1382
|
-
found: true,
|
|
1383
|
-
key: input.key,
|
|
1384
|
-
value: entry.value,
|
|
1385
|
-
scope,
|
|
1386
|
-
createdAt: entry.createdAt,
|
|
1387
|
-
expiresAt: entry.expiresAt
|
|
1388
|
-
};
|
|
1389
|
-
}
|
|
1390
|
-
};
|
|
1391
|
-
RecallTool = __decorateClass([
|
|
1392
|
-
Tool2({
|
|
1393
|
-
name: "recall",
|
|
1394
|
-
description: "Recall something that was previously remembered. Use this to retrieve stored preferences, settings, or any information that was saved with remember_this.",
|
|
1395
|
-
inputSchema: recallInputSchema,
|
|
1396
|
-
outputSchema: recallOutputSchema,
|
|
1397
|
-
annotations: {
|
|
1398
|
-
readOnlyHint: true
|
|
1399
|
-
}
|
|
1400
|
-
})
|
|
1401
|
-
], RecallTool);
|
|
1402
|
-
|
|
1403
|
-
// plugins/plugin-remember/src/tools/forget.tool.ts
|
|
1404
|
-
import { z as z5 } from "@frontmcp/lazy-zod";
|
|
1405
|
-
import { Tool as Tool3, ToolContext as ToolContext3 } from "@frontmcp/sdk";
|
|
1406
|
-
var forgetInputSchema = {
|
|
1407
|
-
key: z5.string().min(1).describe("What memory to forget"),
|
|
1408
|
-
scope: z5.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
|
|
1409
|
-
};
|
|
1410
|
-
var forgetOutputSchema = z5.object({
|
|
1411
|
-
success: z5.boolean(),
|
|
1412
|
-
key: z5.string(),
|
|
1413
|
-
scope: z5.string(),
|
|
1414
|
-
existed: z5.boolean()
|
|
1415
|
-
});
|
|
1416
|
-
var ForgetTool = class extends ToolContext3 {
|
|
1417
|
-
async execute(input) {
|
|
1418
|
-
const remember = this.get(RememberAccessorToken);
|
|
1419
|
-
const config = this.get(RememberConfigToken);
|
|
1420
|
-
const scope = input.scope ?? "session";
|
|
1421
|
-
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1422
|
-
if (!allowedScopes.includes(scope)) {
|
|
1423
|
-
throw this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
|
|
1424
|
-
}
|
|
1425
|
-
const existed = await remember.knows(input.key, { scope });
|
|
1426
|
-
await remember.forget(input.key, { scope });
|
|
1427
|
-
return {
|
|
1428
|
-
success: true,
|
|
1429
|
-
key: input.key,
|
|
1430
|
-
scope,
|
|
1431
|
-
existed
|
|
1432
|
-
};
|
|
1433
|
-
}
|
|
1434
|
-
};
|
|
1435
|
-
ForgetTool = __decorateClass([
|
|
1436
|
-
Tool3({
|
|
1437
|
-
name: "forget",
|
|
1438
|
-
description: "Forget a previously remembered value. Use this when the user wants to delete stored preferences or information.",
|
|
1439
|
-
inputSchema: forgetInputSchema,
|
|
1440
|
-
outputSchema: forgetOutputSchema,
|
|
1441
|
-
annotations: {
|
|
1442
|
-
readOnlyHint: false
|
|
1443
|
-
}
|
|
1444
|
-
})
|
|
1445
|
-
], ForgetTool);
|
|
1446
|
-
|
|
1447
|
-
// plugins/plugin-remember/src/tools/list-memories.tool.ts
|
|
1448
|
-
import { z as z6 } from "@frontmcp/lazy-zod";
|
|
1449
|
-
import { Tool as Tool4, ToolContext as ToolContext4 } from "@frontmcp/sdk";
|
|
1450
|
-
var listMemoriesInputSchema = {
|
|
1451
|
-
scope: z6.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
|
|
1452
|
-
pattern: z6.string().optional().describe('Pattern to filter keys (e.g., "user_*")'),
|
|
1453
|
-
limit: z6.number().positive().max(100).optional().describe("Maximum number of keys to return (default: 50)")
|
|
1454
|
-
};
|
|
1455
|
-
var listMemoriesOutputSchema = z6.object({
|
|
1456
|
-
keys: z6.array(z6.string()),
|
|
1457
|
-
scope: z6.string(),
|
|
1458
|
-
count: z6.number(),
|
|
1459
|
-
truncated: z6.boolean()
|
|
1460
|
-
});
|
|
1461
|
-
var ListMemoriesTool = class extends ToolContext4 {
|
|
1462
|
-
async execute(input) {
|
|
1463
|
-
const remember = this.get(RememberAccessorToken);
|
|
1464
|
-
const config = this.get(RememberConfigToken);
|
|
1465
|
-
const scope = input.scope ?? "session";
|
|
1466
|
-
const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
|
|
1467
|
-
if (!allowedScopes.includes(scope)) {
|
|
1468
|
-
throw this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
|
|
1469
|
-
}
|
|
1470
|
-
const limit = input.limit ?? 50;
|
|
1471
|
-
let keys = await remember.list({ scope, pattern: input.pattern });
|
|
1472
|
-
const truncated = keys.length > limit;
|
|
1473
|
-
if (truncated) {
|
|
1474
|
-
keys = keys.slice(0, limit);
|
|
1475
|
-
}
|
|
1476
|
-
return {
|
|
1477
|
-
keys,
|
|
1478
|
-
scope,
|
|
1479
|
-
count: keys.length,
|
|
1480
|
-
truncated
|
|
1481
|
-
};
|
|
1482
|
-
}
|
|
1483
|
-
};
|
|
1484
|
-
ListMemoriesTool = __decorateClass([
|
|
1485
|
-
Tool4({
|
|
1486
|
-
name: "list_memories",
|
|
1487
|
-
description: "List the remembered keys in one scope (default: session). Use this to see what memories are stored before you recall or forget one.",
|
|
1488
|
-
inputSchema: listMemoriesInputSchema,
|
|
1489
|
-
outputSchema: listMemoriesOutputSchema,
|
|
1490
|
-
annotations: {
|
|
1491
|
-
readOnlyHint: true
|
|
1492
|
-
}
|
|
1493
|
-
})
|
|
1494
|
-
], ListMemoriesTool);
|
|
1495
1572
|
|
|
1496
1573
|
// plugins/plugin-remember/src/remember.context-extension.ts
|
|
1497
1574
|
function getRemember(ctx) {
|
|
@@ -1514,6 +1591,7 @@ export {
|
|
|
1514
1591
|
RememberMemoryProvider,
|
|
1515
1592
|
RememberPlugin,
|
|
1516
1593
|
RememberRedisProvider,
|
|
1594
|
+
RememberScopeNotAllowedError,
|
|
1517
1595
|
RememberStoreToken,
|
|
1518
1596
|
RememberThisTool,
|
|
1519
1597
|
RememberVercelKvProvider,
|