github doobidoo/mcp-memory-service v10.33.0
v10.33.0 — Non-Blocking Async SQLite + Silent Conflict Data-Loss Fix

2 hours ago

What Changed

This release resolves two production-quality issues in SqliteVecMemoryStorage that were exposed under concurrent async load.

Changed

  • Wrap all remaining direct SQLite calls in _execute_with_retry (#663, fixes #637): Eliminated ~119 direct self.conn.execute() / executemany() / commit() calls in async methods. All DB operations now run via asyncio.to_thread() through _execute_with_retry, preventing up to 15-second event-loop freezes under concurrent load (busy_timeout=15000 WAL mode).

    Key correctness guarantees introduced vs the community attempt (PR #654):

    • Cursor thread-safety: all fetchall()/fetchone()/rowcount accesses moved inside closures, never accessed after await asyncio.to_thread()
    • DDL idempotency: ALTER TABLE ADD COLUMN guarded by PRAGMA table_info() check; re-entrant on retry is safe
    • _savepoint_lock (asyncio.Lock) added to serialize store()/store_batch()/evolve_memory() SAVEPOINT sections at the coroutine level without blocking the event loop
    • Unique SAVEPOINT names (store_<hex>, batch_<hex>, evolve_<hex>) to prevent name collision

Fixed

  • _record_conflicts silent data loss (#663): _record_conflicts was writing conflict tags and graph edges inside _execute_with_retry threads but never called self.conn.commit(), causing all conflict data to be silently discarded. Fixed by adding self.conn.commit() inside the _record_all_conflicts closure.
  • store_batch outer-scope mutation (#663): batch_insert closure now returns its results list instead of mutating an outer-scope variable.

Upgrade

Drop-in upgrade — no breaking changes, no migration required.

pip install --upgrade mcp-memory-service
# or
uv add mcp-memory-service==10.33.0

Stats

Full Changelog

See CHANGELOG.md for complete details.

Don't miss a new mcp-memory-service release

NewReleases is sending notifications on new releases.