# cdeust/Cortex [Health: Active]

**Category:** 🧠 Knowledge & Memory  
**Repository:** https://github.com/cdeust/Cortex  
**GitHub Stars:** 71  
**Views:** 2  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/cdeust-cortex

## Description
Persistent memory for Claude Code grounded in computational neuroscience (41 cited papers). Thermodynamic decay, hippocampal-cortical consolidation, predictive-coding write gate, WRRF retrieval. PostgreSQL + pgvector, 33 MCP tools, 7 lifecycle hooks. Benchmarked 97.8% R@10 on LongMemEval. claude plugin marketplace add cdeust/Cortex

## Tools
Capabilities this server exposes over MCP:

- **query_methodology** — Read the user's cognitive profile for the current domain from the cached profiles.json and enrich it with hot memories + any fired prospective triggers matching the current cwd / first_message. Profile fields: thinking style (Felder-Silverman), entry patterns, recurring patterns, blind spots, cross-domain bridges, behavioral feature activations. MANDATORY at session start so subsequent reasoning is calibrated to the user's tendencies. Distinct from `rebuild_profiles` (full rescan from JSONL transcripts, much slower), `detect_domain` (just classifies, no profile body), and `list_domains` (overview across all domains). Read-only on profiles.json; mutates triggered_count for any prospective triggers that fire. Latency <50ms (cached). Returns the full profile dict + hotMemories + firedTriggers, or coldStart=true if no profile exists yet (then call `rebuild_profiles`).
- **detect_domain** — Classify the current working directory + first message into one of the known cognitive domains via a 3-signal weighted score: (1) path tokens (last 3 segments + git root), (2) project ID match against known profiles, (3) keyword overlap with stored domain vocabularies. Returns the best-matching domain plus confidence and the runner-up alternatives. Use this when switching codebases or contexts to recalibrate, or as a cheap preflight before `query_methodology` / `recall`. Distinct from `query_methodology` (returns the FULL profile body, not just the domain id), `list_domains` (enumerates ALL domains), and `rebuild_profiles` (rescans, doesn't classify). Read-only. Latency <20ms. Returns {domain, confidence, alternativeDomains, signals}.
- **rebuild_profiles** — Full rescan of Claude Code session data to rebuild methodology profiles from scratch. Walks ~/.claude/projects/, parses JSONL transcripts, groups by project, and re-derives per-domain cognitive style (Felder-Silverman), entry patterns, blind spots, and cross-domain bridges via the profile_assembler pipeline. Use this on first install, after a major workflow change, or when `query_methodology` returns coldStart=true. Skipped automatically if profiles are <1h old unless force=true. Distinct from `query_methodology` (read the cached profile, no rescan), `record_session_end` (incremental EMA update for one session, no full rebuild), and `detect_domain` (just classifies, doesn't rebuild). Mutates ~/.claude/methodology/profiles.json. Latency <10s on typical histories. Returns {rebuilt_domains, total_sessions, duration_ms}.
- **list_domains** — Read profiles.json and emit an overview row for every cognitive domain Cortex has profiled, sorted by session count. Per domain: id, human label, sessionCount, confidence, lastActive, top-3 work categories with ratios, and dominantMode from the session shape. Use this to discover what domains exist before scoping `recall`, `narrate`, or `rebuild_profiles`. Distinct from `query_methodology` (deep profile for ONE domain), `detect_domain` (classifies the current context, no enumeration), and `memory_stats` (memory-system counts, not domain profiles). Read-only. Takes no arguments. Latency <10ms. Returns {domains: [{id, label, sessionCount, confidence, lastActive, topCategories, dominantMode}], totalDomains, globalStyle}.
- **record_session_end** — Record session-end signals (tools used, duration, turns, keywords) and apply an incremental EMA update to the matching domain's cognitive profile. Also stores an episodic session-summary memory, runs a session self-critique (overall score + top improvement suggestions — each non-empty suggestion is ALSO persisted as its own 'lesson-candidate'-tagged memory, M-D6, so it is never lost the moment this call returns), and creates prospective triggers from any TODO/decision keywords detected in the message stream. Normally invoked automatically by the SessionEnd hook — call manually only when reconstructing offline sessions. Distinct from `rebuild_profiles` (full rescan from scratch, throws away the cache) and `query_methodology` (read-only profile retrieval). Mutates profiles.json + session-log.json + memories table. Latency <200ms. Returns {domain, profile_updated, session_score, critique, lessonCandidatesStored, memory_id?}.
- **explore_features** — Inspect the user's cognitive profile through one of four interpretability lenses (mechanistic-interpretability inspired, Bricken et al. 2023): `features` returns the active sparse-dictionary behavioral features for a domain; `attribution` perturbation-traces which input signals drove the domain's profile, sampling up to 20 of that domain's own recent sessions from disk (empty graph if the domain has no indexed sessions -- run rebuild_profiles first); `persona` returns the 12D persona vector with drift-from-baseline; `crosscoder` compares two domains to detect persistent behavioral features. Use this when facing an unfamiliar pattern and you want a behavioral explanation. Distinct from `query_methodology` (full profile, not the interpretability internals) and `list_domains` (overview, no analysis). Read-only on profiles.json. Latency <100ms. Returns mode-specific JSON: {dictionary | graph | persona | comparison}.
- **remember** — Store a memory through the flat 4-signal predictive-coding write gate (embedding, entity, temporal, and structural novelty — Friston-inspired prediction-error gating). Novel surprising content passes; redundant content is rejected or merged with the most-similar existing memory via active curation. After write: thermodynamic tagging, knowledge-graph entity extraction, neuromodulation (DA/NE/ACh/5-HT), engram allocation. FOR A DURABLE CLAIM (a fact, decision, or lesson meant to outlive this session), include a checkable reference in `content` — a file path, a git commit SHA, a URL, or a content-addressed artifact digest — so it can grade above 'unverifiable' (see the `provenance` response field and coding-standards.md §8, 'no source, no implementation'); testimony without one is still stored, just graded accordingly. Use this after any non-trivial discovery, fix, decision, or lesson — if it would surprise a future session, store it. Distinct from `anchor` (pins an EXISTING memory, doesn't create), `wiki_write` (creates an .md page, not a memory row), `validate_memory` (re-grades EXISTING memories with network-verified checks, not a write path), and `add_rule` (recall-time filter, not stored content). Mutates memories + entities + relationships tables. Latency ~50-100ms. Returns {stored, memory_id, action: stored|merged|rejected, reason, provenance}.
- **recall** — Retrieve memories from the Cortex store using intent-adaptive PG recall (server-side WRRF fusion of vector + FTS + trigram + heat + recency) followed by FlashRank cross-encoder reranking and production enrichments (prospective memory injection, Hebbian co-activation strengthening, neuro-symbolic rules, strategic ordering to mitigate Lost-in-the-Middle, Liu et al. 2023). Use this before any non-trivial work to check what Cortex already knows; running blind is unacceptable when recall takes ~200ms. Distinct from `recall_hierarchical` (returns the L0/L1/L2 cluster topology, not a flat ranked list), `navigate_memory` (graph BFS over co-access edges from one seed memory), and `get_causal_chain` (entity-graph traversal, not memory recall). Not read-only: every returned memory is recorded as a hippocampal replay event — access_count/replay_count increment and hippocampal_dependency decays (CLS-B, Ketz et al. 2023) — so repeat calls are not idempotent (`track_replay_event`, `replay_tracking.py`). Returns ranked memories with scores, heat, and source.
- **memory_stats** — Aggregate population diagnostics for the memory system: total / episodic / semantic / active / archived / stale / protected memory counts, average heat, entity and relationship totals, active prospective triggers, last consolidation timestamp, and vector-search availability (pgvector). Use this for health checks, dashboards, or before/after a `consolidate` run to verify cycles fired. Distinct from `assess_coverage` (scored 0-100 with recommendations, this is raw counts), `detect_gaps` (enumerates specific missing things), and `list_domains` (per-domain profile rows, not memory counts). Read-only. Takes no arguments. Latency ~75ms (includes the grooming-staleness ages below). Returns {total_memories, episodic_count, semantic_count, active_count, archived_count, stale_count, protected_count, avg_heat, total_entities, total_relationships, active_triggers, last_consolidation, has_vector_search, grooming_staleness}. `grooming_staleness` carries last-run age (days) for the three judgment-level grooming kinds (wiki/distillation/promotion) against a sourced threshold -- ages only, no backlog counts (those cost ~1s combined; call `get_grooming_health` for the full picture).
- **checkpoint** — Hippocampal-replay-style save/restore of whole working state across context compaction events (McClelland 1995). `save` writes a checkpoint row capturing current task, files-being-edited, key decisions, open questions, planned next steps, and active errors, tied to the current epoch. `restore` reconstructs post-compaction context by fusing the latest checkpoint with anchored + hot + directory-relevant memories. Use `save` before risking compaction; use `restore` immediately after. Distinct from `anchor` (per-memory pinning, no task state), `remember` (creates one memory, no whole-state snapshot), and `query_methodology` (cognitive profile, not session state). Mutates the checkpoints table on save; read-only on restore. Latency ~50ms (save) / ~100ms (restore). Returns {action, checkpoint_id, restored_context?, memories_attached}.
- **narrative** — Generate a coherent project narrative from stored memories for a directory or domain. Clusters memories by topic + time, identifies the through-line, and renders either a multi-section story or (when `brief=true`) a one-paragraph executive summary. Use this for status updates, README seeds, or to onboard a new contributor with the project's actual history. Distinct from `get_project_story` (period-bucketed chronological chapters with explicit time ranges), `assess_coverage` (numeric score, no prose), and `recall` (raw ranked memories). Read-only. Latency ~300-800ms. Returns {narrative, memory_count, themes}.
- **consolidate** — Run scheduled memory-system maintenance cycles: thermodynamic heat decay, full-text → gist → tag compression, episodic→semantic CLS transfer (McClelland 1995), synaptic plasticity LTP/LTD (Hebb 1949, Bi & Poo 1998), microglial pruning of orphan edges (Wang 2020), homeostatic scaling (Turrigiano 2008), cascade stage advancement (Kandel 2001), and optional deep-sleep replay. Each cycle is delegated to a focused sub-module under handlers/consolidation/; durations are tracked per stage with partial-failure rollup. Use this on a daily/weekly cadence (or after large ingest bursts) to keep recall fast and the heat distribution healthy. Distinct from `wiki_consolidate` (operates on wiki PAGES not memories) and `forget` (one-off deletion, no lifecycle). Mutates memories + entities + relationships tables. Latency varies (~5-60s typical, deep mode minutes). Returns per-cycle counters, duration_ms per stage, status (ok|partial), and failed_stages list. The `cls` and `memify` stages include `reason_for_zero` / `reason_for_inaction` when the cycle produces no mutations, distinguishing early-return from a genuine quiet-store pass (issue #14 P2).
- **import_sessions** — Import Claude Code conversation history from ~/.claude/projects/ into the memory store. Walks JSONL session files, extracts memorable items (decisions, errors-and-fixes, architecture notes, key insights) via session_extractor, and routes each through the `remember` write gate (thermodynamics, hierarchical predictive coding, knowledge graph, engram allocation). Supports project / domain filtering and dry-run preview. Use this for an initial bootstrap or to ingest sessions from another machine. Distinct from `backfill_memories` (preferred for incremental, hash-tracked re-runs over the same source), `seed_project` (codebase structure), and `codebase_analyze` (source files). Mutates memories + entities + relationships tables. Latency varies (~1-30min depending on history size). Returns {sessions_processed, memories_imported, dry_run, errors}.
- **unified_search** — Unified search across Cortex memories and the automatised-pipeline code graph (ADR-0046 Phase 3). Runs cortex.recall and ap.search_codebase in parallel, then merges via Reciprocal Rank Fusion (k=60, Cormack 2009). Returns a single ranked list with ``source_ranks`` on every record so the UI can explain where each hit came from. Falls back to Cortex-only when AP is disabled (CORTEX_MEMORY_AP_ENABLED=0) or unreachable (status=partial).
- **get_telemetry** — Return the in-process telemetry snapshot: per-op call counts, latency, byte volume, success/failure split, and the computed read/write ratio. Use this to verify Cortex's empirical read/write workload distribution (Popper C6 — grounds the paper's '100x more reads than writes' claim in measurement, not assertion). Counters are per-process and reset on restart; the durable record is the JSONL at ~/.claude/methodology/telemetry.jsonl.
- **get_grooming_health** — Backlog size and staleness age for the three judgment-level grooming planners (curate_wiki, curate_distill, lesson_promotion) — distinct from `consolidate`'s mechanical wiki maintenance (purge/backfill/dashboards, which already self-reports and needs no staleness alarm). For each kind, returns the exact eligible-backlog count and how long ago that kind of grooming last actually executed (None = never). `stale=true` when a kind has gone longer than `threshold_days` (sourced from measured session cadence, see core.grooming_health) without running, or has never run at all. Read-only. Latency ~1s (curate_distill + curate_wiki are themselves bounded-scan planners, not indexed aggregates — this tool is meant for explicit on-demand health checks, not the SessionStart hot path).
- **forget** — Delete a memory by integer ID via direct DELETE on the memories table (hard) or by setting is_stale=true + heat=0 (soft, recoverable via SQL). Protected/anchored memories are refused unless force=true. Use this to remove genuinely-wrong memories or accidental captures. Distinct from `rate_memory(useful=false)` (downweights without removing — prefer for low-value memories), `anchor` (protect from deletion), and `validate_memory` (mark stale based on filesystem refs, not user verdict). Mutates the memories table; hard delete is irreversible. Latency ~10ms. Returns {deleted, method, memory_id, content_preview, reason?}.
- **validate_memory** — Graded provenance verifier (I6-D6): checks every reference a memory makes — file paths, git commit SHAs, URLs (bounded HEAD sample), content-addressed artifact digests (sha256[:16] recomputation) — and citations (DOI/arXiv, recognized but never auto-verified). Writes two things: (1) is_stale, from FILE PATHS ONLY (URLs/commits/digests never feed the staleness score — a dead URL does not invalidate a historical fact); bidirectional since I6-D6, a stale memory whose file refs all resolve again is rehabilitated back to is_stale=false. (2) source_attribution, a provenance grade in {verified, verifiable, unverifiable} — the worst outcome among the memory's checkable references. This handler is the sole writer of that grade; it overwrites any prior value on each verification pass. All-memories scope is cursor-paginated via after_id, 1000 per call (below the full active-store size on large corpora — page with the returned next_after_id). Use this after large refactors, file moves, or before a recall that must not return dead links. Scope to one memory, a domain, a directory, or all memories. Distinct from `forget` (deletes memories outright), `rate_memory` (user verdict on usefulness, not filesystem reality), and `wiki_consolidate` (wiki pages, not memories). Mutates is_stale and source_attribution unless dry_run=true. Latency varies (~100ms-30s depending on scope, ref count, and URL sample size). Returns {validated, stale_found, stale_updated, destaled, graded, dry_run, next_after_id, reports: per-memory breakdown}.
- **rate_memory** — Record a usefulness verdict for a memory that just surfaced in recall: increments useful_count when helpful and recomputes metamemory confidence as useful_count / access_count (Nelson & Narens 1990 framework). High-confidence memories resist heat decay and rank higher in future recalls; persistently unhelpful memories drift toward archival. Use this whenever a recalled memory either solved the problem or wasted attention — the feedback loop is what keeps recall accurate. Distinct from `forget` (deletes), `anchor` (pins, doesn't score), and `validate_memory` (filesystem-ref staleness, not user verdict). Mutates the memories table (access_count, useful_count, confidence). Latency ~20ms. Returns {rated, memory_id, useful, access_count, useful_count, confidence, content_preview}.
- **seed_project** — Bootstrap the memory store from an existing codebase via a five-stage structural sweep — each discovery is stored through the standard `remember` write gate. Distinct from `codebase_analyze` (tree-sitter AST per file, much deeper, slower), `backfill_memories` (Claude Code conversation transcripts, not the codebase itself), `wiki_seed_codebase` (seeds the wiki tree from existing markdown, not memories), and `ingest_codebase` (downstream consumer of analyzer output). Latency varies (~5-60s depending on tree size). Stages: (1) config extraction (package.json, pyproject.toml, Cargo.toml, go.mod...), (2) documentation harvesting (README, CLAUDE.md, docs/, ADRs, changelogs), (3) entry-point scan (main.py, index.js, cmd/, __main__.py), (4) CI/CD detection (.github/workflows, Makefile, Dockerfile, tox.ini), and (5) structural summary (top-level layout, language detection, module map). Each discovery is stored via remember (subject to the write gate). Use this on first onboarding to a project. Returns counts and stored memory IDs.
- **anchor** — Mark a memory as compaction-resistant by setting heat=1.0, is_protected=true, importance=1.0, and adding an `_anchor` tag — so the memory survives context compaction, heat decay, and consolidation pruning, and cannot be deleted without force=true. The optional reason is stored as an `[ANCHOR: ...]` content prefix for audit. Use this for critical facts, active architectural decisions, and operating principles that must persist across session boundaries. Distinct from `rate_memory` (raises confidence via metamemory, doesn't pin), `remember` (creates memories, doesn't pin), and `checkpoint` (whole-state snapshot, not per-memory). Mutates the memories table. Latency ~20ms. Returns {anchored, memory_id, content_preview} or {error}.
- **backfill_memories** — Import prior Claude Code conversations from ~/.claude/projects/ into the memory store. Walks JSONL session transcripts, extracts memorable items (decisions, lessons, errors-and-fixes) via the session_extractor, stores them with `backfill` tags via `remember(force=True)` — which BYPASSES the predictive-coding write gate, not the standard write path — and links each to the auto-discovered core concepts of the originating project. Idempotent only at the file level: hashes tracked in backfill_log so a plain re-run skips already-processed files. NOT idempotent overall — `force_reprocess=true` re-imports a file's items with the gate still bypassed, which can create duplicate memory rows. Use this on first install, after long absences, or when migrating to a new machine. Distinct from `import_sessions` (more granular control, manual file selection), `seed_project` (codebase structure, not conversation history), and `codebase_analyze` (source files, not transcripts). Mutates memories + backfill_log tables. Latency varies (~30s-10min depending on history size). Returns {sessions_processed, sessions_skipped, memories_imported, errors}.
- **codebase_analyze** — Walk a codebase and store its structure as memories using tree-sitter AST parsing (with regex fallback for unsupported languages). One memory per file, with symbols as entities and imports as relationships; then cross-file symbol resolution, call-graph extraction, and community detection over the call graph. Incremental — only re-processes files whose content hash changed since last run (tracked via HASH_TAG_PREFIX tags). Use this on first onboarding to a serious codebase, or after a major refactor that invalidates symbol assumptions. Distinct from `seed_project` (5-stage shallow structural sweep, no AST), `backfill_memories` (Claude Code conversations, not source files), `wiki_seed_codebase` (seeds wiki pages from .md docs), and `ingest_codebase` (downstream PRD-generator consumer, and the PRIMARY ingestion path when the automatised-pipeline upstream is reachable — this tool is its explicit fallback, per ADR-0052 sec 2; every written memory carries a src:native provenance tag, and the response states fallback_status so a run made while AP is reachable is never silent). Mutates memories + entities + relationships tables. Latency varies (~10s-10min depending on tree size). Returns {files_analyzed, files_skipped, memories_written, entities_created, relationships_created, fallback_status}.
- **check_setup** — Verify the local Cortex installation before first interactive use. Runs the identical check functions as `python -m mcp_server.doctor` (no duplicated logic), backend-aware. PostgreSQL backend: Python >= 3.10, psycopg/psycopg_pool/pgvector driver imports, DATABASE_URL set, live PostgreSQL connection, pgvector + pg_trgm extensions, ~/.claude/methodology writability, I10 pool-capacity invariant, and an optional automatised-pipeline codebase-tool probe. SQLite backend (zero-config default): the PG checks are replaced by a single SQLite store-open check. Checks run in doctor's own dependency order, so an early failure (e.g. missing DATABASE_URL) explains later ones (e.g. no PG connection) -- fix in list order. Call this once before first session, or whenever diagnosing a setup problem. Read-only but reaches outside the DB (env vars, filesystem, a live connection attempt). Takes no arguments. Returns {ready, summary, fixes_needed, checks: [{name, ok, optional, detail, fix_command}]}. `ready` is true iff every non-optional check passed; the codebase-pipeline probe is optional and never blocks readiness.
- **recall_hierarchical** — Retrieve memories via the fractal three-level hierarchy (L0=individual memories, L1=topic clusters, L2=root clusters), with adaptive level weighting from query length: short queries weight toward broader L2 clusters (you're scanning a topic), long queries toward specific L0 memories (you have a precise question). REQUIRES either `domain` or `memory_ids` to bound the tree build — the uncapped fallback was removed in v3.13.0 because clustering is O(N^2) in the candidate set (infeasible past ~5K memories, see ADR-0045 R3). Use this instead of `recall` when you want the topology of the memory space, not just a flat ranked list. Distinct from `recall` (flat WRRF result, no hierarchy), `drill_down` (consumer of this tool's output, navigates one level deeper into a returned cluster), and `navigate_memory` (graph traversal, not cluster tree). Not read-only: every surfaced memory is recorded as a hippocampal replay event — access_count/replay_count increment and hippocampal_dependency decays (CLS-B, Ketz et al. 2023) — so repeat calls are not idempotent (`track_replay_event`, `replay_tracking.py`). Latency ~150-300ms on domain-scoped calls. Returns {hierarchy: [{cluster_id, level, label, score, members?}], total_clusters}.
- **drill_down** — Descend one level into a fractal memory cluster previously returned by `recall_hierarchical`: an L2 root cluster expands to its L1 sub-clusters; an L1 cluster expands to the individual memories it contains (full content, heat, tags). Cluster IDs use the form `L<level>-<index>`. Use this for interactive top-down exploration — start broad with `recall_hierarchical`, then drill the most-relevant cluster repeatedly until you reach memories. Distinct from `recall` (flat ranked list, no hierarchy), `navigate_memory` (graph BFS via co-access edges, not cluster tree), and `recall_hierarchical` (entry point that builds the tree). Not read-only: every surfaced memory is recorded as a hippocampal replay event — access_count/replay_count increment and hippocampal_dependency decays (CLS-B, Ketz et al. 2023) — so repeat calls are not idempotent (`track_replay_event`, `replay_tracking.py`). Latency <100ms. Returns {cluster_id, level, children: [{id, label, members?, content?}]}.
- **navigate_memory** — Traverse the memory space via a Successor Representation graph (Dayan 1993) built from temporal co-access — pairs of memories accessed within `window_hours` of each other become weighted edges. Starting from a seed memory_id, BFS outward up to `max_depth` (capped at 4) and return neighbors with SR distances. Use this to follow a thread of thinking, explore latent associations, or discover what a topic touches that you didn't know about. Distinct from `recall` (semantic vector + lexical search, no temporal-proximity edges), `get_causal_chain` (entity knowledge-graph BFS, not memory-level co-access), and `drill_down` (fractal cluster tree, not graph). Not read-only: every returned memory (the seed plus each traversed neighbor) is recorded as a hippocampal replay event — access_count/replay_count increment and hippocampal_dependency decays (CLS-B, Ketz et al. 2023) — so repeat calls are not idempotent (`track_replay_event`, `replay_tracking.py`). Latency ~100-300ms depending on depth + 2D-map flag. Returns {seed, neighbors: [{memory_id, distance, content_preview}], map_2d?: [{x, y, id}]}.
- **get_causal_chain** — Walk the Cortex knowledge graph (entities + typed relationships extracted from memory content) via bounded BFS from a seed entity or from every entity in a given memory. Returns chains of causation, dependency, and resolution — useful for understanding why a bug occurred, tracing the origin of a decision, or following imports across modules. Use this when you have a symptom and want the upstream cause, or a cause and want all downstream impact. Distinct from `navigate_memory` (memory-level co-access SR graph, not entity relationships), `recall` (no graph traversal), and `drill_down` (cluster tree, not graph). Read-only. Latency ~100-300ms depending on max_depth/edges. Returns {nodes, edges, paths} capped at max_edges.
- **detect_gaps** — Surface knowledge gaps across four axes: isolated entities (referenced in memories but with zero relationships, cap 10), sparse domains (entity count under 50% of the cross-domain average, cap 5), temporal drift (domains whose most-recently-accessed memory — sampled from up to 10 per domain — exceeds `stale_threshold_days`, cap 5), and cognitive blind spots (per-domain category/tool/pattern gaps from the profile-based blindspot detector, capped to the first 5 domains and 3 spots each). Does not detect duplicates, contradictions, or domainless/sourceless memories. Use this when planning research priorities or auditing coverage. Distinct from `assess_coverage` (numeric coverage SCORE 0-100 per axis, no specific gap list), and `memory_stats` (population counts only, no gap interpretation). Read-only. Latency ~500ms-2s depending on store size. Returns {total_gaps, gaps: [{gap_type, ...}], by_type: {gap_type: count}, domain_filter}.
- **recall_skills** — Retrieve learned procedures (recurring successful tool-use sequences) that apply to the current situation — domain, working directory, and recent actions. Procedural memory is retrieved by SITUATION, not by content similarity, which is what distinguishes it from recall_memories (episodic/semantic). Read-only; returns each skill's action sequence, proficiency, use count, and a human-readable rationale. Additive surface — does not alter declarative recall.
- **why** — Blame path resolver (decision 4255039): turn the ⟦rcpt:N⟧ markers visible in the current context into presence-in-context evidence — which memories each injection channel (recall, session_start, auto_recall, agent_briefing) put into the context, when, at which persisted rank and score. This is evidence of PRESENCE, never causality. Protocol: collect the ⟦rcpt:N⟧ markers that were in context BEFORE the answer being questioned; EXCLUDE the marker injected alongside the current prompt's own memory block (self-pollution guard) — then pass the ids here. To correct a wrong memory surfaced by the evidence, store a superseding memory with remember. Deterministic entry point: the /why slash command. Distinct from `get_causal_chain` (entity-graph traversal over inferred relations) and `recall` (similarity retrieval): why replays RECORDED injection receipts only.
- **sync_instructions** — Render the project's top hot memories (decisions, patterns, conventions, lessons) as bullets and write them into CLAUDE.md between `<!-- cortex:memory-insights:start -->` markers — adding the section if absent, refreshing it in-place if present. Closes the loop between Cortex's thermodynamic memory and the Claude Code instruction file loaded at every session start, so the next session begins informed without manual querying. Use this after a productive session, or on a periodic schedule. Distinct from `recall` (transient API response, not persisted to file), `narrative` (prose summary, not actionable bullets), and `anchor` (per-memory pinning, no CLAUDE.md write). Mutates the CLAUDE.md file in `directory`. Latency ~200ms. Returns {written, path, insight_count, dry_run, preview?}.
- **create_trigger** — Create a prospective-memory trigger that Cortex auto-fires when its condition matches future context (Einstein & McDaniel 2005). Trigger types: `keyword` (fires when user message contains string), `time` (fires after ISO datetime), `file` (fires when path is accessed/modified), `domain` (fires when that cognitive domain becomes active). Triggers are checked at session start (via `query_methodology`) and on demand. Use this to leave instructions for a future session — `next time we touch X, remember Y` — that you would otherwise forget. Distinct from `add_rule` (passive recall filter applied to ALL queries, no context-match firing), `anchor` (pins a memory but doesn't fire), and `remember` (records a fact, doesn't activate on context). Mutates the prospective_memories table. Latency ~30ms. Returns {trigger_id, trigger_type, trigger_condition, content_preview}.
- **add_rule** — Insert a neuro-symbolic rule into memory_rules so the `apply_rules` engine applies it on every subsequent recall — hard rules EXCLUDE matching memories, soft rules boost/penalize their rank, tag rules attach a tag. condition is '<field> <operator> <value>' (operators: ==, !=, contains, not_contains, >, <, >=, <=, matches — field may be a memory attribute like importance/heat, or 'tag'/'tags' to match against the tags list). action is 'filter' (hard only), 'boost:<float>' or 'penalty:<float>' (soft only), or 'tag:<name>' (tag only). Rejected outright (created=False) if the condition or action does not parse, or if the action's mechanism does not match rule_type. Scopes: global, domain, directory; resolved by priority then specificity. Use this to encode operating principles like `never surface deprecated memories` (condition='tag contains deprecated', action='filter', rule_type='hard') or `boost lessons in the recall pipeline` (condition='tag contains lesson', action='boost:0.3', rule_type='soft'). Distinct from `create_trigger` (proactive prospective memory, fires on context match — not a recall filter), and from `anchor` (per-memory pin, not a population rule). Mutates the memory_rules table; effect is visible at the next `recall` call. Latency ~20ms. Returns {rule_id, condition, action, scope, priority}.
- **get_rules** — Enumerate active neuro-symbolic rules in the memory_rules table, optionally filtered by scope (global/domain/directory) or rule_type (hard=filter, soft=rerank, tag=attach metadata). Use this to audit which rules are shaping recall before adding a new one or debugging unexpected results. Distinct from `add_rule` (creates) and `forget` (deletes a memory, not a rule). Read-only. Latency ~30ms. Returns {rules: [{id, scope, scope_value, rule_type, condition, action, priority, active, created_at, source_memory_id}]}. source_memory_id (M-D6) is the lesson memory a rule was promoted from via `lesson_promotion`, or null for directly-created rules.
- **get_project_story** — Generate a period-based autobiographical narrative by bucketing memories chronologically into chapters within a time window (day / week / month / all) — produces a timeline of what actually happened, in order. Use this for retrospectives, status updates, sprint reports, or to brief a collaborator on what they missed. Distinct from `narrative` (generic project summary, no time buckets, no chronology), `assess_coverage` (numeric score, no story), and `recall` (raw memory list, no narrative synthesis). Read-only. Latency ~300-800ms depending on memory count and period. Returns {period, chapters: [{time_range, theme, key_decisions, memory_ids, summary}]}.
- **assess_coverage** — Score the memory store itself across five signals: quantity (scoped memory count vs a 100-memory reference), age distribution (fresh vs stale), entity density (total store entities / scoped memory count — a corpus-wide ratio, not a true per-memory measure), domain balance (distribution of scoped memories across domains), and compression ratio (penalty for compressed content). There is no axis scoring which project source files are remembered. The weighting constants combining these into the 0-100 score are hand-picked, not paper- or benchmark-sourced (coding-standards §8 debt). Emits actionable recommendations (e.g., `run validate_memory`, `run consolidate`). Use this as a memory-store health check. Distinct from `detect_gaps` (lists specific missing connections, no aggregate score), `memory_stats` (raw counts, no scoring), and `narrative` (prose summary, no numeric coverage). Read-only. Latency ~500ms-1s. Returns {coverage_score, total_memories, age_distribution, entity_density, compression, domain_balance, recommendations, directory, domain}.
- **curate_wiki** — Auto-curator: returns structured authoring jobs the in-session LLM (Opus 4.7) consumes to author curated wiki pages from PG memory clusters. Each job carries one cluster's memories, the suggested wiki path, a list of existing related pages for cross-linking, and a complete structured prompt that encodes the wiki documentation conventions (frontmatter, lead, diagrams, 'why this not the alternatives', 'what can go wrong', 'see also', primary sources). The conversational LLM reads each job, authors the page in Markdown, and writes it via `wiki_write`. No external Anthropic API key required — the user's existing Claude Code session is the authoring LLM. Distinct from `wiki_write` (the writer; this is the planner), `narrative` (one summary; this is N pages), and `consolidate` (memory maintenance; this is documentation production). Read-only with respect to PG and wiki. Latency ~300ms for k=5 jobs. Returns {jobs: [{cluster, prompt, suggested_path, related_pages}], total_clusters_eligible, instructions}.
- **lesson_promotion** — Propose promotion jobs for lessons (memories tagged 'lesson' or 'lesson-candidate') that have demonstrated usage evidence (recalled or rated useful at least once). Each job carries the lesson's memory_id, content, and a heuristic suggested_kind ('rule'|'trigger'|'wiki') the in-session LLM may follow or override. The server NEVER calls add_rule/create_trigger/wiki_write itself — a rule reshapes every future recall, so the decision stays with the reviewer. Distinct from `curate_wiki` (wiki authoring jobs from memory clusters, not lesson promotion), `add_rule`/`create_trigger`/`wiki_write` (the actual promotion actions this handler only proposes), and `assess_coverage`/`detect_gaps` (read-only audits with no actionable job queue). Read-only. Latency ~30ms. Returns {jobs: [{memory_id, content, suggested_kind, tags, useful_count, access_count}], candidate_count, instructions}.
- **curate_distill** — Auto-distiller: returns structured jobs the in-session LLM consumes to author understanding-level 'lesson' memories from PG memory dossiers (error->success pairs, recurring co-access families, entity-cohesive clusters). Each job carries a dossier's memory_ids, a marker tag for idempotence, and a complete prompt naming the required `remember` call shape (tags=['lesson', <marker>, 'derived-src:<id>', ...], write_class='deliberate'). The conversational LLM reads each job, decides whether the sources justify a durable lesson, and writes it via `remember` — or skips the dossier. No server-side write happens here. Distinct from `curate_wiki` (wiki PAGES; this is memory-level LESSONS) and `consolidate`'s `memify` stage (memify_derive synthesizes templated inventory facts server-side with no LLM judgment; this delegates judgment to the LLM, per M-D8). Also returns `memify_derive_usage`: a read-only snapshot (count/access/useful) of memify_derive's existing 'derived'-tagged output, for the 30-day keep/retire measurement M-D8 requires. Read-only. Latency ~200-500ms. Returns {jobs: [{job_type, dossier_kind, memory_ids, marker, prompt}], total_dossiers_eligible, memify_derive_usage, instructions}.
- **wiki_write** — Author a new wiki page or append/replace content on an existing one (kind inferred from the first path segment: adr, specs, files, notes, lessons, conventions, guides, reference, journal). Pages live under ~/.claude/methodology/wiki/, written atomically via tmp+rename. After a successful write, registers a protected PG pointer memory tagged `wiki` so the page surfaces in `recall`. Use this for any document that should outlive the session — lessons, conventions, runbooks, anything you might link from a future ADR. Distinct from `wiki_adr` (auto-numbered ADRs from structured Context/Decision/Consequences), `wiki_compile` (publishes already-curated drafts), and `remember` (no markdown page, just a memory). Mutates the wiki/ tree, the memories table, wiki.pages (synced synchronously so the page has a resolvable id immediately), and — when `memory_ids` is passed — wiki.citations (one deduplicated row per memory actually used to author the page; how a curate_wiki job's memory cluster becomes durable, queryable provenance). Latency ~50ms. Returns {path, mode, created, bytes_written, root, citations_written} or {error}.
- **wiki_read** — Fetch the raw markdown source of one wiki page by its wiki-relative path. Path resolution is sandboxed under the wiki root — absolute paths and `../` traversal are rejected at the storage layer. When the page is a redirect stub (frontmatter ``redirect_to:`` or ``redirect_id:``) the chain is followed transparently up to 5 hops; cycles and dangling targets surface as errors. Pass ``follow_redirects: false`` to read the stub itself. Page content is filesystem-only and always returned even if PostgreSQL is unreachable. As an explicit side effect, a successful read within a known Claude Code session records one deduplicated wiki.citations row (page, session) — the primary authority-earning signal driving page heat/citation_count; best-effort, never blocks or fails the read (no window session, PG down, or a page never compiled into PG all degrade to 'read succeeds, no citation'). Distinct from `wiki_list` which enumerates available pages, and from `wiki_export` which renders a page through Pandoc to PDF/DOCX/HTML. Latency <10ms. Returns {path, content, content_length, offset, root, redirect_chain} or {error}. Pages larger than the response budget come back with ``content_truncated: true`` — page via the ``offset`` argument.
- **wiki_list** — Enumerate every authored wiki page under ~/.claude/methodology/wiki/, filesystem-walked from the wiki root. Optionally restrict by kind (adr, specs, guides, reference, conventions, lessons, notes, journal, files). Two filters are applied by default and can be opted out of: (1) redirect stubs (frontmatter ``redirect_to:`` or ``redirect_id:``) are excluded — pass ``include_redirects: true`` to see them; (2) auto-generated pages (frontmatter ``provenance: auto-generated``, produced by ``codebase_analyze``) are excluded — pass ``include_auto_generated: true`` to see them. Read-only; never modifies anything. Distinct from `wiki_reindex` which generates the .generated/INDEX.md from the same enumeration, and from `wiki_read` which fetches one page's content. Latency <200ms on a 9000-page wiki because each page's frontmatter is read once for both filter checks. Returns {root, count, pages, redirect_count, auto_generated_count}.
- **wiki_link** — Add a bidirectional link between two wiki pages: write the forward relation into the `## Related` section of the source page and the inverse relation into the target page, in one idempotent operation. Use this to record dependencies, derivations, supersession chains, or free-form `see also` connections between knowledge artefacts. Distinct from `wiki_write` (authors a page, doesn't link), `wiki_compile` (publishes drafts, doesn't link), and graph-relationship tools (this writes markdown sections, not DB edges). Mutates two .md files atomically. Latency ~30ms. Returns {from_path, to_path, forward_relation, inverse_relation}.
- **wiki_adr** — Create a numbered ADR (Architecture Decision Record) from structured Context/Decision/Consequences fields. Atomically: computes the next free ADR number, renders the standard template, writes wiki/adr/<NNNN>-<slug>.md under the wiki root, and registers a protected pointer memory tagged `wiki`+`adr` so the decision surfaces in `recall`. Use this whenever a non-trivial architectural choice is made — the resulting page is the single citable source of truth. Distinct from `wiki_write` (raw markdown, no auto-numbering, no template), and from `remember` (memory only, no .md file). Mutates the wiki/ tree and the memories table; refuses if the target file already exists. Latency ~50ms. Returns {path, number, title, status, created, bytes_written, root} or {error}.
- **wiki_reindex** — Regenerate the wiki table of contents at <wiki_root>/.generated/INDEX.md by enumerating every authored page and grouping it by kind (adr, specs, guides, reference, conventions, lessons, notes, journal, files). Redirect stubs are excluded; auto-generated pages (``provenance: auto-generated``) are surfaced in a separate ``Auto-generated reference`` section after the human-authored content so they don't dominate the main listing (Phase 5 of ADR-2244). Output is deterministic — sorted by kind then path so unchanged wikis yield byte-identical INDEX files. Authored pages are never touched; the only file written is INDEX.md, atomically via tmp+rename. Use this after bulk wiki edits, imports, or `wiki_compile` runs. Distinct from `wiki_list` (returns the listing in the response, no file write) and from `wiki_consolidate` (heat decay / staleness, not ToC rebuild). Takes no arguments. Latency <500ms on a 9000-page wiki. Returns {path, total_pages, by_kind, auto_generated_by_kind, redirect_count, root}.
- **wiki_purge** — Purge wiki pages that no longer earn their place. Two reject axes: (1) the page no longer passes the current classifier (`core/wiki_classifier`) — used after tightening rules or a polluting backfill; (2) the page is a stub — body is majority placeholder markers (_(to be filled)_ / _To be written._ / _(none identified)_), produced by the groomer or by template_v1 synthesis. Stubs masquerade as content but carry none. Memories remain in the store (still surface via `recall`); only the wiki markdown files are removed from disk. Distinct from `wiki_consolidate` (heat decay + lifecycle, doesn't delete based on classifier), `forget` (deletes a memory, not a wiki page), and `wiki_compile` (publishes drafts, doesn't purge). Defaults to dry-run; pass apply=true to actually delete. Latency ~200-500ms. Returns {kept, purged, purged_paths, purged_reasons, dry_run}.
- **wiki_verify** — Verify that code symbols cited by wiki pages still resolve in the AST (via the automatised-pipeline MCP server, ADR-0046 Phase 2). Takes an optional path (verify one page) or no args (verify every authored page) and returns per-page verdicts: {page, symbol_refs, missing_refs, is_symbol_stale, rationale}. Requires AP enabled (CORTEX_MEMORY_AP_ENABLED=1, the default); when disabled the handler returns status=skipped and never produces a stale verdict. Read-only — never mutates wiki or memory state.
- **wiki_rename** — Move a wiki page from ``from_path`` to ``to_path`` and leave a redirect stub at the old location pointing to the new one. Phase 3.2 of ADR-2244 — the move preserves inbound links because ``wiki_read`` follows redirect stubs transparently. Refuses to operate on pages without a stable ``id`` field (run ``scripts/wiki_backfill_ids.py`` first) or on existing redirect stubs. Returns {from_path, to_path, page_id, stub_created}.
- **wiki_migrate** — One-shot idempotent sync of the filesystem wiki (~/.claude/methodology/wiki/) into wiki.pages / wiki.links / wiki.page_sources. Walks every PAGE_KINDS directory, upserts each page keyed on rel_path (body_hash guards no-op re-writes), re-resolves [[slug]] links, then reconciles: any wiki.pages row whose rel_path no longer exists on disk (deleted file, rename, or a wiki_purge run — which only touches the FS, never PG) is purged from wiki.pages, cascading via FK ON DELETE CASCADE to wiki.links and wiki.page_sources. The `_`-prefixed kind dirs (_kinds/_rules/_views/_bibliography/_dashboards) and the root README.md are outside the scan entirely on both phases, so they are never upserted and never purged. Defaults to dry_run=true (report the ghost rel_paths without deleting); pass dry_run=false to actually purge. Distinct from `wiki_purge` (deletes FS files that fail the classifier, never touches PG) — this tool never touches the FS, only reconciles PG to match it. A frontmatter status outside wiki.pages' DB CHECK union falls back to 'seedling' and is reported in warnings (never blocks the page write). Returns {pages_processed, pages_written, pages_unchanged, links_written, links_resolved_pass3, purge: {dry_run, ghost_count, ghost_paths, purged}, errors, error_count, warnings, warning_count}.
- **ingest_findings** — Ingest an automatised-pipeline (AP) findings run into Cortex's store. Reads runs/<run_id>/ artifacts directly off disk (no network call to AP — AP never pushes, ADR-0052 D1). Verified findings (stage-2 verified:true) get a wiki page under reference/findings/, file-source links (wiki.page_sources, link_kind='finding' for code files the finding is ABOUT — run AP's stage-4 `prepare_prd_input` on the finding BEFORE ingesting if you want this anchoring, otherwise it is empty, not guessed; link_kind='extracted_from' for the source document the finding was extracted FROM, when stage-1's source_path is present — independent of stage-4), one wiki.memos row per stage-2/6/8 receipt (raw-bytes sha256 digest, re-verifiable, plus AP's own transcript_digest copied verbatim from stage-2.verified.json when present — two independent anchors: byte-exact vs AP's semantic claim), and a memory tagged finding,verified. Non-verified findings get a memory only, tagged finding,hypothesis, at low confidence — a hypothesis is not documentation. Idempotent: re-ingesting the same run does not duplicate memories, pages, page_sources, or memos. Distinct from `ingest_codebase` (symbols/files, not findings) and `ingest_prd` (a PRD document, not a findings run). Mutates memories + wiki.pages/page_sources/memos. Returns {ingested, findings_total, verified_count, hypothesis_count, results, errors}.
- **ingest_document** — Ingest a document (.docx or a Confluence storage-format XHTML export) into Cortex's memory/wiki store. Unpacks the container (docx = OOXML zip; Confluence = XHTML file), extracts heading structure + paragraph text + tables into a wiki reference page under documents/<slug>.md, and writes one protected summary memory plus one memory per section — every page and memory stamped with provenance (source path + content version) so documents ride the same staleness/validation path as code references. Embedded images are skipped with an explicit notice (no OCR). Re-ingesting the same document version is idempotent (no duplicate writes). Malformed zip/XML fails loudly, writing nothing. Distinct from `ingest_prd` (markdown PRDs with decision/requirement extraction), `ingest_codebase` (code symbols), and `wiki_write` (manual single page). Returns {ingested, wiki_path, summary_memory_id, section_count, images_skipped, notices, idempotent_skip}.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `uvx` (confidence: high):

```json
"mcpServers": {
  "cortex": {
    "command": "uvx",
    "args": ["hypermnesia-mcp"],
    "env": {
      "CLAUDE_ENVIRONMENT": ""
    }
  }
}
```

**Requires environment variables:** `CLAUDE_ENVIRONMENT` — the values above are empty placeholders; fill in real credentials before running (see the repository for what each one is for).

## Documentation & README

<!-- mcp-name: io.github.cdeust/hypermnesia-mcp -->

<p align="center">
  <img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/banner.svg" alt="Cortex — cross-platform persistent memory for AI coding agents" width="820">
</p>

<p align="center">
  <a href="https://github.com/cdeust/Cortex/actions/workflows/ci.yml"><img src="https://github.com/cdeust/Cortex/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <a href="https://github.com/cdeust/Cortex/blob/HEAD/LICENSE"><img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/badge-license.svg" alt="License: MIT"></a>
  <img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/badge-python.svg" alt="Python 3.10+">
  <img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/badge-tests.svg" alt="tests passing">
  <img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/badge-references.svg" alt="97 referenced papers">
  <img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/badge-version.svg" alt="Version 4.21.0">
  <a href="https://www.bestpractices.dev/projects/13836"><img src="https://www.bestpractices.dev/projects/13836/badge" alt="OpenSSF Best Practices"></a>
  <a href="https://mcptoplist.com/server/io.github.cdeust%2Fhypermnesia-mcp"><img src="https://raw.githubusercontent.com/cdeust/Cortex/HEAD/assets/badge-mcp-toplist.svg" alt="MCP Toplist: Top 1.2% of 81,919 tracked MCP servers, July 2026"></a>
</p>

<p align="center">
  <strong>Memory for AI coding agents that you can hold accountable.</strong><br>
  Keep decisions, fixes and project context between sessions, and inspect what was retrieved.<br>
  Runs locally by default. No account, no API key, no server to manage.
</p>

---

**Sovereign is what it is today.** Everything runs on your machine: a local SQLite file by
default, or PostgreSQL + pgvector if you prefer. No LLM in the retrieval loop, and nothing
leaves localhost unless you configure an integration that does. Your project's memory is a
file you own and can delete.

**Cross-platform is how it is built.** One stdio MCP server and the same 52 tools on Claude
Code, in the Claude Desktop bundle, under Claude Cowork, and on every local stdio MCP host
listed in the table below. What differs per host is stated there, not discovered after
install.

**Eco-responsible is what we are aiming at.** Work that never reaches a datacenter is work
nobody has to power, and an agent that finds the right context first time re-reads fewer
files. We hold that intent to the
[Green Software Foundation's SCI method](https://sci.greensoftware.foundation/), and we
publish **no CO₂ or energy figure**, because we have not measured one.
[What we do and do not claim ↓](#green-software-engineering)

> **36 neuroscience mechanisms · 52 memory tools · 9 lifecycle hooks · a self-curating per-project wiki — all local, all open-source, MIT.**

## Install

**Claude Code** — add the marketplace and install the plugin:

```bash
claude plugin marketplace add cdeust/Cortex
claude plugin install hypermnesia-mcp
```

**Claude Desktop** — download `hypermnesia-mcp.mcpb` from
[Releases](https://github.com/cdeust/Cortex/releases) and open it, or use
**Settings → Extensions**. The bundle carries the tools but no hooks; the MCPB format has none.

**Claude Cowork** is detected automatically (`CLAUDE_ENVIRONMENT=cowork`) and uses the local
SQLite store. No PostgreSQL required.

**Any other stdio MCP host** (Codex, Gemini CLI, Cursor, Windsurf, VS Code) launches the same
server and gets the same tools. The per-host matrix and launch commands are in
[Every other MCP host](#every-other-mcp-host) below. Codex has a native package:
[docs/codex-plugin.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/codex-plugin.md). WSL, TLS client certificates and corporate
proxies are covered in [docs/deployment-scenarios.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/deployment-scenarios.md).

The first use creates a local SQLite store under `~/.claude/methodology/`. Models are downloaded
once when needed and then run offline. The embedding and reranking model files are both fetched
on first use. Optional integrations, remote PostgreSQL, and OTLP telemetry use the network only
when explicitly configured. [PRIVACY.md](https://github.com/cdeust/Cortex/blob/HEAD/PRIVACY.md) lists the exact scope.

An existing PostgreSQL install is never silently downgraded: the installer detects a
configured `DATABASE_URL`, a prior backend marker, or a reachable local `cortex` database and
keeps it across updates.

<details>
<summary><strong>Upgrading from an older plugin identity</strong></summary>

The plugin was renamed `hypermnesia-mcp` in v4.15.0, after a community-directory collision
with an unrelated `cortex` plugin. Memories, configuration and storage paths are untouched.

```bash
claude plugin uninstall cortex
claude plugin install hypermnesia-mcp
```

The visualization companion, <a href="https://github.com/cdeust/cortex-viz">hypermnesia-mcp-viz</a>,
was renamed the same way:

```bash
claude plugin uninstall cortex-viz@cortex-plugins
claude plugin marketplace update cortex-plugins
claude plugin install hypermnesia-mcp-viz@cortex-plugins
```

The retained `cortex-viz@cortex-plugins` entry is a frozen shim that only prints this notice
and exposes no server or tools.

Allowlists, hooks, skills and agents must migrate both composed tool names:
`mcp__plugin_cortex-viz_cortex-viz__open_visualization` becomes
`mcp__plugin_hypermnesia-mcp-viz_hypermnesia-mcp-viz__open_visualization`, and
`mcp__plugin_cortex-viz_cortex-viz__get_methodology_graph` becomes
`mcp__plugin_hypermnesia-mcp-viz_hypermnesia-mcp-viz__get_methodology_graph`.

</details>

## Keep context useful

Across sessions, agents need to remember decisions, bring prior fixes back when a similar problem
returns, and show you which sources support a memory so you can correct it. Cortex keeps that
context available while making its status visible.

Cortex does this with local quality checks: what is written, whether its references resolve, what
happens when a decision changes, and what can fade over time.

### What gets in

A write passes a local novelty check (the implementation calls it a predictive-coding gate) against
what is already stored. Novel content is written; a near-duplicate is merged into the memory it
restates rather than filed beside it.

```js
// Illustrative project decision:
remember({ content: "Keep session state in Redis so TTL expiry is handled consistently." })
// → { stored: true, action: "stored" }
```

Deliberate writes are never rejected for being unsurprising. Unattended capture is, which is
what keeps automatic capture from burying the memories you meant to keep.

### Whether it can be checked

Every memory is graded at write time, locally, with no network call. The grade is not a
confidence score: it is whether the claims carry references that resolve on this machine.

```js
// → provenance: { grade: "unverifiable",
//                 reason: "dead_refs: deps/numpy/_core/_multiarray_umath.cpython-313-darwin.so",
//                 hint: "1 of 9 checkable reference(s) could not be resolved" }
```

That memory named a file that no longer existed, so it was stored and labelled `unverifiable`
instead of being silently presented as verified. Rewritten against paths that resolve, the same
memory grades `verified`. A recalled memory tells you which kind it is; a `verified` grade still
means that the references resolve locally, not that the claim has been independently proven true.

### When it turns out wrong

Corrections supersede rather than overwrite. The new memory records what it replaces, the old
one is demoted in recall, and the chain stays readable.

```js
remember({ content: "...", supersedes_id: 4360411 })
// → { action: "superseded", memory_id: 4360412, superseded_id: 4360411 }
```

### What fades

Memories carry heat that decays unless replay reinforces them, and episodic traces can consolidate
into semantic ones. A specific debugging session may compress to the principle it taught; the
commands can fade while the lesson survives. This lifecycle is designed to keep the store useful
as it grows, though it is not a promise of a fixed size or guaranteed semantic compression.

## What it feels like in use

Here is an illustrative workflow: decisions, prior fixes, and source checks becoming useful again.

**Monday.** An hour debugging a webhook handler ends in a race condition: TTL expiry firing
between the auth check and the permission lookup. You agree on a fix, implement it, close the
session.

**Thursday.** In another session, a user reports intermittent logouts. Cortex surfaces relevant
prior analysis, the Redis decision, and the TTL lesson when their content matches the new work.

**Three weeks later.** The sessions can consolidate into a pattern about authentication and
TTL-based caches; some details may fade while the principle remains useful.

In Claude Code that is automatic: nine lifecycle hooks inject context at session start, recall
per prompt, capture as you work, checkpoint before compaction, and run a per-project wiki that
curates itself. In any other stdio MCP host you call the same 52 tools yourself, or 55 when
the optional `ai-architect-mcp-codebase` and `ai-architect-mcp-spec` integrations are present.

## Does the retrieval work

Measured against a published benchmark, retrieval only. No LLM reader in the loop: the
question is whether the right memory surfaces, not whether a model can write a good answer
from it.

**LongMemEval**: 500 human-curated questions buried in about 40 sessions of history.

| | v4.14.1 (historical) | v4.20.0 (current release) |
|---|---|---|
| Recall@10 | **98.2%** | **97.8%** |
| MRR | **0.9167** | **0.905** |

Both are single runs: n=500, clean database, consolidation disabled, retrieval only.

v4.14.1, 2026-07-14: [artifact JSON](https://github.com/cdeust/Cortex/blob/HEAD/benchmarks/results/repro/20260714-v4.14.1-pretag/longmemeval-s.json);
[code SHA](https://github.com/cdeust/Cortex/commit/28145f0b7a113fc06e22568de6feea7f8444eaf5).
This is the run the ablation campaign in [Verification](#verification) was built around.

v4.20.0, 2026-09-09: [artifact JSON](https://github.com/cdeust/Cortex/blob/HEAD/benchmarks/results/repro/20260909-v4.20.0-longmemeval-s/longmemeval-s.json) and its
[manifest](https://github.com/cdeust/Cortex/blob/HEAD/benchmarks/results/repro/20260909-v4.20.0-longmemeval-s/MANIFEST.json); [code SHA](https://github.com/cdeust/Cortex/commit/86251ab8fc27a18f80f9b09b99a75f3b60edd9cb),
dirty=false. A single run of the LongMemEval-S leg alone (`benchmarks/reproduce.sh --only longmemeval
--no-ablation`) in an isolated ephemeral PostgreSQL container, reranker loaded, consolidation
disabled. Against v4.14.1 the change is 0.4 points of Recall@10 and 0.012 of MRR. The run's own
floor check reports Recall@10 within the 0.005 tolerance of the July floor (0.982) and MRR
0.0093 below its floor (0.914), which the script treats as non-blocking by design;
[docs/agent-guidance.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/agent-guidance.md) records that `main` no longer clears those
floors and that the release gate is `--no-regression` against `origin/main`. The same tree has
no LoCoMo or BEAM figure yet.

Reproduce with `benchmarks/reproduce.sh`, which runs in an isolated ephemeral container, never
against a live store.

Recall@10 is the share of questions whose answer-bearing session appears in the first ten
retrieved sessions. MRR (mean reciprocal rank) rewards finding that session near the top. These
numbers describe retrieval only; they do not measure whether an LLM writes a correct answer.

Retrieval fuses five signals through weighted reciprocal-rank fusion, then reranks with a
cross-encoder: vector similarity, full-text search, trigram match, heat and recency. LoCoMo
and BEAM results, the ablations and the floor gates are in [benchmarks/](https://github.com/cdeust/Cortex/blob/HEAD/benchmarks/).

## Storage

SQLite by default. PostgreSQL is one configuration field, worth it for very large stores or a
database shared across a team.

```bash
bash <plugin-dir>/scripts/install-plugin.sh --postgres
```

|  | SQLite (default) | PostgreSQL 15+ |
|---|---|---|
| Setup | none | pgvector, pg_trgm |
| All 52 tools | yes | yes |
| Retrieval contract | identical | identical |
| Fusion | in-process | server-side PL/pgSQL |
| ANN index | none | pgvector HNSW |
| Cross-agent team decisions, preemptive context, pipeline heat bumps | no-op | active |

Three hook enrichments are PostgreSQL-only and degrade to silent no-ops on SQLite. Session
banners, auto-recall, auto-capture, checkpoints and every memory tool work on both.

## Every other MCP host

The server is host-agnostic. Any host that can launch a stdio process gets the full tool
surface on the default SQLite store. What is not portable are the nine lifecycle hooks, which
are Claude Code plugin machinery; the server never imports or requires them at startup.

| Capability | Claude Code plugin | Local stdio hosts (Gemini CLI, Codex CLI, ChatGPT desktop, Cursor, Windsurf, VS Code, Agents SDK) | ChatGPT web |
|---|---|---|---|
| All 52 memory tools (`remember`, `recall`, wiki, navigation, consolidation, triggers, rules) | ✅ | ✅ | ❌ no remote HTTPS endpoint is shipped |
| SQLite default store / PostgreSQL opt-in | ✅ | ✅ | ❌ would need a remote deployment and a per-user storage and auth model |
| Auto-capture of significant tool output | ✅ PostToolUse hook | ❌ store explicitly with `remember` | ❌ |
| Session-start context injection | ✅ SessionStart hook | ❌ call `recall` yourself | ❌ |
| Per-prompt auto-recall | ✅ | ❌ | ❌ |
| Compaction checkpoints | ✅ | ❌ | ❌ |
| Autonomous wiki cycle | ✅ | ❌ run `consolidate` / `curate_wiki` manually | ❌ |
| Cognitive profiling (`query_methodology`) | ✅ | ⚠️ profiles are mined from Claude Code session logs under `~/.claude/`; without them the profile is empty | ❌ |

On Claude Code memory is ambient: hooks capture and inject automatically. On every other host
memory is tool-driven: the agent stores and retrieves when instructed, and nothing happens
between prompts.

The launch command on every host is the PyPI package. The `[sqlite]` extra enables
sqlite-vec vector search; without it the store still works, with vector search disabled.

```bash
uvx --from "hypermnesia-mcp[sqlite]" hypermnesia-mcp
```

**Gemini CLI** ships as an extension (`gemini-extension.json` is in this repository):

```bash
gemini extensions install https://github.com/cdeust/Cortex
```

**Codex and ChatGPT desktop** have a native plugin with a 10-tool lean surface. Pre-install
the package once so the plugin's first `uvx` handshake reuses the local uv cache instead of
spending its startup budget downloading a Python environment:

```bash
uv tool install "hypermnesia-mcp[sqlite]"
codex plugin marketplace add cdeust/Cortex
codex plugin add hypermnesia-mcp-codex@cortex-codex-plugins
```

The direct fallback registers the executable without the plugin:

```bash
codex mcp add cortex --env CORTEX_MEMORY_STORE_BACKEND=sqlite -- hypermnesia-mcp
```

The host boundary, the measured startup ceiling and the public-directory requirements Cortex
deliberately does not claim are in [docs/codex-plugin.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/codex-plugin.md).

## Green software engineering

Cortex runs a standing efficiency programme, gated by the same evidence rule as
the retrieval work: **no unsourced efficiency claim ships.** Waste is treated as
a defect with a reproduction, not as a virtue to advertise.

### The measurement harness — and what it does not establish

`benchmarks/energy/` implements the [Green Software Foundation SCI
specification](https://sci.greensoftware.foundation/): operational emissions
`O = E × I`, embodied allocation `M = TE × TS × RS`, reported per functional
unit. For the embedding path the functional unit is **1000 model input tokens**,
counted from the tokenizer's own `attention_mask` — never estimated from
characters.

Read `benchmarks/energy/README.md` before quoting anything from it. Its own
first paragraph is the important one: the automated fixtures exercise arithmetic
and failure paths, they **do not measure device energy and do not establish an
energy improvement.** Further, by design:

- **No default carbon factors.** `--carbon-intensity` (gCO2eq/kWh) and
  `--embodied` (gCO2eq/s, an *already allocated* rate) are mandatory operator
  inputs, validated before any model import. The harness records the values and
  their units; it does not vouch for their provenance. You supply the region,
  observation period, lifecycle assessment and reservation assumptions.
- **A stated boundary.** `raw_system_energy_j` is the sensor's combined
  CPU+GPU+ANE estimate. It is neither wall-plug energy nor a complete device SCI
  score: memory, storage, screen, power-supply losses, model warm-up and token
  counting are all excluded.
- **Artifacts or it did not happen.** A successful run preserves `results.json`,
  a `MANIFEST.json` of commit and source hashes, and the exact analyzed
  `powermetrics.txt` snapshot.

No energy results are committed to this repository. That is deliberate: a
figure measured on one operator's machine, region and duty cycle is not a
property of the software, and publishing it as one would be the drift this
programme exists to prevent.

### What has actually shipped

Efficiency work lands as ordinary reviewed PRs. Two workstreams are merged:

| Workstream | Change | PR |
|---|---|---|
| **CI / build** | run pytest once, on the coverage leg, instead of twice | [#475](https://github.com/cdeust/Cortex/pull/475) |
| | build runtime images only on Docker changes + a weekly validation | [#476](https://github.com/cdeust/Cortex/pull/476) |
| | cache pinned dependency and actionlint downloads | [#477](https://github.com/cdeust/Cortex/pull/477) |
| | sdist under 5 MB, with a byte-identical wheel | [#478](https://github.com/cdeust/Cortex/pull/478) |
| | measured job timeouts; cancel superseded PR runs | [#479](https://github.com/cdeust/Cortex/pull/479) |
| | bound the local Docker build context | [#481](https://github.com/cdeust/Cortex/pull/481) |
| | stop exporting an unreadable layer cache on every PR run | [#506](https://github.com/cdeust/Cortex/pull/506) |
| **Runtime** | defer unused pipeline hook imports | [#482](https://github.com/cdeust/Cortex/pull/482) |
| | route PostToolUse hooks by the tool names they handle | [#483](https://github.com/cdeust/Cortex/pull/483) |
| | audit and clean orphan plugin dependencies | [#484](https://github.com/cdeust/Cortex/pull/484) |
| | rotate telemetry and detached-worker logs | [#485](https://github.com/cdeust/Cortex/pull/485) |
| | persist hook cascade cadence; cool down misses | [#486](https://github.com/cdeust/Cortex/pull/486) |
| | pinned CPU-only Torch on Linux — no CUDA payload pulled | [#487](https://github.com/cdeust/Cortex/pull/487) |

The hook work is the load-bearing one, because hooks run on *every* tool event.
Deferring the handler/store stack keeps hook boot at **~0.05 s** against
**~0.6 s** for the full registry import (measured 2026-07-28; the constant is
cited in `mcp_server/hooks/auto_recall.py` at its call sites, per the
no-invented-constants rule).

### Demand reduction is the primary lever

The largest efficiency term in an LLM-assisted workflow is not this server's own
CPU — it is the tokens a model must process because the right context was not
found the first time. That makes retrieval quality an energy property, and it is
why the benchmark tables above and this section are the same programme:
`response_budget.py` bounds a payload and keeps ids so truncation stays
resumable, the reranker degrades to first-stage scores rather than fetching a
model, and `CORTEX_RERANKER_OFFLINE=1` refuses the download outright.

This paragraph is a design rationale, not a measurement. Cortex publishes no
token-savings or CO2 figure for end-to-end agent sessions, because it has not
measured one.

---

## Verification

The v4.14.1 figures above are backed by a per-mechanism ablation campaign — full *n*, single-seed, with code SHAs, dirty flags, manifests, and per-row JSON preserved; the v4.20.0 figures are a single measurement without one:

- **LongMemEval-S, 17 rows, n=500** — `docs/benchmarks/e1-v3-results.md`. Per-mechanism deltas at the calibrated equilibrium + category-specialization analysis.
- **LoCoMo, 14 rows, n=1986** — `docs/benchmarks/e1-v3-locomo-results.md` (pre-fix) and `docs/benchmarks/e1-v3-locomo-results-post-fix.md` (post plasticity result-shape fix). Two-baseline design (NO_CONSOLIDATION / WITH_CONSOLIDATION).

The full per-mechanism evidence lives in the thermodynamic paper (§6.3); the BEAM decay dose-response (§6.4) documents a re-scoped negative result after a dirty-store confound was caught and traced. **[Thermodynamic Memory vs. Flat-Importance Stores (PDF, 34 pages)](https://github.com/cdeust/Cortex/blob/HEAD/docs/arxiv-thermodynamic/main.pdf)** · **[Stage-Aware Context Assembly (PDF, 39 pages)](https://github.com/cdeust/Cortex/blob/HEAD/docs/arxiv-context-assembly/main.pdf)**.

---

## Under the hood

The mechanisms above are implemented as 36 system mechanisms spanning encoding, consolidation,
retrieval and forgetting. Each is cited to published work and exposed as a live system vital. The
[bibliography](https://github.com/cdeust/Cortex/blob/HEAD/docs/papers/bibliography.md) is
the check: its entry count is what the references badge reports, and a gate fails the build if
the two disagree.

Clean Architecture, concentric layers: `server → handlers → core ← shared`, and
`infrastructure → shared`. Core is pure and testable without mocks.
[docs/agent-guidance.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/agent-guidance.md) is the map;
[docs/mcp-tools.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/mcp-tools.md) is the tool reference.

## Limits worth knowing before you install

- The automatic behaviour is Claude Code plugin machinery. Elsewhere you call the tools
  yourself, and the host table above says exactly what is missing where.
- SQLite fusion is in-process and unindexed. Fine at personal scale, slower at very large one.
- The retrieval scores above are retrieval-only. They say nothing about answer quality.
- Provenance grading is local and structural. It checks that a reference resolves, not that a
  claim is true; a DOI or arXiv link is never auto-verified.
- No energy or carbon figure is published, for the reasons stated above.
- First use downloads both the embedding and reranking model files. Optional integrations, remote
  PostgreSQL and OTLP telemetry add network activity only when explicitly configured; see
  [PRIVACY.md](https://github.com/cdeust/Cortex/blob/HEAD/PRIVACY.md).

## Security

Runs **100% locally** — MCP over stdio, the storage backend (SQLite file or PostgreSQL on localhost) never leaves your machine (the optional [hypermnesia-mcp-viz](https://github.com/cdeust/cortex-viz) companion binds its server to 127.0.0.1). No data leaves your machine. SafeSkill scan: **94/100** (code 97, content 88 — [docs/safeskill-report.json](https://github.com/cdeust/Cortex/blob/HEAD/docs/safeskill-report.json)).

## Privacy Policy

Cortex is **local-first**: your memories, conversations, and profiles stay on your machine — stored in a local SQLite database (`~/.claude/methodology/memory.db`) by default, or in a PostgreSQL database you control. Cortex sends **no** memories, content, or telemetry to the author, Anthropic, or any third party. The only outbound network activity is a one-time download of open-source embedding/reranking models from Hugging Face (model files only), plus any integrations you explicitly configure. Full policy: **[PRIVACY.md](https://github.com/cdeust/Cortex/blob/HEAD/PRIVACY.md)**.

## Support

- **Issues & bug reports:** [GitHub Issues](https://github.com/cdeust/Cortex/issues)
- **Security disclosures:** see [SECURITY.md](https://github.com/cdeust/Cortex/blob/HEAD/SECURITY.md)
- **Contact:** [admin@ai-architect.tools](mailto:admin@ai-architect.tools)

## Development

```bash
pytest                                # full suite; assets/badge-tests.svg carries the current count
ruff check . && ruff format --check . # lint and format, both enforced in CI
python scripts/check_doc_claims.py    # advertised counts must match the repo
python scripts/check_craftsmanship.py # file and method caps, layer whitelist, sourced constants
```

[CONTRIBUTING.md](https://github.com/cdeust/Cortex/blob/HEAD/CONTRIBUTING.md) describes the gates a change has to clear.
[GOVERNANCE.md](https://github.com/cdeust/Cortex/blob/HEAD/GOVERNANCE.md) says who decides and what happens if the maintainer stops.
[docs/ROADMAP.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/ROADMAP.md) says where the project is going, and
[docs/ASSURANCE-CASE.md](https://github.com/cdeust/Cortex/blob/HEAD/docs/ASSURANCE-CASE.md) states the security argument and its limits.
[CHANGELOG.md](https://github.com/cdeust/Cortex/blob/HEAD/CHANGELOG.md) is the complete release history.

## License

MIT — see [LICENSE](https://github.com/cdeust/Cortex/blob/HEAD/LICENSE).

This software is the independent work of Clément Deust. It was developed outside any
employment relationship and is not affiliated with, endorsed by, or owned by any past or
present employer. It is part of the ai-architect ecosystem
([zetetic-team-subagents](https://github.com/cdeust/zetetic-team-subagents),
[ai-architect-mcp-codebase](https://github.com/cdeust/ai-architect-mcp-codebase),
[ai-architect-mcp-spec](https://github.com/cdeust/ai-architect-mcp-spec)).

The neuroscience and information-retrieval algorithms encoded in this software are derived
from published academic work cited in
[`docs/papers/bibliography.md`](https://github.com/cdeust/Cortex/blob/HEAD/docs/papers/bibliography.md) and inline in the source via
`# source:` annotations (Friston on predictive coding, Anderson & Lebiere on rate-distortion
forgetting, Nader et al. on retrieval-induced lability, McClelland et al. on consolidation,
and others). The MIT license covers this implementation; it does not assert ownership over
the underlying mechanisms, which remain attributable to their original authors and
publications.

## Citation

The paper PDFs on `main` are the canonical artefacts (arXiv IDs forthcoming, endorsement in
progress):

```bibtex
@software{cortex2026,
  title={Cortex: Persistent Memory for Claude Code},
  author={Deust, Clement},
  year={2026},
  url={https://github.com/cdeust/Cortex}
}

@unpublished{deust2026thermodynamic,
  title={Thermodynamic Memory vs. Flat-Importance Stores:
         Why Long-Term Retrieval Collapses Without Decay},
  author={Deust, Clement},
  year={2026},
  note={arXiv ID forthcoming, endorsement in progress},
  url={https://github.com/cdeust/Cortex/blob/main/docs/arxiv-thermodynamic/main.pdf}
}

@unpublished{deust2026context,
  title={Stage-Aware Context Assembly for Long-Context Memory Retrieval},
  author={Deust, Clement},
  year={2026},
  note={arXiv ID forthcoming, endorsement in progress},
  url={https://github.com/cdeust/Cortex/blob/main/docs/arxiv-context-assembly/main.pdf}
}
```

