Skip to content

Releases: MemPalace/mempalace

v3.4.0

06 Jun 08:58
be95467

Choose a tag to compare

v3.4.0 — pluggable backends, Docker, and reliability fixes

Features

  • Pluggable vector backends — Qdrant, pgvector, and sqlite_exact alongside the default ChromaDB, selectable via MEMPALACE_BACKEND / --backend.
  • Docker images (CPU + GPU) for the MCP server and CLI.
  • mempalace migrate-wings — one-time migration that normalizes legacy wing names (strip leading/trailing separators) so pre-upgrade palaces stay discoverable. See docs/recovery/wing-name-migration.md.
  • Known-systems lexicon keeps multi-word product names atomic in entity detection.

Fixes

  • embeddinggemma (the default model) now works with ChromaDB 1.5.x — semantic search was silently failing on fresh installs.
  • Prevent silent data loss from drawer_id hash collisions.
  • Importing mcp_server no longer recreates ~/.mempalace (respects the privacy kill-switch).
  • diary_write accepts a content alias and restores the missing-parameter diagnostic.
  • Explicit-vector backends handle single-document inputs correctly.

Infrastructure

  • PyPI publishing via GitHub Actions Trusted Publishing (OIDC), gated by manual approval.

v3.3.6 — multilingual recall, living graph, surgical reads

06 Jun 07:27
db1fbe8

Choose a tag to compare

3.3.6 is a features release. The cycle's headline work: multilingual recall by default (embeddinggemma replaces MiniLM, cross-lingual cosine jumps from 0.35 → 0.88), the first cut of the living-memory graph (hallways within wings, tunnels across wings, Hebbian potentiation + Ebbinghaus decay so connections strengthen with use and fade without), office-document mining (PDF, DOCX, PPTX, XLSX, RTF, EPUB via the new --mode extract), virtual line numbers + surgical closet pointers that cite exact line ranges on exact dates, and the entity-detection cleanup pass that keeps "Code" out of your hallways and "Claude Code" atomic.

The promises haven't moved. Every word stored exactly. Everything stays on your machine. No telemetry. Each release sharpens what's already there.

Features

  • Office-document mining via --mode extract. New mempalace mine <dir> --mode extract ingests PDFs, Word (.docx), PowerPoint (.pptx), Excel (.xlsx), RTF, and EPUB books in addition to the existing source-code/text path. Install with pip install mempalace[extract] — pulls striprtf for RTF and MarkItDown (with [docx,pdf,pptx,xlsx] sub-extras) for the binary formats. Python 3.9 users get RTF coverage only because MarkItDown requires 3.10+. Drawers from the extract path carry extract_mode metadata so the convo miner's "already mined?" check and drawer-id generation stay isolated per mode (#1528). (#1555)

  • Virtual line numbers + surgical closet pointers. Stored drawers now carry virtual line numbers so the read CLI verb and closet pointers can cite exact line ranges. Closet pointers (Tier 6a) include date+line-range information derived from filename and content-body date parsing (python-dateutil is now a core dep), so MemPalace can point you to exact lines on exact dates rather than just "somewhere in this drawer." (#1555, #1584)

  • Within-wing hallways. When two entities (people, projects, topics) co-occur in the same drawer, the miner now records a "hallway" — a graph edge connecting them inside that wing. Computed automatically as part of the post-mine step in compute_hallways_for_wing so the graph grows incrementally with new content, no separate command. Foundation for cross-room entity navigation inside one palace. (#1558, #1560)

  • Cross-wing tunnels promoted from hallways. When the same entity appears in hallways across multiple wings, MemPalace now automatically promotes that into a tunnel — letting queries hop from one person's wing to a project wing they appear in, without anyone calling create_tunnel manually. Topic tunnels from the existing compute_topic_tunnels path remain unchanged. (#1565)

  • Living-memory dynamics (Hebbian potentiation + Ebbinghaus decay). Hallways and tunnels get stronger every time the same connection is reinforced by new content ("what fires together wires together") and fade gradually if a connection stops appearing in incoming drawers. Navigation weights track real palace usage instead of being static, so retrieval ranking improves over time as the palace is actually used. (#1578)

  • API-tool transcripts auto-route to wing_api. Conversation transcripts from API-style AI tools (Claude Code, Claude.ai, ChatGPT, Slack-bot exports, generic OpenAI-shape JSON, etc.) now route into a dedicated wing_api instead of mixing into the human-conversation wings. Keeps tool-call traffic from polluting personal/project wings and improves search precision when you're looking for "what did I say" vs. "what did the agent say." (#1236)

  • Multilingual embedding by default for new installs: embeddinggemma-300m ONNX (q8, MRL→384-dim). MemPalace's previous embedder (all-MiniLM-L6-v2) is trained English-only — cross-lingual cosine similarity on parallel-translated text averages 0.35 across DE/FR/HI/IT/KO/RU (RU at 0.17, near-orthogonal). A Russian-speaking user effectively cannot find their own memories, which breaks the "100% recall" design promise from CLAUDE.md. New EmbeddinggemmaONNX class in mempalace/embedding.py brings this to 0.88 average (validated lossless vs the Ollama gguf via direct ONNX-runtime test). Lazy-downloads onnx-community/embeddinggemma-300m-ONNX (~300 MB) on first use via huggingface_hub. Output is truncated to 384 dims via Matryoshka Representation Learning so the model is a drop-in for ChromaDB's 384-dim collections — no schema change. Sim prefix ("task: sentence similarity | query: ") is applied automatically.

    Onboarding (python -m mempalace.onboarding) now offers the multilingual model as the default — choosing it writes embedding_model: embeddinggemma to config.json so subsequent runs pick it up without re-prompting. Existing installs that never set the env var or ran onboarding stay on minilm (back-compat). MEMPALACE_EMBEDDING_MODEL=minilm|embeddinggemma overrides both. Switching models on an existing palace requires re-embedding — run mempalace repair rebuild-index after the change. (#1483)

  • Multilingual deps moved to core. huggingface_hub, tokenizers, and numpy are now required deps so the multilingual path works out of the box after pip install mempalace. The [multilingual] extra is kept as a no-op alias for back-compat with install scripts. The 300 MB ONNX model itself is still lazy-downloaded on first use, not at install time.

  • Friendlier ChromaDB EF-name-mismatch error. Switching MEMPALACE_EMBEDDING_MODEL on an existing palace without running rebuild-index previously surfaced ChromaDB's bare Embedding function conflict: new: X vs persisted: Y ValueError — accurate but didn't tell users how to recover. ChromaBackend.get_collection() now wraps that error and points at both options: revert the env var, or run mempalace repair rebuild-index --palace <path>. (#1483)

  • hooks.auto_save toggle for silent-mode sessions. New config knob (and --silent CLI flag wiring through the save hook) lets users opt out of automatic diary saves on Stop / PreCompact. Useful for "silent mode" sessions where you don't want every conversation captured. Default behavior is unchanged — auto-save still runs unless explicitly disabled. (#711)

  • Filter common English content words from entity detection. High-frequency English content words ("system", "user", "memory", "project", "context", etc.) were getting tagged as entities by the per-drawer detector and polluting the entity registry as "people." A shipped COCA wordlist (top-N content words) is now consulted during entity classification so these get filtered before they reach the registry. Hardened against malformed JSON in the bundled wordlist. (#1605)

  • Case-insensitive entity matching at mine time. The initial palace build (mempalace init) matched entity names case-insensitively, but the per-drawer tagger used during incremental mining did not — so the same person was tagged differently between init and ingest ("Aya" vs. "aya" became distinct entities). The incremental tagger now mirrors the case-insensitive matcher, restoring entity-tag consistency across the palace lifecycle. (#1557)

Bug Fixes

  • Silent data loss in three upsert paths. Three upsert sites (file ingest, conversation ingest, and one repair branch) were calling the embedder on unchunked content, silently truncating at the embedder's max-token limit. Long drawers landed with only their leading section indexed, breaking the "100% recall" promise on long-form content. All three now route through the chunker first so the full document is embedded and stored. (#1540, follow-up to #1539)

  • Paragraph chunker emitted oversized chunks for long paragraphs. The paragraph splitter assumed paragraphs were always shorter than CHUNK_SIZE and emitted them whole; long paragraphs (legal text, dense technical writeups) silently exceeded the embedder's context window. The splitter now hard-caps each emitted chunk to honor CHUNK_SIZE. (#1538, fixes #1534)

  • Per-file chunk cap was hardcoded and too low for large transcripts. A safety limit capped chunks per file at a value tuned for source code; mining very large conversation transcripts silently dropped the tail past that cap. Now configurable, with the default raised to cover realistic transcript sizes. (#1554, fixes #1455)

  • Hook subprocess / ChromaDB deadlock on Windows. Stop/PreCompact hooks could deadlock against an already-open ChromaDB client on Windows, leaving the host (Claude Code) stuck waiting on the hook. Three-part fix: stale-PID timeout on mine-lock reclamation, idle-exit path in the MCP server, and structured errors when the deadlock pattern is detected so the host can recover. (#1562, fixes #1552)

  • create_tunnel corrupted hyphenated wing names. The endpoint parser split on -, so wings whose name contained a hyphen (mem-palace, my-app) were truncated mid-name and the tunnel pointed at a non-existent endpoint. Endpoint parsing now preserves the full slug. (#1529, fixes #1504)

  • MCP knowledge-graph cache produced duplicate graphs for symlinked / differently-cased palace paths. Cache key was the raw path string, so /Users/me/.mempalace/palace and /Users/me/.mempalace/Palace (case-folded on macOS) or a symlinked alias produced two separate cached KnowledgeGraph instances pointing at the same SQLite file, with stale-read risk. Cache now normalizes via realpath + normcase so they collapse onto a single canonical key. (#1383, fixes #1372)

  • Save-hook truncated hyphenated project folder names. Wing-name parser was splitting on - and keeping only the first segment, so mem-palace became mem. Fix preserves the full project-folder slug so hyphenated palaces stay coherent across hook invocations. (#1424, fixes #1410)

  • Miner silently skipped symlinks. Users were confused about missing data after mining; the miner was skipping symlinks without surfacing it. Now logs e...

Read more

v3.3.5 — integrity, recovery, and cross-process correctness

10 May 23:32
d0163a7

Choose a tag to compare

3.3.5 is a fixes release. No new user-facing features — the cycle's energy went into data integrity, recovery, and cross-process correctness. If your palace ever hit Internal error: Error finding id after a big mine, or you had a knowledge-graph triple silently disappear into the void, or you're running on Windows / a multi-tenant host — this release is for you.

The headline fixes:

  • mempalace repair --mode from-sqlite recovers palaces stuck on apply_logs. When ChromaDB's HNSW segment writer wedges (the corruption class reported upstream and in #1308), --mode legacy and the inline repair both call Collection.count() as their first read — which is exactly the call that raises. The old failure mode was a repair printing Cannot recover — palace may need to be re-mined from source files even though the SQLite tables were fully intact. The new mode reads (id, document, metadata) directly from chroma.sqlite3 via the metadata segment join, never opens a chromadb client against the corrupt palace, and re-upserts everything into a fresh palace under your configured embedding function. Verified end-to-end on a 52,300-row real-world corrupt palace. (#1308)

  • Two silent-loss classes in the knowledge graph are now write-time errors. Triples with valid_to < valid_from used to be durably stored but unreachable (the temporal filter matched no as_of); add_triple() now rejects inverted intervals at write time. And date strings forwarded to SQLite are validated up front via sanitize_iso_temporal() (alias sanitize_iso_date()), which accepts YYYY-MM-DD and canonical UTC datetimes (YYYY-MM-DDTHH:MM:SSZ / +00:00) and rejects everything else — natural-language inputs like "yesterday" no longer silently produce empty result sets. Behavior change: partial-date inputs that worked in 3.3.4 ("2026", "2026-05") now error; pass a full date or canonical UTC datetime instead. (#1214, #1164, #1167, #1374, #1417)

  • EntityRegistry.save() is now crash-safe. The people/projects map is months of mining data, and the old code did a non-atomic Path.write_text() — a power loss, OOM, or kill -9 between truncate and full-flush would silently wipe it (the registry's load() swallows JSONDecodeError). Save now writes to a sibling temp file, fsyncs, and os.replace()s into place. The previous registry stays intact on any crash before the rename returns. (#1215)

  • MCP tool_search rides through the post-bulk-mine HNSW flush window. After a CLI mine, ChromaDB's HNSW segment metadata can be unflushed for ~30-60s; wing-scoped MCP search was hitting Internal error: Error finding id for that entire window. tool_search now detects this specific transient, drops both the MCP-local and shared-backend caches for the palace, sleeps 2s, and retries once. Successful retries are tagged with index_recovered: true so callers can observe when it fired. Partial fix for the broader #1315 cluster — tool_check_duplicate and other index-touching tools still need the same wrapper. (#1396)

  • Cross-process correctness on Windows and multi-tenant hosts. ChromaBackend.close_palace() now properly releases ChromaDB's rust-side SQLite file lock — reopening the same palace path after shutil.rmtree no longer fails with SQLITE_READONLY_DBMOVED. And the MCP server's _kg is no longer a module-level singleton: multi-tenant hosts rotating MEMPALACE_PALACE_PATH between tool calls now hit the right SQLite file via a lazy per-path cache. (#1067, #1105, #1136, #1160)

  • Windows stdio is UTF-8 across the board. mempalace search > out.txt and piped fact_checker invocations no longer mojibake Cyrillic / CJK drawer text at the process boundary. mcp_server, hooks_cli, and cli/fact_checker all reconfigure identically. (#1282)

  • miner.detect_room routing fix for monorepos. The substring check was bidirectional, so any token that was a substring of a room name or vice versa matched — views/billing-page/src/Foo.test.tsx routed to an interviews room because "views" in "interviews" matched first. Now uses separator-bounded token matching (-, _, ., /). (#1004, closes #1002)

  • mempalace compress no longer crashes on palaces above ~32k drawers. Drawer fetch is now paginated, mirroring the #851 fix in miner.py. (#1073, #1107)

Internal: test reliability got a pass too — tests/test_palace_locks.py and tests/test_chroma_collection_lock.py switched from fork to spawn for subprocess spawning (Python 3.13 + multi-threaded parent = deadlock under fork, and macOS forbids fork-without-exec via CoreFoundation), and several test files now wrap sqlite3.connect(...) in contextlib.closing() so connections release on the failure path too. (#1430, #1431)

The promises haven't moved. Every word stored exactly. Everything stays on your machine. No telemetry. No fallbacks to cloud APIs we didn't tell you about. Each release sharpens what's already there.

What's Changed

  • fix(mcp_server): pass embedding_function= on collection reopen (#1299) by @igorls in #1303
  • fix(hooks): quote plugin-root paths with spaces (#1076) by @mvalentsev in #1077
  • fix(cli): cmd_compress writes to mempalace_closets (#1244) by @igorls in #1319
  • fix(mcp): case-insensitive agent name in diary read/write (#1243) by @igorls in #1323
  • fix(backends/chroma): wire quarantine_stale_hnsw into _client() (#1121 #1132 #1263) by @igorls in #1322
  • fix(mcp): omit absolute filesystem paths from MCP tool responses by @igorls in #1325
  • feat(searcher): candidate_strategy="union" — BM25 candidates joined with vector pool before hybrid rerank by @igorls in #1306
  • fix(mcp): forward valid_to and source params in kg_add/kg_invalidate (#1314) by @igorls in #1320
  • fix(cli): honor --palace flag in cmd_init (#1313) by @igorls in #1321
  • fix(kg): reject inverted intervals in add_triple (valid_to < valid_from) by @arnoldwender in #1214
  • fix(backends/chroma): release SQLite file lock on close_palace/close (#1067) by @mvalentsev in #1105
  • fix(entity_registry): atomic write to prevent partial corruption on crash by @arnoldwender in #1215
  • fix: paginate closet_llm col.get (#1073) by @sha2fiddy in #1107
  • fix(cli, fact-checker): reconfigure stdio to UTF-8 on Windows by @mvalentsev in #1282
  • fix(kg): validate ISO-8601 date formats at MCP boundary by @arnoldwender in #1167
  • fix(mcp): lazy per-path KnowledgeGraph cache (#1136) by @mvalentsev in #1160
  • docs(changelog): batch entries for 7 v3.3.5 fixes by @igorls in #1370
  • fix: serialize ChromaCollection writes through palace lock by @imtylervo in #1162
  • fix(hooks): treat absent ~/.mempalace as auto-save off by @lcatlett in #1305
  • fix: add total count to tool_list_drawers pagination response by @Sathvik-1007 in #1114
  • fix(mcp): force UTF-8 on stdio to fix -32000 on non-ASCII payloads (Windows) by @alonehobo in #1060
  • fix: guard None metadata/doc in tool_check_duplicate and Layer1/Layer2 by @eldar702 in #1030
  • fix(lint): hoist hooks_cli_mod import to top of test_hooks_cli (E402) by @igorls in #1375
  • fix(searcher): clamp effective_distance to valid cosine range [0, 2] by @eldar702 in #1029
  • fix(mcp): handle null JSON-RPC request payloads safely by @alpiua in #987
  • fix: MCP server JSON output ensure_ascii=False for non-ASCII support by @hzx945627450-eng in #1293
  • fix: clamp similarity scores to [0,1] to prevent negative values by @bobo-xxx in #988
  • fix(searcher): guard against None metadata/doc in search result loops by @cantenesse in #1019
  • fix: reject non-http(s) LLM endpoints + clear ruff bugbear/silent-except findings by @anthonyonazure in #1138
  • fix(mcp): retry _get_collection once on transient failure (#1286) by @igorls in #1377
  • docs: add 30-day expiry callout + ship 4 auto-save tools by @milla-jovovich in #1391
  • fix(repair): add --mode from-sqlite to recover palaces with corrupt HNSW (#1308) by @potterdigital in #1310
  • fix: harden Chroma repair preflight and rollback recovery by @mjc in #1285
  • fix(miner): harden Windows mine against ONNX bad_alloc + silent partial exits (#1296) by @igorls in #1402
  • fix: use configured collection in repair recovery paths by @mjc in #1312
  • fix(migrate): verify write roundtrip before bailout by @fatkobra in #1359
  • fix(storage): quarantine bloated HNSW link payloads by @fatkobra in #1339
  • fix(repair): preflight poisoned max_seq_id before rebuild by @...
Read more

v3.3.4

01 May 03:59
d53129e

Choose a tag to compare

  • Setup got smart and a local language model does the work for free. Mempalace init now uses a local LLM if you have one running, Ollama or LM Studio or llama.cpp, whichever you prefer. Zero cloud calls, no API key to set up, nothing costs anything. If you do not have one running, it falls back gracefully and never blocks. You are never stuck waiting on something that is not there.

  • The palace now connects ideas across projects. Cross wing topic tunnels are a new feature where, when two projects talk about the same theme, like a framework you use everywhere or a person who shows up across domains, the palace links them together. So when an LLM scans your memories for one project, it can follow the thread into related projects without you having to set anything up.

  • Setup and first ingest are now one step. When you run mempalace init, it asks if you want to mine the directory right after onboarding, and shows you a size estimate first so you are not surprised by a long ingest. One command, two things done, no manual second pass.

  • A storage fix made big palaces dramatically smaller. There was a bug where active palaces could bloat into many gigabytes on disk over time. One contributor reported their palace dropped from about thirty gigabytes down to under four hundred megabytes after the fix landed, and operations that were timing out before now respond instantly. The number is one person's field report, but the underlying fix is in place for everyone.

  • Background hooks now correctly recognize Claude Code conversations. The hooks that auto save your sessions used to treat conversation transcripts as if they were source code, which caused indexing confusion. Now they are tagged correctly as conversations, which means cleaner storage and better recall when you go looking for what you said.

  • The promises have not moved. Every word stored exactly. Everything stays on your machine. Nothing goes anywhere we have not explicitly told it to go. No telemetry. Zero. Each release sharpens what is already there instead of asking you to give up something you care about.

What's Changed

  • perf(mining): batch per-chunk upserts + optional GPU acceleration by @igorls in #1185
  • feat(graph): cross-wing tunnels by shared topics (#1180) by @igorls in #1184
  • chore: add OpenArena owner claim verification file by @igorls in #1189
  • fix(search): CLI hybrid rerank, legacy-metric warning, invariant tests (3.3.4) by @igorls in #1179
  • feat(cli): init prompts to mine, mine handles Ctrl-C gracefully (#1181, #1182) by @igorls in #1183
  • docs: fix HOOKS_TUTORIAL.md paths, matcher, and missing timeout (#1037) by @wahajahmed010 in #1101
  • chore(deps): bump actions/deploy-pages from 4 to 5 by @dependabot[bot] in #967
  • chore(deps): bump actions/upload-pages-artifact from 3 to 5 by @dependabot[bot] in #968
  • chore(deps): bump actions/checkout from 4 to 6 by @dependabot[bot] in #969
  • ci: add pip caching and bump Python on macOS/Windows by @mvalentsev in #939
  • fix(security): restrict tunnels.json file permissions by @arnoldwender in #1168
  • fix: HNSW graph corruption, PreCompact deadlock, mine fan-out (closes #974, #965, #955) by @felipetruman in #976
  • ci: bump Windows and macOS jobs to Python 3.13 by @igorls in #1205
  • fix: guard against data loss in repair, migrate, and CLI rebuild by @shaun0927 in #935
  • fix(repair): refuse to overwrite when extraction looks truncated (#1208) by @bensig in #1210
  • fix: sanitize topic parameter in tool_diary_write by @shaun0927 in #936
  • feat(init): context-aware corpus detection by @milla-jovovich in #1211
  • fix: call quarantine_stale_hnsw() in make_client(); lower threshold to 5min by @jphein in #1173
  • feat(corpus-origin): merge LLM fields into heuristic result instead of replacing by @milla-jovovich in #1221
  • fix: skip _fix_blob_seq_ids sqlite open on already-migrated palaces (#1090) by @jphein in #1177
  • fix(palace_graph): skip None metadata in build_graph by @jphein in #1201
  • fix(searcher): tolerate None documents in BM25 reranker by @jphein in #1198
  • feat(privacy): warn when LLM tier sends content to external API by @milla-jovovich in #1224
  • chore(corpus-origin): tag merged evidence by tier + pin confidence-source contract by @igorls in #1223
  • feat(privacy): treat Tailscale CGNAT range (100.64.0.0/10) as local by @milla-jovovich in #1225
  • fix(repair): detect HNSW capacity divergence and fall back to BM25 (#1222) by @igorls in #1227
  • fix(hooks): pass --mode convos when mining Claude Code transcript dirs by @igorls in #1230
  • fix(hooks): always mine the active transcript as convos, additive to MEMPAL_DIR by @igorls in #1231
  • fix(graph): normalize wing slug at init so topic tunnels fire for hyphenated dirs (#1194) by @bensig in #1195
  • fix(tunnels): normalize wing names in topic tunnel lookup for hyphenated dirs by @wahajahmed010 in #1197
  • fix: narrow _fix_blob_seq_ids + add repair --mode max-seq-id by @sha2fiddy in #1135
  • fix: prevent HNSW index bloat from resize+persist cycles by @funguf in #1191
  • feat(privacy): blocking consent gate for env-fallback LLM API keys by @milla-jovovich in #1233
  • feat(normalize): Gemini CLI session JSONL adapter by @milla-jovovich in #1234
  • fix(repair): decode BLOB embeddings.seq_id in max-seq-id heuristic (#1254) by @igorls in #1288
  • fix(repair): scale HNSW divergence floor with hnsw:sync_threshold by @messelink in #1287
  • fix(storage): stop ChromaDB from crashing when reopening an existing … by @Legion345 in #1262
  • fix(mcp_server): split get_or_create_collection on reopen (follow-up to #1262) by @igorls in #1289
  • chore(release): v3.3.4 by @igorls in #1232

New Contributors

Full Changelog: v3.3.3...v3.3.4

v3.3.3 — restore install integrity

24 Apr 20:10
94f1689

Choose a tag to compare

Bug Fixes

  • Install regressionmempalace-mcp console script is now declared in pyproject.toml alongside .claude-plugin/plugin.json's reference to it. In v3.3.2 the two drifted apart (plugin.json shipped the new "command": "mempalace-mcp" form before the matching entry point landed), so every fresh pip install mempalace==3.3.2 produced a Claude Code plugin config pointing at a binary that wasn't installed. (#1093, #340)
  • Restore silent-save visibility after the Claude Code 2.1.114 client regression — production transcript saves were failing silently until this PR. (#1021)
  • Paginate status-path metadata fetches so large palaces don't trip SQLite variable limits. (#851)
  • Resolve the Claude plugin hook runner across platform / plugin-dir variations; previously broke on Windows and some macOS layouts. (#942)
  • Real python3 resolution for .sh hooks with a MEMPAL_PYTHON override path. (#833)
  • Add optional wing parameter to tool_diary_write / tool_diary_read and derive per-project wing from the Claude Code transcript path when writing from the stop hook — diary entries from different projects no longer collapse into a shared default wing. (#659)
  • Treat empty string as "no filter" in mempalace_search wing/room; LLM agents that default to filling every optional parameter with "" no longer get bounced with must be a non-empty string. (#1097, #1084)
  • Broaden _wing_from_transcript_path to handle Claude Code project folders without a -Projects- segment (e.g. ~/dev/<parent>/<project>, ~/code/<project>). The project name is now derived from the final dash-separated token of the encoded folder, so Linux users with code outside ~/Projects/ get per-project diary scoping instead of falling through to wing_sessions. (#1145, follow-up to #659)
  • mempalace_diary_read(wing="") now returns diary entries from every wing this agent has written to, matching the #1097 "empty-string as no filter" pattern. Previously defaulted to wing_<agent>, siloing entries that hooks wrote to project-derived wings. (#1145)
  • mempalace mine now skips the generated entities.json file so its contents aren't re-ingested as project content. (#1175)

Improvements

  • Deterministic hook saves. Save hook now uses a silent Python API path, so successive hook invocations produce reproducible results and zero data loss on the hot path. (#673)
  • Graph cache with write-invalidation inside build_graph() — warm-path calls no longer rebuild the palace-graph per request. (#661)
  • mempalace init entity detection overhaul. Canonical project names now come from package manifests (package.json, pyproject.toml, Cargo.toml, go.mod) and real people come from git commit authors, rather than being inferred from prose. Includes union-find dedup across name/email aliases, bot filtering that keeps @users.noreply.github.com humans, and automatic "mine" flagging by contribution share. (#1148)
  • Regex detector accuracy. CamelCase extraction so MemPalace, ChromaDB, OpenAI aren't fragmented; tighter versioned/hyphenated pattern kills context-manager / multi-word false positives; dialogue ^NAME:\s requires ≥2 hits so Created: <date> metadata stops classifying field names as people; expanded stopwords for common English participles and descriptors; high-pronoun signal classifies as person rather than dumping to uncertain. (#1148)
  • Init → miner wire-up. Confirmed entities merge into ~/.mempalace/known_entities.json on init, which the miner reads to tag drawer metadata for entity-filtered search. Previously init's output was not consumed by the miner; the per-project entities.json is kept as an audit trail. (#1157)
  • Case-insensitive project dedup across manifest, git, and convo sources so casing variants of the same project name collapse into one review entry. (#1175)

Added

  • i18n: Belarusian translation. (#1051)
  • i18n: entity detection for German, Spanish, and French locales. (#1001)
  • i18n: Traditional + Simplified Chinese entity detection. (#945)
  • mempalace init --llm: optional LLM-assisted entity classification. Defaults to local Ollama (zero-API); also supports any OpenAI-compatible endpoint (LM Studio, llama.cpp server, vLLM, OpenRouter, etc.) and the Anthropic Messages API. Runs interactively with a progress indicator; Ctrl-C cancels cleanly and returns partial results. Useful for prose-heavy folders where the regex detector struggles (diaries, transcripts, research notes). Opt-in only — default init path remains zero-API. (#1150)
  • Claude Code conversation scanner. ~/.claude/projects/<slug>/ directories now contribute project entities using each session's authoritative cwd metadata, avoiding slug-decoding ambiguity. (#1150)

Known — deferred to v3.3.4

  • HNSW parallel-insert SIGSEGV when hnsw:num_threads is unset on collection creation (#974) — fix in-flight as #976, awaiting rebase against develop.

Install

pip install --upgrade mempalace==3.3.3

See the full changelog for historical releases.

v3.3.2

21 Apr 04:48
cf0477b

Choose a tag to compare

What's Changed

Bug fixes

  • PID file guard — prevents stacking mine processes (#1023)
  • Quarantine stale HNSW — recover from HNSW/sqlite drift, fixes SIGSEGV crash (#1000)
  • Windows Unicode — replace Unicode checkmark with ASCII for Windows encoding (#681)

Copilot review fixes

  • Address Copilot review on release/3.3.2 (#1045)

Full Changelog: v3.3.1...v3.3.2

MemPalace v3.3.1

18 Apr 04:19
6889c6f

Choose a tag to compare

MemPalace v3.3.1

Highlights

  • Multi-language entity detection — 5 new locales (Portuguese, Russian, Italian, Hindi, Indonesian) with full entity-detection patterns
  • Script-aware word boundaries — fixes name truncation for Devanagari, Arabic, Hebrew, Thai, Tamil, Khmer scripts
  • Case-insensitive BCP 47 language codes--lang PT-BR, zh-cn, Pt-Br all resolve correctly
  • KG thread safety — lock on close(), query_relationship, timeline, stats
  • entity_registry.research() defaults to local-only (no outbound Wikipedia calls without opt-in)
  • Precompact hook no longer blocks compaction on failure/timeout
  • MCP stdout redirect — library logging can't corrupt JSON-RPC channel
  • File permission hardening on sensitive palace data

See CHANGELOG.md for full details.

Install / Upgrade

pip install --upgrade mempalace

MemPalace v3.3.0

14 Apr 11:11
4aa7e1e

Choose a tag to compare

Visit mempalaceofficial.com for the full story behind this release and a visual guide to the architecture.


Highlights

Closets are here

The architecture we designed — wings, rooms, closets, drawers — is finally complete. Closets are the searchable index layer: compact AAAK pointers that tell the searcher which drawer to open. Search hits closets first (fast), then hydrates the full verbatim content from drawers.

Closets are a boost signal, not a gate — direct drawer search always runs as the floor. Closets can only improve results, never hide them.

  • R@1: 0.42 → 0.58 (+38%) with regex closets
  • R@5: locked at 1.00 — no regression
  • Optional LLM closets (bring-your-own endpoint) push R@1 to 0.67

BM25 Hybrid Search

Search now combines vector similarity (60%) with BM25 keyword matching (40%). Catches exact names, project codes, and error messages that embeddings miss. Real Okapi-BM25 with Lucene IDF, not a placeholder.

8 Languages

MemPalace speaks English, French, Korean, Japanese, Spanish, German, Simplified Chinese, and Traditional Chinese. CLI output, AAAK compression instructions, and regex patterns all localized. Add a language by translating one JSON file.

Halls — content type routing

Drawers are now tagged by content type: technical, emotions, family, memory, creative, identity, consciousness. Halls connect rooms within a wing by what KIND of content they hold — search "emotional moments in my project" and get exactly those.

Multi-Agent Safety

File-level locking prevents concurrent agents from creating duplicate drawers. The delete+insert cycle is now atomic — two agents mining the same file can't interleave.

Cross-Wing Tunnels

Agents can create explicit links between projects. "This API design in project_api relates to the database schema in project_database." Four new MCP tools: create, list, delete, follow tunnels.

Background Everything

Save hooks no longer ask the agent to write in chat. Conversations are mined automatically from the transcript — no configuration needed. Zero tokens spent on bookkeeping.


What's New (since v3.1.0)

New Features

  • Closet layer — searchable index pointing to drawers
  • BM25 hybrid search — keyword + vector combined
  • i18n — 8 languages with per-language regex patterns
  • Diary ingest — day-based drawers, one per day, upsert as day grows
  • Cross-wing tunnels — explicit project-to-project links
  • Hall detection — content type routing (7 hall types)
  • Entity metadata — names stamped on drawers and closets
  • Fact checker — verify text against entity registry + knowledge graph
  • LLM closet regeneration — bring-your-own endpoint (Haiku, Gemma, any model)
  • Drawer-grep — search returns best-matching chunk + neighbors, not whole file
  • Backend seam for pluggable storage (#413)
  • mempalace migrate — recover palaces across ChromaDB versions (#502)
  • New MCP tools: drawer CRUD, tunnel management, hook settings, export (29 tools total)
  • Auto-save uses transcript path — no env var needed

Security

  • Palace deletion guardrails, WAL redaction, MCP input validation (#739)
  • Input validation, argument whitelisting, concurrency safety (#647)
  • Credential paths removed from benchmarks (#177)
  • Shell injection fixes in hooks (#387)

Bug Fixes

  • Remove chromadb <0.7 upper bound — unblocks 1.x installs (#690)
  • Fix convo_miner 8-line response truncation (#708)
  • Prevent HNSW bloat from duplicate add() calls (#544)
  • Unicode support in sanitize_name() — Latvian, CJK, Cyrillic (#683)
  • Auto-repair BLOB seq_ids for chromadb migration (#664)
  • Parse Claude.ai privacy export format (#685)
  • Detect mtime changes to prevent stale HNSW index (#757)
  • Full-content hash in drawer IDs for stable re-mines (#716)
  • Remove 10k drawer cap from status display (#707)
  • Noise stripping — system tags and Claude UI chrome removed from drawers
  • 30+ additional bug fixes

Documentation

  • CHANGELOG.md added
  • CLOSETS.md — closet lifecycle documentation
  • 42 TDD tests verifying every README claim against code
  • README audit: tool count (29), version badge, token costs, AAAK description all corrected

Internal

  • 109 commits since v3.1.0
  • Test suite: 860+ tests (up from ~90 at v3.1.0)
  • ruff 0.4.x lint + format clean

Install / Upgrade

pip install --upgrade mempalace

Thank you from Milla and Lu ✨

MemPalace v3.1.0

09 Apr 18:06
3919f13

Choose a tag to compare

First PyPI cut since v3.0.0 on 2026-04-06 — 39 merged PRs. This release closes the pip/plugin version drift (#290, #296) and lands the first-week community fixes.

🔒 Security

  • #387 Input validation at MCP entry points, shell-injection fix in save hook, file size guard + symlink skip, SQLite connection leak fix, WAL audit trail, hardened file perms
  • #141 Sanitize SESSION_ID in save hook
  • #139 Sanitize MCP error responses, remove sys.exit from library code

🐛 Bug fixes (highlights)

  • #399 MCP null args hang, cmd_repair infinite recursion, 500 MB OOM guard
  • #270 Claude + Codex plugin packaging — one-step install (closes #187)
  • #137 10K safety cap on unbounded ChromaDB metadata fetches (closes #180)
  • #129 Windows Unicode crash fix (closes #47)
  • #123 --yes flag bypasses all init prompts (closes #179)
  • #78 Respect nested .gitignore rules during mining (closes #233)
  • #236 Silence ChromaDB telemetry + Apple Silicon CoreML segfault (closes #163)
  • #324 Negotiate MCP protocol version instead of hardcoding
  • #145 Room detection checks keywords against folder paths
  • #136 SQLite WAL mode + consistent LIMIT in KG timeline
  • #66 Batch ChromaDB reads to avoid SQLite variable limit
  • #140 Upsert + deterministic IDs prevent data stagnation
  • Plus more — see full commit log

✨ Features

  • #61 OpenAI Codex CLI JSONL normalizer (first in the #59 import format umbrella)
  • #223 Scale benchmark suite (106 tests)
  • #135 Cache ChromaDB PersistentClient — big perf win

📊 Benchmarks (the honest version)

  • #147 Honest AAAK stats (word-based token estimator, lossy labels)
  • Retired the recall_any@5 headline — see the aa10f8f README correction and the ongoing methodology threads in #27, #29, #39, #214, #168

📦 Packaging

  • #142 Tightened chromadb range (>=0.5.0,<0.7) + py.typed marker
  • #281 Test coverage 30% → 85% + Windows encoding fixes
  • #131 Migrated tests to uv, 20 → 92 tests
  • #16 Unified package and MCP version reporting

🙏 Thanks

Massive thanks to everyone who ran audits, caught real bugs, and sent clean PRs in the first week — especially @lhl, @dial481, @gizmax, @rohithzr, @hugooconnor, @anthonyonazure, @fubak, @fuzzymoomoo, @vanachterjacob, @SethRosenthal100, @cktang88, @adv3nt3, @slapglif, @skuznetsov, @rusel95, @M0nkeyFl0wer, @EndeavorYen, @bobmatnyc, @kpulik, @kevgathuku, @mvalentsev, @mvanhorn, @jonashertner.

Closes #290 and #296.

📥 Install

pip install --upgrade mempalace

MemPalace v3.0.0

06 Apr 22:05

Choose a tag to compare

MemPalace v3.0.0

The highest-scoring AI memory system ever benchmarked. And it's free.

Install

pip install mempalace

PyPI: https://pypi.org/project/mempalace/

Highlights

  • 96.6% LongMemEval R@5 — highest published score with zero API calls
  • 100% LongMemEval R@5 — with optional Haiku rerank
  • Palace architecture — wings, rooms, halls, tunnels, closets, drawers — +34% retrieval from structure alone
  • AAAK compression — 30x lossless shorthand dialect, works with any LLM (Claude, GPT, Gemini, Llama, Mistral)
  • Knowledge graph — temporal entity-relationship triples in SQLite (local, free)
  • Specialist agents — each agent gets its own wing and diary in the palace
  • MCP server — 19 tools, auto-teaches AAAK to your AI
  • Auto-save hooks — for Claude Code (save every N messages + pre-compaction emergency save)
  • Split command — break concatenated mega-transcripts into per-session files before mining
  • Fully local — no API key, no cloud, no subscription. Everything on your machine.

What's New in v3

  • mempalace split command for splitting concatenated transcript files
  • Specialist agent system with per-agent diaries
  • Improved entity detection during init
  • Room detection from folder structure
  • Ruff-clean codebase

Requirements

  • Python 3.9+
  • No API key required