# Exocortex

> Personal unified memory system for AI agents. SQLite-backed, local-first, hybrid RAG retrieval with MCP integration.

- **Type:** MCP server
- **Install:** `agentstack add mcp-shawnhack-exocortex`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [shawnhack](https://agentstack.voostack.com/s/shawnhack)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [shawnhack](https://github.com/shawnhack)
- **Source:** https://github.com/shawnhack/exocortex

## Install

```sh
agentstack add mcp-shawnhack-exocortex
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

Exocortex

  Personal unified memory system — SQLite-backed, local-first, hybrid RAG retrieval with MCP integration.

  Quick Start &middot;
  MCP Server &middot;
  CLI &middot;
  REST API &middot;
  Dashboard

---

Exocortex gives AI coding agents persistent memory across sessions. It stores memories with embeddings, scores them using Reciprocal Rank Fusion, and exposes everything through an MCP server, REST API, CLI, and React dashboard. Works with any MCP-compatible tool — Claude Code, Codex, Gemini, Copilot, and others. All data stays local — no cloud, no API keys for embeddings.

**97.0% Recall@5 on LongMemEval** — surpassing the highest published scores, zero API calls. [Full benchmark results →](benchmarks/BENCHMARKS.md)

## Dashboard

  

  

More screenshots

  

  

  

  

---

## Quick Start

Requires **Node.js >= 20** and **pnpm**.

```bash
git clone https://github.com/shawnhack/exocortex.git
cd exocortex
pnpm install
pnpm build        # first build downloads the embedding model (~80MB)
```

Start the server and dashboard:

```bash
pnpm exec exo serve
# → http://localhost:3210
```

Or use the CLI directly:

```bash
pnpm exec exo add "Remember this" --tags "test,demo" --importance 0.8
pnpm exec exo search "remember" --verbose
```

### Connect an AI agent

The MCP server works with any tool that supports the [Model Context Protocol](https://modelcontextprotocol.io):

**Claude Code:**
```bash
claude mcp add --scope user exocortex node /path/to/exocortex/packages/mcp/dist/index.js
```

**Codex CLI** (`~/.codex/config.json`):
```json
{ "mcpServers": { "exocortex": { "command": "node", "args": ["/path/to/exocortex/packages/mcp/dist/index.js"] } } }
```

**Gemini CLI** (`~/.gemini/settings.json`):
```json
{ "mcpServers": { "exocortex": { "command": "node", "args": ["/path/to/exocortex/packages/mcp/dist/index.js"] } } }
```

**VS Code (Copilot / Cline / etc.)** (`.vscode/mcp.json`):
```json
{ "servers": { "exocortex": { "command": "node", "args": ["/path/to/exocortex/packages/mcp/dist/index.js"] } } }
```

---

## How It Works

```
User prompt → Agent reads/writes memories via MCP tools
                ↓
            MCP Server (stdio)
                ↓
          MemoryStore / MemorySearch (core)
                ↓
    ┌───────────┼───────────┐
    │           │           │
 SQLite     FTS5 Index   Vector Store
 (memories)  (full-text)  (384-dim embeddings)
                ↓
    Reciprocal Rank Fusion scoring
    + recency/frequency/usefulness boost
    + graph-aware expansion (1-hop links)
                ↓
     Ranked results + linked context
```

See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed Mermaid diagrams of the module dependency graph, storage flow, search pipeline, intelligence pipeline, and scoring system.

**Key design choices:**
- **No external services** — embeddings run locally via HuggingFace transformers
- **Five-tier knowledge** — working (24h auto-expire), episodic (events, decays), semantic (permanent facts), procedural (permanent techniques), reference (permanent documents). Tier-aware scoring boosts permanent knowledge
- **Hybrid retrieval** — vector similarity + BM25 full-text search, fused with RRF
- **Graph-aware retrieval** — search results include 1-hop linked memories for richer context
- **Usefulness feedback** — memories accessed after search get implicit quality signals, improving future ranking
- **Automatic enrichment** — entity extraction, auto-tagging, deduplication, and temporal expiry detection on every write
- **Auto query expansion** — server-side domain synonym expansion for embedding (opt-out via `search.auto_expansion`)
- **LLM re-ranking** — optional re-rank pass on top-N results after hybrid scoring (opt-in via `search.rerank_enabled`)
- **Source immutability** — ingested URLs are flagged immutable and excluded from consolidation/decay
- **Temporal expiry** — content with "tomorrow", "by Friday", "in 3 days" auto-sets `expires_at`
- **Importance decay** — unused memories lose importance over time, frequently accessed ones gain it
- **Privacy stripping** — `` blocks are stripped before storage/embedding

---

## Packages

| Package | Description |
|---------|-------------|
| `@exocortex/core` | Storage, retrieval, embedding, scoring, entity extraction, intelligence, ingestion |
| `@exocortex/mcp` | MCP server — exposes all memory tools via stdio (works with any MCP client) |
| `@exocortex/server` | Hono REST API on port 3210 + serves the React dashboard |
| `@exocortex/cli` | CLI tool (`exo`) — add, search, import/export, serve, consolidate, retrieval-regression, backfill, verify-backup |
| `@exocortex/dashboard` | React SPA with Neural Interface theme — memories, chat, graph, entities, goals, analytics, library, sources, timeline, skills, trash, mobile-responsive |

---

## MCP Server

The MCP server exposes all Exocortex tools over stdio. See [Quick Start](#connect-an-ai-agent) for setup with your preferred tool.

### Tools

| Tool | Description |
|------|-------------|
| `memory_store` | Store a new memory with tags, importance, content type, and knowledge tier |
| `memory_search` | Hybrid search with RRF scoring, token budgets, and compact mode |
| `memory_get` | Fetch full content for specific memory IDs (use after compact search) |
| `memory_update` | Update content, tags, importance, or content type of an existing memory |
| `memory_forget` | Delete a memory by ID |
| `memory_context` | Load contextual memories for a topic (use at session start) |
| `memory_browse` | Browse memories by tags, type, or date range without semantic search |
| `memory_feedback` | Mark retrieved memories as useful to improve ranking |
| `memory_entities` | List tracked entities with optional tag filtering |
| `memory_timeline` | Query decision history, lineage, or topic evolution over time |
| `memory_ingest` | Index markdown files — splits by `##` headers, deduplicates by `source_uri`, supports globs |
| `memory_link` | Create/remove memory-to-memory links for graph-aware retrieval |
| `memory_digest_session` | Digest a coding session transcript into a structured session summary |
| `memory_maintenance` | Run maintenance: importance adjustment, archival, health checks, search friction, re-embedding, entity backfill, importance recalibration, graph densification, co-retrieval links, adaptive weight tuning, entity orphan pruning |
| `memory_consolidate` | Find and merge clusters of similar memories into summaries |
| `memory_graph` | Entity graph analysis — full graph, bridge detection, community detection |
| `memory_contradictions` | List and resolve detected contradictions between memories |
| `memory_tag_cleanup` | Find and merge near-duplicate tags (preview or apply) |
| `memory_diff` | See what changed since a timestamp — new, updated, and archived memories |
| `memory_project_snapshot` | Quick project snapshot: recent activity, goals, decisions, techniques |
| `memory_decay_preview` | Dry-run preview of what maintenance would archive |
| `memory_ping` | Health check — memory counts, entity/tag stats, date range, uptime |
| `memory_lint` | Comprehensive knowledge-base audit — contradictions, stale claims, orphan entities, suggested wiki topics |
| `memory_wiki_refresh` | Incrementally recompile only wiki articles with stale memories |
| `memory_promote` | Promote an analysis or synthesis into a persistent wiki article + semantic memory |
| `memory_clip` | One-click URL ingest — fetch, chunk, and store with immutable source flag |
| `memory_correct` | Correct a wrong memory — creates replacement, supersedes old, preserves history |
| `memory_job_health` | Record job outcomes and query fleet health with alert thresholds |
| `memory_obsidian_sync` | Incrementally sync changed memories to an Obsidian vault as .md files |
| `memory_compile` | Compile the memory system into a browsable wiki of interlinked markdown articles |
| `wiki_write_article` | Write or update a synthesized wiki article |
| `goal_create` | Create a persistent goal |
| `goal_list` | List goals by status |
| `goal_get` | Get goal details with milestones and progress |
| `goal_update` | Update goal fields/status/metadata |
| `goal_log` | Log progress on a goal |
| `goal_add_milestone` | Add a milestone to a goal |
| `goal_update_milestone` | Update milestone title/status/order/deadline |
| `goal_remove_milestone` | Remove a milestone from a goal |
| `memory_facts` | Query structured subject-predicate-object facts extracted from memories |
| `prediction_create` | Create a prediction with claim, confidence, deadline, and domain |
| `prediction_list` | List predictions filtered by status, domain, source, or overdue |
| `prediction_get` | Get full details of a specific prediction |
| `prediction_resolve` | Resolve a prediction as true, false, or partial |
| `prediction_stats` | Calibration statistics: Brier score, calibration curve, overconfidence bias |

### Search workflow

Token-efficient layered retrieval:

```
1. memory_search(query, compact=true)     → IDs + previews + scores (~50 tokens/result)
2. Review results, pick relevant IDs
3. memory_get(ids=[...])                  → Full content for selected memories
```

Or use `max_tokens` to let the server pack results into a token budget:

```
memory_search(query, max_tokens=2000)     → As many full results as fit in 2000 tokens
```

### Session digestion

The `memory_digest_session` tool reads a session transcript JSONL file, extracts meaningful actions (edits, writes, bash commands, web fetches), and stores a structured summary:

```
Session 2026-02-01 (project: exocortex)
- Edit packages/core/src/memory/digest.ts
- Bash: pnpm test
- Bash: git commit -m "Add session digestion"
- Edit README.md

Files changed: 2 | Commands: 2 | Tools used: 2
```

Read-only tools (Read, Glob, Grep) and Exocortex's own MCP calls are filtered out. Consecutive edits to the same file are deduplicated. The project is auto-detected from file paths.

### Stop hook (Claude Code only, optional)

An optional stop hook can remind the agent to store a session summary before exiting substantial sessions. Not enabled by default. To enable, add to `~/.claude/settings.json`:

```json
{
  "hooks": {
    "Stop": [{ "type": "command", "command": "node /path/to/exocortex/packages/mcp/src/hooks/stop.js" }]
  }
}
```

---

## CLI

```bash
pnpm exec exo  [options]
```

| Command | Description |
|---------|-------------|
| `add ` | Add a new memory. Options: `-t/--tags`, `-i/--importance`, `--type`, `--source` |
| `search ` | Hybrid retrieval search. Options: `-l/--limit`, `--after`, `--before`, `-t/--tags`, `--type`, `-v/--verbose` |
| `import ` | Import from file. Options: `-f/--format` (json\|markdown\|chatexport\|chatgpt\|claude\|obsidian), `--dry-run`, `-d/--decrypt`. Structured Exocortex backup JSON is auto-detected. Obsidian format walks a vault directory, parses YAML frontmatter and wikilinks, infers tiers from folder structure. |
| `stats` | Show memory statistics — counts, breakdowns by type/source, date range |
| `serve` | Start HTTP server + dashboard. Options: `-p/--port` (default 3210), `-H/--host` (default 127.0.0.1) |
| `mcp` | Start MCP server on stdio |
| `consolidate` | Find and merge similar memories. Options: `--dry-run`, `--similarity`, `--min-size`, `--history` |
| `entities` | List and manage entities. Options: `--type`, `--search`, `--memories` |
| `contradictions` | View and manage contradictions. Options: `--status`, `--detect`, `--resolve `, `--dismiss ` |
| `export` | Export JSON backup (memories, entities, goals, links, settings) |
| `obsidian-export` | Export memories to Obsidian-compatible markdown vault |
| `retrieval-regression` | Run golden-query retrieval drift checks and baseline management |
| `verify-backup` | Verify backup integrity — checks row counts, embeddings, entity links |
| `backfill` | Backfill canonical memory state. Options: `--dry-run`, `--limit` |

---

## REST API

### Health

```
GET  /health                    — DB connection status
```

### Memories

```
POST   /api/memories            — Create memory
GET    /api/memories/:id        — Get by ID
PATCH  /api/memories/:id        — Update (content, tags, importance, is_active)
DELETE /api/memories/:id        — Permanent delete
POST   /api/memories/search     — Hybrid search
POST   /api/memories/context-graph — Search + 1-hop linked context
GET    /api/memories/recent     — Recent memories
POST   /api/memories/import     — Bulk import
GET    /api/memories/archived   — List archived/trashed memories
POST   /api/memories/:id/restore — Restore an archived memory
GET    /api/memories/:id/links  — List memory-to-memory links
GET    /api/memories/namespaces — List available namespaces
GET    /api/memories/diff       — Changes since a timestamp (new, updated, archived)
POST   /api/memories/bulk-tag   — Add/remove tags on multiple memories
POST   /api/memories/bulk-update — Bulk update memory fields
```

### Entities

```
GET    /api/entities            — List entities (filter by tags; optional type for manually classified entities)
POST   /api/entities            — Create entity
GET    /api/entities/tags       — List all distinct entity tags
GET    /api/entities/:id        — Get by ID
PATCH  /api/entities/:id        — Update (name, aliases, tags, optional manual type)
DELETE /api/entities/:id        — Delete
GET    /api/entities/:id/memories       — Linked memories
GET    /api/entities/:id/relationships  — Entity relationships
GET    /api/entities/graph              — All entities + relationships (single query)
GET    /api/entities/graph/analysis     — Centrality, communities, stats
```

### Chat

```
POST   /api/chat               — RAG chat (requires ai.api_key in settings)
```

Send `{ message, history?, conversation_id? }`. The server searches memories for context, sends prior conversation history + retrieved context to the configured LLM, and returns `{ response, sources, conversation_id }`. Supports Anthropic (default) and OpenAI providers via `ai.provider` setting.

### Intelligence

```
POST   /api/consolidate         — Find and consolidate memory clusters
GET    /api/consolidations      — Consolidation history
POST   /api/contradictions/detect — Scan for contradictions
GET    /api/contradictions      — List contradictions
GET    /api/contradictions/:id  — Get contradiction by ID
PATCH  /api/contradictions/:id  — Update contradiction (resolve/dismiss)
POST   /api/archive             — Archive stale memories
POST   /api/importance-adjust   — Adjust importance from access patterns
GET    /api/timeline            — Memory timeline with filters
GET    /api/temporal-stats      — Temporal analysis (streaks, averages)
GET    /api/hierarchy           — Temporal hierarchy (epoch → theme → episode)
POST   /api/reembed             — Re-embed memories with missing embeddings
POST   /api/auto-consolidate    — Run auto-consolidation
GET    /api/retrieval-regression/runs   — Regression run history
GET    /api/retrieval-regression/latest — Latest run per-query breakdown
```

### Analytics

```
GET    /api/analytics/summary             — Overview stats (counts, trends)
GET    /api/analytics/access-distribution — Access count distribution
GET    /api/analytics/tag-effectiveness   — Tag usage and effectiveness
GET    /api/analytics/tag-health          — Tag quality metrics
GET    /api/analytics/producer-quality    — Quality by provider/model/agent
GET    /api/analytics/quality-trend       — Quality over time
GET    /api/analytics/quality-distribution — Quality score distribution
GET    /api/analytics/quality-histogram   — Quality score histogram (10 buckets)
GET    /api/analytics/embedding-health    — Embedding coverage and gaps
GET    /api/analytics/decay-preview       — Preview importance decay candidates
GET    /api/analytics/search-misses       — Zero-result queries
GET    /api/analytics/knowledge-gaps      — Detected knowledge gaps
```

### Goals

```
GET    /api/goals              — List goals

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [shawnhack](https://github.com/shawnhack)
- **Source:** [shawnhack/exocortex](https://github.com/shawnhack/exocortex)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-shawnhack-exocortex
- Seller: https://agentstack.voostack.com/s/shawnhack
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
