Persistent local memory for Claude Code. Longer sessions. Cross-session recall. Zero cloud.
> /plugin marketplace add hjertefolger/cortex> /plugin install cortex@cortex
Persistent local memory for Claude Code. Longer sessions. Cross-session recall. Zero cloud.
Ψ 47 ●●○○○ 45% ✓ 5m
| Problem | Cortex Solution |
|---|---|
| Session limits hit mid-task | Auto-save on context step (5%) & session end |
/clear wipes everything | SQLite persistence survives clears |
| Re-explaining context every session | Hybrid search recalls relevant memories |
| Cloud memory privacy concerns | 100% local — ~/.cortex/memory.db |
Inside a Claude Code instance:
Step 1: Add the marketplace
/plugin marketplace add hjertefolger/cortex
Step 2: Install the plugin
On Linux, /tmp is often a separate filesystem (tmpfs), which causes plugin installation to fail with:
EXDEV: cross-device link not permitted
Fix: Set TMPDIR before installing:
mkdir -p ~/.cache/tmp && TMPDIR=~/.cache/tmp claude
Then run the install command below in that session.
/plugin install cortex
Step 3: Run the setup wizard
Ask Claude to run the setup skill:
Please setup Cortex (or run /cortex-setup manually)
The wizard will initialize the database, download the embedding model, and configure the statusline.
Step 4: Customize settings
Ask Claude to configure your preferences:
Please configure Cortex (or run /cortex-configure manually)
Done! Restart Claude Code to activate the statusline.
To update Cortex to the latest version:
Step 1: Update the marketplace
/plugin marketplace update cortex
Step 2: Update the plugin
/plugin update cortex
Step 3: Run the setup wizard
Ask Claude to run the setup skill:
Please setup Cortex (or run /cortex-setup manually)
The wizard will install dependencies and download the embedding model for the new version. Your memories and configuration in ~/.cortex/ are preserved.
Step 4: Restart Claude Code to load the new version.
Note: Due to a known Claude Code issue, always update the marketplace first. After restart, you can ask Claude to verify the update by checking if the cached plugin matches the latest release.
The statusline is configured automatically by /cortex-setup. Restart Claude Code after setup to see it.
Ψ 47 ●●○○○ 45% ✓ 5m
Ψ — Cortex identifier47 — Memory fragment count (compact: 1.1K, 10.2M, etc.)●●○○○ — Context usage (filled/empty circles, color-coded)45% — Context percentage⠋ Saving — Animated spinner during background save✓ Autosaved — Success indicator (shows for ~5s after save)✓ 5m — Time since last save ┌──────────────────────────────────────┐
│ Claude Code │
└──────────────┬───────────────────────┘
│ stdin (JSON)
┌──────────────▼───────────────────────┐
│ Command Router │
│ (src/index.ts) │
└──────────────┬───────────────────────┘
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
┌──────────▼──────────┐ ┌──────────▼──────────┐ ┌──────────▼──────────┐
│ Database │ │ Embeddings │ │ Search │
│ (sql.js/WASM) │ │ (Nomic Embed v1.5) │ │ (Vector + FTS5) │
│ + FTS5 + Backup │ │ 768 dims │ │ + RRF Fusion │
└──────────┬──────────┘ └──────────┬──────────┘ └──────────┬──────────┘
│ │ │
└───────────────────────────┼───────────────────────────┘
│
┌──────────────▼───────────────────────┐
│ ~/.cortex/memory.db │
│ (SQLite + Embeddings) │
└──────────────────────────────────────┘
| Module | Lines | Responsibility |
|---|---|---|
index.ts | 836 | Command router, hooks, statusline |
mcp-server.ts | 850 | MCP protocol, 11 tools exposed |
database.ts | 1143 | SQLite, FTS5, backups, recovery |
archive.ts | 873 | Transcript parsing, chunking |
embeddings.ts | 337 | Nomic Embed v1.5, quantization |
search.ts | 308 | Hybrid search, RRF fusion |
config.ts | 563 | Zod validation, presets |
analytics.ts | 288 | Session tracking, insights |
Total: ~5,700 lines TypeScript
Cortex uses a hybrid search combining three signals:
┌─────────────────────────────────────────────────────────────────┐
│ Query: "auth flow" │
└─────────────────────────┬───────────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Vector │ │ FTS5 │ │ Recency │
│ Search │ │ Keyword │ │ Decay │
│ (60%) │ │ (40%) │ │ (7-day) │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
└───────────────┼───────────────┘
▼
┌──────────────────┐
│ RRF Fusion │
│ (k=60) │
└────────┬─────────┘
▼
┌──────────────────┐
│ Ranked Results │
└──────────────────┘
1/(k + rank) aggregation across both listsSkills are for multi-step workflows. Atomic operations use MCP tools directly.
| Command | Purpose |
|---|---|
/cortex-setup | First-time initialization wizard |
/cortex-configure <preset> | Apply configuration preset |
/cortex-manage | Delete or manage memories |
| Tool | Purpose | Side Effects |
|---|---|---|
cortex_recall | Search memory | Read-only |
cortex_remember | Save specific insight | Creates memory |
cortex_save | Archive full session | Creates memories |
cortex_stats | Get statistics + list projects | Read-only |
cortex_restore | Get restoration context | Read-only |
cortex_analytics | Usage insights | Read-only |
cortex_update | Update memory content/project | Modifies memory |
cortex_rename_project | Bulk rename project | Modifies memories |
cortex_delete | Delete memory | Destructive |
cortex_forget_project | Delete project memories | Destructive |
cortex_remember vs cortex_savecortex_remember("JWT refresh tokens must use httpOnly cookies")
→ Creates ONE memory fragment from the string
cortex_save()
→ Parses transcript, extracts HIGH-VALUE content, creates MULTIPLE fragments
| Hook | Trigger | Behavior |
|---|---|---|
SessionStart | New session | Shows memory count, injects awareness + restoration context |
PostToolUse | After any tool | Monitors context %, triggers auto-save |
PreCompact | Before /clear | Archives session, prepares restoration |
Location: ~/.cortex/config.json
{
"statusline": {
"enabled": true,
"showFragments": true,
"showLastArchive": true,
"showContext": true
},
"archive": {
"projectScope": true,
"minContentLength": 50
},
"autosave": {
"onSessionEnd": true,
"onPreCompact": true,
"contextStep": {
"enabled": true,
"step": 5
}
},
"restoration": {
"tokenBudget": 2000,
"messageCount": 5,
"turnCount": 3
},
"awareness": {
"enabled": false,
"userName": null,
"timezone": null
}
}
/cortex-configure full # All features (statusline, auto-archive, warnings)
/cortex-configure essential # Statusline + auto-archive only
/cortex-configure minimal # Commands only, no automation
| Setting | Default | Description |
|---|---|---|
autosave.contextStep.step | 5 | % context increase to trigger auto-save |
autosave.onPreCompact | true | Archive session before /compact or /clear |
autosave.onSessionEnd | true | Archive session on exit (Ctrl+C x2) |
restoration.tokenBudget | 2000 | Max tokens for key decision restoration |
restoration.turnCount | 3 | Number of raw conversation turns to restore |
awareness.enabled | false | Inject user/date/time at session start and after clear |
awareness.userName | null | User name shown in awareness context |
awareness.timezone | null | IANA timezone (null = auto-detect, "off" = omit date/time) |
CREATE TABLE memories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
content TEXT NOT NULL,
content_hash TEXT UNIQUE, -- SHA256 for deduplication
embedding BLOB NOT NULL, -- 768 × float32 = 3KB
project_id TEXT, -- NULL for global scope
source_session TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_memories_project_id ON memories(project_id);
CREATE INDEX idx_memories_timestamp ON memories(timestamp);
CREATE INDEX idx_memories_content_hash ON memories(content_hash);
-- Optional FTS5 (graceful fallback to LIKE if unavailable)
CREATE VIRTUAL TABLE memories_fts USING fts5(content);
~/.cortex/
├── memory.db # SQLite database (~2-3MB per 1000 memories)
├── memory.db.backup.* # Rotated backups (max 5)
├── config.json # User configuration
├── analytics.json # Session tracking
└── autoSaveState.json # Transient state
npm test
Note:
npm testruns with synthetic/fake data for speed and isolation.
To test against a real production transcript (35MB+):
Locate a real transcript:
Find a large .jsonl file in your ~/.claude/ directory.
Place it in tests:
Copy it to tests/sample_transcript.jsonl.
cp ~/.claude/your-session-id.jsonl tests/sample_transcript.jsonl
Run the E2E test:
node --test tests/e2e_transcript.test.js
200+ tests covering:
cortex is a Claude Code plugin with 3 hand-picked skills, indexed on Flowy in the Agent Memory category. Install it with the command on its page. It includes cortex-configure, cortex-manage, cortex-setup. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
Is this plugin yours?
Claim it with GitHubSubmit a pluginPromote it