Skip to content

Repository files navigation

Local Memory

A local-first memory layer for AI agents

LocalMemory provides AI agents with persistent, searchable, and evolvable long-term memory capabilities. It enables AI to remember user preferences, project context, and learned knowledge across sessions.

License: MIT


Table of Contents


Why LocalMemory?

Current AI systems have a fundamental flaw: no persistent memory. Every conversation starts from scratch. LocalMemory solves this by providing:

  • Privacy-first: All data stays on your machine
  • Cross-session continuity: AI remembers previous interactions
  • Structured memory: Memories are typed, tagged, and associatively linked
  • Automatic evolution: New information merges intelligently with existing knowledge
  • Time-aware: Important memories persist; stale ones decay naturally

The Problem

Traditional AI:
┌─────────────────────────────────────┐
│  Session 1: "I prefer Go language"  │
└─────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────┐
│  Session 2: "What language?"        │ ← AI forgot!
└─────────────────────────────────────┘

With LocalMemory:

┌─────────────────────────────────────┐
│  Session 1: Save "prefers Go"      │
└─────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────┐
│  Memory Store (persistent)          │
│  └── preference: "Go language"      │
└─────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────┐
│  Session 2: Query "language"        │ ← AI remembers!
└─────────────────────────────────────┘

Key Features

Feature Description
Memory Types preference, fact, event, skill, goal, relationship
Scopes global (shared), session (temporary), agent (private)
Semantic Search Vector-based similarity search with ranking
Memory Evolution Automatic merging of related memories
Time Decay Configurable decay for memory importance
Soft Delete Recoverable deletion with restore support
Memory Linking Graph-based associations between memories
MCP Integration Native Claude Code integration via MCP protocol

Architecture

System Overview

┌──────────────────────────────────────────────────────────────────┐
│                         LocalMemory                                │
├──────────────────────────────────────────────────────────────────┤
│  Interface Layer                                                  │
│  ┌────────────┐  ┌─────────────┐  ┌─────────────────────────┐   │
│  │    CLI     │  │  HTTP API   │  │   MCP Server (stdio)     │   │
│  └────────────┘  └─────────────┘  └─────────────────────────┘   │
├──────────────────────────────────────────────────────────────────┤
│  Core Layer                                                       │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌────────────┐ │
│  │  Store  │ │  Recall │ │  Evolve │ │  Decay  │ │   Forget   │ │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘ └────────────┘ │
├──────────────────────────────────────────────────────────────────┤
│  Supporting Layer                                                 │
│  ┌────────────────────┐  ┌────────────────────────────────────┐  │
│  │   SQLite (metadata) │  │   Vector Store (Qdrant/USearch)  │  │
│  └────────────────────┘  └────────────────────────────────────┘  │
│  ┌────────────────────┐  ┌────────────────────────────────────┐  │
│  │   Python AI Bridge  │  │   Embedding Service (optional)      │  │
│  └────────────────────┘  └────────────────────────────────────┘  │
└──────────────────────────────────────────────────────────────────┘

Directory Structure

