@frontmcp/plugin-remember 1.9.5 → 1.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,71 +1,178 @@
1
1
  # @frontmcp/plugin-remember
2
2
 
3
- Remember plugin for FrontMCP - provides encrypted session memory with an approval system for secure tool authorization.
3
+ Gives the tools of a [FrontMCP](https://frontmcp.dev) server a small encrypted key-value memory, `this.remember`, so a
4
+ tool can store something on one call and read it on a later one: a user's language, a draft, the last record they
5
+ opened. Values are encrypted before they're stored, in memory, Redis or Vercel KV. Each value lives in a scope
6
+ (`session`, `user`, `tool` or `global`) that decides who can read it back. Turn on `tools.enabled` and the plugin also
7
+ gives the model four tools to remember things itself.
4
8
 
5
- ## Installation
9
+ [![npm](https://img.shields.io/npm/v/@frontmcp/plugin-remember.svg)](https://www.npmjs.com/package/@frontmcp/plugin-remember) [![License](https://img.shields.io/npm/l/@frontmcp/plugin-remember.svg)](https://github.com/agentfront/frontmcp/blob/main/LICENSE)
10
+
11
+ ## Install
6
12
 
7
13
  ```bash
8
14
  npm install @frontmcp/plugin-remember
9
15
  ```
10
16
 
17
+ The plugin runs inside a FrontMCP server, so your app needs `@frontmcp/sdk`, at the same version as this package, and
18
+ Node.js 24 or later. Its peer dependency `@frontmcp/lazy-zod` comes with the SDK.
19
+
20
+ For the Vercel KV store (`type: 'vercel-kv'`, or `'global-store'` with a Vercel KV provider), also install the optional
21
+ peer `@vercel/kv`. The Redis stores use `ioredis`, which is already a dependency.
22
+
11
23
  ## Usage
12
24
 
13
- ```typescript
25
+ Register the plugin with `RememberPlugin.init()` in the `plugins` of `@FrontMcp` (every app) or of one `@App` (that
26
+ app only). Importing the package also tells TypeScript about `this.remember`.
27
+
28
+ ```ts
14
29
  import { RememberPlugin } from '@frontmcp/plugin-remember';
15
- import { FrontMcp } from '@frontmcp/sdk';
30
+ import { App, FrontMcp, Tool, ToolContext, z } from '@frontmcp/sdk';
31
+
32
+ @Tool({
33
+ name: 'set_language',
34
+ description: 'Set the language the user wants answers in',
35
+ inputSchema: { language: z.string() },
36
+ })
37
+ class SetLanguageTool extends ToolContext {
38
+ async execute({ language }: { language: string }) {
39
+ await this.remember.set('language', language, { scope: 'user' });
40
+ return { language };
41
+ }
42
+ }
16
43
 
17
- const app = new FrontMcp({
18
- plugins: [RememberPlugin],
19
- });
44
+ @Tool({ name: 'get_language', description: 'The language the user wants answers in', inputSchema: {} })
45
+ class GetLanguageTool extends ToolContext {
46
+ async execute() {
47
+ const language = await this.remember.get('language', { scope: 'user', defaultValue: 'en' });
48
+ return { language };
49
+ }
50
+ }
51
+
52
+ @App({ id: 'preferences', name: 'Preferences', tools: [SetLanguageTool, GetLanguageTool] })
53
+ class PreferencesApp {}
54
+
55
+ @FrontMcp({
56
+ info: { name: 'assistant', version: '1.0.0' },
57
+ apps: [PreferencesApp],
58
+ plugins: [RememberPlugin.init({ type: 'memory' })],
59
+ })
60
+ export default class Server {}
20
61
  ```
21
62
 
22
- ## Features
63
+ `user` scope needs a signed-in caller. An anonymous caller is refused with `RememberIdentityError`; see
64
+ [Scopes](#scopes).
65
+
66
+ ## Options
67
+
68
+ Every option is optional. `RememberPlugin.init()` and `plugins: [RememberPlugin]` both keep values in memory.
69
+
70
+ | Option | Type | Default | Description |
71
+ | ---------------------- | ------------------------------------------------------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------- |
72
+ | `type` | `'memory' \| 'redis' \| 'redis-client' \| 'vercel-kv' \| 'global-store'` | `'memory'` | Where values are kept. See [Stores](#stores). |
73
+ | `keyPrefix` | `string` | `'remember:'` | Starts every key in the store. Give each server its own when several share a Redis. |
74
+ | `defaultTTL` | `number` (seconds) | | How long a value set without `ttl` lives. A whole number; `0` means no default expiry. |
75
+ | `encryption.enabled` | `boolean` | `true` | Encrypt values before they're stored. With `false`, values are stored as plain JSON. |
76
+ | `encryption.customKey` | `string` | | The secret keys are derived from, in place of `REMEMBER_SECRET`. See [Encryption](#encryption). |
77
+ | `config` | `{ host, port, password?, db? }` | | With `type: 'redis'`: where to connect. |
78
+ | `client` | `Redis` (ioredis) | | With `type: 'redis-client'`: a client you created. |
79
+ | `url`, `token` | `string` | `KV_REST_API_URL`, `KV_REST_API_TOKEN` | With `type: 'vercel-kv'`: the store's REST URL and token. |
80
+ | `tools.enabled` | `boolean` | `false` | Register the [memory tools](#memory-tools). |
81
+ | `tools.prefix` | `string` | | Starts the memory tools' names: `'memory_'` gives `memory_recall`, and so on. |
82
+ | `tools.allowedScopes` | `RememberScope[]` | all four | Which scopes the memory tools accept. Another scope fails with `RememberScopeNotAllowedError`. |
83
+ | `skipLegacyPurge` | `boolean` | `false` | Don't delete entries written by older versions of the plugin, whose keys can no longer be read. |
84
+ | `legacyPurgeDelayMs` | `number` | `86400000` (24 hours) | How long after the current key layout first reached the store to wait before that purge. |
23
85
 
24
- - **Encrypted Memory**: Store and retrieve values with AES-256-GCM encryption
25
- - **Scoped Storage**: Session, user, tool, and global scopes
26
- - **Approval System**: Tool approval workflow with configurable requirements
27
- - **TTL Support**: Automatic expiration of stored values
28
- - **Multiple Backends**: Redis, Vercel KV, or in-memory storage
86
+ ### Stores
29
87
 
30
- ## Usage in Tools
88
+ | `type` | Where values live |
89
+ | ---------------- | ---------------------------------------------------------------------------------------------------- |
90
+ | `'memory'` | A `Map` in the server's process. Lost on restart, and not shared between instances. |
91
+ | `'redis'` | A Redis server the plugin connects to with `config`. |
92
+ | `'redis-client'` | Your own `ioredis` client, in `client`. |
93
+ | `'vercel-kv'` | Vercel KV, through `@vercel/kv`. |
94
+ | `'global-store'` | The store in `@FrontMcp({ redis })`: Redis, or Vercel KV. Without `redis`, the server doesn't start. |
31
95
 
32
- ```typescript
33
- @Tool({ name: 'my_tool' })
34
- class MyTool extends ToolContext {
35
- async execute(input) {
36
- // Store a value
37
- await this.remember.set('theme', 'dark');
96
+ ## `this.remember`
38
97
 
39
- // Retrieve a value
40
- const theme = await this.remember.get('theme', { defaultValue: 'light' });
98
+ `this.remember` is available in tools, resources, prompts and agents. Every method takes a `scope` option, which
99
+ defaults to `'session'`.
41
100
 
42
- // Store with TTL (expires in 5 minutes)
43
- await this.remember.set('token', 'xyz', { ttl: 300 });
101
+ | Method | Returns | Description |
102
+ | ------------------------------ | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
103
+ | `set(key, value, options?)` | `Promise<RememberEntry>` | Stores a JSON-serializable `value`. Options: `scope`, `ttl` (seconds), `brand`, `metadata`. |
104
+ | `get(key, options?)` | `Promise<T \| undefined>` | The value, or `options.defaultValue` when there is none or it expired. |
105
+ | `getEntry(key, options?)` | `Promise<RememberEntry \| undefined>` | The value with its `brand`, `metadata`, `createdAt`, `updatedAt` and `expiresAt`. |
106
+ | `update(key, value, options?)` | `Promise<boolean>` | Replaces the value, keeping its metadata, and its expiry unless you pass `ttl`. `false` when there's nothing to update. |
107
+ | `knows(key, options?)` | `Promise<boolean>` | Whether `get()` would find a value. |
108
+ | `forget(key, options?)` | `Promise<void>` | Deletes the value. |
109
+ | `list(options?)` | `Promise<string[]>` | The keys in a scope. `options.pattern` filters them with `*` and `?`. |
44
110
 
45
- // Check if remembered
46
- if (await this.remember.knows('onboarded')) {
47
- // Skip onboarding
48
- }
49
- }
50
- }
51
- ```
111
+ `this.get(RememberAccessorToken)` returns the same accessor, and `this.tryGet(RememberAccessorToken)` returns it or
112
+ `undefined` where the plugin isn't installed.
52
113
 
53
- ## Configuration
114
+ ## Scopes
54
115
 
55
- ```typescript
56
- import { RememberPlugin } from '@frontmcp/plugin-remember';
116
+ | Scope | Who can read a value back |
117
+ | ------------------- | --------------------------------------------------------------------------------------------------- |
118
+ | `session` (default) | The same session, as the server verified it. Without a verified session, the same signed-in caller. |
119
+ | `user` | The same signed-in caller, across sessions. |
120
+ | `tool` | The same caller as `session`, and only from the tool that stored it. |
121
+ | `global` | Every caller. |
57
122
 
58
- const app = new FrontMcp({
59
- plugins: [
60
- RememberPlugin.configure({
61
- store: 'redis',
62
- encryption: { enabled: true },
63
- approval: { enabled: true },
64
- }),
65
- ],
66
- });
67
- ```
123
+ A scope with no caller to keep values apart throws `RememberIdentityError`: `user` scope for an anonymous caller, and
124
+ `session` or `tool` scope for an anonymous caller without a verified session. Under MCP 2026-07-28, which has no
125
+ sessions, `session` values belong to the signed-in caller and last across all their requests, so give
126
+ conversation-sized state a `ttl`.
127
+
128
+ ## Encryption
129
+
130
+ With encryption on (the default), each value is encrypted with AES-256-GCM, with a key derived (HKDF-SHA256) from a
131
+ server secret and the scope's identity. The server secret is `encryption.customKey` when you set it, otherwise:
132
+
133
+ 1. `REMEMBER_SECRET`, `MCP_MEMORY_SECRET` or `MCP_SESSION_SECRET` from the environment.
134
+ 2. Outside production (`NODE_ENV` isn't `production`): a secret the plugin generates and saves to
135
+ `.frontmcp/remember-secret.json`. Keep `.frontmcp/` out of version control.
136
+ 3. In production: a random secret for this process, with a warning. Values can't be read after a restart, or by
137
+ another instance.
138
+
139
+ Set `REMEMBER_SECRET`, or `encryption.customKey`, to the same value on every instance that shares a store.
140
+
141
+ ## Memory tools
142
+
143
+ With `tools.enabled: true`, the plugin registers four tools, named with `tools.prefix` if you set one:
144
+
145
+ | Tool | Arguments |
146
+ | --------------- | -------------------------------------------------------- |
147
+ | `remember_this` | `key`, `value`, `scope?`, `ttl?`, `brand?` |
148
+ | `recall` | `key`, `scope?` |
149
+ | `forget` | `key`, `scope?` |
150
+ | `list_memories` | `scope?`, `pattern?`, `limit?` (default 50, at most 100) |
151
+
152
+ The package also exports their classes, `RememberThisTool`, `RecallTool`, `ForgetTool` and `ListMemoriesTool`, to list
153
+ in an app's `tools` yourself. Use one way or the other, not both.
154
+
155
+ ## Docs
156
+
157
+ - [Remember plugin reference](https://frontmcp.dev/reference/plugins/remember): every option, scope and error.
158
+ - [Remembering across calls](https://frontmcp.dev/learn/remembering-across-calls): a step-by-step guide.
159
+ - [Redis](https://frontmcp.dev/reference/deployment/redis): the `@FrontMcp({ redis })` store that `type: 'global-store'`
160
+ uses.
161
+
162
+ ## Related packages
163
+
164
+ - [`@frontmcp/sdk`](https://www.npmjs.com/package/@frontmcp/sdk): the FrontMCP framework this plugin runs in.
165
+ - [`@frontmcp/plugin-approval`](https://www.npmjs.com/package/@frontmcp/plugin-approval): refuses a tool until an
166
+ approval is recorded for the caller. Tool approval lives there, not in this plugin.
167
+ - [`@frontmcp/plugin-cache`](https://www.npmjs.com/package/@frontmcp/plugin-cache): caches tool results.
168
+ - [`@frontmcp/plugins`](https://www.npmjs.com/package/@frontmcp/plugins): re-exports this plugin with other official
169
+ plugins.
170
+
171
+ ## Contributing
172
+
173
+ Source: [`plugins/plugin-remember`](https://github.com/agentfront/frontmcp/tree/main/plugins/plugin-remember). Issues
174
+ and pull requests are welcome; see [CONTRIBUTING.md](https://github.com/agentfront/frontmcp/blob/main/CONTRIBUTING.md).
68
175
 
69
176
  ## License
70
177
 
71
- Apache-2.0
178
+ Apache-2.0. See [LICENSE](https://github.com/agentfront/frontmcp/blob/main/LICENSE).
package/esm/package.json CHANGED
@@ -1,20 +1,23 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-remember",
3
- "version": "1.9.5",
4
- "description": "Remember plugin for FrontMCP - encrypted session memory with approval system for secure tool authorization",
3
+ "version": "1.9.7",
4
+ "description": "Remember plugin for FrontMCP: encrypted key-value memory for tools (this.remember) in session, user, tool and global scopes, stored in memory, Redis or Vercel KV",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
7
7
  "engines": {
8
8
  "node": ">=24.0.0"
9
9
  },
10
10
  "keywords": [
11
+ "frontmcp",
11
12
  "mcp",
13
+ "model-context-protocol",
14
+ "remember",
12
15
  "memory",
13
16
  "session",
14
17
  "encryption",
15
- "approval",
18
+ "redis",
19
+ "vercel-kv",
16
20
  "plugin",
17
- "frontmcp",
18
21
  "agentfront"
19
22
  ],
20
23
  "repository": {
@@ -49,12 +52,12 @@
49
52
  }
50
53
  },
51
54
  "dependencies": {
52
- "@frontmcp/sdk": "1.9.5",
53
- "@frontmcp/utils": "1.9.5",
55
+ "@frontmcp/utils": "1.9.7",
54
56
  "ioredis": "^5.8.0"
55
57
  },
56
58
  "peerDependencies": {
57
- "@frontmcp/lazy-zod": "1.9.5",
59
+ "@frontmcp/lazy-zod": "1.9.7",
60
+ "@frontmcp/sdk": "1.9.7",
58
61
  "@vercel/kv": "^2.0.0 || ^3.0.0"
59
62
  },
60
63
  "peerDependenciesMeta": {
@@ -63,6 +66,7 @@
63
66
  }
64
67
  },
65
68
  "devDependencies": {
69
+ "@frontmcp/sdk": "1.9.7",
66
70
  "reflect-metadata": "^0.2.2"
67
71
  }
68
72
  }
package/package.json CHANGED
@@ -1,20 +1,23 @@
1
1
  {
2
2
  "name": "@frontmcp/plugin-remember",
3
- "version": "1.9.5",
4
- "description": "Remember plugin for FrontMCP - encrypted session memory with approval system for secure tool authorization",
3
+ "version": "1.9.7",
4
+ "description": "Remember plugin for FrontMCP: encrypted key-value memory for tools (this.remember) in session, user, tool and global scopes, stored in memory, Redis or Vercel KV",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
7
7
  "engines": {
8
8
  "node": ">=24.0.0"
9
9
  },
10
10
  "keywords": [
11
+ "frontmcp",
11
12
  "mcp",
13
+ "model-context-protocol",
14
+ "remember",
12
15
  "memory",
13
16
  "session",
14
17
  "encryption",
15
- "approval",
18
+ "redis",
19
+ "vercel-kv",
16
20
  "plugin",
17
- "frontmcp",
18
21
  "agentfront"
19
22
  ],
20
23
  "repository": {
@@ -49,12 +52,12 @@
49
52
  }
50
53
  },
51
54
  "dependencies": {
52
- "@frontmcp/sdk": "1.9.5",
53
- "@frontmcp/utils": "1.9.5",
55
+ "@frontmcp/utils": "1.9.7",
54
56
  "ioredis": "^5.8.0"
55
57
  },
56
58
  "peerDependencies": {
57
- "@frontmcp/lazy-zod": "1.9.5",
59
+ "@frontmcp/lazy-zod": "1.9.7",
60
+ "@frontmcp/sdk": "1.9.7",
58
61
  "@vercel/kv": "^2.0.0 || ^3.0.0"
59
62
  },
60
63
  "peerDependenciesMeta": {
@@ -63,6 +66,7 @@
63
66
  }
64
67
  },
65
68
  "devDependencies": {
69
+ "@frontmcp/sdk": "1.9.7",
66
70
  "reflect-metadata": "^0.2.2"
67
71
  }
68
72
  }
@@ -21,6 +21,7 @@
21
21
  *
22
22
  * @packageDocumentation
23
23
  */
24
+ import type { ExecutionContextBase } from '@frontmcp/sdk';
24
25
  import type { RememberAccessor } from './providers/remember-accessor.provider';
25
26
  declare module '@frontmcp/sdk' {
26
27
  interface ExecutionContextBase {
@@ -52,14 +53,10 @@ declare module '@frontmcp/sdk' {
52
53
  *
53
54
  * @throws Error if RememberPlugin is not installed
54
55
  */
55
- export declare function getRemember<T extends {
56
- get: (token: unknown) => unknown;
57
- }>(ctx: T): RememberAccessor;
56
+ export declare function getRemember<T extends Pick<ExecutionContextBase, 'get'>>(ctx: T): RememberAccessor;
58
57
  /**
59
58
  * Try to get the RememberAccessor, returning undefined if not available.
60
59
  * Use this for graceful degradation when the plugin might not be installed.
61
60
  */
62
- export declare function tryGetRemember<T extends {
63
- tryGet?: (token: unknown) => unknown;
64
- }>(ctx: T): RememberAccessor | undefined;
61
+ export declare function tryGetRemember<T extends Partial<Pick<ExecutionContextBase, 'tryGet'>>>(ctx: T): RememberAccessor | undefined;
65
62
  //# sourceMappingURL=remember.context-extension.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remember.context-extension.d.ts","sourceRoot":"","sources":["../src/remember.context-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAO/E,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,oBAAoB;QAC5B;;;;;;;;;;;WAWG;QACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KACrC;IAGD,UAAU,aAAa;QACrB;;;WAGG;QACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KACrC;CACF;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CAAE,EAAE,GAAG,EAAE,CAAC,GAAG,gBAAgB,CAEpG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CAAE,EAC/E,GAAG,EAAE,CAAC,GACL,gBAAgB,GAAG,SAAS,CAK9B"}
1
+ {"version":3,"file":"remember.context-extension.d.ts","sourceRoot":"","sources":["../src/remember.context-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAO/E,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,oBAAoB;QAC5B;;;;;;;;;;;WAWG;QACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KACrC;IAGD,UAAU,aAAa;QACrB;;;WAGG;QACH,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KACrC;CACF;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,gBAAgB,CAEjG;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC,EACpF,GAAG,EAAE,CAAC,GACL,gBAAgB,GAAG,SAAS,CAK9B"}