Why Use Remember?
Session Memory
Store user preferences, conversation context, and state across tool invocations
Encrypted Storage
AES-256-GCM encryption protects sensitive data at rest
Multiple Backends
Redis, Vercel KV, or in-memory storage for different deployment needs
Scoped Storage
Organize data by session, user, tool, or global scope
For tool approval workflows (Claude Code-style permissions), see the Approval Plugin.
Installation
How It Works
1
Context Extension
The plugin adds
this.remember to all execution contexts (ToolContext, AgentContext, etc.)2
Scoped Storage
Data is organized by scope (session, user, tool, global) with automatic key prefixing
3
Encryption
Values are encrypted before storage using keys derived from session/user identifiers
4
TTL Management
Entries expire automatically based on configured TTL or scope lifetime
All stored values are encrypted by default using AES-256-GCM. Keys are derived using HKDF-SHA256 from session and user identifiers.
Quick Start
Basic Setup
Using Memory in Tools
The plugin extends all execution contexts withthis.remember:
Memory Scopes
Memory is organized into four scopes with different visibility and lifetime:Using Scopes
Data Structure
Entry Format
Each stored value is wrapped in an entry with metadata:Branded Payloads
Use brands to categorize stored data semantically:Storage Options
In-Memory (Default)
Best for: Single-instance deployments, development, non-persistent dataRedis (Recommended for Production)
Best for: Multi-instance deployments, persistent memory, productionVercel KV
Best for: Vercel deployments, serverless environmentsGlobal Store
Use the store configuration from@FrontMcp decorator:
Encryption
All stored values are encrypted by default using AES-256-GCM.How Keys Are Derived
- A master secret is derived from the
REMEMBER_SECRETenvironment variable (or auto-generated and persisted) - Per-entry keys are derived using HKDF-SHA256 over that secret plus the scope’s identity
- Each entry gets a unique key based on its scope and identity
session and tool included. A session id is not a
secret — the client knows it and it travels in the mcp-session-id header — so a key derived
from it alone could be recomputed by anyone who had seen it.
Upgrading past the key-derivation change
Two changes moved data written by earlier versions:- Key derivation.
sessionandtoolkeys now mix in the master secret, so ciphertext written before the change no longer decrypts. - Namespace encoding.
session,toolanduserprefixes now percent-encode every variable component, so an identity containing a characterencodeURIComponentescapes — a:in a user id, for instance — now lives under a different key.
null and a moved key simply misses,
so the value reads as absent rather than raising.
These three scopes are therefore stored under a v2: segment
(remember:v2:session:<identity>:<key>), and the plugin purges the pre-v2 entries
automatically, logging a warning with the number removed. The version segment is what makes
that safe: a purge pattern of remember:session:* cannot match a live remember:v2:session:*
key, not even one written concurrently by another instance.
global is not versioned and is not purged — neither its keys nor its key derivation changed.
When the purge runs
Twenty-four hours after the fleet first reached thev2: layout — not after this process
started — and never on the request path.
The first instance to reach the store stamps a marker at <keyPrefix>__layout__:
v2: for a while”, and an instance that
booted early would fire on its own schedule no matter when the last old instance drained. The
marker is written once and never overwritten, so a later instance cannot reset it, and whichever
instance is alive when the window passes completes the sweep.
The window has to outlast two things: the rollout, and the period in which a bad deploy gets
rolled back. The second is the one that matters — a rollback after the sweep makes the old
fleet permanent again with its memory already deleted. Waiting costs nothing, because the
entries are unreadable the whole time. Tune it with legacyPurgeDelayMs:
Serverless and edge runtimes. An invocation that ends before the timer fires never
purges, and the timer is unreferenced so it will not hold a process open. That is the safe
outcome — the entries are inert either way. Clear them with the commands below if you want
the storage back.
If the marker cannot be read or written — a permission error, or a value that is not the
expected JSON — the purge stands down and deletes nothing. It never treats a missing clock
as licence to delete.
Secret Persistence
In development, the plugin automatically generates and persists an encryption secret to.frontmcp/remember-secret.json:
Configuration
API Reference
RememberAccessor Methods
Promise<void>
Store a value with optional scope, TTL, and metadata
Promise<T | undefined>
Retrieve a value with optional default
Promise<RememberEntry<T> | undefined>
Retrieve the full entry including metadata, timestamps, and brand
Promise<boolean>
Update an existing value while preserving metadata. Returns
false if key doesn’t exist.Promise<boolean>
Check if a key exists
Promise<void>
Delete a key
Promise<string[]>
List keys with optional pattern matching
LLM-Accessible Tools
Enable built-in tools that let the LLM manage memory directly:memory_remember_this, memory_recall, memory_forget, and memory_list_memories. Without prefix they are remember_this, recall, forget and list_memories; with enabled unset or false no memory tool is registered. Each tool’s description names its prefixed siblings, and a scope outside allowedScopes is rejected with a public REMEMBER_SCOPE_NOT_ALLOWED error (HTTP 400) whose message lists the allowed scopes, so the model can retry. That includes the default session scope when a call omits scope and allowedScopes does not list it; the refusal used to surface as Internal FrontMCP error in production.
Each takes an optional scope (default session), described to the model the same way in all four tools:
An anonymous caller cannot use
user, nor session or tool without a session. None of these lifetimes is “until
disconnect” or “forever”: entries last until they are forgotten or their ttl runs out, and session memory without a
session belongs to the signed-in caller rather than ending with a connection.
Best Practices
1. Use Appropriate Scopes
1. Use Appropriate Scopes
- Session: Temporary data, current conversation context
- User: Preferences, settings that should persist
- Tool: Tool-specific cache to avoid scope pollution
- Global: Only for true application-wide settings
2. Set TTLs for Sensitive Data
2. Set TTLs for Sensitive Data
Don’t store sensitive data forever:
3. Use Redis for Production
3. Use Redis for Production
Redis provides:
- Persistence across restarts
- Sharing across multiple server instances
- Better memory management with eviction policies
4. Set REMEMBER_SECRET in Production
4. Set REMEMBER_SECRET in Production
In development, the secret is auto-generated and stored in
.frontmcp/remember-secret.json. Add this file to .gitignore.Complete Example
Links & Resources
Source Code
View the remember plugin source code
Approval Plugin
For tool authorization workflows
Plugin Guide
Learn more about FrontMCP plugins
Cache Plugin
For tool response caching