mcp-learning-memory
v0.2.1
Published
MCP server for AI agent memory that adapts to feedback
Maintainers
Readme
mcp-learning-memory
Memory that adapts to your feedback.
What is this?
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)
Unique Features
Trust Score
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
Decay Factor
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)
Auto-Deduplication
Prevents duplicate insights using Levenshtein distance:
- Detects typos: "Bug Fix" vs "Bux Fix" (distance=1)
- Case-insensitive comparison
- Offers overwrite option for intentional updates
Features
- 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
Architecture
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 --> JSONInstallation
Prerequisites
- Node.js 18+
- Claude CLI or Claude Desktop
Build from source
git clone https://github.com/nulone/mcp-learning-memory
cd mcp-learning-memory
npm install
npm run build
npm test # 81 tests should passConfiguration
Claude CLI
# 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"]
}
}
}Claude Desktop
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.
Usage
Natural language (via Claude)
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 markdownDirect tool calls
# 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"API Reference
add_insight
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=truelist_index
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
get_detail
Load full content of an insight. Updates lastUsed timestamp.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | ✅ | Insight ID (e.g., ace-000001) |
mark_helpful
Increment helpful counter (+1). Updates lastUsed timestamp.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | ✅ | Insight ID |
mark_harmful
Increment harmful counter (+1). Use for outdated/incorrect information.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | ✅ | Insight ID |
search_insights
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_insight
Delete an insight permanently.
| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | id | string | ✅ | Insight ID to delete |
export_memory
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)
Data Storage
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
Development
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 emptyProject Structure
mcp-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.jsonSafety Features
No stdout pollution
MCP uses stdout for JSON-RPC. All logging goes to stderr.
Mutex protection
Concurrent requests are serialized to prevent lost updates.
Atomic writes
Writes use temp file + rename pattern for crash safety.
Isolated testing
Tests run in temporary directories to protect user data.
Troubleshooting
MCP not connecting
# Check if server starts
node dist/index.js
# Should see: [INFO] server running
# Verify config path is absolute
cat ~/.claude.jsonData not persisting
ls -la ~/.local/share/ace-flash-memory/
cat ~/.local/share/ace-flash-memory/memory.jsonCorrupted data
# List backups
ls ~/.local/share/ace-flash-memory/*.corrupt.*
# Restore if needed
cp memory.json.corrupt.TIMESTAMP memory.jsonLicense
MIT
Credits
Built with Model Context Protocol SDK, TypeScript, and Vitest.