local-memory/
├── cmd/                        # Application entry points
│   ├── cli/                    # CLI tool
│   │   ├── main.go
│   │   └── commands/           # save, query, list, forget, stats
│   ├── server/                 # HTTP API server
│   │   └── main.go
│   └── mcp/                    # MCP Server for Claude Code
│       └── main.go
│
├── core/                       # Core memory logic (no dependencies)
│   ├── memory.go              # Memory struct & types
│   ├── store.go              # Save with evolution
│   ├── recall.go             # Query & retrieval
│   ├── ranker.go            # Ranking algorithm
│   ├── decay.go              # Time-based decay
│   ├── evolve.go             # Memory merging
│   ├── forget.go             # Soft/hard delete
│   └── link.go               # Memory associations
│
├── storage/                   # Storage layer
│   ├── sqlite.go             # SQLite adapter (metadata)
│   └── vector/              # Vector storage
│       ├── interface.go      # VectorStore interface
│       ├── qdrant.go        # Qdrant adapter
│       └── usearch.go       # USearch adapter (in-memory)
│
├── bridge/                    # Go-Python communication
│   ├── http.go              # HTTP client
│   └── pybridge.go          # Python service wrapper
│
├── server/                    # HTTP API service
│   ├── handlers.go          # API handlers
│   └── middleware.go        # Logger, CORS
│
├── agent/                     # Agent integration
│   └── mcp/
│       └── server.go        # MCP JSON-RPC server
│
├── config/                    # Configuration
│   └── config.go            # JSON config loader
│
├── python/                     # Python AI services
│   ├── server.py            # FastAPI server
│   ├── ai/
│   │   ├── embedding.py     # sentence-transformers
│   │   └── extractor.py     # Rule-based memory extraction
│   └── requirements.txt
│
├── tests/                     # Test suites
│   ├── unit/                # Unit tests
│   └── integration/         # Integration tests (require CGO)
│
├── config.json               # Configuration file
├── Makefile                  # Build automation
├── Dockerfile               # Container image
├── docker-compose.yaml      # Full stack deployment
└── web/                      # Web UI (React + Three.js)
    ├── src/                  # Source code
    ├── README.md             # Web UI documentation
    └── package.json          # Dependencies

Data Flow

┌─────────────────────────────────────────────────────────────────┐
│                         Save Memory Flow                          │
└─────────────────────────────────────────────────────────────────┘

User Input
    │
    ▼
┌─────────────┐    ┌──────────────┐    ┌─────────────────────────┐
│   CLI/API   │───▶│  Store.Save  │───▶│  Evolve (if same key)  │
└─────────────┘    └──────┬───────┘    └───────────┬─────────────┘
                          │                        │
                          ▼                        ▼
                   ┌──────────────┐        ┌───────────────┐
                   │    SQLite     │        │ Merge memory  │
                   │  (metadata)   │        │ Update conf. │
                   └──────────────┘        └───────────────┘
                          │
                          ▼ (async)
                   ┌──────────────┐        ┌───────────────┐
                   │   Python AI  │───────▶│  Embedding    │
                   │   (bridge)   │        │  generation   │
                   └──────────────┘        └───────┬───────┘
                                                   │
                                                   ▼
                                           ┌──────────────┐
                                           │   Qdrant     │
                                           │ (vector DB)   │
                                           └──────────────┘


┌─────────────────────────────────────────────────────────────────┐
│                         Query Memory Flow                        │
└─────────────────────────────────────────────────────────────────┘

Query Input
    │
    ▼
┌─────────────┐    ┌──────────────┐    ┌─────────────────────────┐
│   CLI/API   │───▶│ Recall.Query │───▶│  Generate embedding     │
└─────────────┘    └──────┬───────┘    └───────────┬─────────────┘
                          │                        │
                          ▼ (if vector available)   ▼
                   ┌──────────────┐        ┌───────────────┐
                   │   Qdrant     │───────▶│ Vector search │
                   │              │        │ Return IDs    │
                   └──────────────┘        └───────┬───────┘
                                                   │
                                                   ▼
                                           ┌──────────────┐
                                           │    SQLite     │
                                           │  Get full    │
                                           │  memories    │
                                           └───────┬──────┘
                                                   │
                                                   ▼
                                           ┌──────────────┐
                                           │   Ranker     │
                                           │ (score by    │
                                           │ similarity + │
                                           │ recency +    │
                                           │ confidence)  │
                                           └───────┬──────┘
                                                   │
                                                   ▼
                                           ┌──────────────┐
                                           │  Top-K       │
                                           │  Results     │
                                           └──────────────┘

Quick Start

Prerequisites

  • Go 1.21+
  • Python 3.10+ (for AI features)
  • Docker & Docker Compose (for full deployment)
  • Node.js 18+ (for web UI)

Option 1: CLI Only (MVP)

