Claude Code Memory: Persistent Project Intelligence
Use the Memory MCP server with Claude Code to keep a knowledge graph across sessions: setup, entities and relations, what to store, and maintenance patterns.
Updated October 21, 2026: Corrected against the current docs and the
@modelcontextprotocol/server-memory2.0 release:MEMORY_FILE_PATHmust be absolute (and now stores JSONL), the knowledge-graph fields areentityType/relationType, the/memory-*commands are custom skills rather than built-ins, and the built-in system is Claude Code’s auto memory.
One of the most frustrating aspects of AI assistants is session amnesia—every conversation starts fresh. Claude Code now ships with built-in auto memory: a file-based memory directory that persists per project across sessions. You can layer the Memory MCP on top of it—an optional knowledge graph system for structured, queryable project knowledge.
This guide covers everything you need to know about building persistent project intelligence.
The Problem: Session Amnesia
Traditional AI workflows suffer from context loss:
Session 1: "We decided to use Redis for caching because..."
Session 2: "Why are we using Redis?"
Session 3: "Should we switch to Memcached?"
Session 4: [Repeats same discussion]
Every session, you re-explain decisions. Every session, context is lost. This is institutional memory failure.
The Solution: Memory MCP
The Memory MCP creates a persistent knowledge graph that stores:
- Entities - Named concepts with observations
- Relations - Connections between entities
- Observations - Facts about entities
┌─────────────────────────────────────────────────────────────┐
│ Knowledge Graph │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ authentication │◄──uses──│ redis_cache │ │
│ │ │ │ │ │
│ │ Observations: │ │ Observations: │ │
│ │ - Uses JWT │ │ - Selected for │ │
│ │ - Tokens valid │ │ speed │ │
│ │ for 24h │ │ - v7.2 │ │
│ └────────────────┘ └────────────────┘ │
│ │ │ │
│ │ │ │
│ └──────────┬───────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ user_session │ │
│ │ │ │
│ │ Observations: │ │
│ │ - 30 min TTL │ │
│ │ - Refresh │ │
│ │ strategy │ │
│ └────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Setting Up Memory MCP
Step 1: Add Memory MCP to Project
Use the official CLI to add the Memory MCP:
# Add with project isolation (CRITICAL!)
# Run from the project root; the shell expands $PWD to an absolute path
claude mcp add memory \
-e MEMORY_FILE_PATH="$PWD/.claude/memory.jsonl" \
-- npx -y @modelcontextprotocol/server-memory
Important: The MEMORY_FILE_PATH environment variable isolates memory per project. Without it, all projects share the same memory file. The path must be absolute (a leading ~/ also works): the server resolves a relative path against its own package directory, not your project. To share the server through a committed .mcp.json, add --scope project and reference a variable each developer sets, such as "MEMORY_FILE_PATH": "${PROJECT_MEMORY_PATH}".
Step 2: Verify Installation
# Check MCP status: each server is listed with a health status
claude mcp list
# Inspect one server (command, scope, status, last error)
claude mcp get memory
Step 3: Initialize Memory
On first use, create initial context:
User: "Save initial project context to memory"
Claude:
→ Creates entities for: project, tech_stack, key_decisions
→ Establishes relations between entities
→ Stores initial observations
Memory Operations
Creating Entities
Entities are named concepts with a type and observations:
{
"name": "authentication_system",
"entityType": "component",
"observations": [
"Uses JWT tokens for stateless auth",
"Tokens expire after 24 hours",
"Refresh tokens rotate on each use",
"Implemented in auth/ directory"
]
}
Creating Relations
Relations connect entities with named relationships:
{
"from": "authentication_system",
"to": "redis_cache",
"relationType": "uses"
}
Adding Observations
Add new facts to existing entities:
{
"entityName": "authentication_system",
"contents": [
"Added MFA support on 2026-01-10",
"MFA uses TOTP algorithm"
]
}
Memory Commands
The server exposes nine tools that Claude calls directly: create_entities, create_relations, add_observations, delete_entities, delete_observations, delete_relations, read_graph, search_nodes, and open_nodes. Plain language is enough to drive them. The /memory-* commands below are custom skills you create in .claude/skills/, not built-in Claude Code commands — Claude Code’s own command is /memory, which edits CLAUDE.md files and manages auto memory.
Save Knowledge
/memory-save
Or in natural language:
"Save this decision to memory: We chose PostgreSQL over MySQL because..."
Claude will:
- Identify entities to create/update
- Extract observations
- Establish relations
- Store to knowledge graph
Search Knowledge
/memory-search
Or in natural language:
"What do we know about our caching strategy?"
Claude will:
- Search the knowledge graph
- Find relevant entities
- Return observations and relations
List All Knowledge
/memory-list
Shows all stored entities and their observations.
Audit Memory
/memory-audit
Identifies:
- Stale information
- Duplicate entities
- Missing relations
- Cleanup recommendations
What to Store in Memory
Architecture Decisions
Entity: database_choice
Type: decision
Observations:
- "Selected PostgreSQL for JSONB support"
- "Considered MySQL but needed JSON queries"
- "Decision date: 2026-01-05"
- "Decision maker: Tech lead"
Design Patterns
Entity: error_handling_pattern
Type: pattern
Observations:
- "Use Result type for all async operations"
- "Never throw in domain layer"
- "Log errors at boundary only"
- "Pattern documented in ARCHITECTURE.md"
Bug Fixes
Entity: auth_timeout_bug
Type: bug_fix
Observations:
- "Issue: Users logged out after 5 minutes"
- "Root cause: Token refresh race condition"
- "Solution: Implemented mutex around refresh"
- "PR: #234, Merged: 2026-01-08"
Team Conventions
Entity: code_review_process
Type: process
Observations:
- "All PRs require 2 reviews"
- "Security-sensitive code needs security-auditor"
- "Use conventional commits"
- "Squash merge only"
External Dependencies
Entity: stripe_integration
Type: integration
Observations:
- "API version: 2024-11-20"
- "Webhook endpoint: /api/webhooks/stripe"
- "Using Stripe Checkout for payments"
- "Test mode API key in STRIPE_SECRET_KEY"
Memory Patterns
Pattern 1: Session Start Load
Start each session by loading relevant context:
"What do we know about the feature I'm working on?"
Claude searches memory and provides context.
Pattern 2: Decision Recording
After making decisions, record them:
"Save this decision to memory: We're using Redis for
session caching because it provides sub-millisecond
latency and we need 10K+ concurrent sessions."
Pattern 3: Bug Context
When fixing bugs, save the context:
"Save this bug fix to memory: The login timeout was
caused by token refresh race condition. Fixed by
adding mutex. Relevant files: auth/refresh.ts"
Pattern 4: Periodic Review
Regularly audit and clean memory:
/memory-audit
Then:
"Clean up outdated observations about the old auth system"
Integration with Workflows
Director Mode Integration
Memory enables true Director Mode by providing persistent context:
"Implement user profile editing based on our existing
patterns and decisions."
Claude:
→ Searches memory for: patterns, conventions, decisions
→ Finds: error handling pattern, API conventions
→ Implements following established patterns
Multi-Session Projects
For complex projects spanning multiple days:
Day 1: "We're building a payment system. Save the architecture."
Day 2: "Continue payment work. What did we decide yesterday?"
Day 3: "Finish payment integration. What's left?"
Memory provides continuity across sessions.
Team Knowledge Sharing
Memory becomes shared team knowledge:
// .claude/memory.jsonl (committed to repo), one object per line
{"type":"entity","name":"Authentication System","entityType":"Architecture","observations":["Uses JWT with 24-hour expiration"]}
{"type":"relation","from":"Authentication System","to":"Database Schema","relationType":"uses"}
New team members inherit institutional knowledge.
Advanced Memory Techniques
Hierarchical Knowledge
Organize knowledge in hierarchies:
project
├── architecture
│ ├── frontend
│ │ └── React patterns, state management
│ ├── backend
│ │ └── API conventions, auth patterns
│ └── database
│ └── Schema decisions, indexing strategies
└── decisions
├── technical
└── product
Temporal Context
Include timing in observations:
Observations:
- "[2026-01-05] Initial choice: MySQL"
- "[2026-01-08] Migrated to PostgreSQL for JSONB"
- "[2026-01-10] Added read replica for analytics"
Confidence Levels
Mark observation confidence:
Observations:
- "[CONFIRMED] Uses JWT for auth"
- "[ASSUMPTION] Token TTL is 24 hours (verify)"
- "[OUTDATED] Previous used session cookies"
Cross-Reference Patterns
Link related knowledge:
Entity: auth_bug_001
Observations:
- "Related to: token_refresh_mechanism"
- "See also: session_management"
- "Fixed in: PR #234"
Memory Architecture
File Structure
.mcp.json # Project-scoped MCP servers (committed)
.claude/
├── memory.jsonl # Knowledge graph storage
├── settings.json # Project settings (permissions, approvals)
└── skills/ # Custom skills
Memory Graph Format
On disk the server writes JSONL: one {"type":"entity",...} or {"type":"relation",...} object per line. The read_graph tool returns the same data as a single object:
{
"entities": [
{
"name": "entity_name",
"entityType": "component|decision|pattern|...",
"observations": ["observation 1", "observation 2"]
}
],
"relations": [
{
"from": "entity_a",
"to": "entity_b",
"relationType": "uses|depends_on|implements|..."
}
]
}
Storage Strategy
Option 1: Project Local (Recommended)
MEMORY_FILE_PATH="$PWD/.claude/memory.jsonl"
- Committed with code
- Team-shared knowledge
- Project-specific
Option 2: User Global
MEMORY_FILE_PATH=~/.claude/memory.jsonl
- Personal knowledge
- Cross-project patterns
- User preferences
Option 3: Hybrid
Project: <project>/.claude/memory.jsonl (architecture, decisions)
User: ~/.claude/memory.jsonl (personal patterns)
Each MCP client starts its own server process, so two clients pointed at one file are two writers. Every write takes an exclusive <memory file>.lock next to the file, so concurrent writes take turns.
Memory Maintenance
Regular Cleanup
/memory-audit
Identifies:
- Entities not accessed in 30+ days
- Duplicate or conflicting observations
- Orphaned relations
- Suggested consolidations
Migration Strategy
When refactoring:
"Update memory: We migrated from Express to Fastify.
Mark all Express-related observations as outdated."
Archiving
For completed projects:
"Archive all memory related to v1 authentication
with note: 'Replaced by v2 OAuth implementation'"
Memory vs Other Persistence
| Feature | Memory MCP | Auto memory | CLAUDE.md | Git History |
|---|---|---|---|---|
| Structured | Yes (graph) | Partial (one topic per file) | No (text) | No |
| Queryable | Yes | Partial (Claude reads topic files on demand) | No | Partial |
| Temporal | Yes | modified timestamp per file | Manual | Yes |
| Team-shared | Yes | No (machine-local) | Yes | Yes |
| Context cost | Low (on-demand) | Low (index loaded) | High (always loaded) | N/A |
Auto memory is Claude Code’s built-in system: Claude writes notes itself into ~/.claude/projects/<project>/memory/, one topic file per memory plus a MEMORY.md index. Only the first 200 lines (or 25KB) of MEMORY.md load at the start of every conversation; topic files are read on demand. It’s on by default in local sessions, machine-local, and shared across all worktrees of one repository. Toggle it in /memory, with the autoMemoryEnabled setting, or CLAUDE_CODE_DISABLE_AUTO_MEMORY=1; relocate it with autoMemoryDirectory.
When to Use Memory vs CLAUDE.md
Use Memory for:
- Decisions and rationale
- Bug fixes and resolutions
- Evolving patterns
- Session-to-session context
Use CLAUDE.md for:
- Static policies
- Tool configurations
- Project structure
- Workflow definitions
Troubleshooting
Memory Not Persisting
- Check
MEMORY_FILE_PATHis set to an absolute path - Verify file write permissions (the server also needs to create a
.lockfile beside it) - Check MCP is connected:
claude mcp list, thenclaude mcp get memory
Search Not Finding Results
search_nodesmatches substrings case-insensitively against entity names, types, and observations — if nothing matches, the words aren’t stored- Verify observations contain search terms
- Use broader search terms (queries are capped at 2,048 characters)
Duplicate Entities
- Run
/memory-audit - Merge duplicates: “Merge entity A and B”
- Update relations to point to merged entity
Best Practices
1. Save Immediately
When making decisions, save right away:
"Save this decision to memory now before we forget the context."
2. Be Specific
Good observation:
"Selected PostgreSQL for JSONB support needed for user preferences storage"
Avoid:
"Using PostgreSQL"
3. Include Context
Add the “why” not just the “what”:
"Chose Redis over Memcached because we need data structures (lists, sets) for session management"
4. Update Regularly
When things change:
"Update memory: We increased token TTL from 24h to 7 days per user feedback"
5. Audit Monthly
Schedule regular maintenance:
/memory-audit
Getting Started
Today:
- Add Memory MCP to your project
- Save one architecture decision
- Try
/memory-search
This week:
- Build initial knowledge graph
- Save all major decisions
- Integrate with daily workflow
This month:
- Complete knowledge graph coverage
- Establish team conventions
- Regular audit schedule
Memory transforms Claude Code into a knowledgeable partner. Build your knowledge graph, and every session starts with full context.
Sources: Claude Code memory documentation, Memory MCP server