@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/index.js CHANGED
@@ -50,6 +50,7 @@ __export(index_exports, {
50
50
  RememberMemoryProvider: () => RememberMemoryProvider,
51
51
  RememberPlugin: () => RememberPlugin,
52
52
  RememberRedisProvider: () => RememberRedisProvider,
53
+ RememberScopeNotAllowedError: () => RememberScopeNotAllowedError,
53
54
  RememberStoreToken: () => RememberStoreToken,
54
55
  RememberThisTool: () => RememberThisTool,
55
56
  RememberVercelKvProvider: () => RememberVercelKvProvider,
@@ -61,7 +62,7 @@ __export(index_exports, {
61
62
  module.exports = __toCommonJS(index_exports);
62
63
 
63
64
  // plugins/plugin-remember/src/remember.plugin.ts
64
- var import_sdk6 = require("@frontmcp/sdk");
65
+ var import_sdk11 = require("@frontmcp/sdk");
65
66
 
66
67
  // plugins/plugin-remember/src/providers/remember-accessor.provider.ts
67
68
  var import_sdk2 = require("@frontmcp/sdk");
@@ -310,6 +311,16 @@ var RememberIdentityError = class extends import_sdk.PublicMcpError {
310
311
  super(message, "REMEMBER_IDENTITY_REQUIRED", 403);
311
312
  }
312
313
  };
314
+ var RememberScopeNotAllowedError = class extends import_sdk.PublicMcpError {
315
+ name = "RememberScopeNotAllowedError";
316
+ constructor(scope, allowedScopes) {
317
+ super(
318
+ `Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`,
319
+ "REMEMBER_SCOPE_NOT_ALLOWED",
320
+ 400
321
+ );
322
+ }
323
+ };
313
324
 
314
325
  // plugins/plugin-remember/src/remember.legacy-purge.ts
315
326
  var LEGACY_SCOPES = ["session", "tool", "user"];
@@ -416,6 +427,9 @@ var STORAGE_LAYOUT_VERSION = "v2";
416
427
  function encodeKeyPart(value) {
417
428
  return encodeURIComponent(value);
418
429
  }
430
+ function remainingSeconds(expiresAt, now) {
431
+ return Math.max(1, Math.ceil((expiresAt - now) / 1e3));
432
+ }
419
433
  var RememberAccessor = class {
420
434
  store;
421
435
  ctx;
@@ -465,16 +479,8 @@ var RememberAccessor = class {
465
479
  */
466
480
  async get(key, options = {}) {
467
481
  const scope = options.scope ?? "session";
468
- const storageKey = this.buildStorageKey(key, scope);
469
- const raw = await this.store.getValue(storageKey);
470
- if (!raw) return options.defaultValue;
471
- const entry = this.encryptionEnabled ? await deserializeAndDecrypt(raw, this.getKeySource(scope)) : this.parseEntry(raw);
472
- if (!entry) return options.defaultValue;
473
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
474
- await this.forget(key, { scope });
475
- return options.defaultValue;
476
- }
477
- return entry.value;
482
+ const entry = await this.readEntry(this.buildStorageKey(key, scope), scope);
483
+ return entry ? entry.value : options.defaultValue;
478
484
  }
479
485
  /**
480
486
  * Get the full entry including metadata.
@@ -485,16 +491,7 @@ var RememberAccessor = class {
485
491
  */
486
492
  async getEntry(key, options = {}) {
487
493
  const scope = options.scope ?? "session";
488
- const storageKey = this.buildStorageKey(key, scope);
489
- const raw = await this.store.getValue(storageKey);
490
- if (!raw) return void 0;
491
- const entry = this.encryptionEnabled ? await deserializeAndDecrypt(raw, this.getKeySource(scope)) : this.parseEntry(raw);
492
- if (!entry) return void 0;
493
- if (entry.expiresAt && Date.now() > entry.expiresAt) {
494
- await this.forget(key, { scope });
495
- return void 0;
496
- }
497
- return entry;
494
+ return this.readEntry(this.buildStorageKey(key, scope), scope);
498
495
  }
499
496
  /**
500
497
  * Forget (delete) a value from memory.
@@ -508,19 +505,18 @@ var RememberAccessor = class {
508
505
  await this.store.delete(storageKey);
509
506
  }
510
507
  /**
511
- * Check if a key is remembered (exists and not expired).
508
+ * Check if a key is remembered: true exactly when `get()` would return its value.
512
509
  *
513
510
  * @param key - The key to check
514
511
  * @param options - Options (scope)
515
- * @returns true if the key exists
512
+ * @returns true if the key exists and has not expired
516
513
  */
517
514
  async knows(key, options = {}) {
518
515
  const scope = options.scope ?? "session";
519
- const storageKey = this.buildStorageKey(key, scope);
520
- return this.store.exists(storageKey);
516
+ return await this.readEntry(this.buildStorageKey(key, scope), scope) !== void 0;
521
517
  }
522
518
  /**
523
- * List all remembered keys for a scope.
519
+ * List all remembered keys for a scope: the keys `get()` would return a value for.
524
520
  *
525
521
  * @param options - Options (scope, pattern)
526
522
  * @returns Array of keys (without the scope prefix)
@@ -528,13 +524,16 @@ var RememberAccessor = class {
528
524
  async list(options = {}) {
529
525
  const scope = options.scope ?? "session";
530
526
  const scopePrefix = this.buildScopePrefix(scope);
531
- const fullPattern = scopePrefix + (options.pattern ?? "*");
532
- const keys = await this.store.keys(fullPattern);
533
- return keys.map((k) => k.slice(scopePrefix.length));
527
+ const storageKeys = await this.store.keys(scopePrefix + (options.pattern ?? "*"));
528
+ const entries = await Promise.all(storageKeys.map((storageKey) => this.readEntry(storageKey, scope)));
529
+ return storageKeys.filter((_storageKey, index) => entries[index] !== void 0).map((storageKey) => storageKey.slice(scopePrefix.length));
534
530
  }
535
531
  /**
536
532
  * Update an existing entry's value while preserving metadata.
537
533
  *
534
+ * With a `ttl` the entry expires that many seconds from now; without one it keeps its current
535
+ * expiry, in the store as well, so the store does not keep it past that (rounded up to a second).
536
+ *
538
537
  * @param key - The key to update
539
538
  * @param value - The new value
540
539
  * @param options - Options (scope, ttl)
@@ -543,15 +542,18 @@ var RememberAccessor = class {
543
542
  const scope = options.scope ?? "session";
544
543
  const existing = await this.getEntry(key, { scope });
545
544
  if (!existing) return false;
545
+ const now = Date.now();
546
+ const expiresAt = options.ttl ? now + options.ttl * 1e3 : existing.expiresAt;
546
547
  const entry = {
547
548
  ...existing,
548
549
  value,
549
- updatedAt: Date.now(),
550
- expiresAt: options.ttl ? Date.now() + options.ttl * 1e3 : existing.expiresAt
550
+ updatedAt: now,
551
+ expiresAt
551
552
  };
552
553
  const storageKey = this.buildStorageKey(key, scope);
553
554
  const serialized = this.encryptionEnabled ? await encryptAndSerialize(entry, this.getKeySource(scope)) : JSON.stringify(entry);
554
- await this.store.setValue(storageKey, serialized, options.ttl);
555
+ const storageTtl = options.ttl ?? (expiresAt !== void 0 ? remainingSeconds(expiresAt, now) : void 0);
556
+ await this.store.setValue(storageKey, serialized, storageTtl);
555
557
  return true;
556
558
  }
557
559
  // ─────────────────────────────────────────────────────────────────────────────
@@ -669,6 +671,18 @@ var RememberAccessor = class {
669
671
  toolName: scope === "tool" ? this.toolName : void 0
670
672
  });
671
673
  }
674
+ /** The entry stored under `storageKey`, if readable and unexpired; an expired one is deleted. */
675
+ async readEntry(storageKey, scope) {
676
+ const raw = await this.store.getValue(storageKey);
677
+ if (!raw) return void 0;
678
+ const entry = this.encryptionEnabled ? await deserializeAndDecrypt(raw, this.getKeySource(scope)) : this.parseEntry(raw);
679
+ if (!entry) return void 0;
680
+ if (entry.expiresAt && Date.now() > entry.expiresAt) {
681
+ await this.store.delete(storageKey);
682
+ return void 0;
683
+ }
684
+ return entry;
685
+ }
672
686
  /**
673
687
  * Parse a JSON entry (when encryption is disabled).
674
688
  */
@@ -1150,8 +1164,267 @@ var RememberAccessorToken = /* @__PURE__ */ Symbol(
1150
1164
  "plugin:remember:accessor"
1151
1165
  );
1152
1166
 
1167
+ // plugins/plugin-remember/src/tools/remember-tools.factory.ts
1168
+ var import_sdk10 = require("@frontmcp/sdk");
1169
+
1170
+ // plugins/plugin-remember/src/tools/forget.tool.ts
1171
+ var import_lazy_zod2 = require("@frontmcp/lazy-zod");
1172
+ var import_sdk6 = require("@frontmcp/sdk");
1173
+
1174
+ // plugins/plugin-remember/src/tools/remember-scope.description.ts
1175
+ 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.";
1176
+
1177
+ // plugins/plugin-remember/src/tools/remember-tool-names.ts
1178
+ function rememberToolNames(prefix = "") {
1179
+ return {
1180
+ rememberThis: `${prefix}remember_this`,
1181
+ recall: `${prefix}recall`,
1182
+ forget: `${prefix}forget`,
1183
+ listMemories: `${prefix}list_memories`
1184
+ };
1185
+ }
1186
+
1187
+ // plugins/plugin-remember/src/tools/forget.tool.ts
1188
+ var forgetInputSchema = {
1189
+ key: import_lazy_zod2.z.string().min(1).describe("What memory to forget"),
1190
+ scope: import_lazy_zod2.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
1191
+ };
1192
+ var forgetOutputSchema = import_lazy_zod2.z.object({
1193
+ success: import_lazy_zod2.z.boolean(),
1194
+ key: import_lazy_zod2.z.string(),
1195
+ scope: import_lazy_zod2.z.string(),
1196
+ existed: import_lazy_zod2.z.boolean()
1197
+ });
1198
+ function forgetDescription() {
1199
+ return "Forget a previously remembered value. Use this when the user wants to delete stored preferences or information.";
1200
+ }
1201
+ function forgetToolMetadata(names = rememberToolNames()) {
1202
+ return {
1203
+ name: names.forget,
1204
+ description: forgetDescription(),
1205
+ inputSchema: forgetInputSchema,
1206
+ outputSchema: forgetOutputSchema,
1207
+ annotations: { readOnlyHint: false }
1208
+ };
1209
+ }
1210
+ var ForgetTool = class extends import_sdk6.ToolContext {
1211
+ async execute(input) {
1212
+ const remember = this.get(RememberAccessorToken);
1213
+ const config = this.get(RememberConfigToken);
1214
+ const scope = input.scope ?? "session";
1215
+ const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1216
+ if (!allowedScopes.includes(scope)) {
1217
+ throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
1218
+ }
1219
+ const existed = await remember.knows(input.key, { scope });
1220
+ await remember.forget(input.key, { scope });
1221
+ return {
1222
+ success: true,
1223
+ key: input.key,
1224
+ scope,
1225
+ existed
1226
+ };
1227
+ }
1228
+ };
1229
+ ForgetTool = __decorateClass([
1230
+ (0, import_sdk6.Tool)(forgetToolMetadata())
1231
+ ], ForgetTool);
1232
+
1233
+ // plugins/plugin-remember/src/tools/list-memories.tool.ts
1234
+ var import_lazy_zod3 = require("@frontmcp/lazy-zod");
1235
+ var import_sdk7 = require("@frontmcp/sdk");
1236
+ var listMemoriesInputSchema = {
1237
+ scope: import_lazy_zod3.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
1238
+ pattern: import_lazy_zod3.z.string().optional().describe('Pattern to filter keys (e.g., "user_*")'),
1239
+ limit: import_lazy_zod3.z.number().positive().max(100).optional().describe("Maximum number of keys to return (default: 50)")
1240
+ };
1241
+ var listMemoriesOutputSchema = import_lazy_zod3.z.object({
1242
+ keys: import_lazy_zod3.z.array(import_lazy_zod3.z.string()),
1243
+ scope: import_lazy_zod3.z.string(),
1244
+ count: import_lazy_zod3.z.number(),
1245
+ truncated: import_lazy_zod3.z.boolean()
1246
+ });
1247
+ function listMemoriesDescription(names = rememberToolNames()) {
1248
+ 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.`;
1249
+ }
1250
+ function listMemoriesToolMetadata(names = rememberToolNames()) {
1251
+ return {
1252
+ name: names.listMemories,
1253
+ description: listMemoriesDescription(names),
1254
+ inputSchema: listMemoriesInputSchema,
1255
+ outputSchema: listMemoriesOutputSchema,
1256
+ annotations: { readOnlyHint: true }
1257
+ };
1258
+ }
1259
+ var ListMemoriesTool = class extends import_sdk7.ToolContext {
1260
+ async execute(input) {
1261
+ const remember = this.get(RememberAccessorToken);
1262
+ const config = this.get(RememberConfigToken);
1263
+ const scope = input.scope ?? "session";
1264
+ const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1265
+ if (!allowedScopes.includes(scope)) {
1266
+ throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
1267
+ }
1268
+ const limit = input.limit ?? 50;
1269
+ let keys = await remember.list({ scope, pattern: input.pattern });
1270
+ const truncated = keys.length > limit;
1271
+ if (truncated) {
1272
+ keys = keys.slice(0, limit);
1273
+ }
1274
+ return {
1275
+ keys,
1276
+ scope,
1277
+ count: keys.length,
1278
+ truncated
1279
+ };
1280
+ }
1281
+ };
1282
+ ListMemoriesTool = __decorateClass([
1283
+ (0, import_sdk7.Tool)(listMemoriesToolMetadata())
1284
+ ], ListMemoriesTool);
1285
+
1286
+ // plugins/plugin-remember/src/tools/recall.tool.ts
1287
+ var import_lazy_zod4 = require("@frontmcp/lazy-zod");
1288
+ var import_sdk8 = require("@frontmcp/sdk");
1289
+ var recallInputSchema = {
1290
+ key: import_lazy_zod4.z.string().min(1).describe("What memory to recall"),
1291
+ scope: import_lazy_zod4.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
1292
+ };
1293
+ var recallOutputSchema = import_lazy_zod4.z.object({
1294
+ found: import_lazy_zod4.z.boolean(),
1295
+ key: import_lazy_zod4.z.string(),
1296
+ value: import_lazy_zod4.z.unknown().optional(),
1297
+ scope: import_lazy_zod4.z.string(),
1298
+ createdAt: import_lazy_zod4.z.number().optional(),
1299
+ expiresAt: import_lazy_zod4.z.number().optional()
1300
+ });
1301
+ function recallDescription(names = rememberToolNames()) {
1302
+ return `Recall something that was previously remembered. Use this to retrieve stored preferences, settings, or any information that was saved with ${names.rememberThis}.`;
1303
+ }
1304
+ function recallToolMetadata(names = rememberToolNames()) {
1305
+ return {
1306
+ name: names.recall,
1307
+ description: recallDescription(names),
1308
+ inputSchema: recallInputSchema,
1309
+ outputSchema: recallOutputSchema,
1310
+ annotations: { readOnlyHint: true }
1311
+ };
1312
+ }
1313
+ var RecallTool = class extends import_sdk8.ToolContext {
1314
+ async execute(input) {
1315
+ const remember = this.get(RememberAccessorToken);
1316
+ const config = this.get(RememberConfigToken);
1317
+ const scope = input.scope ?? "session";
1318
+ const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1319
+ if (!allowedScopes.includes(scope)) {
1320
+ throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
1321
+ }
1322
+ const entry = await remember.getEntry(input.key, { scope });
1323
+ if (!entry) {
1324
+ return {
1325
+ found: false,
1326
+ key: input.key,
1327
+ scope
1328
+ };
1329
+ }
1330
+ return {
1331
+ found: true,
1332
+ key: input.key,
1333
+ value: entry.value,
1334
+ scope,
1335
+ createdAt: entry.createdAt,
1336
+ expiresAt: entry.expiresAt
1337
+ };
1338
+ }
1339
+ };
1340
+ RecallTool = __decorateClass([
1341
+ (0, import_sdk8.Tool)(recallToolMetadata())
1342
+ ], RecallTool);
1343
+
1344
+ // plugins/plugin-remember/src/tools/remember-this.tool.ts
1345
+ var import_lazy_zod5 = require("@frontmcp/lazy-zod");
1346
+ var import_sdk9 = require("@frontmcp/sdk");
1347
+ var rememberThisInputSchema = {
1348
+ key: import_lazy_zod5.z.string().min(1).describe('What to call this memory (e.g., "user_preference", "last_action")'),
1349
+ value: import_lazy_zod5.z.unknown().describe("The value to remember (any JSON-serializable data)"),
1350
+ scope: import_lazy_zod5.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
1351
+ ttl: import_lazy_zod5.z.number().positive().optional().describe("Forget after this many seconds"),
1352
+ brand: import_lazy_zod5.z.enum(["preference", "cache", "state", "conversation", "custom"]).optional().describe("Type hint for the stored value")
1353
+ };
1354
+ var rememberThisOutputSchema = import_lazy_zod5.z.object({
1355
+ success: import_lazy_zod5.z.boolean(),
1356
+ key: import_lazy_zod5.z.string(),
1357
+ scope: import_lazy_zod5.z.string(),
1358
+ expiresAt: import_lazy_zod5.z.number().optional()
1359
+ });
1360
+ function rememberThisDescription(names = rememberToolNames()) {
1361
+ 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.`;
1362
+ }
1363
+ function rememberThisToolMetadata(names = rememberToolNames()) {
1364
+ return {
1365
+ name: names.rememberThis,
1366
+ description: rememberThisDescription(names),
1367
+ inputSchema: rememberThisInputSchema,
1368
+ outputSchema: rememberThisOutputSchema,
1369
+ annotations: { readOnlyHint: false }
1370
+ };
1371
+ }
1372
+ var RememberThisTool = class extends import_sdk9.ToolContext {
1373
+ async execute(input) {
1374
+ const remember = this.get(RememberAccessorToken);
1375
+ const config = this.get(RememberConfigToken);
1376
+ const scope = input.scope ?? "session";
1377
+ const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1378
+ if (!allowedScopes.includes(scope)) {
1379
+ throw this.fail(new RememberScopeNotAllowedError(scope, allowedScopes));
1380
+ }
1381
+ await remember.set(input.key, input.value, {
1382
+ scope,
1383
+ ttl: input.ttl,
1384
+ brand: input.brand
1385
+ });
1386
+ const expiresAt = input.ttl ? Date.now() + input.ttl * 1e3 : void 0;
1387
+ return {
1388
+ success: true,
1389
+ key: input.key,
1390
+ scope,
1391
+ expiresAt
1392
+ };
1393
+ }
1394
+ };
1395
+ RememberThisTool = __decorateClass([
1396
+ (0, import_sdk9.Tool)(rememberThisToolMetadata())
1397
+ ], RememberThisTool);
1398
+
1399
+ // plugins/plugin-remember/src/tools/remember-tools.factory.ts
1400
+ function createRememberTools(prefix = "") {
1401
+ if (!prefix) return [RememberThisTool, RecallTool, ForgetTool, ListMemoriesTool];
1402
+ const names = rememberToolNames(prefix);
1403
+ let PrefixedRememberThisTool = class extends RememberThisTool {
1404
+ };
1405
+ PrefixedRememberThisTool = __decorateClass([
1406
+ (0, import_sdk10.Tool)(rememberThisToolMetadata(names))
1407
+ ], PrefixedRememberThisTool);
1408
+ let PrefixedRecallTool = class extends RecallTool {
1409
+ };
1410
+ PrefixedRecallTool = __decorateClass([
1411
+ (0, import_sdk10.Tool)(recallToolMetadata(names))
1412
+ ], PrefixedRecallTool);
1413
+ let PrefixedForgetTool = class extends ForgetTool {
1414
+ };
1415
+ PrefixedForgetTool = __decorateClass([
1416
+ (0, import_sdk10.Tool)(forgetToolMetadata(names))
1417
+ ], PrefixedForgetTool);
1418
+ let PrefixedListMemoriesTool = class extends ListMemoriesTool {
1419
+ };
1420
+ PrefixedListMemoriesTool = __decorateClass([
1421
+ (0, import_sdk10.Tool)(listMemoriesToolMetadata(names))
1422
+ ], PrefixedListMemoriesTool);
1423
+ return [PrefixedRememberThisTool, PrefixedRecallTool, PrefixedForgetTool, PrefixedListMemoriesTool];
1424
+ }
1425
+
1153
1426
  // plugins/plugin-remember/src/remember.plugin.ts
1154
- var RememberPlugin = class extends import_sdk6.DynamicPlugin {
1427
+ var RememberPlugin = class extends import_sdk11.DynamicPlugin {
1155
1428
  options;
1156
1429
  constructor(options = {}) {
1157
1430
  super();
@@ -1166,6 +1439,11 @@ __publicField(RememberPlugin, "defaultOptions", {
1166
1439
  keyPrefix: "remember:",
1167
1440
  encryption: { enabled: true }
1168
1441
  });
1442
+ /**
1443
+ * The memory tools, when `tools.enabled` is set: `remember_this`, `recall`, `forget` and
1444
+ * `list_memories`, under `tools.prefix`.
1445
+ */
1446
+ __publicField(RememberPlugin, "dynamicTools", (options) => options.tools?.enabled ? createRememberTools(options.tools.prefix) : []);
1169
1447
  /**
1170
1448
  * Dynamic providers based on plugin options.
1171
1449
  */
@@ -1180,10 +1458,10 @@ __publicField(RememberPlugin, "dynamicProviders", (options) => {
1180
1458
  providers.push({
1181
1459
  name: "remember:store:global",
1182
1460
  provide: RememberStoreToken,
1183
- inject: () => [import_sdk6.FrontMcpConfig],
1461
+ inject: () => [import_sdk11.FrontMcpConfig],
1184
1462
  useFactory: (frontmcpConfig) => {
1185
- const storeConfig = (0, import_sdk6.getGlobalStoreConfig)("RememberPlugin", frontmcpConfig);
1186
- if ((0, import_sdk6.isVercelKvProvider)(storeConfig)) {
1463
+ const storeConfig = (0, import_sdk11.getGlobalStoreConfig)("RememberPlugin", frontmcpConfig);
1464
+ if ((0, import_sdk11.isVercelKvProvider)(storeConfig)) {
1187
1465
  return new RememberVercelKvProvider({
1188
1466
  url: storeConfig.url,
1189
1467
  token: storeConfig.token,
@@ -1264,14 +1542,14 @@ __publicField(RememberPlugin, "dynamicProviders", (options) => {
1264
1542
  providers.push({
1265
1543
  name: "remember:accessor",
1266
1544
  provide: RememberAccessorToken,
1267
- scope: import_sdk6.ProviderScope.CONTEXT,
1268
- inject: () => [RememberStoreToken, import_sdk6.FRONTMCP_CONTEXT, RememberConfigToken, import_sdk6.FrontMcpLogger],
1545
+ scope: import_sdk11.ProviderScope.CONTEXT,
1546
+ inject: () => [RememberStoreToken, import_sdk11.FRONTMCP_CONTEXT, RememberConfigToken, import_sdk11.FrontMcpLogger],
1269
1547
  useFactory: (store, ctx, cfg, logger) => createRememberAccessor(store, ctx, cfg, logger)
1270
1548
  });
1271
1549
  return providers;
1272
1550
  });
1273
1551
  RememberPlugin = __decorateClass([
1274
- (0, import_sdk6.Plugin)({
1552
+ (0, import_sdk11.Plugin)({
1275
1553
  name: "remember",
1276
1554
  description: "Help your LLM remember things across sessions",
1277
1555
  providers: [
@@ -1297,223 +1575,20 @@ RememberPlugin = __decorateClass([
1297
1575
  ], RememberPlugin);
1298
1576
 
1299
1577
  // plugins/plugin-remember/src/remember.types.ts
1300
- var import_lazy_zod2 = require("@frontmcp/lazy-zod");
1301
- var rememberScopeSchema = import_lazy_zod2.z.enum(["session", "user", "tool", "global"]);
1578
+ var import_lazy_zod6 = require("@frontmcp/lazy-zod");
1579
+ var rememberScopeSchema = import_lazy_zod6.z.enum(["session", "user", "tool", "global"]);
1302
1580
  function brand(data, _brand) {
1303
1581
  return data;
1304
1582
  }
1305
- var rememberEntrySchema = import_lazy_zod2.z.object({
1306
- value: import_lazy_zod2.z.unknown(),
1307
- brand: import_lazy_zod2.z.enum(["approval", "preference", "cache", "state", "conversation", "custom"]).optional(),
1308
- createdAt: import_lazy_zod2.z.number(),
1309
- updatedAt: import_lazy_zod2.z.number(),
1310
- expiresAt: import_lazy_zod2.z.number().optional(),
1311
- metadata: import_lazy_zod2.z.record(import_lazy_zod2.z.string(), import_lazy_zod2.z.unknown()).optional()
1583
+ var rememberEntrySchema = import_lazy_zod6.z.object({
1584
+ value: import_lazy_zod6.z.unknown(),
1585
+ brand: import_lazy_zod6.z.enum(["approval", "preference", "cache", "state", "conversation", "custom"]).optional(),
1586
+ createdAt: import_lazy_zod6.z.number(),
1587
+ updatedAt: import_lazy_zod6.z.number(),
1588
+ expiresAt: import_lazy_zod6.z.number().optional(),
1589
+ metadata: import_lazy_zod6.z.record(import_lazy_zod6.z.string(), import_lazy_zod6.z.unknown()).optional()
1312
1590
  });
1313
1591
 
1314
- // plugins/plugin-remember/src/tools/remember-this.tool.ts
1315
- var import_lazy_zod3 = require("@frontmcp/lazy-zod");
1316
- var import_sdk7 = require("@frontmcp/sdk");
1317
-
1318
- // plugins/plugin-remember/src/tools/remember-scope.description.ts
1319
- 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.";
1320
-
1321
- // plugins/plugin-remember/src/tools/remember-this.tool.ts
1322
- var rememberThisInputSchema = {
1323
- key: import_lazy_zod3.z.string().min(1).describe('What to call this memory (e.g., "user_preference", "last_action")'),
1324
- value: import_lazy_zod3.z.unknown().describe("The value to remember (any JSON-serializable data)"),
1325
- scope: import_lazy_zod3.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
1326
- ttl: import_lazy_zod3.z.number().positive().optional().describe("Forget after this many seconds"),
1327
- brand: import_lazy_zod3.z.enum(["preference", "cache", "state", "conversation", "custom"]).optional().describe("Type hint for the stored value")
1328
- };
1329
- var rememberThisOutputSchema = import_lazy_zod3.z.object({
1330
- success: import_lazy_zod3.z.boolean(),
1331
- key: import_lazy_zod3.z.string(),
1332
- scope: import_lazy_zod3.z.string(),
1333
- expiresAt: import_lazy_zod3.z.number().optional()
1334
- });
1335
- var RememberThisTool = class extends import_sdk7.ToolContext {
1336
- async execute(input) {
1337
- const remember = this.get(RememberAccessorToken);
1338
- const config = this.get(RememberConfigToken);
1339
- const scope = input.scope ?? "session";
1340
- const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1341
- if (!allowedScopes.includes(scope)) {
1342
- throw this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
1343
- }
1344
- await remember.set(input.key, input.value, {
1345
- scope,
1346
- ttl: input.ttl,
1347
- brand: input.brand
1348
- });
1349
- const expiresAt = input.ttl ? Date.now() + input.ttl * 1e3 : void 0;
1350
- return {
1351
- success: true,
1352
- key: input.key,
1353
- scope,
1354
- expiresAt
1355
- };
1356
- }
1357
- };
1358
- RememberThisTool = __decorateClass([
1359
- (0, import_sdk7.Tool)({
1360
- name: "remember_this",
1361
- 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.",
1362
- inputSchema: rememberThisInputSchema,
1363
- outputSchema: rememberThisOutputSchema,
1364
- annotations: {
1365
- readOnlyHint: false
1366
- }
1367
- })
1368
- ], RememberThisTool);
1369
-
1370
- // plugins/plugin-remember/src/tools/recall.tool.ts
1371
- var import_lazy_zod4 = require("@frontmcp/lazy-zod");
1372
- var import_sdk8 = require("@frontmcp/sdk");
1373
- var recallInputSchema = {
1374
- key: import_lazy_zod4.z.string().min(1).describe("What memory to recall"),
1375
- scope: import_lazy_zod4.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
1376
- };
1377
- var recallOutputSchema = import_lazy_zod4.z.object({
1378
- found: import_lazy_zod4.z.boolean(),
1379
- key: import_lazy_zod4.z.string(),
1380
- value: import_lazy_zod4.z.unknown().optional(),
1381
- scope: import_lazy_zod4.z.string(),
1382
- createdAt: import_lazy_zod4.z.number().optional(),
1383
- expiresAt: import_lazy_zod4.z.number().optional()
1384
- });
1385
- var RecallTool = class extends import_sdk8.ToolContext {
1386
- async execute(input) {
1387
- const remember = this.get(RememberAccessorToken);
1388
- const config = this.get(RememberConfigToken);
1389
- const scope = input.scope ?? "session";
1390
- const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1391
- if (!allowedScopes.includes(scope)) {
1392
- this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
1393
- }
1394
- const entry = await remember.getEntry(input.key, { scope });
1395
- if (!entry) {
1396
- return {
1397
- found: false,
1398
- key: input.key,
1399
- scope
1400
- };
1401
- }
1402
- return {
1403
- found: true,
1404
- key: input.key,
1405
- value: entry.value,
1406
- scope,
1407
- createdAt: entry.createdAt,
1408
- expiresAt: entry.expiresAt
1409
- };
1410
- }
1411
- };
1412
- RecallTool = __decorateClass([
1413
- (0, import_sdk8.Tool)({
1414
- name: "recall",
1415
- description: "Recall something that was previously remembered. Use this to retrieve stored preferences, settings, or any information that was saved with remember_this.",
1416
- inputSchema: recallInputSchema,
1417
- outputSchema: recallOutputSchema,
1418
- annotations: {
1419
- readOnlyHint: true
1420
- }
1421
- })
1422
- ], RecallTool);
1423
-
1424
- // plugins/plugin-remember/src/tools/forget.tool.ts
1425
- var import_lazy_zod5 = require("@frontmcp/lazy-zod");
1426
- var import_sdk9 = require("@frontmcp/sdk");
1427
- var forgetInputSchema = {
1428
- key: import_lazy_zod5.z.string().min(1).describe("What memory to forget"),
1429
- scope: import_lazy_zod5.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION)
1430
- };
1431
- var forgetOutputSchema = import_lazy_zod5.z.object({
1432
- success: import_lazy_zod5.z.boolean(),
1433
- key: import_lazy_zod5.z.string(),
1434
- scope: import_lazy_zod5.z.string(),
1435
- existed: import_lazy_zod5.z.boolean()
1436
- });
1437
- var ForgetTool = class extends import_sdk9.ToolContext {
1438
- async execute(input) {
1439
- const remember = this.get(RememberAccessorToken);
1440
- const config = this.get(RememberConfigToken);
1441
- const scope = input.scope ?? "session";
1442
- const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1443
- if (!allowedScopes.includes(scope)) {
1444
- throw this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
1445
- }
1446
- const existed = await remember.knows(input.key, { scope });
1447
- await remember.forget(input.key, { scope });
1448
- return {
1449
- success: true,
1450
- key: input.key,
1451
- scope,
1452
- existed
1453
- };
1454
- }
1455
- };
1456
- ForgetTool = __decorateClass([
1457
- (0, import_sdk9.Tool)({
1458
- name: "forget",
1459
- description: "Forget a previously remembered value. Use this when the user wants to delete stored preferences or information.",
1460
- inputSchema: forgetInputSchema,
1461
- outputSchema: forgetOutputSchema,
1462
- annotations: {
1463
- readOnlyHint: false
1464
- }
1465
- })
1466
- ], ForgetTool);
1467
-
1468
- // plugins/plugin-remember/src/tools/list-memories.tool.ts
1469
- var import_lazy_zod6 = require("@frontmcp/lazy-zod");
1470
- var import_sdk10 = require("@frontmcp/sdk");
1471
- var listMemoriesInputSchema = {
1472
- scope: import_lazy_zod6.z.enum(["session", "user", "tool", "global"]).optional().describe(REMEMBER_SCOPE_DESCRIPTION),
1473
- pattern: import_lazy_zod6.z.string().optional().describe('Pattern to filter keys (e.g., "user_*")'),
1474
- limit: import_lazy_zod6.z.number().positive().max(100).optional().describe("Maximum number of keys to return (default: 50)")
1475
- };
1476
- var listMemoriesOutputSchema = import_lazy_zod6.z.object({
1477
- keys: import_lazy_zod6.z.array(import_lazy_zod6.z.string()),
1478
- scope: import_lazy_zod6.z.string(),
1479
- count: import_lazy_zod6.z.number(),
1480
- truncated: import_lazy_zod6.z.boolean()
1481
- });
1482
- var ListMemoriesTool = class extends import_sdk10.ToolContext {
1483
- async execute(input) {
1484
- const remember = this.get(RememberAccessorToken);
1485
- const config = this.get(RememberConfigToken);
1486
- const scope = input.scope ?? "session";
1487
- const allowedScopes = config.tools?.allowedScopes ?? ["session", "user", "tool", "global"];
1488
- if (!allowedScopes.includes(scope)) {
1489
- throw this.fail(new Error(`Scope '${scope}' is not allowed. Allowed scopes: ${allowedScopes.join(", ")}`));
1490
- }
1491
- const limit = input.limit ?? 50;
1492
- let keys = await remember.list({ scope, pattern: input.pattern });
1493
- const truncated = keys.length > limit;
1494
- if (truncated) {
1495
- keys = keys.slice(0, limit);
1496
- }
1497
- return {
1498
- keys,
1499
- scope,
1500
- count: keys.length,
1501
- truncated
1502
- };
1503
- }
1504
- };
1505
- ListMemoriesTool = __decorateClass([
1506
- (0, import_sdk10.Tool)({
1507
- name: "list_memories",
1508
- description: "List the remembered keys in one scope (default: session). Use this to see what memories are stored before you recall or forget one.",
1509
- inputSchema: listMemoriesInputSchema,
1510
- outputSchema: listMemoriesOutputSchema,
1511
- annotations: {
1512
- readOnlyHint: true
1513
- }
1514
- })
1515
- ], ListMemoriesTool);
1516
-
1517
1592
  // plugins/plugin-remember/src/remember.context-extension.ts
1518
1593
  function getRemember(ctx) {
1519
1594
  return ctx.get(RememberAccessorToken);
@@ -1536,6 +1611,7 @@ function tryGetRemember(ctx) {
1536
1611
  RememberMemoryProvider,
1537
1612
  RememberPlugin,
1538
1613
  RememberRedisProvider,
1614
+ RememberScopeNotAllowedError,
1539
1615
  RememberStoreToken,
1540
1616
  RememberThisTool,
1541
1617
  RememberVercelKvProvider,