# Clone and build
git clone https://github.com/yourusername/local-memory.git
cd local-memory
make build

# Save a memory (value only, key defaults to first 50 chars)
./localmemory save "User prefers Go language for backend development"

# Save with explicit key-value separation
./localmemory save "language_pref" "User prefers Go language for backend"

# List memories
./localmemory list

# Query memories
./localmemory query "Go language"

# Delete a memory
./localmemory forget <memory-id>

# View statistics
./localmemory stats

Option 2: Full Stack with Docker

# Start all services
docker-compose up -d

# Wait for services to be ready
docker-compose ps

# Save via HTTP API
curl -X POST http://localhost:8080/api/v1/memories \
  -H "Content-Type: application/json" \
  -d '{"type":"preference","key":"language","value":"Go","scope":"global"}'

# Query via API
curl -X POST http://localhost:8080/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{"query":"language","topk":5}'

Option 3: Claude Code Integration

Step 1: Build the MCP binary

# From the local-memory directory
go build -o localmemory-mcp.exe ./cmd/mcp/

Step 2: Add MCP server to Claude Code

# Use claude mcp CLI to add the server
claude mcp add localmemory -- /path/to/localmemory-mcp.exe

# Windows example:
claude mcp add localmemory -- D:\code\local-memory\localmemory-mcp.exe

# Linux/macOS example:
claude mcp add localmemory -- /home/user/local-memory/localmemory-mcp

Step 3: Restart Claude Code

After adding the MCP server, completely exit Claude Code (ensure the process terminates) and restart.

Step 4: Verify connection

Run /mcp in Claude Code to confirm the localmemory server is connected.

Available tools:

Tool Description
memory_save Save a new memory (key, value, type, scope, tags, confidence)
memory_query Search memories semantically (query, topk, scope)
memory_list List memories (limit, scope)
memory_forget Delete a memory by ID

Example usage in Claude Code:

User: Remember I prefer Go over Python
AI: [calls memory_save with type="preference", key="language", value="Go"]

User: What language should I use?
AI: [calls memory_query to find language preferences]

User: List all my memories
AI: [calls memory_list to show all memories]

Option 4: Web UI

A modern web interface with 3D neural graph visualization:

# Start the backend server (required for API)
.\localmemory-server.exe

# In another terminal, start the web UI
cd web
npm install
npm run dev

Then open http://localhost:5173 in your browser.

Web UI Features:

  • Dashboard with memory statistics
  • Memory list with type filtering
  • 3D Neural Graph visualization (drag to rotate, scroll to zoom, hover for details)

Installation

From Source

# Clone repository
git clone https://github.com/yourusername/local-memory.git
cd local-memory

# Download dependencies
go mod download

# Build all binaries
make build

# Install to ~/.localmemory/
make install

Using Makefile

make help                # Show all targets
make build              # Build CLI, server, and MCP binaries
make test               # Run unit tests
make test-integration   # Run integration tests (requires CGO)
make run               # Run CLI with sample data
make docker-build      # Build Docker image
make docker-up          # Start with docker-compose
make clean             # Clean build artifacts

Docker Deployment

# Build image
docker build -t localmemory:latest .

# Or use docker-compose for full stack
docker-compose up -d

# View logs
docker-compose logs -f localmemory

# Stop services
docker-compose down

Configuration

Configuration File

Create ~/.localmemory/config.json or use the default location config.json:

{
  "database": {
    "path": "./data/localmemory.db"
  },
  "vector_db": {
    "type": "qdrant",
    "url": "http://127.0.0.1:6333",
    "collection": "memories"
  },
  "bridge": {
    "type": "tcp",
    "tcp_url": "127.0.0.1:8081"
  },
  "ai": {
    "embedding_model": "all-MiniLM-L6-v2"
  },
  "decay": {
    "lambda": 0.01
  },
  "server": {
    "port": 8080
  },
  "cli": {
    "default_topk": 5,
    "default_scope": "global"
  },
  "agent": {
    "id": "localmemory",
    "name": "LocalMemory"
  }
}

