Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

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

The open source memory layer for AI.

One memory. Every AI tool. Yours forever.

License: MITTypeScriptBunTests


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:

RankerWhat it doesSignal
BM25Term frequency + inverse document frequencyExact keyword matches
VectorCosine similarity on TF-IDF embeddingsSemantic meaning
Entity GraphGraph traversal from query entitiesStructural relationships
TemporalStrength × recency decayWhat'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

ToolDescription
rememberExtract and store facts from natural language
recallSearch memories semantically
get_memory_contextGet formatted context for AI injection
aboutEverything known about an entity
forgetForget a specific fact
memory_statsSystem statistics

API Reference

EndpointMethodDescription
/healthGETHealth check + stats
/api/v1/addPOSTAdd memories (auto-extracts facts)
/api/v1/searchPOSTSemantic search
/api/v1/contextPOSTFormatted AI context
/api/v1/entity/:nameGETEntity lookup
/api/v1/graphGETKnowledge graph
/api/v1/entitiesGETList all entities
/api/v1/statsGETStatistics
/api/v1/decayPOSTTrigger 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

OpenMemorySuperMemoryMem0
CostFree (local)Paid APIPaid API
Data100% on your machineCloudCloud
ExtractionGrammar-based (no AI)LLM-basedLLM-based
SearchBM25 + Vector + RRFVector onlyVector only
ContradictionsAuto-resolvedManualManual
Smart decayExponential + access boostBasicBasic
SpeedSub-millisecondNetwork latencyNetwork latency

Tech Stack

Configuration

Create ~/.openmemory/.env:

# Optional: API key for REST server authOPENMEMORY_API_KEY=your-secret-key# Optional: Use Claude for smarter extractionOPENMEMORY_EXTRACTION_PROVIDER=local# local | claude | ollamaANTHROPIC_API_KEY=sk-ant-...# only if using claude# ServerPORT=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