Install
$ agentstack add mcp-victorv2i-enfold ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Enfold
Local SQLite memory with provenance, current-state rules, and a small daemon.
Enfold is a local-first memory service for durable facts. It stores evidence and history in SQLite, keeps current state separate from superseded and conflicted facts, and exposes a Unix-socket daemon with an optional stdio MCP bridge. There is no hosted service.
Install
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e '.[mcp,sqlite-vec]'
sqlite-vec is optional and pinned to 0.1.9. The canonical fact_embeddings table remains the source of truth. If the extension, its index, or its metadata is unavailable, retrieval automatically uses brute-force cosine scoring instead. Rebuild an index only in a maintenance window:
python -m enfold.ops rebuild-vector-index /absolute/path/to/memory.db \
--embedding-identity 'provider:model:document:policy:version' \
--dimensions 768
Run
Create a user-owned JSON configuration with explicit database, socket, retrieval, and client grants. ci retrieval is deterministic plumbing only, not a semantic embedding model. See [server deployment](docs/SERVER_DEPLOYMENT.md) for the full configuration contract.
enfold-server --config /absolute/path/to/server.json check
enfold-server --config /absolute/path/to/server.json run
The optional MCP bridge connects to an already-running daemon and never opens SQLite itself:
enfold-mcp-proxy --socket-path /absolute/private/enfold.sock \
--client-id workstation-1 --surface local --agent-id worker-1 \
--session-id session-1
Retrieval and context
Candidates are authorized and filtered for current, settled facts before dense ranking. The default ranking is:
score = 0.90 × (0.35 × FTS + 0.25 × Jaccard + 0.40 × cosine)
+ 0.05 × trust + 0.02 × kind + 0.03 × recency
The kind prior is state 1.00, insight 0.75, untyped 0.50, and event 0.25. Recency uses an exponential 365-day half-life. These values and the confidence gates are RankingConfig defaults in enfold/hybrid_retrieval.py: score_floor: 0.12 rejects weak candidates and ambiguity_margin: 0.005 abstains when the top two results are too close. A named anchor in the query also requires that anchor in a candidate.
memory_context produces a bounded, cited Markdown block. It estimates tokens as Unicode characters divided by four, truncates individual facts to fit, omits unsafe or duplicate state slots, and can use maximal marginal relevance (MMR) to choose diverse context. MMR uses dense similarity when present and token overlap otherwise.
Writes and typed state
Writes are idempotent and carry provenance. Exact duplicates reuse the current fact. For untyped near duplicates, the service finds an FTS-bounded semantic candidate, writes the incoming observation, and merges the two by retaining one surviving fact while superseding the other. This is not a claim that every similar sentence is rejected.
Extraction accepts typed proposals with state, preference, commitment, or event labels when confidence is at least 0.8. Only state is routed into a structured (scope, subject_key, predicate_key) state slot. A changed state can supersede the prior slot value; competing current state is recorded as a conflict. The other labels remain attributed facts with their extracted type in metadata.
MCP tools
The bridge provides memory_write, memory_search, memory_context, memory_evidence, memory_history, memory_conflicts, memory_resolve_conflict, and memory_extraction_enqueue.
It also provides change and entity views:
memory_changes(since, until)lists created, superseded, and resolved facts
in a half-open time window.
memory_timeline(subject_or_query)returns chronological settled events.memory_entities()ranks visible entities from current subjects and tags.memory_entity(name)returns that entity's current facts, recent changes,
and open conflicts.
Operations
Use SQLite's backup API rather than copying a live database file:
python -m enfold.ops backup SOURCE.sqlite BACKUP.sqlite \
--secondary-directory /mounted/offsite \
--age-recipient-path /secure/recipients.txt
The primary backup is verified. A secondary destination is best effort: failure does not invalidate a completed primary backup. When age is available, Enfold uses age -R and places only an encrypted .age artifact in the secondary destination. Without age, it warns and makes a private plain copy. Keep identities and recipient files outside the repository and server config.
Rehearse the newest *.sqlite backup without changing the live database:
python -m enfold.backup_rehearsal LIVE_DB BACKUP_DIR STATE_DIR \
--fact-count-tolerance 100
The rehearsal restores to a temporary directory, runs quick_check, compares fact counts, writes a dated JSON pass/fail report, and exits nonzero on failure.
For a read-only local browser, configure browse_scopes, then create a filtered snapshot. It includes only current, settled, normal-sensitivity facts in those scopes and a small metadata.json for Datasette. Serve the resulting immutable SQLite file with a local Datasette installation:
python -m enfold.ops browse-snapshot /absolute/path/to/server.json
Regenerate the snapshot when browser-visible facts change. It does not serve or modify the live database.
Evaluation
The public Arena is a synthetic regression harness. It does not read a live store or measure production embedding quality:
python -m memory_eval.public_arena --provider core-fts-current --limit 5
The personal Arena harness is public, but its corpus remains private by design. Keep real cases and reports outside the repository, then run:
python -m memory_eval.personal_arena \
--cases ~/.config/enfold/private-arena/cases-v0.jsonl \
--db ~/.hermes/memory_store.db --seed 0
Each JSONL line has id, query, and category. Add either or both of expected_fact_ids and expected_content_regexes for an answerable case; omit both for an abstention case. forbidden_content_regexes identifies text that must not appear in the top three, and asof is an optional human-auditable time annotation. See the synthetic [format sample](memoryeval/fixtures/personalarena_sample.jsonl).
License
MIT, see [LICENSE](LICENSE).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: victorv2i
- Source: victorv2i/enfold
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.