Configuration Options

Section Option Default Description
database.path - ./data/localmemory.db SQLite database file path
vector_db.type - qdrant Vector store type: qdrant or usearch
vector_db.url - http://127.0.0.1:6333 Qdrant server URL
vector_db.collection - memories Qdrant collection name
bridge.type - tcp Go-Python communication type
bridge.tcp_url - 127.0.0.1:8081 Python AI server address
ai.embedding_model - all-MiniLM-L6-v2 Sentence-transformers model
decay.lambda - 0.01 Decay coefficient (higher = faster decay)
server.port - 8080 HTTP API server port
cli.default_topk - 5 Default number of results
cli.default_scope - global Default memory scope

Environment Variables

# Override config file path
LOCALMEMORY_CONFIG=/path/to/config.json

# Or use inline config
LOCALMEMORY_DB_PATH=./data/localmemory.db

Usage

Quick Start by Platform

Windows

# Download and run directly (no installation required)
.\localmemory.exe save "User prefers Go language"
.\localmemory.exe save "language" "User prefers Go language"
.\localmemory.exe list
.\localmemory.exe query Go
.\localmemory.exe stats
.\localmemory.exe forget <memory-id>

# Start HTTP server
.\localmemory-server.exe

Linux

# Download and make executable
chmod +x localmemory
./localmemory save "User prefers Go language"
./localmemory save "language" "User prefers Go language"
./localmemory list
./localmemory query Go
./localmemory stats
./localmemory forget <memory-id>

# Start HTTP server
./localmemory-server &

macOS

# Download and make executable
chmod +x localmemory
./localmemory save "User prefers Go language"
./localmemory save "language" "User prefers Go language"
./localmemory list
./localmemory query Go
./localmemory stats
./localmemory forget <memory-id>

# Start HTTP server
./localmemory-server &

CLI Commands

# Save a memory (value only, key defaults to first 50 chars of value)
localmemory save "User prefers dark mode"

# Save with explicit key-value separation
localmemory save "theme" "User prefers dark mode"
localmemory save "language" "Go developer" --type fact --scope global

# Save with additional options
localmemory save "Image description" --type fact --media-type image

# Query memories
localmemory query "theme preference" --topk 10
localmemory query "programming language" --scope global

# List memories
localmemory list
localmemory list --scope global --limit 20 --offset 0
localmemory list --all  # Include deleted

# Delete memory (soft delete)
localmemory forget <memory-id>

# Permanent delete
localmemory forget <memory-id> --hard

# View statistics
localmemory stats

HTTP API

# Base URL
export BASE_URL=http://localhost:8080

# Health check
curl $BASE_URL/health

# Create memory
curl -X POST $BASE_URL/api/v1/memories \
  -H "Content-Type: application/json" \
  -d '{
    "type": "preference",
    "scope": "global",
    "key": "editor",
    "value": "VS Code",
    "confidence": 0.9,
    "tags": ["editor", "development"]
  }'

# List memories
curl "$BASE_URL/api/v1/memories?scope=global&limit=10"

# Get single memory
curl "$BASE_URL/api/v1/memories/<id>"

# Query memories (semantic search)
curl -X POST $BASE_URL/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{"query": "editor preference", "topk": 5, "scope": "global"}'

# Delete memory
curl -X DELETE "$BASE_URL/api/v1/memories/<id>"

# Get statistics
curl $BASE_URL/api/v1/stats

MCP Tools (Claude Code)

After configuring MCP in Claude Code settings:

User: Remember I prefer TypeScript over Python
AI: [uses memory_save tool to store preference]

User: What language should I use for this backend?
AI: [uses memory_query to find language preferences]

Development

Running Tests

# Unit tests only (no CGO required)
go test ./tests/unit/... -v

# Integration tests (requires CGO-enabled Go)
CGO_ENABLED=1 go test ./tests/integration/... -v

