Skip to main content


Cortex Claude

Memory that remembers what matters. Built for Claude Code.

License Version Python

Quick Start • How It Works • Tools • Dashboard • Configuration • Benchmarks • Development

Cortex gives Claude Code persistent memory through a local MCP server. Unlike solutions that dump everything into context, Cortex uses progressive recall — a 3-layer retrieval system that returns only what's relevant, using the minimum tokens needed.


Cortex Claude Dashboard

Interactive knowledge graph — explore entities, facts, and memories visually.


The Problem

Memory solutions for AI assistants today waste tokens. They inject entire memory banks into every prompt, regardless of relevance. Cortex takes a different approach:

Save once:

"The auth service uses JWT tokens with 24-hour expiry. Refresh tokens are stored in httpOnly cookies."

Ask later, get back only what matters:

Layer 1: Facts (cheapest)
  auth service → use → jwt tokens
  auth service → use → hour expiry

Layer 2: Summary (~25% of original)

Layer 3: Full content (only if needed)

The system stops at the cheapest layer that answers the question. 66% fewer tokens on average.


Key Features

  • Progressive recall — 3 layers (facts → summaries → full content), stops at the cheapest sufficient layer
  • Code graph — tree-sitter extracts symbols (functions, classes, calls, imports) from Python, JS, TS, Go, Java, Swift, Kotlin into the same knowledge graph. cortex_code(symbol) returns definition + callers + callees in ~100 tokens vs ~1000+ to read the file
  • Auto-clustering — memories self-organize into semantic sub-graphs by embedding similarity. Labels derived from the most frequent entities. Navigate top-down via cortex_clusters
  • Smart capture filter — heuristic gate (keywords, entity density, tool type) decides what to keep from auto-capture. Optional LLM-judge for ambiguous cases. No more polluting memory with ls and trivial reads.
  • Knowledge graph — auto-extracts structured facts via spaCy NLP with multi-hop traversal
  • Smart extraction — handles bullet lists, key:value pairs, comma lists, slash-separated tech, parentheticals, passive voice
  • Claude fallback — optional Claude-assisted extraction when local NLP isn't enough
  • Entity normalization — "postgres", "PostgreSQL", "pg" all resolve to the same entity
  • Graph traversal — navigate entity connections across multiple hops (A → B → C)
  • Hybrid search — vector similarity + FTS5 keyword search combined
  • Configurable scopes — global, per-project, or custom memory boundaries
  • Deduplication — detects and merges near-identical memories automatically
  • Fact merging — when multiple memories mention the same fact, it's consolidated into one with boosted confidence
  • Temporal awareness — facts detect when things happened ("in April 2024", "yesterday", "since v2") and attach timestamps
  • Confidence recalibration — facts gain confidence when accessed frequently, lose it when contradicted by newer information
  • Decay system — unused memories lose relevance over time, keeping results fresh
  • Auto-capture — hooks automatically save tool results (Bash, Read, Grep, Edit, Write) to memory
  • Session context injection — injects memory stats and known facts at session start
  • Background daemon — pre-loaded model for instant saves via Unix socket (~0.3s vs ~5s cold start)
  • Multi-language — EN, PT (auto-detected). ES, DE, FR with additional spaCy models
  • Embedding model choice — 11 models supported, from fast (all-MiniLM, 384d) to high-quality (bge-large, 1024d). Auto-detects dimensions
  • Local-first — SQLite + local embeddings + local NLP. Zero API calls, zero network, zero cost
  • Privacy tags — wrap sensitive content in <private>...</private> to exclude it from memory
  • Fully configurable — all thresholds, ratios, and behaviors via config.json

Quick Start

Cortex depends on spaCy and PyTorch, which don't have wheels for every Python version — installing with whatever python3/pip happens to be on your PATH is the most common source of install failures (cryptic compilation errors, version conflicts with other packages). uv sidesteps this entirely: it downloads and manages an isolated, compatible Python interpreter for you, with zero manual version wrangling.

# Install uv if you don't have it yet (one-time, ~5s)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install cortex-claude — uv picks a compatible Python automatically,
# fully isolated from your system Python. No version conflicts.
uv tool install cortex-claude --python 3.12
cortex-claude setup

