Skip to content

MCP server for AI agent memory that learns from feedback

Notifications You must be signed in to change notification settings

nulone/mcp-learning-memory

Repository files navigation

mcp-learning-memory

Memory that adapts to your feedback.

CI MCP License

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_index returns titles and previews (cheap, fast, with filtering)
  • search_insights finds relevant insights with contextual ranking
  • get_detail loads 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 --> JSON
Loading

Installation

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 pass

Configuration

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 · ✔ connected

Or 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 markdown

Direct 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=true to 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_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 empty

Project 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.json

Safety 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.json

Data not persisting

ls -la ~/.local/share/ace-flash-memory/
cat ~/.local/share/ace-flash-memory/memory.json

Corrupted data

# List backups
ls ~/.local/share/ace-flash-memory/*.corrupt.*

# Restore if needed
cp memory.json.corrupt.TIMESTAMP memory.json

License

MIT

Credits

Built with Model Context Protocol SDK, TypeScript, and Vitest.

About

MCP server for AI agent memory that learns from feedback

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •