{"slug": "show-hn-cortex-local-first-encrypted-memory-for-ai-agents-rust-mcp", "title": "Show HN: Cortex – local-first encrypted memory for AI agents (Rust, MCP)", "summary": "Cortex, a new open-source memory system for AI agents, launched as a local-first, encrypted solution that runs entirely client-side in Rust with a 124KB WASM binary. It offers sub-millisecond latency, zero cloud dependencies, and features like Bayesian belief correction and cross-platform people graphs, aiming to replace cloud-based memory services like Mem0 and OpenAI Memory.", "body_md": "— zero install, 124KB WASM, runs entirely client-side.[🧠 Try Cortex in your browser]\n\nIf Cortex helps your AI remember,— it takes 1 second and helps others discover the project.[give it a ⭐]\n\n**Your AI's memory lives on your device — your data never leaves, never costs, never spies.** Pure Rust. 3.8MB binary. No third-party servers in the data path, zero telemetry, zero cost. Syncs through your own cloud storage. (On-device semantic search downloads a ~30MB model once on first use, then runs fully offline — or go 100% offline with `CORTEX_NO_EMBEDDINGS=1`\n\n. See [Security & Privacy](#security--privacy).)\n\nPhilosophy:Your memories are yours — not a cloud provider's training data, not a startup's monetization asset, not a government's surveillance target. Cortex runs 100% on your hardware, stores everything in your own database, and syncs only through your own cloud storage (iCloud, Google Drive, OneDrive, Dropbox). No middleman ever sees your data. No API key required. No account to create. Just plug it into your AI agent and it remembers — privately, permanently, and at sub-millisecond speed.\n\nLLMs start blank every session. Your assistant forgets your name, your preferences, the conversation you had yesterday, the decision you made last week. Current \"memory\" solutions are flat text files, keyword grep, or cloud APIs that add 200-500ms latency, charge you for the privilege, and send your personal data to someone else's server.\n\nCortex fixes this. It gives your AI a structured, queryable, self-evolving long-term memory that persists across sessions, channels, and contexts — with Bayesian beliefs that self-correct, a people graph that resolves identities across platforms, and sub-millisecond performance on everything. All running locally, all yours.\n\n| Cortex | Mem0 | OpenAI Memory | |\n|---|---|---|---|\nPrivacy |\n100% local, zero cloud | Cloud API (your data on their servers) | OpenAI servers |\nLatency |\n156µs ingest, 568µs search |\n~200-500ms | ~300-800ms |\nCost |\nFree, forever | $99+/mo (Pro) | ChatGPT Plus ($20/mo) |\nMemory tiers |\n4 (Working/Episodic/Semantic/Procedural) | 1 (flat) | 1 (flat) |\nBayesian beliefs |\nSelf-correcting with evidence | No | No |\nPeople graph |\nCross-channel identity resolution | Paid tier only | No |\nConversation compression |\nAutomatic session summarization | No | No |\nRelationship inference |\nPattern-based (EN + CN) | No | No |\nTemporal retrieval |\nIntent-aware (\"recently\" / \"first time\") | No | No |\nContradiction detection |\nAutomatic with confidence scores | No | No |\nConsolidation |\nEpisodic → Semantic auto-promotion | No | No |\nContext injection |\nToken-budgeted LLM-ready output | Manual | Automatic but opaque |\nImport/Export |\nFull JSON backup & restore | API only | No export |\nSelf-hosted |\nNative binary, Docker, MCP | Cloud only | Cloud only |\nBinary size |\n3.8 MB | npm package | N/A |\nDependencies |\n0 runtime services (single binary) | Node.js + cloud | N/A |\nOpen source |\nMIT | Partial | No |\nEncryption |\nAES-256-GCM encrypted sync (opt-in) | No | No |\nKey rotation |\nVersioned envelopes, forward secrecy | No | No |\nPrivacy levels |\nPrivate (default, never syncs) / Shared / Public — per-memory opt-in, demote retracts from other devices | No | No |\nTool authorization |\nDeny-by-default capability policy on the MCP surface | No | No |\nZero telemetry |\nNo analytics, no phone-home, verifiable | Unknown | No |\nCost |\nFree forever, unlimited | $99+/mo (Pro) | $20/mo (Plus) |\nChinese NLP |\nNative (inference, retrieval, relationships) | No | Limited |\nNamespace isolation |\nPer-user/context memory separation | No | No |\nPlugin system |\nCompile-time hooks for ingest/retrieve/consolidation | No | No |\nMCP tools |\n30 tools for Claude/LLM integration | 3rd party | N/A |\n\n| Operation | Cortex | Mem0 (cloud) | File-based |\n|---|---|---|---|\n| Ingest | 156µs |\n~200ms | ~1ms |\n| Search (top-10) | 568µs |\n~300ms | ~10ms |\n| Context generation | 621µs |\n~500ms | manual |\n| Belief update | 66µs |\nN/A | N/A |\n| People graph | 51µs |\npaid tier | N/A |\n| Structured facts | 45µs |\nN/A | N/A |\n| 1K memories search | 1.6ms |\n~500ms | ~50ms |\n\n**528x faster** than Mem0 cloud. With features neither Mem0 nor OpenAI Memory offer.\n\nNote:Benchmarks include proactive inference (auto-extracting facts, preferences, relationships) on every ingest. Raw ingest without inference is ~15µs. Numbers from`cargo bench`\n\non M-series Mac.\n\n### LoCoMo Benchmark ([ACL 2024](https://snap-research.github.io/locomo/))\n\nAcademic-grade long-term conversation memory evaluation — 10 conversations, 1540 QA pairs across 4 categories.\n\n| System | Single-hop | Multi-hop | Open-domain | Temporal | Overall |\n|---|---|---|---|---|---|\n| Backboard | 89.4% | 75.0% | 91.2% | 91.9% | 90.0% |\n| MemMachine v0.2 | — | — | — | — | 84.9% |\nCortex v1.7 |\n72.5% |\n59.5% |\n88.8% |\n74.1% |\n73.7% |\n| Mem0-Graph | 65.7% | 47.2% | 75.7% | 58.1% | 68.4% |\n| Mem0 | 67.1% | 51.2% | 72.9% | 55.5% | 66.9% |\n| OpenAI Memory | — | — | — | — | 52.9% |\n\n**Key findings:**\n\n**Open-domain 88.8%**— leads Mem0 (72.9%) by +15.9%** Temporal 74.1%**— leads Mem0 (55.5%) by +18.6%** Single-hop 72.5%**— leads Mem0 (67.1%) by +5.4%** Multi-hop 59.5%**— leads Mem0 (51.2%) by +8.3%** Overall 73.7%**— beats Mem0 (66.9%) by +6.8%, beats OpenAI Memory (52.9%) by +20.8%\n\nCortex outperforms Mem0 on all 4 categories — while running 100% locally, end-to-end encrypted, at $0 cost.\n\nSetup:Claude Sonnet 4 (QA + judge), nomic-embed-text (embeddings via Ollama), top-30 retrieval. Fully reproducible:`python3 bench/locomo_bench.py`\n\nCortex implements a 4-tier memory model inspired by human cognition:\n\n```\n                    +---------------------+\n                    |   Working Memory    |  Current session context\n                    +---------------------+\n                              |\n                    +---------------------+\n                    |   Episodic Memory   |  Raw experiences: conversations, events, observations\n                    +---------------------+\n                              |  consolidation (decay, promotion, pattern extraction)\n                    +---------------------+\n                    |   Semantic Memory   |  Distilled facts, preferences, relationships\n                    +---------------------+\n                              |\n                    +---------------------+\n                    | Procedural Memory   |  Learned routines, user-specific workflows\n                    +---------------------+\n```\n\n**Working** holds the current session scratch pad. **Episodic** stores raw experiences with timestamps and source metadata. The **Consolidation Engine** periodically promotes recurring patterns into **Semantic** facts and decays stale episodes. **Procedural** captures learned workflows and routines.\n\nCross-channel identity resolution. The same person messaging you on Telegram, emailing you, and showing up in calendar events gets unified into a single identity node. Interactions, relationship strength, and communication patterns are tracked per-person.\n\nSelf-correcting understanding of the world. Beliefs are formed from evidence, updated with each new observation, and can be contradicted. Confidence scores reflect actual certainty rather than recency bias.\n\n```\ncortex.observe_belief(\"user_prefers_morning_meetings\", true, 0.8)?;\ncortex.observe_belief(\"user_prefers_morning_meetings\", false, 0.6)?;\n// Confidence adjusts automatically via Bayesian update\n```\n\nEpisodic-to-semantic promotion, decay of stale memories, and pattern extraction. Runs as a background cycle that keeps the memory store lean and queryable. Returns a report of what was promoted, decayed, and merged.\n\nQueries combine five signals for relevance ranking:\n\n**Similarity**-- vector cosine distance against query embedding** Temporal**-- recency weighting with configurable decay** Salience**-- importance scoring from access patterns and explicit hints** Social**-- boost for memories involving specific people** Channel**-- filter or boost by source channel\n\nGenerates LLM-ready context strings from memory state. Pass a token budget, optional channel/person filters, and get back a structured text block your LLM can consume directly.\n\nSQLite for persistence, in-memory vector index for fast similarity search. Single-file database, no external services required. Designed for edge deployment -- runs on a laptop, a Raspberry Pi, or a server.\n\nSync memories across devices through your own cloud storage — no third-party server involved.\n\n```\nDevice A (Mac)              Your Cloud Storage              Device B (iPhone)\n┌──────────┐         ┌──────────────────────┐         ┌──────────┐\n│ SQLite DB │ ──W──>  │ iCloud / GDrive /    │  <──R── │ SQLite DB│\n│ (local)   │         │ OneDrive / Dropbox   │         │ (local)  │\n│           │ <──R──  │                      │  ──W──> │          │\n└──────────┘         └──────────────────────┘         └──────────┘\n```\n\n**Changelog-based**: Each device writes append-only operation logs to its own subfolder** No conflicts**: Devices never write to the same file. Merge uses Last-Writer-Wins with Hybrid Logical Clocks** Encrypted**: AES-256-GCM encryption (opt-in). Even if your cloud account is compromised, memories stay private** Tamper-evident**: the sync manifest and every operation carry an HMAC; tampered or plaintext-injected oplog lines are rejected, and a manifest without integrity protection refuses to load (no key-rollback path)**Key rotation & forward secrecy**: rotate to a new key version (`ENC2`\n\nenvelopes) without re-encrypting history; old versions stay readable, new writes are unreadable to a leaked old key**Privacy-aware, per-memory opt-in**: Private memories (the default) never leave your device. Mark a memory`shared`\n\nto sync it; demote it back to`private`\n\nand a retraction**deletes it from your other devices**(local copy kept)** Survives restarts**: sync settings persist in the database (passphrase never touches disk — macOS login Keychain or`CORTEX_SYNC_PASSPHRASE`\n\n); the server resumes sync and starts background pull (30s poll + fs watcher) automatically\n\nSupported providers: **iCloud Drive**, **Google Drive**, **OneDrive**, **Dropbox** (auto-detected).\n\n```\nuse cortex_core::sync::SyncConfig;\nuse cortex_core::types::PrivacyLevel;\n\n// Enable sync with encryption (settings persist; passphrase goes to the OS keychain)\nlet config = SyncConfig::new(sync_dir, device_id, device_name)\n    .with_encryption(\"my-strong-passphrase\");\ncortex.enable_sync(config)?;\n\n// Opt a memory into sync — everything is Private unless you say otherwise\ncortex.set_memory_privacy(mem_id, PrivacyLevel::Shared { scope: \"all\".into() })?;\n\n// Pull changes from other devices (also happens automatically in the background)\nlet applied = cortex.sync_pull()?;\nprintln!(\"Applied {} remote changes\", applied);\n```\n\n| Feature | Detail |\n|---|---|\nEncryption |\nAES-256-GCM with Argon2id key derivation (per-line random nonce) |\nKey rotation |\nVersioned `ENC2` envelopes with per-version passphrase-derived keys — forward secrecy against AES-key exfiltration, no full re-encryption needed |\nIntegrity |\nHMAC on the sync manifest and on every sync operation; plaintext lines in an encrypted oplog are rejected outright (injection defense) |\nPrivacy levels |\nPrivate (default, never syncs), Shared, Public — set at ingest (`privacy` arg / `--privacy` ) or later (`memory_set_privacy` ); demoting to Private retracts the memory from other devices |\nCapability policy |\nDeny-by-default tool authorization on the MCP surface: a `capabilities.json` grants tool groups (`read` /`write` /`sync` /`plugins` ) or exact tools; ungranted tools are invisible and uncallable; malformed policy fails closed |\nQuery budget |\nEvery retrieval is bounded (candidate cap + wall-clock cap) — query cost never scales with total store size; DoS guard and timing-side-channel bound in one |\nSecret handling |\nSync passphrase is never written to disk by Cortex — macOS login Keychain or env var only; missing passphrase fails safe (sync off, never plaintext) |\nMemory zeroization |\nSensitive data cleared from RAM on drop (`zeroize` crate) |\nZero telemetry |\nNo analytics, no phone-home, no user data ever leaves the device — enforced in CI (`scripts/check-no-network-egress.sh` ): the build fails if any network/telemetry crate enters `cortex-core` 's default tree, and the check also proves the `--no-default-features` binary is completely zero-network. |\nEmbedding model fetch (one-time) |\nThe default `cortex-mcp-server` enables on-device semantic search, which downloads a ~30 MB model (all-MiniLM-L6-v2) from the Hugging Face CDN on first ingest, then runs fully offline and sends none of your data. For a 100%-offline setup: run with `CORTEX_NO_EMBEDDINGS=1` (keyword/FTS recall, zero network) or build `--no-default-features` . A one-time stderr notice is printed before any download — nothing is ever fetched silently. |\nNo accounts |\nNo API key, no registration, no cloud dependency |\n\nSee [SECURITY.md](/gambletan/cortex/blob/main/SECURITY.md) for the full threat model.\n\nInstall the [Rust toolchain](https://rustup.rs/) (provides `cargo`\n\n):\n\n```\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n```\n\nAfter installation, either restart your terminal or run:\n\n```\nsource \"$HOME/.cargo/env\"\n```\n\nVerify:\n\n```\ncargo --version\n```\n\nImagine your AI assistant across a week of real conversations:\n\n```\n# Day 1 — You chat on Telegram\nYou: \"Sarah works at Stripe. She's interested in our API.\"\n\n  Cortex auto-extracts:\n  ├── episodic memory stored (156µs)\n  ├── fact: Sarah → works_at → Stripe (confidence: 0.70)\n  └── person resolved: sarah_telegram\n\n# Day 2 — Sarah emails you\nFrom: sarah@stripe.com\n\"Here's the technical spec we discussed.\"\n\n  Cortex:\n  ├── person resolved: sarah@stripe.com → merged with sarah_telegram\n  │   (same person, different channel — automatic identity resolution)\n  └── fact: Sarah → sent → technical spec\n\n# Day 3 — You ask your AI\nYou: \"What's the status with Stripe?\"\n\n  Cortex retrieves (568µs):\n  ├── Sarah works at Stripe (semantic fact)\n  ├── Meeting went well, interested in API (episodic, Day 1)\n  ├── She sent technical spec (episodic, Day 2)\n  └── Cross-channel context: Telegram + Email unified under one person\n\n  Your AI responds with full context — no \"sorry, I don't remember\" 🎯\n\n# Day 5 — New information arrives\nYou: \"Sarah now works at Anthropic.\"\n\n  Cortex:\n  ├── contradiction detected: Sarah works_at Stripe vs Sarah works_at Anthropic\n  ├── old fact superseded + decayed: Stripe (salience ×0.3, kept as history)\n  ├── new fact stored: Sarah → works_at → Anthropic\n  └── current employer now ranks first; self-correcting, no manual cleanup\n\n  (Third-party relations are extracted from natural-language verbs —\n   \"works at / works for / joined / now works at\", \"runs on\", \"hosted in\",\n   \"manages\", \"part of\", … — between two proper-noun entities.)\n\n# Day 7 — Consolidation runs\n  Cortex auto-consolidation:\n  ├── 3 episodic memories about Sarah → promoted to semantic summary\n  ├── stale memories from other topics → decayed\n  └── pattern detected: you have recurring Monday meetings\n```\n\nAll of this happens **locally in <1ms per operation**. No cloud. No API calls. No one else sees your data.\n\n```\nbrew tap gambletan/tap\nbrew install cortex-mcp-server\ncargo build --release -p cortex-mcp-server\ncp target/release/cortex-mcp-server ~/.local/bin/\njs\nuse cortex_core::Cortex;\n\n// Open (or create) a memory database\nlet cortex = Cortex::open(\"memory.db\")?;\n\n// Ingest a memory from a Telegram conversation\nlet embedding = your_embedding_fn(\"Met with Alice about the Q3 roadmap\");\ncortex.ingest(\n    \"Met with Alice about the Q3 roadmap\",\n    \"telegram\",               // source channel\n    Some(\"alice_123\"),         // user ID (triggers identity resolution)\n    Some(0.8),                 // salience hint\n    Some(embedding),           // vector embedding\n)?;\n\n// Add a semantic fact directly\ncortex.add_fact(\n    \"Alice\", \"works_at\", \"Acme Corp\",\n    0.95, \"telegram\", None,\n)?;\n\n// Store a preference\ncortex.add_preference(\"timezone\", \"America/Los_Angeles\", 0.9)?;\n\n// Retrieve relevant memories\nlet results = cortex.retrieve(\n    \"What do I know about Alice?\",\n    5,                         // top-k\n    None,                      // any channel\n    None,                      // any person\n    Some(query_embedding),     // vector for similarity search\n)?;\n\n// Generate LLM-ready context (token-budgeted)\nlet context = cortex.get_context(\n    2000,                      // max tokens\n    Some(\"telegram\"),          // channel filter\n    None,                      // no person filter\n)?;\n// Pass `context` as system/user message prefix to your LLM\n\n// Run consolidation (call periodically)\nlet report = cortex.run_consolidation()?;\nprintln!(\"Promoted: {}, Decayed: {}\", report.promoted, report.decayed);\n```\n\nComing soon via [PyO3](https://pyo3.rs). The `cortex-python`\n\ncrate will expose the full API as a native Python module:\n\n``` python\nfrom cortex import Cortex\n\ncx = Cortex.open(\"memory.db\")\ncx.ingest(\"Had lunch with Bob at the Thai place\", channel=\"imessage\", user_id=\"bob\")\nresults = cx.retrieve(\"Where does Bob like to eat?\", limit=5)\n```\n\nCortex is designed as the memory layer for [unified-channel-hub](https://github.com/gambletan/unified-channel-hub). Messages flow in from any channel adapter, Cortex ingests and indexes them, and the context injection protocol feeds relevant memory back to your LLM before each response.\n\n```\nTelegram ─┐                          ┌─ Context\nDiscord  ─┤  unified-channel-hub  →  │  Cortex  →  LLM\nEmail    ─┤  (ingest)                 │  (retrieve + inject)\nCalendar ─┘                          └─ Response\n```\n\nAdd persistent memory to any [LangGraph](https://github.com/langchain-ai/langgraph) agent via [langchain-mcp-adapters](https://github.com/langchain-ai/langchain-mcp-adapters) — no custom code needed.\n\n``` python\nfrom langchain_mcp_adapters.client import MultiServerMCPClient\nfrom langgraph.prebuilt import create_react_agent\nfrom langchain_openai import ChatOpenAI\n\nmodel = ChatOpenAI(model=\"gpt-4o\")\n\nasync with MultiServerMCPClient({\n    \"cortex\": {\n        \"command\": \"cortex-mcp-server\",\n        \"args\": [\"~/.cortex/memory.db\"]\n    }\n}) as client:\n    agent = create_react_agent(model, client.get_tools())\n    # Agent now has all 30 Cortex memory tools\n    result = await agent.ainvoke({\n        \"messages\": [{\"role\": \"user\", \"content\": \"What do you remember about Alice?\"}]\n    })\n```\n\nYour LangGraph agent gets instant access to memory_search, memory_ingest, fact_add, belief_observe, person_resolve, and 25 more tools — all running locally.\n\nCortex works as a persistent memory layer for [DeerFlow](https://github.com/bytedance/deer-flow) — ByteDance's open-source multi-agent orchestration platform. Zero code changes needed.\n\n```\n# Add to DeerFlow config.yaml\nmcp_servers:\n  cortex-memory:\n    command: cortex-mcp-server\n    args:\n      - ~/.cortex/deerflow.db\n```\n\nAll DeerFlow agents (Telegram, Slack, Feishu) get instant access to 30 memory tools — cross-session memory, fact storage, people graph, and belief tracking across all channels.\n\nCortex doubles as a standalone CLI tool — no MCP client required.\n\n``` bash\n$ cortex-mcp-server --help\nCortex memory engine — MCP server & CLI tools\n\nUsage: cortex-mcp-server [DB_PATH] [COMMAND]\n\nCommands:\n  ingest  Store a new memory\n  search  Search memories\n  stats   Show memory statistics\n  sync    Show cloud sync status and detected providers\n  export  Export all data as JSON\n  import  Import data from JSON file\n  info    Show version, DB path, and capabilities\n  help    Print this message or the help of the given subcommand(s)\n\nArguments:\n  [DB_PATH]  Path to the Cortex database file (default: ~/.cortex/memory.db)\n\nOptions:\n  -h, --help     Print help\n  -V, --version  Print version\n```\n\n**Examples:**\n\n```\n# Store a memory\ncortex-mcp-server ~/.cortex/memory.db ingest \"Met with Alice about Q3 roadmap\"\ncortex-mcp-server ~/.cortex/memory.db ingest -c telegram \"Sarah now works at Anthropic\"\n\n# Search\ncortex-mcp-server ~/.cortex/memory.db search \"Alice\"\ncortex-mcp-server ~/.cortex/memory.db search -l 10 \"Q3 roadmap\"\n\n# Stats\ncortex-mcp-server ~/.cortex/memory.db stats\n\n# Cloud sync\ncortex-mcp-server ~/.cortex/memory.db sync                        # status\ncortex-mcp-server ~/.cortex/memory.db sync enable                  # auto-detect provider\ncortex-mcp-server ~/.cortex/memory.db sync enable -p icloud        # specific provider\ncortex-mcp-server ~/.cortex/memory.db sync pull                    # pull remote changes\n\n# Export / Import (backup & restore)\ncortex-mcp-server ~/.cortex/memory.db export -o backup.json\ncortex-mcp-server ~/.cortex/new.db import backup.json\n\n# Version & capabilities\ncortex-mcp-server ~/.cortex/memory.db info\n```\n\n**No subcommand = MCP stdio mode** (for Claude Code / Claude Desktop integration).\n\nCortex ships as an MCP server — works with any MCP-compatible client.\n\n**1. Build & install the binary:**\n\n```\nmkdir -p ~/.local/bin ~/.cortex\ncargo build --release -p cortex-mcp-server\ncp target/release/cortex-mcp-server ~/.local/bin/\n```\n\n**2. Register as MCP server:**\n\nClaude Code (CLI):\n\n```\n# Global (all projects)\nclaude mcp add cortex --scope user -- ~/.local/bin/cortex-mcp-server ~/.cortex/memory.db\n\n# Or per-project\nclaude mcp add cortex -- ~/.local/bin/cortex-mcp-server ~/.cortex/memory.db\n```\n\nClaude Desktop — add to `~/Library/Application Support/Claude/claude_desktop_config.json`\n\n:\n\n```\n{\n  \"mcpServers\": {\n    \"cortex\": {\n      \"command\": \"/Users/you/.local/bin/cortex-mcp-server\",\n      \"args\": [\"/Users/you/.cortex/memory.db\"]\n    }\n  }\n}\n```\n\n**3. Allow tools in \"don't ask\" mode:**\n\nAdd to `~/.claude/settings.json`\n\n→ `permissions.allow`\n\n:\n\n```\n\"mcp__cortex__*\"\n```\n\nNote: MCP tool permissions do not support parentheses format (e.g.\n\n`mcp__cortex__memory_ingest(*)`\n\n). Use the wildcard`mcp__cortex__*`\n\ninstead.\n\n**4. Make it automatic** — add to your `CLAUDE.md`\n\n(project or global `~/.claude/CLAUDE.md`\n\n):\n\n```\n# Memory (Cortex)\nYou have persistent memory via Cortex MCP tools. Use them automatically:\n- Start of conversation: call `memory_context` to load what you know about the user\n- When the user shares a preference, fact, or personal info: call `memory_ingest` to store it\n- When you learn a structured fact: call `fact_add` (e.g. \"User works_at Google\")\n- When you detect a preference: call `preference_set` (e.g. editor=neovim)\n- When evidence supports or contradicts a belief: call `belief_observe`\n- When talking to someone new: call `person_resolve` to track identity\n- Periodically: call `memory_consolidate` to clean up stale memories\n```\n\n**5. Auto-inject memory on session start** (Claude Code hooks — fully automatic):\n\nCreate `~/.claude/hooks/cortex-memory-inject.sh`\n\n:\n\n``` bash\n#!/bin/bash\nCORTEX_BIN=\"${CORTEX_BIN:-$HOME/.local/bin/cortex-mcp-server}\"\nCORTEX_DB=\"${CORTEX_DB:-$HOME/.cortex/memory.db}\"\n[ -x \"$CORTEX_BIN\" ] || exit 0\n\nprintf '%s\\n%s\\n%s\\n' \\\n  '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2024-11-05\",\"capabilities\":{},\"clientInfo\":{\"name\":\"hook\",\"version\":\"1.0\"}}}' \\\n  '{\"jsonrpc\":\"2.0\",\"method\":\"notifications/initialized\"}' \\\n  '{\"jsonrpc\":\"2.0\",\"id\":2,\"method\":\"tools/call\",\"params\":{\"name\":\"memory_context\",\"arguments\":{\"max_tokens\":1500}}}' \\\n  | \"$CORTEX_BIN\" \"$CORTEX_DB\" 2>/dev/null \\\n  | grep '\"id\":2' \\\n  | python3 -c \"import sys,json; r=json.load(sys.stdin); print(r['result']['content'][0]['text'])\" 2>/dev/null\n```\n\nAdd to `~/.claude/settings.json`\n\n:\n\n```\n{\n  \"hooks\": {\n    \"SessionStart\": [\n      {\n        \"matcher\": \"\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"~/.claude/hooks/cortex-memory-inject.sh\"\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\nNow every new Claude Code session automatically loads your memory context — **zero manual effort**. Claude learns as you work and remembers across sessions.\n\nYour Claude's memory follows you across all your devices — MacBook, iMac, work laptop — through your own cloud storage.\n\n**Enable sync (one command):**\n\n```\nYou: \"Enable cross-device memory sync\"\n\nClaude calls sync_enable → auto-detects iCloud Drive →\n  generates device ID + AES-256-GCM encryption key → done.\n\nOutput:\n  Provider:   iCloud Drive\n  Encryption: AES-256-GCM\n  Passphrase: a1b2c3...  ← save this for your other devices\n```\n\n**On your second device** — one script does everything (build/install, wait for iCloud, join, restore):\n\n```\ngit clone https://github.com/gambletan/cortex && cortex/scripts/setup-device-sync.sh\n# Prompts for your passphrase (hidden input; or set CORTEX_SYNC_PASSPHRASE)\n# → full restore on join, passphrase saved to that device's login Keychain\n```\n\nOr conversationally:\n\n```\nYou: \"Enable sync with passphrase a1b2c3...\"\n\nClaude calls sync_enable(passphrase: \"a1b2c3...\") →\n  connects to the same iCloud sync folder → pulls all memories.\n\nNow both devices share the same memory — and keep sharing it\nautomatically (background sync: 30s poll + filesystem watcher).\n```\n\n**What syncs and what doesn't:**\n\n- Private memories (default)\n**never leave your device**. Opt in per memory:`memory_ingest`\n\nwith`privacy: \"shared\"`\n\n,`cortex-mcp-server ingest --privacy shared`\n\n, or`memory_set_privacy`\n\non an existing memory - Demote a shared memory back to\n`private`\n\nand it is**retracted (deleted) from your other devices**— the local copy stays - All sync data is\n**AES-256-GCM encrypted** with HMAC integrity — even if your cloud account is compromised, memories stay private and tampering is detected - Sync survives restarts: settings persist, the passphrase lives in the OS keychain, the server resumes automatically\n- No server, no API, no account — just your own cloud folder\n\n**CLI alternative:**\n\n```\n# Device A\ncortex-mcp-server sync enable\n# Save the passphrase from the output\n\n# Device B\ncortex-mcp-server sync enable --passphrase \"your-passphrase-from-device-A\"\n\n# Manual pull (background sync also pulls automatically)\ncortex-mcp-server sync pull\n```\n\nWorking across multiple projects? Use **separate databases** for physical memory isolation — no cross-project leakage, zero code changes needed.\n\n```\n~/.cortex/\n├── global.db          # User preferences, people graph, cross-project knowledge\n├── my-app.db          # Project A memories\n└── my-api.db          # Project B memories\n```\n\n**Global config** (`~/.claude/settings.json`\n\n) — user-level knowledge:\n\n```\n{\n  \"mcpServers\": {\n    \"cortex-global\": {\n      \"command\": \"~/.local/bin/cortex-mcp-server\",\n      \"args\": [\"~/.cortex/global.db\"]\n    }\n  },\n  \"permissions\": { \"allow\": [\"mcp__cortex-global__*\", \"mcp__cortex-project__*\"] }\n}\n```\n\n**Per-project config** (`~/.claude/projects/<path>/settings.json`\n\n) — project-specific:\n\n```\n{\n  \"mcpServers\": {\n    \"cortex-project\": {\n      \"command\": \"~/.local/bin/cortex-mcp-server\",\n      \"args\": [\"~/.cortex/my-app.db\"]\n    }\n  }\n}\n```\n\nThen add these memory isolation rules to your project's `CLAUDE.md`\n\n:\n\n```\n## Memory Isolation\n\nTwo Cortex MCP servers: `cortex-project` (project DB) and `cortex-global` (global DB).\n\n### Write Policy\n- Save to `cortex-project` if the memory is about this repo's architecture, code,\n  modules, tests, workflows, configs, bugs, decisions, or terminology.\n- Save to `cortex-global` only for long-term user preferences, communication style,\n  cross-project habits, or personal background useful across repos.\n- **Default: if uncertain, save to `cortex-project`.**\n\n### Read Policy\n1. Query `cortex-project` first.\n2. Query `cortex-global` second, only for user-level preferences.\n3. Prefer project memory when they conflict.\n\n### Anti-Leak Rules\n- Never auto-copy from `cortex-project` into `cortex-global`.\n- Never store repo-specific paths, module names, or account names in `cortex-global`.\n- Never treat project implementation details as user-global preferences.\n\n### Update Rule\n- Cortex is append-only. To update: search old entry → delete → ingest new.\n```\n\nThis gives you two independent Cortex instances per project — complete isolation with shared user knowledge.\n\nTool access is governed by an optional\n\ndeny-by-default capability policy: drop a`capabilities.json`\n\nnext to your database (`{\"version\":1,\"grants\":[\"read\",\"write\"]}`\n\n) and only granted tool groups (`read`\n\n/`write`\n\n/`sync`\n\n/`plugins`\n\n/`all`\n\n) or exact tool names are listed and callable. No policy file = everything enabled (legacy).\n\n| Tool | Purpose |\n|---|---|\n`memory_ingest` |\nStore a memory (text, channel, person context, optional `privacy` ) |\n`memory_set_privacy` |\nChange a memory's privacy level — promote to `shared` to sync it, demote to `private` to retract it from other devices |\n`memory_search` |\nSemantic search across all memory tiers |\n`memory_context` |\nGenerate LLM-ready context summary (token-budgeted) |\n`memory_consolidate` |\nRun decay + promotion + sweep cycle |\n`memory_infer` |\nPreview inference without storing |\n`memory_compress` |\nCompress old conversation sessions |\n`memory_stats` |\nGet memory statistics (counts per tier, index size) |\n`memory_decay` |\nRun temporal decay on episodic memories |\n`belief_observe` |\nUpdate a Bayesian belief with evidence |\n`belief_list` |\nQuery beliefs above confidence threshold |\n`fact_add` |\nStore structured knowledge (subject-predicate-object) |\n`fact_query` |\nQuery facts by entity (SQL-indexed) |\n`preference_set` |\nStore user preference with confidence |\n`preference_query` |\nQuery preferences by key pattern |\n`person_resolve` |\nCross-channel identity resolution |\n`person_list` |\nList all known people |\n`contradiction_check` |\nCheck for fact contradictions |\n`relationship_extract` |\nExtract relationships from text |\n`sync_status` |\nCloud sync status (provider, devices, pending ops) |\n`sync_providers` |\nDetect available cloud storage providers |\n`sync_enable` |\nEnable cross-device cloud sync with optional encryption |\n`sync_pull` |\nPull and apply remote changes from other devices |\n`memory_archive` |\nArchive a memory to cold storage |\n`memory_restore` |\nRestore an archived memory back to an active tier |\n`memory_delete` |\nPermanently delete a memory by ID |\n`memory_ingest_batch` |\nIngest multiple memories in a single transaction |\n`tag_list_taxonomy` |\nList all tags in use across memories with counts |\n`namespace_list` |\nList all namespaces with memory counts |\n`person_merge` |\nMerge two person identities into one |\n\nGive your OpenClaw agent persistent memory with auto-recall and auto-capture.\n\n**Install:**\n\n```\n# 1. Install Cortex binary\ncurl -fsSL https://raw.githubusercontent.com/gambletan/cortex/main/install.sh | bash\n\n# 2. Install the OpenClaw plugin\nopenclaw plugin add @cortex-ai-memory/cortex-memory\n```\n\n**Configure** (optional — works with defaults):\n\n```\n{\n  \"plugins\": {\n    \"@cortex-ai-memory/cortex-memory\": {\n      \"autoCapture\": true,\n      \"autoRecall\": true,\n      \"topK\": 10\n    }\n  }\n}\n```\n\n**What it does:**\n\n`autoCapture`\n\n: Automatically stores conversation context after each turn`autoRecall`\n\n: Injects relevant memories before each turn (your agent \"remembers\")- 7 tools: memory_search, memory_store, fact_add, belief_observe, person_resolve, and more\n\nSee `openclaw-plugin/README.md`\n\nfor full configuration options.\n\n```\ncortex/\n├── cortex-core/          # Rust core library (all memory logic)\n│   ├── src/\n│   │   ├── lib.rs              # Cortex entry point\n│   │   ├── types.rs            # MemObject, MemoryTier, etc.\n│   │   ├── inference.rs        # Proactive inference (EN + CN)\n│   │   ├── episode.rs          # Episodic memory store\n│   │   ├── semantic.rs         # Semantic facts + preferences\n│   │   ├── working.rs          # Working memory (session scratch pad)\n│   │   ├── procedural.rs       # Learned routines\n│   │   ├── people.rs           # People graph + identity resolution\n│   │   ├── belief.rs           # Bayesian belief system\n│   │   ├── consolidation.rs    # Episodic→semantic promotion + decay\n│   │   ├── retrieval.rs        # Multi-signal retrieval engine\n│   │   ├── context.rs          # LLM context generation\n│   │   ├── sync/               # Cloud sync (oplog, HLC, merge, encryption)\n│   │   └── storage/            # SQLite + in-memory vector index\n│   └── benches/                # Performance benchmarks\n├── cortex-http/          # HTTP REST API (axum, local-only)\n├── cortex-mcp-server/    # MCP server binary (3.8MB)\n├── cortex-python/        # Python bindings (PyO3, WIP)\n├── openclaw-plugin/      # OpenClaw memory plugin\n├── Dockerfile            # Self-hosted Docker image\n└── Cargo.toml            # Workspace root\n```\n\nCortex ships a lightweight HTTP server for integration with any language or framework. Binds to `127.0.0.1`\n\nby default — your data never leaves your machine.\n\n```\n# Build & run\ncargo build --release -p cortex-http\n./target/release/cortex-http --port 3315 --db ~/.cortex/memory.db\n\n# Or via Docker (pre-built from GHCR)\ndocker run -v ~/.cortex:/data -p 3315:3315 ghcr.io/gambletan/cortex/cortex-http:latest\n\n# Or build locally\ndocker build -t cortex .\ndocker run -v ~/.cortex:/data -p 3315:3315 cortex\n```\n\n| Method | Path | Description |\n|---|---|---|\n| GET | `/health` |\nHealth check |\n| POST | `/v1/memories` |\nIngest a memory |\n| POST | `/v1/memories/search` |\nSemantic search |\n| GET | `/v1/memories/context` |\nGenerate LLM context |\n| POST | `/v1/memories/consolidate` |\nRun consolidation cycle |\n| POST | `/v1/memories/infer` |\nPreview inference (no store) |\n| POST | `/v1/facts` |\nAdd a semantic fact |\n| POST | `/v1/facts/contradictions` |\nCheck for contradictions |\n| POST | `/v1/preferences` |\nSet a preference |\n| GET | `/v1/beliefs` |\nList beliefs |\n| POST | `/v1/beliefs/observe` |\nUpdate belief with evidence |\n| POST | `/v1/people` |\nResolve person identity |\n| POST | `/v1/memories/compress` |\nCompress old conversation sessions |\n| POST | `/v1/relationships/extract` |\nExtract relationships from text |\n| GET | `/v1/export` |\nExport all data (JSON backup) |\n| POST | `/v1/import` |\nImport data from backup |\n\n```\n# Store a memory\ncurl -X POST http://localhost:3315/v1/memories \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"text\": \"I prefer dark mode\", \"channel\": \"cli\"}'\n\n# Search\ncurl -X POST http://localhost:3315/v1/memories/search \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"query\": \"preferences\", \"limit\": 5}'\n\n# Export all data (backup to iCloud, NAS, etc.)\ncurl http://localhost:3315/v1/export > ~/iCloud/cortex-backup.json\n\n# Import from backup\ncurl -X POST http://localhost:3315/v1/import \\\n  -H 'Content-Type: application/json' \\\n  -d @~/iCloud/cortex-backup.json\n```\n\n**v0.2**✅ — Local embedding integration (all-MiniLM-L6-v2/ONNX), batch queries, importance-aware decay + auto-consolidation** v0.3**✅ — Proactive inference (auto-extract facts), temporal awareness, contradiction detection, Chinese NLP** v0.4**✅ — HTTP REST API (axum), import/export (JSON backup), Docker packaging** v0.5**✅ — Conversation compression, relationship inference (EN + CN), temporal retrieval enhancement, 112 tests** v1.0**✅ — Feature comparison table, benchmark update, 18-feature Cortex vs Mem0 vs OpenAI** v1.1**✅ — HNSW vector index (50K search: 12ms → 91µs), Python SDK (`pip install cortex-ai-memory`\n\n)**v1.2**✅ — Negation detection (EN + CN), multi-hop retrieval, 117 tests** v1.3**✅ — Context quality optimization, query expansion, bidirectional relationships, 126 tests** v1.4**✅ — Incremental HNSW, SQL-indexed entity queries, LLM summarizer hook, 18 MCP tools, configurable decay, LLM-assisted inference, 131 tests**v1.5**✅ — Docker image (GHCR auto-publish), batch ingest, dedup, namespace isolation, plugin system, event bus, archival, 351 tests**v1.6**✅ — Int8 quantization (75% storage reduction), materialized column indexes, FTS5 triggers, LRU caches (MemObject + entity-facts), rayon parallel decay, Arc embedding, generation-based cache invalidation, 25 MCP tools, batch inference, enhanced Chinese NLP**v1.7**✅ —** Cloud sync**(changelog-based, HLC ordering, LWW merge),** AES-256-GCM encryption**(Argon2id KDF),** privacy enforcement**(Private/Shared/Public),** zeroize**(memory wiping), SECURITY.md, 27 MCP tools, 400+ tests** v2.0**✅ — Background sync (filesystem watcher + polling), Web Dashboard, Homebrew tap, integration docs (CrewAI/AutoGen/LangGraph/DeerFlow),`/v1/memories/recent`\n\nAPI, 12 rounds Codex review fixes, 489 tests**v2.1**✅ — WASM build (124KB, runs entirely in the browser, GitHub Pages demo)** v2.2**✅ —** Security hardening series**(self-evolution iterations 11–17): manifest + per-operation HMAC, plaintext-injection rejection, timing-attack hardening,**key rotation with forward secrecy**(`ENC2`\n\n),**bounded query budget**,** deny-by-default MCP capability policy**,** per-memory privacy opt-in with cross-device retraction**,** persistent sync (Keychain) + auto background sync**, frecency ranking, one-shot device setup script, 30 MCP tools, 500+ tests** v2.3**— Mobile targets (iOS/Android), multi-modal memory\n\nIf you find Cortex useful, please consider giving it a star ⭐ — it helps others discover the project and motivates continued development!\n\nMIT", "url": "https://wpnews.pro/news/show-hn-cortex-local-first-encrypted-memory-for-ai-agents-rust-mcp", "canonical_source": "https://github.com/gambletan/cortex", "published_at": "2026-06-13 14:00:22+00:00", "updated_at": "2026-06-13 14:17:46.739077+00:00", "lang": "en", "topics": ["ai-agents", "ai-products", "ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["Cortex", "Mem0", "OpenAI", "Claude", "Rust", "WASM", "MCP"], "alternates": {"html": "https://wpnews.pro/news/show-hn-cortex-local-first-encrypted-memory-for-ai-agents-rust-mcp", "markdown": "https://wpnews.pro/news/show-hn-cortex-local-first-encrypted-memory-for-ai-agents-rust-mcp.md", "text": "https://wpnews.pro/news/show-hn-cortex-local-first-encrypted-memory-for-ai-agents-rust-mcp.txt", "jsonld": "https://wpnews.pro/news/show-hn-cortex-local-first-encrypted-memory-for-ai-agents-rust-mcp.jsonld"}}