That's it. The setup command:

  • Configures the MCP server globally for Claude Code
  • Installs hooks (SessionStart, PreToolUse, PostToolUse)
  • Creates ~/.claude/CLAUDE.md with instructions for Claude to use Cortex automatically
  • Downloads the embedding model (~80MB) and spaCy model (~12MB)
  • Starts the background daemon for instant saves
  • Prints a clear pass/fail summary for every step, and is safe to re-run if anything failed (e.g. a model download blocked by a proxy/firewall)

Restart Claude Code and it works in every project, no per-project config needed. Claude will automatically consult Cortex before saying "I don't know" and save important context to memory.

Upgrading

uv tool install cortex-claude is idempotent by design — if it's already installed, running it again is a no-op and does not fetch a newer version, even after you've uv tool installed a fresh copy. Use the dedicated upgrade command instead:

uv tool upgrade cortex-claude
cortex-claude setup

(pip install --upgrade cortex-claude is the equivalent if you installed via pip.)

Alternative: pip

pip install cortex-claude && cortex-claude setup

Requires Python 3.11–3.13 available as pip's interpreter. If you hit install errors (common causes: a Python 3.14+ system interpreter, or a pip that resolves to a version without spaCy/PyTorch wheels), use the uv tool install method above instead — it manages the Python version for you.

With Claude-assisted extraction (optional)

pip install cortex-claude[claude]
# or: uv tool install cortex-claude[claude] --python 3.12

Manual Setup (alternative)

If you prefer manual configuration, add a .mcp.json to your project root, pointing command at wherever cortex-claude was installed (run which cortex-claude to find it):

{
  "mcpServers": {
    "cortex": {
      "type": "stdio",
      "command": "cortex-claude",
      "args": []
    }
  }
}

Use

Just talk to Claude naturally. Cortex works in the background:

"Remember that the API uses rate limiting at 500 req/min"
"What do you know about rate limiting?"
"What facts do you have about the API?"
"What's connected to the auth service?"
"Forget what I said about the old API key"
"Show me the memory status"

Tools

Cortex exposes 10 MCP tools to Claude Code:

Tool What it does Token cost
cortex_save Store memory with auto fact extraction, summarization, and embedding N/A
cortex_recall Progressive retrieval: facts → summaries → full content Controlled via max_tokens
cortex_facts Direct knowledge graph query, returns structured triplets ~5-15 tokens per fact
cortex_traverse Navigate the knowledge graph; accepts start="cluster:42" to begin from a sub-graph ~5-15 tokens per connection
cortex_code Look up a code symbol: definition, callers, callees, mentions ~50-150 tokens vs ~1000+ to read the file
cortex_index_code Index a file or directory into the code graph (Python, JS/TS, Go, Java, Swift, Kotlin) N/A
cortex_clusters List or rebuild memory sub-graphs (auto-formed by similarity) ~10 tokens per cluster
cortex_forget Delete memories by query or ID (dry-run by default) N/A
cortex_scopes Manage scopes: list, create, delete, link/unlink directories N/A
cortex_status Dashboard: memory count, fact count, storage size per scope N/A

Recall Depth Modes

Mode Returns When to use
auto Starts cheap, escalates if needed Default — best for most queries
facts Only knowledge graph triplets Quick lookups, minimal token use
summaries Facts + compressed summaries Medium detail needed
full All layers including original text Full context needed

How It Works

Save: content → embedding + fact extraction + summarization → SQLite

Recall (progressive):
  1. Facts layer     (~5-15 tokens/fact)   → sufficient? stop
  2. Summaries layer (~25% of original)    → sufficient? stop
  3. Full chunks     (original content)    → return

Fact Extraction

Three methods combined for maximum coverage:

  1. spaCy NLP — dependency parsing, NER, passive voice handling, conjunction expansion
  2. Pattern matching — bullet lists (- X for Y), key:value, comma lists, slash-separated (React/TypeScript), parentheticals (FastAPI (Python)), with/for constructs
  3. Claude fallback (opt-in) — when local extraction produces < 2 high-confidence facts, falls back to Claude Haiku. Off by default.

Entities are normalized and deduplicated: "postgres" → "postgresql", "js" → "javascript", "k8s" → "kubernetes".

Graph Traversal

Navigate entity connections across multiple hops:

auth → JWT → express-jwt → middleware
  ↓
  httpOnly cookies

Query cortex_traverse("auth") and discover everything connected.