# All tests
make test

Project Structure Guidelines

┌─────────────────────────────────────────────────────────────┐
│                    Package Organization                       │
├─────────────────────────────────────────────────────────────┤
│  core/          │ Pure Go, no external dependencies         │
│                 │ Business logic only                        │
├─────────────────┼───────────────────────────────────────────┤
│  storage/       │ Data persistence abstractions               │
│                 │ SQLite, Qdrant, USearch adapters          │
├─────────────────┼───────────────────────────────────────────┤
│  bridge/        │ External service communication              │
│                 │ Python AI service bridge                   │
├─────────────────┼───────────────────────────────────────────┤
│  cmd/           │ Application entry points                    │
│                 │ CLI, HTTP server, MCP server              │
├─────────────────┼───────────────────────────────────────────┤
│  server/        │ HTTP API implementation                     │
│                 │ Handlers, middleware, routing             │
├─────────────────┼───────────────────────────────────────────┤
│  agent/         │ Agent protocol implementations             │
│                 │ MCP JSON-RPC server                        │
├─────────────────┼───────────────────────────────────────────┤
│  python/        │ AI services (separate process)            │
│                 │ FastAPI, sentence-transformers            │
└─────────────────┴───────────────────────────────────────────┘

Adding New Memory Types

  1. Define type in core/memory.go:
const (
    TypePreference MemoryType = "preference"
    // Add new type
    TypeCustom    MemoryType = "custom"
)
  1. Update validation and handlers as needed.

Adding Vector Store Backends

Implement the VectorStore interface in storage/vector/interface.go:

type VectorStore interface {
    Upsert(id string, vector []float32, metadata map[string]any) error
    Search(query []float32, topK int, filter *Filter) ([]Result, error)
    Delete(id string) error
    Close() error
}

Architecture Deep Dive

Memory Evolution (Evolve)

When saving a memory with an existing key:

Existing Memory          New Memory
┌─────────────────┐     ┌─────────────────┐
│ key: language   │     │ key: language   │
│ value: "Go"     │     │ value: "Python" │
│ confidence: 0.9 │     │ confidence: 0.8  │
└────────┬────────┘     └─────────────────┘
         │
         ▼ Merge
┌─────────────────┐
│ key: language   │
│ value: "Go\n    │  ← Appended
│        Python"  │
│ confidence: 1.0 │  ← Incremented
└─────────────────┘

Ranking Algorithm

Final score combines multiple factors:

Score = (similarity × 0.7) + (recency × 0.2) + (confidence × 0.1)

Where:

  • similarity: Vector distance from query (semantic match)
  • recency: Exponential decay based on creation time
  • confidence: User-assigned or system-computed trust level

Time Decay

Memory importance naturally fades:

weight = e^(-λ × Δt)

Examples:
  λ = 0.01, Δt = 1 hour  → weight ≈ 0.97 (93% importance)
  λ = 0.01, Δt = 1 day   → weight ≈ 0.42 (42% importance)
  λ = 0.01, Δt = 7 days  → weight ≈ 0.00045 (<1% importance)

Memory Linking

Create associations between memories:

┌──────────────────┐         ┌──────────────────┐
│ Memory: Go偏好    │◀──────▶│ Memory: 项目架构  │
│ ID: abc123       │  link   │ ID: def456       │
└──────────────────┘         └──────────────────┘
         │
         ▼ (traverse)
┌──────────────────┐         ┌──────────────────┐
│ Memory: Web服务   │◀──────▶│ Memory: 数据库    │
│ ID: ghi789       │         │ ID: jkl012       │
└──────────────────┘         └──────────────────┘

Use Link() to connect, GetRelated() to traverse.


License

MIT License - see LICENSE for details.


Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines.

Support

About

LocalMemory is a local-first memory layer for AI agents with semantic search, memory decay, and association linking, integrable with Claude Code via the MCP protocol.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages