Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

   ___                   __  __
  / _ \ _ __   ___ _ __ |  \/  | ___ _ __ ___   ___  _ __ _   _
 | | | | '_ \ / _ \ '_ \| |\/| |/ _ \ '_ ` _ \ / _ \| '__| | | |
 | |_| | |_) |  __/ | | | |  | |  __/ | | | | | (_) | |  | |_| |
  \___/| .__/ \___|_| |_|_|  |_|\___|_| |_| |_|\___/|_|   \__, |
       |_|                                                  |___/

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MIT TypeScript Bun Tests


The Problem

Every AI tool you use starts with zero context. Claude doesn't know what you told ChatGPT. Cursor doesn't know your preferences from Claude Code. Your AI has amnesia.

OpenMemory fixes this. It's a universal memory engine that any AI tool plugs into β€” one brain, shared everywhere.

How It Works

You: "I prefer TypeScript over JavaScript"
                    ↓
            β”Œβ”€β”€ Extract ──┐
            β”‚  user        β”‚
            β”‚  prefers     β”‚   ← Atomic fact (no blobs)
            β”‚  TypeScript  β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
        β”Œβ”€β”€ Contradiction? ──┐
        β”‚  Same subject +    β”‚
        β”‚  predicate exists? β”‚   ← "user prefers JavaScript" β†’ superseded
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
         β”Œβ”€β”€ Knowledge Graph ──┐
         β”‚  user ──prefers──▢ TypeScript  β”‚
         β”‚       ──uses────▢ Bun          β”‚   ← Entities + relations
         β”‚       ──named───▢ Ranbir       β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    ↓
          β”Œβ”€β”€ Smart Decay ──┐
          β”‚  Accessed = strong  β”‚
          β”‚  Forgotten = fades  β”‚   ← No bloat, stays sharp
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Features

  • Facts, not blobs β€” Stores atomic knowledge triples (subject β†’ predicate β†’ object), not paragraphs
  • Contradiction resolution β€” "I switched to Deno" automatically supersedes "I use Bun"
  • Smart forgetting β€” Unused facts decay. Accessed facts stay strong. Memory stays sharp
  • Knowledge graph β€” Entities and relationships, not flat storage
  • BM25 + Vector + RRF β€” 4-signal retrieval fusion for sub-millisecond search
  • Zero AI dependency β€” Grammar-based extraction works offline, no API keys needed
  • MCP server β€” Plug into Claude Code, Cursor, Windsurf, any MCP client
  • REST API β€” Any app can read/write memories
  • 100% local β€” All data stays on your machine. SQLite. No cloud

Installation

Prerequisites

Install Bun (required):

curl -fsSL https://bun.sh/install | bash

Option 1: Clone and Run (recommended)

git clone https://github.com/AndroidPoet/openmemory.git
cd openmemory
bun install
bun run dev

Option 2: npx (one-liner)

bunx openmemory-ai serve

Option 3: Global Install

bun install -g openmemory-ai
openmemory serve
openmemory mcp    # start MCP server

Server starts at http://localhost:3838.

Setup with AI Tools

Claude Code

Add to ~/.claude/claude_desktop_config.json or your project's .mcp.json:

{
  "mcpServers": {
    "openmemory": {
      "command": "bun",
      "args": ["run", "/path/to/openmemory/src/index.ts", "mcp"]
    }
  }
}

If installed globally:

{
  "mcpServers": {
    "openmemory": {
      "command": "openmemory",
      "args": ["mcp"]
    }
  }
}

Cursor / Windsurf / Any MCP Client

Same config β€” just point command to bun and args to the path.

REST API (ChatGPT, custom apps, anything)

Start the server and call the API from any language:

bun run dev   # http://localhost:3838

Then just talk naturally:

"Remember that I prefer dark mode" "What do you know about my project?" "What's my name?"

Usage

Add memories (extracts facts automatically)

curl -X POST http://localhost:3838/api/v1/add \
  -H "Content-Type: application/json" \
  -d '{"content": "I prefer TypeScript. My runtime is Bun. I work on OpenMemory."}'
{
  "stored": 3,
  "facts": [
    { "fact": "user prefers TypeScript", "confidence": 0.85 },
    { "fact": "user uses Bun", "confidence": 0.75 },
    { "fact": "user works_on OpenMemory", "confidence": 0.8 }
  ]
}

Search memories

curl -X POST http://localhost:3838/api/v1/search \
  -H "Content-Type: application/json" \
  -d '{"query": "What runtime does the user prefer?"}'

Get AI context

curl -X POST http://localhost:3838/api/v1/context \
  -H "Content-Type: application/json" \
  -d '{"query": "Tell me about the user", "format": "markdown"}'

Architecture

src/
β”œβ”€β”€ extract/          Fact extraction (grammar-based, zero AI)
β”‚   β”œβ”€β”€ index.ts      8 specialized extractors, ordered by specificity
β”‚   └── embedding.ts  Local TF-IDF embeddings (768-dim)
β”œβ”€β”€ graph/            Knowledge graph (entities + relations)
β”œβ”€β”€ resolve/          Contradiction detection + resolution
β”œβ”€β”€ decay/            Smart forgetting (exponential decay + access boost)
β”œβ”€β”€ serve/            Context retrieval + ranking
β”‚   β”œβ”€β”€ hot-index.ts  In-memory index (sub-ms search)
β”‚   β”œβ”€β”€ bm25.ts       Okapi BM25 ranking
β”‚   └── fusion.ts     Reciprocal Rank Fusion
β”œβ”€β”€ api/              REST API (Hono)
β”œβ”€β”€ mcp/              MCP server (6 tools)
└── db/               SQLite + sqlite-vec

Search Pipeline

Every query runs through 4 independent rankers, fused via RRF:

Ranker What it does Signal
BM25 Term frequency + inverse document frequency Exact keyword matches
Vector Cosine similarity on TF-IDF embeddings Semantic meaning
Entity Graph Graph traversal from query entities Structural relationships
Temporal Strength Γ— recency decay What's fresh and strong

Results are fused using Reciprocal Rank Fusion β€” each ranker votes independently, ranks are combined. No single signal dominates.

Adaptive weighting: When BM25 finds strong keyword matches, it gets 2x weight. When keywords miss, vector similarity takes over.

MCP Tools

Tool Description
remember Extract and store facts from natural language
recall Search memories semantically
get_memory_context Get formatted context for AI injection
about Everything known about an entity
forget Forget a specific fact
memory_stats System statistics

API Reference

Endpoint Method Description
/health GET Health check + stats
/api/v1/add POST Add memories (auto-extracts facts)
/api/v1/search POST Semantic search
/api/v1/context POST Formatted AI context
/api/v1/entity/:name GET Entity lookup
/api/v1/graph GET Knowledge graph
/api/v1/entities GET List all entities
/api/v1/stats GET Statistics
/api/v1/decay POST Trigger memory decay

Performance

Search latency:  0.05 - 0.07ms (20 facts, in-memory)
Scaling:         ~1.9ms at 500 facts
Boot time:       < 1ms (loads all facts into RAM)
Memory usage:    ~3.8KB per fact
Extraction:      4Β΅s per sentence (no AI, pure grammar)
Embeddings:      10Β΅s per text
Cosine sim:      0.6Β΅s per comparison (1.6M ops/sec)

199 tests. 0 failures. 254ms.

How It's Different

OpenMemory SuperMemory Mem0
Cost Free (local) Paid API Paid API
Data 100% on your machine Cloud Cloud
Extraction Grammar-based (no AI) LLM-based LLM-based
Search BM25 + Vector + RRF Vector only Vector only
Contradictions Auto-resolved Manual Manual
Smart decay Exponential + access boost Basic Basic
Speed Sub-millisecond Network latency Network latency

Tech Stack

  • Runtime: Bun
  • Language: TypeScript
  • Database: SQLite (bun:sqlite)
  • API: Hono
  • MCP: @modelcontextprotocol/sdk
  • Search: BM25 + TF-IDF vectors + Reciprocal Rank Fusion

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server auth
OPENMEMORY_API_KEY=your-secret-key

# Optional: Use Claude for smarter extraction
OPENMEMORY_EXTRACTION_PROVIDER=local  # local | claude | ollama
ANTHROPIC_API_KEY=sk-ant-...          # only if using claude

# Server
PORT=3838

Roadmap

  • Web dashboard (knowledge graph visualization)
  • SDK packages (npm, pip)
  • Conversation stream listener (auto-extract from live chats)
  • Import/export (JSON, Markdown)
  • Multi-user support
  • Ollama embeddings (upgrade from TF-IDF)

Contributing

PRs welcome. The codebase is small (~1500 lines) and readable.

bun install
bun run dev        # REST API on :3838
bun run mcp        # MCP server
bun test           # 199 tests
bun run bench      # Performance benchmarks

Find this repository useful? ❀️

Support it by joining stargazers for this repository. ⭐
Also, follow me on GitHub for my next creations! 🀩

License

MIT


One memory. Every AI tool. Zero cloud.

Built by Ranbir Singh

About

Open source AI memory engine. Universal memory layer for Claude, ChatGPT, Cursor, and any AI tool. Sub-millisecond search, knowledge graph, smart forgetting. Zero cloud.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages