TL;DR
Add persistent memory to AI agents in 4 steps:
- Set up an MCP memory server with
remember,recall,search, androllbacktools. - Add memory instructions to agent prompts.
- Configure
~/.claude/settings.jsonfor Claude Code or.cursor/mcp.jsonfor Cursor. - Use memory patterns for decision logging, agent handoffs, and session checkpoints.
Agents retain context across sessions—no more copy-pasting previous conversations.
Solve the “I don’t remember yesterday” problem. Add persistent memory to AI agents using MCP protocol, and they’ll recall decisions, deliverables, and context from previous sessions.
You know the drill:
Day 1: "Build the user authentication system"
Agent: [Builds JWT auth, creates users table, implements refresh tokens]
Day 2: "Continue from yesterday"
Agent: "I don't have context from previous sessions. Can you paste what we did?"
You copy-paste the previous conversation. The agent reads 2000 lines of context. You both waste 15 minutes getting back up to speed.
Persistent memory fixes this. With MCP (Model Context Protocol) memory, agents store decisions automatically and recall them when needed. No copy-paste. No re-explanation.
In this guide, you’ll set up MCP memory for AI agents. You’ll see how to store decisions from Backend Architect sessions, recall context when switching to Database Optimizer, and hand off deliverables to Frontend Developer—all without losing context. These memory patterns work whether you’re building APIs with Apidog integration or managing multi-day development sprints.
What Is MCP Memory?
MCP memory lets AI agents store and retrieve information across sessions. Think of it as a shared notebook that agents can write to and read from.
Four tools power MCP memory:
| Tool | Purpose | Example |
|---|---|---|
remember |
Store information with tags | Save “users table with UUID, bcrypt” |
recall |
Search by keyword or tag | Find “auth decisions” |
rollback |
Restore to previous state | Undo bad schema changes |
search |
Find across sessions | “What did Backend Architect decide?” |
┌─────────────────┐ ┌──────────────────┐ ┌─────────────┐
│ AI Agent │ │ MCP Memory │ │ Storage │
│ (Claude Code) │◄───────►│ Server │◄───────►│ (SQLite) │
└─────────────────┘ JSON └──────────────────┘ I/O └─────────────┘
Step 1: Set Up an MCP Memory Server
You need an MCP server that exposes memory tools. There are several open-source implementations. Here are two options:
Option A: Use a hosted memory server
npm install -g @example/mcp-memory-server
Option B: Run a simple local server
Create memory-server.js:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import fs from "fs/promises";
import path from "path";
const MEMORY_FILE = path.join(process.env.HOME, ".mcp-memory", "memories.json");
const server = new McpServer({
name: "memory",
version: "1.0.0"
});
// Ensure memory file exists
async function initMemory() {
await fs.mkdir(path.dirname(MEMORY_FILE), { recursive: true });
try {
await fs.access(MEMORY_FILE);
} catch {
await fs.writeFile(MEMORY_FILE, JSON.stringify([]));
}
}
// Tool: remember
server.tool(
"remember",
{
content: z.string().describe("Information to store"),
tags: z.array(z.string()).describe("Tags for retrieval (e.g., ['backend', 'auth'])"),
agent: z.string().optional().describe("Agent name for tagging")
},
async ({ content, tags, agent }) => {
await initMemory();
const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8"));
const memory = {
id: Date.now().toString(),
content,
tags,
agent,
timestamp: new Date().toISOString()
};
memories.push(memory);
await fs.writeFile(MEMORY_FILE, JSON.stringify(memories, null, 2));
return { content: [{ type: "text", text: `Stored memory with tags: ${tags.join(", ")}` }] };
}
);
// Tool: recall
server.tool(
"recall",
{
query: z.string().describe("Search query or tag to find"),
agent: z.string().optional().describe("Filter by agent name")
},
async ({ query, agent }) => {
await initMemory();
const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8"));
const results = memories.filter(m => {
const matchesQuery = m.content.toLowerCase().includes(query.toLowerCase()) ||
m.tags.some(t => t.toLowerCase().includes(query.toLowerCase()));
const matchesAgent = !agent || m.agent === agent;
return matchesQuery && matchesAgent;
});
return {
content: [{
type: "text",
text: results.length === 0
? "No memories found"
: results.map(m => `[${m.timestamp}] ${m.content}`).join("\n\n")
}]
};
}
);
// Tool: search
server.tool(
"search",
{
tags: z.array(z.string()).describe("Tags to search for"),
limit: z.number().optional().default(10)
},
async ({ tags, limit }) => {
await initMemory();
const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8"));
const results = memories
.filter(m => tags.some(t => m.tags.includes(t)))
.slice(0, limit);
return {
content: [{
type: "text",
text: results.map(m => `[${m.agent || "unknown"}] ${m.content}`).join("\n\n")
}]
};
}
);
// Tool: rollback
server.tool(
"rollback",
{
agent: z.string().describe("Agent name to rollback"),
timestamp: z.string().describe("Rollback to this timestamp")
},
async ({ agent, timestamp }) => {
await initMemory();
const memories = JSON.parse(await fs.readFile(MEMORY_FILE, "utf-8"));
const rolledBack = memories.filter(m =>
m.agent !== agent || new Date(m.timestamp) <= new Date(timestamp)
);
await fs.writeFile(MEMORY_FILE, JSON.stringify(rolledBack, null, 2));
return {
content: [{
type: "text",
text: `Rolled back ${agent} to ${timestamp}`
}]
};
}
);
const transport = new StdioServerTransport();
await server.connect(transport);
Run the server:
node memory-server.js
Step 2: Add Memory Instructions to Any Agent
You don’t need to modify agent files. Add memory instructions in your prompt:
You have access to MCP memory tools: remember, recall, search, rollback.
Follow these memory protocols:
**When you start a session:**
1. Recall context: recall(query="ecommerce-api", agent="Backend Architect")
2. Review pending items from last session
**When you complete work:**
1. Remember deliverables with tags:
- remember(content="Created users table with UUID primary key, bcrypt password hashing, JWT auth with refresh tokens", tags=["ecommerce-api", "database", "auth"], agent="Backend Architect")
2. Include decisions made and pending items
**When handing off to another agent:**
1. Leave context for the receiving agent:
- remember(content="API endpoints: /auth/login, /auth/register, /products, /orders. Auth flow: JWT access token (15min) + refresh token (7 days). Known issue: rate limiting not yet implemented", tags=["ecommerce-api", "handoff"], agent="Backend Architect", for="Frontend Developer")
**When something fails:**
1. Search for last known-good state
2. Use rollback to restore
Example in action:
You: "Activate Backend Architect mode. Design the user system for our e-commerce API."
[Agent designs the system, creates schema, implements auth]
Agent: "User system complete. Storing memory..."
→ Calls: remember("users table with UUID, bcrypt, JWT + refresh tokens", tags: ["ecommerce-api", "auth", "database"])
[Session ends]
[Next day]
You: "Continue from yesterday"
Agent: "Recalling context..."
→ Calls: recall(query="ecommerce-api")
→ Returns: "users table with UUID, bcrypt, JWT + refresh tokens"
Agent: "Yesterday I designed the users table with UUID primary keys, implemented bcrypt password hashing, and set up JWT authentication with refresh tokens. Next step: product catalog schema. Ready to continue."
Step 3: Configure for Claude Code
Add the memory server to your MCP configuration.
Edit ~/.claude/settings.json:
{
"mcpServers": {
"memory": {
"command": "node",
"args": ["/absolute/path/to/memory-server.js"],
"env": {
"HOME": "/Users/your-username"
}
}
}
}
Restart Claude Code. The memory tools should now be available.
Test it:
Use the remember tool to store: "Test memory for ecommerce project"
Tags: ["test", "ecommerce-api"]
Use the recall tool to find memories about "test"
Step 4: Configure for Cursor
Create .cursor/mcp.json in your project:
{
"mcpServers": {
"memory": {
"command": "node",
"args": ["/absolute/path/to/memory-server.js"]
}
}
}
Test it:
@memory remember "Starting ecommerce API project with PostgreSQL"
Tags: ["ecommerce-api", "setup"]
@memory recall query="ecommerce"
Memory Patterns for Real Workflows
Pattern 1: Decision Logging
Log every technical decision:
remember({
content: "Chose PostgreSQL over MySQL for: (1) JSONB support for flexible product attributes, (2) better full-text search, (3) UUID native support",
tags: ["ecommerce-api", "database", "decision"],
agent: "Backend Architect"
})
Later, retrieve the decision:
recall(query="PostgreSQL MySQL decision")
Pattern 2: Agent Handoffs
Leave a handoff note when switching agents:
remember({
content: "Backend complete. Endpoints: POST /auth/login, POST /auth/register, GET /products, POST /orders. Auth: JWT 15min access + 7 day refresh. Pending: rate limiting, email verification. Frontend needs: login form, product list, cart, checkout.",
tags: ["ecommerce-api", "handoff", "backend-complete"],
agent: "Backend Architect",
for: "Frontend Developer"
})
Frontend Developer starts with:
recall(query="handoff", agent="Backend Architect")
Pattern 3: Session Checkpoints
At the end of each work session:
remember({
content: "Session complete. Done: users table, auth endpoints, product schema. Next session: order system, payment webhook. Blockers: waiting for Stripe API keys.",
tags: ["ecommerce-api", "checkpoint", "session-1"],
agent: "Backend Architect"
})
Resume next session:
recall(query="checkpoint session-1")
Pattern 4: Bug Tracking
When you find a bug:
remember({
content: "BUG: Refresh token not expiring after logout. Token stored in memory, not persisted. Fix: move to Redis with TTL.",
tags: ["ecommerce-api", "bug", "auth"],
agent: "Code Reviewer",
severity: "high"
})
Search for bugs later:
search(tags=["bug", "ecommerce-api"])
Troubleshooting
Memory not persisting:
- Check the memory file path (
~/.mcp-memory/memories.json) - Ensure the MCP server is running
- Verify Claude Code/Cursor has the MCP config
Too many results on recall:
- Add more specific tags
- Filter by agent name
- Use exact phrases in quotes
Memory file growing large:
- Periodically archive old memories
- Use
rollbackto clean up completed projects - Add expiration dates to your memory schema
What You Built
| Component | Purpose |
|---|---|
| MCP Memory Server | Stores/retrieves information across sessions |
remember tool |
Log decisions, deliverables, handoffs |
recall tool |
Find context from previous sessions |
search tool |
Query by tags across all memories |
rollback tool |
Restore to previous state when needed |
| Memory patterns | Decision logging, handoffs, checkpoints, bug tracking |
Next Steps
Extend the memory server:
- Add semantic search with embeddings
- Implement memory expiration (auto-archive after 30 days)
- Add memory summarization (condense long sessions)
Build team memory:
- Share a central memory server across your team
- Tag memories by project and developer
- Create onboarding flows for new team members
Integrate with tools:
- Auto-log git commits as memories
- Sync with project management (Jira, Linear)
- Export memories to documentation
Troubleshooting Common Issues
Memory not persisting between sessions:
- Check that the MCP server is running before starting Claude Code
- Verify the memory file path exists:
ls -la ~/.mcp-memory/memories.json - Ensure file permissions allow read/write:
chmod 644 ~/.mcp-memory/memories.json - Confirm the server config in
~/.claude/settings.jsonpoints to the correct path
Recall returns empty results:
- Verify the query matches stored tags (case-sensitive)
- Try broader search terms or use
searchwith specific tags - Check if memories were actually stored:
cat ~/.mcp-memory/memories.json - Ensure the agent name filter matches (if using
agentparameter)
Memory file growing too large:
- Implement automatic archiving for memories older than 30 days
- Add a
prunetool that deletes memories by date range - Split memories into separate files by project or date
- Use a database backend (SQLite) instead of JSON for large-scale use
Server fails to start:
- Check Node.js version:
node --version(should be 18+) - Install missing dependencies:
npm install @modelcontextprotocol/sdk zod - Look for syntax errors in the server code
- Run directly to see errors:
node memory-server.js
Multiple agents overwriting each other’s memories:
- Always include the
agentfield when callingremember - Use unique tags per project:
["project-x", "backend", "auth"] - Filter recall by agent name when retrieving context
- Consider separate memory files per project
Memory Server Security Considerations
API Key Storage: If your memory server stores sensitive data (API keys, passwords), implement encryption:
import crypto from 'crypto';
const ENCRYPTION_KEY = process.env.MEMORY_ENCRYPTION_KEY;
const ALGORITHM = 'aes-256-gcm';
function encrypt(text) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY), iv);
const encrypted = cipher.update(text, 'utf8', 'hex');
return {
encryptedData: encrypted + cipher.final('hex'),
iv: iv.toString('hex'),
authTag: cipher.getAuthTag().toString('hex')
};
}
function decrypt(encrypted) {
const decipher = crypto.createDecipheriv(
ALGORITHM,
Buffer.from(ENCRYPTION_KEY),
Buffer.from(encrypted.iv, 'hex')
);
decipher.setAuthTag(Buffer.from(encrypted.authTag, 'hex'));
return decipher.update(encrypted.encryptedData, 'hex', 'utf8') + decipher.final('utf8');
}
Access Control: For team memory servers, add authentication:
- Require API key in memory tool calls
- Implement user-specific memory namespaces
- Log all memory operations for audit trails
- Rate limit requests per user
Your AI agents now have persistent memory. They remember yesterday. They recall decisions. They hand off context without copy-paste.
No more “I don’t have context from previous sessions.” No more re-explaining. No more wasted time.
That’s the power of MCP memory: give your agents a shared notebook, and watch them become actually useful across multi-day projects.
FAQ
What is MCP memory?
MCP memory is a protocol implementation that lets AI agents store and retrieve information across sessions. Think of it as a shared notebook agents can write to and read from, persisting context beyond single conversations.
How do I set up persistent memory for Claude Code?
Install an MCP memory server, then add it to ~/.claude/settings.json with the server command and path. Restart Claude Code and the memory tools (remember, recall, search, rollback) become available.
Which AI agents support MCP memory?
Any agent running on MCP-compatible clients (Claude Code, Cursor, Windsurf) can use memory tools. You don’t need to modify agent files—just add memory instructions to your prompts.
What are the best memory patterns for agent handoffs?
Use remember with tags like ["handoff", "project-name"] to leave context for the next agent. Include completed work, pending items, and known issues. The receiving agent calls recall(query="handoff") to retrieve it.
How much memory can MCP servers store?
Depends on implementation. The reference server uses a JSON file that grows indefinitely. Production servers should add expiration policies, auto-archiving, or database backends for large-scale use.
Can teams share a central memory server?
Yes. Run the memory server on a shared machine or cloud instance, configure all team members’ clients to connect to it, and tag memories by project and developer for organized retrieval.
What if memory recall returns too many results?
Add more specific tags when storing memories. Filter by agent name in your recall queries. Use exact phrases in quotes. Consider implementing semantic search with embeddings for smarter retrieval.
Top comments (0)