Decay

Memories that aren't accessed lose relevance over time:

score = e^(-lambda * days) * (1 + log(access_count))

Recalculated on server startup. Frequently accessed memories get boosted. Stale ones fade.

Auto-Capture & Hooks

Cortex uses Claude Code hooks to work automatically:

  • SessionStart — injects memory stats and known facts when you open a session. Claude knows it has memory and consults it before saying "I don't know". It also fires a fire-and-forget request to the daemon to index the whole current project into the code graph (cortex_index_code-equivalent scan, capped at 2000 files) if that scope hasn't been indexed yet — so the first question about an unfamiliar codebase can often be answered via cortex_code(symbol) instead of exploratory Read/Grep. Runs once per project: subsequent sessions skip the scan and rely on the incremental Read/Edit indexing to keep it fresh. If no scope is explicitly linked for the project directory, indexing uses an auto-derived project:<dir-name> scope rather than polluting global.
  • PreToolUse (Bash only) — rewrites a small, conservative set of known-verbose commands to compact, semantically-equivalent flags before execution (e.g. git status → git status --short --branch, git log → git log --oneline -n 20). Only rewrites exact recognized patterns; a command that already has custom flags passes through untouched. This reduces tokens the agent has to read from command output itself — complementary to, not a replacement for, memory capture.
  • PostToolUse — captures results from all tools in background: Bash, Read, Edit, Write, Grep, Glob, Agent, WebSearch, WebFetch, and all third-party MCP tools. Code files (Python, JS/TS, Go, Java, Swift, Kotlin) trigger an additional index_code step that extracts symbols into the code graph.
  • Capture filter — before persisting, every auto-captured save passes through a heuristic gate (size, signal keywords, tool type, entity density). ls, trivial reads, and noisy edits are dropped. Ambiguous cases can optionally consult an LLM judge.
  • Background Daemon — keeps the embedding model pre-loaded via Unix socket. First save after boot: ~5s (model load). Subsequent saves: ~0.3s. On the first startup after upgrading to v0.6.0 (schema v7), the daemon auto-backfills clusters for any scope with memories but no clusters yet.

All hooks are installed globally by cortex-claude setup. No per-project config needed.

Code Graph

Tree-sitter parses your source files into structured facts in the same knowledge graph used for memories:

my_func   → defined_in  → /path/to/file.py:42
my_func   → in_language → python
my_func   → calls       → other_func
MyClass   → extends     → BaseClass
sample    → imports     → json

Trigger manually with cortex_index_code(path) for a directory, or let auto-capture index files as you read/edit them. Look up symbols with cortex_code(symbol) — returns definition, callers, callees, extends, imports, and which memories mention it. Supported languages: Python, JavaScript, TypeScript/TSX, Go, Java, Swift, Kotlin.

When a saved memory mentions a known symbol, Cortex automatically creates a memory:<id> → mentions → <symbol> fact, linking decisions and bug reports to the code they reference.

Memory Clusters (Sub-graphs)

As memories accumulate, Cortex groups them into semantic clusters using cosine similarity on their embeddings. Each cluster gets a human-readable label derived from the most frequent entities in its facts (e.g. "embeddings, vectors, sqlite-vec").

# List clusters
cortex_clusters

# Traverse the graph starting from a cluster
cortex_traverse start="cluster:42"

# Rebuild clusters after tuning similarity_threshold
cortex_clusters action="backfill"

Clustering runs incrementally in the background after every N saves (default 20, with a 5-minute cooldown). The default similarity_threshold=0.70 balances cluster coherence with singleton noise — tune it in config.json if your corpus needs tighter or looser grouping.

Privacy

Wrap sensitive content in <private> tags to exclude it from memory:

The API uses JWT for auth. <private>API_KEY=sk-abc123secret</private> Tokens expire in 24h.

Cortex strips everything between <private>...</private> before saving. Works in both manual saves and auto-capture. If the entire content is private, nothing is saved.

Combines vector similarity (semantic meaning) with FTS5 (exact keyword match) for best recall. FTS5 synced automatically via SQLite triggers.

Web Dashboard

Browse, explore and prune your memory:

cortex-claude web
# Opens at http://localhost:37800

The dashboard navigates the way recall does — cheapest layer first. It never draws the whole graph, so it stays responsive on a database with tens of thousands of facts.

