agentic-mcp-tools/memora
MCP Developer ToolsA persistent memory layer for AI agents with structured storage, semantic retrieval, and graph relations across sessions.
Features
- Persistent SQLite storage with optional cloud sync (S3, R2, D1)
- Hierarchical organization of memories with auto‑hierarchy assignment
- Semantic search using vector embeddings (TF‑IDF, sentence‑transformers, OpenAI)
- LLM‑powered deduplication and memory linking via typed edges
- Document storage as searchable markdown fragment trees
Recent releases
View all 15 releases →- Issues tab in web UI with inline status and category editing for memories of type: issue
Full changelog
Notable changes since v0.2.27
Fixes
- MCP schema sanitizer (
memora/server.py) — strips Pydantic-generated nullableanyOfcombinators from tool input schemas before servingtools/list. Anthropic's tool validator rejected these, which 400'd the entire MCP handshake and made Claude Code disconnect the server. Reviewed end-to-end by an inter-agent bus loop (claude-B audit + codex review). 19 of 41 memora tools were affected; all clean after sanitize. - Embedding fallback observability (#457) — stops silent fallback to TF-IDF when the OpenAI embedding endpoint fails; warns visibly instead of degrading silently. Also adds explicit warn-on-fallback log path.
- API issue filter tightening —
/api/memoriesissue filter now requires strictmetadata.typematch instead of fuzzy heuristic. - Graph spin fixes (5 commits) —
vis-networkphysics now disables after stabilization, force-disables 1.5s after drag, re-enables on dragStart for elasticity, explicitly starts simulation on drag events, and stops endless spinning aftermemory_updaterealtime reload. - Favorites filter (#544) — fetches the full memory set from the server instead of filtering only the loaded page.
Features
- Issues tab in web UI — inline status / category editing for memories of
type: issue.
Reverts
- Reverted Block 4 of duplicate-review UI action-buttons wiring (held back pending follow-up work).
- `memory_store_document`, `memory_get_document`, `memory_delete_document` APIs for markdown document storage with typed fragments
- Structure‑aware parser (`document.py`) that splits by headings, tables, lists, and risk sections
- Graph UI shows only the document root node while hiding fragment nodes
Full changelog
What's New
Structured Document Storage
memory_store_document— Store markdown documents as a root memory + searchable typed fragments (claims, plan items, references, risks, section chunks)memory_get_document— Retrieve documents by key with optional fragment type filteringmemory_delete_document— Cascade delete a document and all its fragments- Structure-aware parser (
document.py) — splits by headings, tables, numbered lists, URL lists, and risk sections instead of blind token chunking - Fragment integrity guards — protects document fragments from accidental delete, merge, absorb, duplicate detection, and supersession detection
- Graph UI — document fragments hidden from visualization (local + cloud); only the document root node is visible
Auto-categorization Improvements
- Auto-assign
metadata.sectionfrom detected project at write time - Normalize generic tags to project-prefixed tags automatically
- Backfill tag detection now catches subsection changes
- Derive subsections from bare tags when no prefixed tags exist
- Broader project detection with tag-based fallback and more content patterns
Bug Fixes
- Fix
find_duplicate_candidatestype error when crossref entries have mixed ID types - Fix crossref computation to exclude document fragments from similarity graph
- Skip typed link entries (supersedes, extends, etc.) in duplicate candidate scanning
- memory_detect_supersessions tool for retroactive supersession detection with 6-way LLM relation enum
- Lineage-aware retrieval via `follow` parameter and context-efficient retrieval improvements
- --version flag added to memora-server CLI
Full changelog
What's New
memory_detect_supersessions — Retroactive supersession detection
New MCP tool that scans existing memories for pairs where one updates/replaces another, then creates supersedes edges between them. Complements memory_absorb which only catches supersessions at write time.
- Neutral LLM classification with 6-way relation enum (a_supersedes_b, b_supersedes_a, duplicate, related, contradicts, neither)
- Conservative defaults:
dry_run=True,min_confidence=0.75 - 30s rate limit cooldown
- No schema changes required
Bug fixes
- Fix three bugs in
memory_absorbthat broke LLM classification and fact grouping - Consolidate related new facts into single richer memories via LLM synthesis
- Bump graph cluster thresholds back to 0.4
Other improvements
- Lineage-aware retrieval:
followparameter for supersession chain walking - Context-efficient retrieval: compact defaults, fields projection, hybrid filter fix
- Add
--versionflag to memora-server CLI - Add install script for server, skill, and MCP config guidance
- New optional env var `MEMORA_VECTOR_SCAN_PAGE_SIZE` (default: 1000) – rarely needs tuning
- XSS attribute injection fix in graph UI (#36)
- Stale draft cancellation security improvement (#37)
- `memory_create` / `memory_update` latency reduced from ~10 s to ~2 s on D1 backend (5× faster)
- Cached `ensure_schema()` runs once per backend instance, eliminating repeated round‑trips
- Single paginated LEFT JOIN replaces two‑step memory/vector scan, reducing D1 calls
Full changelog
Headline
`memory_create` / `memory_update` drop from 10s+ to ~2s per call on the D1 backend — 5× faster.
Three independent fixes, all landing together:
- Cached `ensure_schema()` per backend instance — previously ran 7–9 D1 round-trips on every MCP tool call (~4–8s wasted each). Now runs once per backend per process. [`memora/schema.py`]
- Single paginated LEFT JOIN for crossref/vector scan — replaces the old `list_memories(...) + _get_embeddings_for_ids(...)` two-step that cost ~10 sequential D1 round-trips on stores with many memories. [`memora/storage.py`]
- Per-instance D1 session token + backend-level keep-max bookmark mirror — the old class-level token could be stomped by cross-thread code (`cloud_sync`'s `threading.Timer`), corrupting read-your-writes. Now safe under concurrency. [`memora/backends.py`]
Also in this release
- Durable Object request reduction — WebSocket keepalive ping removed, broadcasts skipped when no clients connected, disconnect on hidden tab. Direct Cloudflare cost savings.
- Schema cache correctness — `CloudSQLiteBackend.sync_before_use()` can `shutil.move` a fresh DB file over `cache_path`; the cache now invalidates via inode-based signature so long-lived processes don't run against a post-replacement DB with stale schema assumptions.
- Security (merged from main) — XSS attribute injection fix in graph UI (#36), stale draft cancellation (#37).
- Docs — eventual-consistency model of the `related` graph documented in `memory_related` and `memory_rebuild_crossrefs` MCP tool docstrings.
Upgrade notes
- No schema migration required.
- No public API signature changes.
- No configuration changes required.
- New optional env var `MEMORA_VECTOR_SCAN_PAGE_SIZE` (default: 1000) — rarely needs tuning.
- 39/39 tests passing.
Verified performance
Measured against live D1 (steady-state, medium-length memory):
| Operation | Before | After |
|---|---|---|
| `storage.connect()` 1st | — | ~1.9s |
| `storage.connect()` 2nd+ | ~4–8s (schema probe) | ~0ms (cache hit) |
| `add_memory` | 10s+ | ~1.8s |
| `update_memory` | 10s+ | ~1.1s |
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.