Memory that adapts to your feedback.
An MCP (Model Context Protocol) server that gives AI assistants persistent memory with learning capabilities. Save insights, track feedback, and let the system learn which information is valuable over time.
Pattern: Index → Detail
list_indexreturns titles and previews (cheap, fast, with filtering)search_insightsfinds relevant insights with contextual rankingget_detailloads full content only when needed (on-demand)
Insights are ranked by a computed trust score based on user feedback:
trustScore = (helpful - harmful × 2) / (helpful + harmful + 1)
- Penalizes harmful feedback more heavily (×2 weight)
- Insights with negative scores display a warning
- Boosts reliable information in search results
Older insights gradually lose ranking priority:
- Fresh insights (< 7 days): Full score + bonus
- Aging insights: Score decays linearly over 90 days
- Minimum decay: 10% (never fully forgotten)
Prevents duplicate insights using Levenshtein distance:
- Detects typos: "Bug Fix" vs "Bux Fix" (distance=1)
- Case-insensitive comparison
- Offers overwrite option for intentional updates
- 8 MCP Tools: add, list, search, get, delete, export, mark helpful/harmful
- Smart Search: Contextual ranking with trust score and time decay
- Multi-tag Filtering: Filter insights by tags, helpful count, and more
- Persistent Storage: JSON file survives restarts
- Race-Safe: Mutex protection for concurrent access
- Atomic Writes: No data corruption on crash
- Auto-Recovery: Graceful handling of corrupted data files
- XDG Compliant: Respects
$XDG_DATA_HOME - Source Tracking: Optional sourceUrl for traceability
flowchart TB
subgraph Client["🤖 AI Client"]
CLI[Claude CLI]
Desktop[Claude Desktop]
end
subgraph Protocol["📡 MCP Protocol"]
RPC[JSON-RPC over stdio]
end
subgraph Server["⚡ mcp-learning-memory"]
Index[index.ts<br/>8 Tools]
Tools[tools.ts<br/>Business Logic]
end
subgraph Features["✨ Unique Features"]
Trust[trustScore]
Decay[decay_factor]
Dedup[auto_dedup]
end
subgraph Storage["💾 Storage"]
JSON[(memory.json)]
end
CLI --> RPC
Desktop --> RPC
RPC --> Index
Index --> Tools
Tools --> Features
Tools --> JSON
- Node.js 18+
- Claude CLI or Claude Desktop
git clone https://github.com/nulone/mcp-learning-memory
cd mcp-learning-memory
npm install
npm run build
npm test # 81 tests should pass# Add MCP server
claude mcp add learning-memory node /path/to/mcp-learning-memory/dist/index.js
# Verify
claude
/mcp # Should show: learning-memory · ✔ connectedOr manually edit ~/.claude.json:
{
"mcpServers": {
"learning-memory": {
"command": "node",
"args": ["/path/to/mcp-learning-memory/dist/index.js"]
}
}
}macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"learning-memory": {
"command": "node",
"args": ["/path/to/mcp-learning-memory/dist/index.js"]
}
}
}Restart Claude Desktop after editing.
Save an insight "React hooks tips" with tags react, hooks and content "Always call hooks at top level"
Show all my insights
Mark the React insight as helpful
Delete the outdated insight
Export my memory as markdown
# Add new insight with source URL
add_insight: title="JWT Auth Pattern", tags=["auth","jwt"], content="Use refresh tokens...", sourceUrl="https://example.com/article"
# List with filters
list_index: tags=["auth"], sortBy="helpful", limit=10
# Search with ranking (uses trust score + decay)
search_insights: query="authentication", limit=5
# Get full content
get_detail: id="ace-000001"
# Provide feedback
mark_helpful: id="ace-000001"
mark_harmful: id="ace-000002"
# Delete insight
delete_insight: id="ace-000003"
# Export for backup
export_memory: format="markdown"
Save a new insight to memory.
| Parameter | Type | Required | Description |
|---|---|---|---|
| title | string | ✅ | Short title (1-200 chars after trim) |
| tags | string[] | ✅ | Category tags (1-10 items, normalized) |
| content | string | ✅ | Full content (max 10,000 chars after trim) |
| overwrite | boolean | ❌ | Update existing insight with same title |
| sourceUrl | string | ❌ | Source URL for traceability (max 2,000 chars) |
Auto-Deduplication:
- Detects similar titles using Levenshtein distance (< 3)
- Case-insensitive comparison
- Returns existing insight ID when duplicate found
- Use
overwrite=trueto update intentionally
Examples:
# Basic insight
add_insight: title="React Tips", tags=["react"], content="Use memo for expensive renders"
# With source URL
add_insight: title="API Design", tags=["api","rest"], content="...", sourceUrl="https://docs.example.com"
# Overwrite existing
add_insight: title="React Tips", tags=["react","hooks"], content="Updated content", overwrite=true
List all insights with metadata and content preview.
| Parameter | Type | Required | Description |
|---|---|---|---|
| tags | string[] | ❌ | Filter by tags (AND logic) |
| minHelpful | number | ❌ | Minimum helpful count (default: 0) |
| sortBy | string | ❌ | Sort: created, lastUsed, helpful (default: lastUsed) |
| limit | number | ❌ | Maximum results (default: 50) |
Response includes:
- Content preview (100 chars)
- Trust score (computed)
- Warning for low trust insights
- Source URL if present
Load full content of an insight. Updates lastUsed timestamp.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Insight ID (e.g., ace-000001) |
Increment helpful counter (+1). Updates lastUsed timestamp.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Insight ID |
Increment harmful counter (+1). Use for outdated/incorrect information.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Insight ID |
Search with contextual ranking using trust score and decay factor.
| Parameter | Type | Required | Description |
|---|---|---|---|
| query | string | ✅ | Search query (searches title, content, tags) |
| limit | number | ❌ | Maximum results (default: 5) |
Scoring Algorithm:
- Exact title match: +10 points
- Partial title match: +5 points
- Content match: +3 points
- Tag match: +2 points per tag
- Helpful count: +1 point per helpful
- Recent usage (7 days): +3 points
- Trust score bonus: +trustScore × 5
- Decay factor: score × max(0.1, 1 - daysOld/90)
Delete an insight permanently.
| Parameter | Type | Required | Description |
|---|---|---|---|
| id | string | ✅ | Insight ID to delete |
Export all insights for backup or documentation.
| Parameter | Type | Required | Description |
|---|---|---|---|
| format | string | ❌ | json (default) or markdown |
Markdown format includes:
- Trust scores for each insight
- Source URLs
- Statistics (helpful/harmful counts)
Location: $XDG_DATA_HOME/ace-flash-memory/memory.json
- Linux/macOS default:
~/.local/share/ace-flash-memory/memory.json
Automatic Recovery:
- Corrupted files are backed up with timestamp
- System continues with empty memory
- No data loss from temporary corruption
npm install
npm run build
npm test # 81 integration tests
# Verify no console.log (MCP requires stderr only)
grep -r "console.log" src/ # Should be emptymcp-learning-memory/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── tools.ts # 8 tool implementations + Mutex
│ ├── storage.ts # Atomic file I/O + recovery
│ ├── validation.ts # Input validation & normalization
│ ├── logger.ts # stderr-only logging
│ └── types.ts # TypeScript interfaces
├── tests/
│ └── integration.test.ts # 81 tests in isolated env
├── dist/ # Compiled JavaScript
├── package.json
└── tsconfig.json
MCP uses stdout for JSON-RPC. All logging goes to stderr.
Concurrent requests are serialized to prevent lost updates.
Writes use temp file + rename pattern for crash safety.
Tests run in temporary directories to protect user data.
# Check if server starts
node dist/index.js
# Should see: [INFO] server running
# Verify config path is absolute
cat ~/.claude.jsonls -la ~/.local/share/ace-flash-memory/
cat ~/.local/share/ace-flash-memory/memory.json# List backups
ls ~/.local/share/ace-flash-memory/*.corrupt.*
# Restore if needed
cp memory.json.corrupt.TIMESTAMP memory.jsonMIT
Built with Model Context Protocol SDK, TypeScript, and Vitest.