Features:

  • Cluster map — the landing view is your semantic sub-graphs, sized by member count. Open one to see its own sub-graph and its strongest memories.
  • Entity focus — click a node for that entity's neighbourhood, its facts, and the memories that mention it.
  • Memory browser — search, filter by scope and tag, sort by recency, relevance, last use or size. Paginated server-side.
  • Bulk cleanup — select by tag, scope, cluster or regex and preview exactly what goes before anything is deleted. Removing a memory takes its facts and its vector with it.
  • Live stats — memory and fact counts, clusters, storage, and a 30-day intake sparkline for spotting the day auto-capture ran away with itself.

The dashboard binds to localhost only, sends no CORS headers, and validates Host and Origin so no other page in your browser can read or modify your memory.


Cortex vs Traditional Memory (claude-mem, etc.)

Most memory solutions for AI assistants follow the same pattern: capture observations, compress them, inject into every prompt. Cortex takes a fundamentally different approach.

Traditional (claude-mem) Cortex
Storage model Compressed text / summaries Knowledge graph (structured triplets) + summaries + full text
Retrieval Auto-inject into every session (~500-2000 tokens) Progressive recall: facts → summaries → full (~50-100 tokens)
Intelligence Linear summaries Structured facts with entity relationships + graph traversal
Search Keyword / vector Hybrid: semantic embedding + FTS5 keyword + graph traversal
Extraction Captures tool call observations NLP fact extraction (spaCy + patterns + optional Claude)
Entity awareness None "postgres" = "postgresql" = "pg" (normalized + fuzzy match)
Graph navigation None Multi-hop traversal (A → B → C)
Staleness No decay Unused memories lose relevance over time
Duplicates Can accumulate Auto-merged (cosine similarity > 0.92)
Auto-capture All tool calls via hooks All tools (Bash, Read, Edit, Write, Grep, Glob, Agent, MCP, Web) via hooks + daemon
Session injection Full context dump on start Lightweight facts injection via direct SQLite (<1s)
Dependencies Node.js, Bun, Chroma vector DB Python + SQLite only (zero external services)
Web UI Viewer on localhost:37777 Interactive graph dashboard on localhost:37800

Where Cortex wins

  • Token efficiency — 66% fewer tokens returned. Progressive recall stops at the cheapest sufficient layer.
  • Structured understanding — knowledge graph with traversal vs flat text. Ask "what's connected to auth?" and get real graph navigation.
  • Entity intelligence — normalizes and deduplicates entities across memories. "postgres", "PostgreSQL", and "pg" are the same thing.
  • Freshness — decay system ensures frequently accessed memories rank higher. Old, unused memories fade.
  • Zero external services — no Chroma, no Bun, no Node.js. Just Python + SQLite.
  • Multi-language — fact extraction works in EN, PT (auto-detected), with ES/DE/FR support.

