mcpmem-core 1.0.0

Transactional SQLite knowledge-graph core for the mcpmem MCP server: entities, relations, observations, FTS5 projections and a durable event outbox.
Documentation

mcpmem-core

The transactional SQLite knowledge-graph core of mcpmem, an MCP server that gives LLM agents persistent memory.

This crate is a library. It holds no transport and no MCP layer. Install the server crate instead if you want to run the server:

cargo install mcpmem

What this crate owns

  • The graph. Entities, relations and observations, with the FTS5 projections over names and observation bodies.
  • The schema bootstrap. schema::initialize_database creates the base tables, the full-text tables, the triggers and the seeded counters in one transaction, then applies the ordered migrations. Every runtime role calls it, so a worker process and the server agree on the database layout.
  • The migrations. events::MIGRATIONS embeds the SQL files under migrations/. The runner records each version in schema_migration with a SHA-256 checksum. A changed checksum for an applied version stops startup, and a database newer than the binary stops startup.
  • The mutation service. Every mutation runs in one BEGIN IMMEDIATE transaction that covers the graph rows, the derived counters, the change events and the index jobs. A guard rolls back on any later failure, so a partial write cannot happen.
  • The change log and the outbox. change_event is immutable and a trigger protects it. event_outbox and index_job carry the durable work for the two worker crates.
  • The relation-integrity repair. The audit and the backup-gated repair that the mcpmem-maintenance binary runs.

Data model

Entity(name, entityType, observations[])   ──relationType──▶   Entity(...)
  • Entity — a named node with a type, for example person, company or project. Names are unique and case-sensitive.
  • Relation — a directed edge (from, to, relationType). Traversal follows both directions.
  • Observation — a fact attached to an entity. An observation carries a body, the server-owned createdAtUs, an optional caller-supplied occurredAtUs, and originEntityName when a merge copied it.

Search uses FTS5 with unicode61 remove_diacritics 2 tokenization. Names and observation bodies live in separate external-content FTS5 tables, name_fts and obs_fts.

Tables

Table Purpose
entity Primary storage; materialized obs_count, out_deg, in_deg; name_hash for O(1) routing
observation Observations of one entity, with created_us, occurred_us and the merge origin
relation Directed edges with covering indexes. A new database also gets UNIQUE INDEX relation_unique_triple
name_fts, obs_fts External-content FTS5 over names and observation bodies
type_dict Interned entity and relation types with live counts
graph_stat WITHOUT ROWID counters: entities, relations, observations, sequences
change_event The immutable change log
event_outbox Pending webhook deliveries, with leases
index_job Pending embedding work, one row per entity and profile
webhook_subscription The subscriptions that receive change events

Concurrency

GraphHandle holds one writer connection behind a mutex, plus a read-only connection pool for concurrent reads under WAL. A reader that needs a consistent bundle, for example describe_entity, takes one snapshot.

Documentation

The full server documentation is in the workspace README. The release notes are in CHANGES.md.

License

Apache-2.0. See LICENSE and NOTICE, which records the derivation from corporatepiyush/mcp-memory 5.2.1.