Where claude-mem wins

  • Broader auto-capture — captures all tool calls including MCP tools from third-party servers.
  • Web viewer — real-time memory browser (Cortex has an interactive graph dashboard, but claude-mem's is more mature).
  • One-command install — npx claude-mem install vs manual MCP config.
  • Larger community — more stars, Discord, extensive documentation site.

The fundamental difference

Traditional memory asks "what happened?" — Cortex asks "what matters?"

Traditional solutions observe and replay. Cortex understands, structures, and retrieves surgically. The result: fewer tokens, more relevant answers, and a knowledge graph that grows smarter over time.


Benchmarks

With 10 stored memories (244 total tokens):

Depth Tokens returned Reduction Latency
facts 82 66% ~10ms
auto 82 66% ~10ms
full 244 0% ~12ms
Operation Latency
cortex_facts query 0.1ms
Graph traversal (2 hops) 0.2ms
Save (after model load) ~30ms

Run benchmarks yourself:

uv run python scripts/benchmark.py

How Token Counts Work

The percentages and token counts above are estimates, not exact Claude token counts. Cortex has no access to Claude's real tokenizer (it isn't publicly available outside Anthropic's API), so count_tokens() uses OpenAI's tiktoken (cl100k_base encoding) as a stand-in. It's close enough to drive internal budgeting decisions (recall depth, max_tokens cutoffs, dedup thresholds), but the absolute numbers can differ from what Claude itself would count — treat them as directionally correct, not exact.

The benchmarks above were also measured against a small corpus (10 memories). Some operations that report sub-millisecond latency here (e.g. cortex_facts) rely on non-indexed LIKE '%word%' scans internally and will not stay sub-millisecond as the fact table grows into the tens of thousands of rows — see the note on fact search in core/engine.py for where that fallback is used.


Configuration

All behavior is customizable via ~/.cortex-claude/config.json:

{
  "recall": {
    "default_max_tokens": 200,
    "default_depth": "auto",
    "sufficiency": {
      "coverage_threshold": 0.7,
      "confidence_threshold": 0.6
    }
  },
  "embeddings": {
    "model": "all-MiniLM-L6-v2",
    "batch_size": 32,
    "_available_models": [
      "all-MiniLM-L6-v2 (384d, 80MB, fast)",
      "all-mpnet-base-v2 (768d, 420MB, medium)",
      "BAAI/bge-small-en-v1.5 (384d, 130MB, fast)",
      "BAAI/bge-base-en-v1.5 (768d, 440MB, medium)",
      "BAAI/bge-large-en-v1.5 (1024d, 1.3GB, best quality)",
      "intfloat/e5-large-v2 (1024d, 1.3GB, best quality)",
      "intfloat/multilingual-e5-small (384d, 470MB, multilingual)"
    ]
  },
  "facts": {
    "extraction_method": "local",
    "min_confidence": 0.5,
    "claude_fallback": false,
    "claude_confidence_threshold": 0.5
  },
  "decay": {
    "lambda": 0.05,
    "recalculate_interval_hours": 6,
    "min_score": 0.01
  },
  "deduplication": {
    "similarity_threshold": 0.92,
    "merge_strategy": "append"
  },
  "scopes": {
    "mappings": {
      "/path/to/project-a": "project:a",
      "/path/to/project-b": "project:b"
    },
    "default": "global",
    "search_order": "project_first"
  },
  "storage": {
    "max_db_size_mb": 500
  }
}

All fields are optional. Defaults are used for anything not specified.

See examples/ for ready-to-use configuration files.


Development

git clone https://github.com/rafaelaugustos/cortex-claude.git
cd cortex-claude
uv venv --python python3.13
uv sync --all-extras
uv run python -m spacy download en_core_web_sm
uv run pytest
# Run the demo
uv run python scripts/demo.py

# Run benchmarks
uv run python scripts/benchmark.py

See CONTRIBUTING.md for contribution guidelines.

Architecture

See ARCHITECTURE.md for the full technical specification.


Something Missing?

We'd love to hear from you. Open an issue on GitHub:

Found a bug?

  1. Go to Issues
  2. Describe what happened vs. what you expected
  3. Include your Python version, OS, and steps to reproduce

Have a feature request?

  1. Go to Issues
  2. Describe the problem you're trying to solve
  3. Suggest a solution if you have one

Want to contribute?

  1. Check CONTRIBUTING.md for guidelines
  2. Look for issues labeled good first issue
  3. Fork, branch, code, test, PR

License

MIT — see LICENSE.


Built with Python • Powered by Claude Code • Made by Rafael Augusto

Metadata

Release files for cortex-claude 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cortex-claude 0.8.0
File Size Uploaded
cortex_claude-0.8.0.tar.gz 4.4 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for cortex-claude 0.8.0
File Interpreter ABI Platform
cortex_claude-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 4.8 MB

Release files / cortex_claude-0.8.0.tar.gz

Download URL cortex_claude-0.8.0.tar.gz
Size 4.4 MB
Tags Source
SHA-256 checksum
How to use checksums
166f25294515f5003bdc4a979192877a9284273c74ab7e8e5d4f5444b48b4b66
BLAKE2b-256 checksum
How to use checksums
590b962c57934b3379c696dd90a674fbd11b341c9d283803700f4e68e9b707ce
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release files / cortex_claude-0.8.0-py3-none-any.whl

Download URL cortex_claude-0.8.0-py3-none-any.whl
Size 384.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f4aa91bd7697671c0aba8ed93b3608958d77f9b801be07850b1b3b4678737a51
BLAKE2b-256 checksum
How to use checksums
66d4e8d245e06f23a067a4dd470c59f4c78eb365284cb5892c5a19689021680d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page