mnemochain
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mnemochainverify the claim that the meeting was rescheduled"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Mnemochain
A memory, ledger, reflection, replay, and citation-backed semantic recall layer for AI agents — built as one data structure, not six separate systems. Runs entirely on your own machine. $0 to build, $0 to run, no server, no API key required.
(This project used to be two separate ones — Chronicle, the log/ledger/ replay layer, and agentmem, a hallucination-resistant memory library. They merged, with agentmem's trust layer becoming just another view on Chronicle's log — a genuine simplification, not just glue code, see "Why merging simplified things" below. The merged project was renamed to Mnemochain afterward: "Chronicle" was already taken by several other published projects on PyPI and elsewhere, and mnemo- [memory] + chain [the hash chain] describes what this actually is more precisely anyway.)
The idea
An agent's entire history is a single append-only, hash-chained log (think "git for agent cognition"). Every other capability is just a view on that log:
Capability | How it's implemented |
Memory (raw) |
|
Memory (semantic, cited) |
|
Paraphrase-augmented recall | optionally store 3-5 alternate phrasings of each fact so recall() also matches differently-worded queries — a local Ollama model if you have one, or a zero-dependency synonym swap if you don't; only the original fact is ever cited — |
Hallucination checking |
|
Contradiction detection | two active memories that disagree get flagged automatically, even with no explicit key linking them |
Verifiable ledger | each row's hash covers its content + the previous row's hash (plain SHA-256, no blockchain, no gas fees) — |
Reflection | a scheduled job folds recent entries into a distilled "lesson," using a local model if you have one, or a zero-dependency rule-based summarizer if you don't — |
Skill-sharing | lessons are just JSON — export them, commit to a git repo or drop in a shared folder, another agent imports them — |
Replay / rollback | the log is immutable, so "rollback" is a read-only view of an earlier point, never a delete — |
Cost control | a rule-based router defaults every task to the local backend; it only touches a paid API if you explicitly flip |
Important naming distinction: ledger.verify_chain() checks the log
hasn't been tampered with. semantic.SemanticView.verify_claim() checks
whether a fact is actually true according to memory. These are
deliberately different names for deliberately different kinds of trust —
don't confuse them.
Related MCP server: neurakeep
Why merging simplified things, not just combined them
agentmem used to track supersession with an explicit superseded_by field
that got mutated in place. Mnemochain's log is append-only — nothing can be
mutated. So "the active fact for key X" is just the latest log entry with
that key, derived fresh each time. No mutation tracking needed at all;
the append-only design gives you supersession for free.
It also structurally fixed a real bug: the standalone agentmem had a
cached TF-IDF vocabulary that could go stale between calls (see
docs/ROADMAP.md for that story). SemanticView caches nothing between
calls — every recall()/verify_claim() re-derives from the log — so that
whole bug class is now impossible by construction, not just patched.
Why this stays at $0
Storage: SQLite (stdlib, no server).
Hashing:
hashlib.sha256(stdlib, no blockchain fees).Semantic recall: TF-IDF via scikit-learn by default (one local install); swap in
sentence-transformersfor real embeddings, still local and free.Reflection: Ollama running a local open-weight model if installed; otherwise an offline rule-based summarizer that ships with zero dependencies and always works.
Paraphrase generation: same local-first pattern — Ollama if reachable, otherwise a zero-dependency synonym swap. Either way, a few extra sentences of SQLite storage per fact; nothing like the cost of training or fine-tuning anything.
Sharing: a git repo or plain file copy — no hosting bill.
MCP server:
pip install "mcp[cli]"— one local install, still $0, no hosting.The only code path that can ever cost money (
backends/api.py) is intentionally unimplemented and inert until you wire a key yourself.
Packaging note: import mnemochain alone stays stdlib-only — it does
NOT pull in numpy. Only from mnemochain import semantic (or running the
CLI's semantic commands / the MCP server) needs pip install numpy scikit-learn. This was almost broken during the merge — an earlier draft
eagerly imported semantic from __init__.py, which silently forced
numpy onto every user of the base log/ledger/replay functionality. Caught
by testing the import with numpy blocked before shipping.
Quickstart
python examples/quickstart.py # the original log/ledger/reflect/replay demo
python examples/semantic_demo.py # the new citation/verify/contradiction demoOr via the CLI:
python -m mnemochain.cli add agent-1 action '{"task": "search papers"}'
python -m mnemochain.cli reflect agent-1
python -m mnemochain.cli verify # tamper check
python -m mnemochain.cli export lessons.json
python -m mnemochain.cli import lessons.json agent-2
# semantic commands (need: pip install numpy scikit-learn):
python -m mnemochain.cli remember agent-1 "The user's name is Priya." --key user.name
python -m mnemochain.cli recall "what's the user's name?"
python -m mnemochain.cli verify-claim "The user's name is Priya." # fact check, not tamper check
python -m mnemochain.cli contradictions
# store alternate phrasings too, to improve recall against different wording:
python -m mnemochain.cli remember agent-1 "The user moved to Munich." --key user.location --paraphrase
python -m mnemochain.cli recall "where does the user live?"Using it as an MCP server
Needs one local install with network access — still $0, no hosting:
pip install "mcp[cli]"
python -m mnemochain.mcp_serverClaude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"mnemochain": {
"command": "python",
"args": ["-m", "mnemochain.mcp_server"]
}
}
}Exposes: remember (with an optional paraphrase flag), recall,
verify_claim, list_contradictions (semantic memory) plus verify_chain,
reflect (audit + distillation) — one server, both capabilities. Every
tool call opens its own fresh SQLite connection rather than sharing one
cached globally (see "Bugs found and fixed" below for why that matters).
Everything persists to a single SQLite file (default ./mnemochain.db,
override with MNEMOCHAIN_DB_PATH) — that IS the durable store, no
separate save/load step.
mcp_server.py is directly tested via MCPServer.call_tool()/
.list_tools() in tests/test_mcp_server.py (needs pip install "mcp[cli]", skips itself gracefully otherwise) — not just the do_*
functions it calls. That closed a real gap: an earlier version of this
project had no network access to install mcp at all, so the server file
had never actually been run. The first real install surfaced two genuine
bugs on the very first try (see below) — worth stating plainly, since
"never run" and "no bugs" are different claims and it would have been easy
to conflate them.
Run the tests
python -m unittest discover -s tests -v62 tests with every optional extra installed (numpy, scikit-learn,
mcp[cli]) — 55 without mcp, which test_mcp_server.py detects and
skips gracefully rather than failing. The base log/ledger/reflect/replay
suite needs neither.
Project layout
mnemochain/
log.py # append-only hash-chained log
ledger.py # chain verification / tamper detection
reflect.py # distill entries into lessons
skills.py # export/import lessons between agents
replay.py # fold/replay, checkpoints, rollback views
router.py # local-first cost router
mirror.py # JSONL durability mirror, rebuild a lost DB from it
identity.py # HMAC / Ed25519 signing
embeddings.py # pluggable embedding backends (TF-IDF now, real embeddings later)
semantic.py # citation-backed recall, verify_claim, contradiction detection
paraphrase.py # optional alternate-phrasing generation to widen recall()
mcp_tools.py # MCP tool logic, fully tested, zero mcp-package dependency
mcp_server.py # MCP protocol wiring, directly tested via call_tool()
cli.py # command-line interface (base commands + semantic commands)
backends/
rule_based.py # zero-dependency fallback (always available)
local.py # Ollama backend (free, local)
ollama_client.py # shared HTTP client for the local Ollama server
api.py # optional paid backend (inert by default)
tests/
test_basic.py
test_robustness.py
test_semantic.py
test_paraphrase.py
test_mcp_server.py # skips itself without `pip install "mcp[cli]"`
examples/
quickstart.py
semantic_demo.py
docs/
ROADMAP.md # full phase-by-phase history, what's done, what's nextRobustness
Hardening passes on the base log design, plus the merge itself, each with its own tests:
Concern | What was added | Honest limit |
Concurrency | WAL journal mode + 30s busy_timeout on every connection | Doesn't make concurrent writers coordinate — just stops them crashing on lock contention |
Reflection & paraphrase reliability |
| Still falls back to the rule-based summarizer / synonym swap, which is much less rich than a real model |
MCP server concurrency | Every tool call opens its own SQLite connection instead of sharing one cached global | A cached connection crashed the moment two calls landed on different worker threads — see "Bugs found and fixed" below |
Authorship |
| HMAC uses one shared secret per agent — forgeable by anyone who also holds that secret. For strangers, use |
Scale |
| Incremental verification trusts prior checkpoints — won't catch tampering behind one. Run a full |
Durability |
| The mirror only helps if anchored somewhere an attacker doesn't also control (e.g. committed to git separately) |
Hard $0 ceiling |
| Only enforced where you actually call it — nothing stops code that bypasses the router |
Semantic recall (merge) |
| O(n²) contradiction scan and a full TF-IDF refit on every call — fine to a few thousand memories, a documented scale ceiling, not a silent one |
Bugs found and fixed
Every entry here came with its own regression test, so if the mistake ever
tries to sneak back in, it gets caught immediately instead of silently
breaking things again. docs/ROADMAP.md has the full phase-by-phase story;
the ones below are specifically what real network access and a real
Windows + Ollama environment surfaced that a network-less sandbox couldn't:
ollama runcorrupted output on Windows two independent ways.subprocess.run(text=True)decodes stdout using the process's locale codepage (cp1252 on this machine), not UTF-8 — any non-cp1252 byte in a model's reply raisedUnicodeDecodeErrorin a background thread. Separately,ollama runrenders as if for an interactive terminal, so raw ANSI cursor-control codes (e.g.\x1b[7D\x1b[K) leaked into the captured text. Both reproduced against a real local Ollama install before being fixed by talking to Ollama's HTTP API directly (ollama_client.py) instead of shelling out.MemoryView.citation()crashed on narrower Windows codepages. It embedded a Unicode em-dash; encoding that on cp437 (a commoncmd.exedefault) raisesUnicodeEncodeErrorand crashes the process outright — reproduced directly against the exact string, not hypothetical. Fixed by using a plain ASCII separator in every string that's actually printed or raised at runtime (citations, and two similar exception messages); docstrings/comments were left alone since those are never printed.mcp_server.pyhad never actually been run. An earlier version targeted themcppackage's olderFastMCPAPI from memory, with no network access available to verify it. The first realpip install "mcp[cli]"pulled mcp 2.x, which renamedFastMCPtoMCPServer— immediateModuleNotFoundError. Fixed by migrating to the real, installed API and testing it directly viaMCPServer.call_tool().The MCP server's cached connection crashed under real dispatch.
MCPServerruns synchronous tool functions on a thread pool; a sqlite3 connection can only be used from the thread that created it. The first version cached one connection in a module global, which broke withSQLite objects created in a thread can only be used in that same threadthe moment two tool calls landed on different worker threads — reproduced directly in-process, then fixed by opening a fresh connection per call instead (see the Robustness table above).
Contradiction detection: what it catches, what it doesn't
Flags two active memories as conflicting when they share a strong anchor
and either (a) one negates the other ("is open" vs "is not open" — catches
yes/no, done/not-done, enabled/disabled) or (b) they differ on a real value
— a number or proper noun (dates, places, names, amounts). Known miss:
plain lowercase antonyms with no negation and no number ("the light is
red" vs "the light is green") — closing that needs real NLP, tracked in
docs/ROADMAP.md, not silently pretended to be solved.
Paraphrase generation: what it catches, what it doesn't
SynonymSwapParaphraser (the zero-dependency fallback) only recognizes
literal phrases in its own small built-in table — it returns nothing
rather than fabricating a variant for wording it doesn't know, same
honesty standard as the rest of this project's fallback backends.
OllamaParaphraser is far more general (it's a real local model) but
still, like the underlying TF-IDF matcher, works on exact tokens: it
doesn't stem, so a paraphrase using "lives" won't match a query using
"living" or "live" unless the wording is genuinely identical. Swapping in
SentenceTransformerBackend narrows that gap further; paraphrasing and
better embeddings are complementary, not substitutes for each other.
Roadmap ideas
See docs/ROADMAP.md for the full phase-by-phase history (including
every bug found and fixed along the way — the merge-time stale-vocabulary
bug and numpy-import leak, plus the Windows/Ollama/MCP bugs above) and
what's next: LangChain/CrewAI adapters, a proper hallucination benchmark
(LOCOMO/LongMemEval), peer-to-peer lesson exchange, a static-HTML chain
browser, and real NLP for the contradiction-detection antonym gap.
License
AGPLv3, dual-licensed with a commercial option — see LICENSE and
COMMERCIAL.md.
Free to use, self-host, and modify under AGPLv3, including commercially — with AGPLv3's core condition: if you run a modified version as a network service, you must make that modified source available to your users. A separate commercial license (terms negotiated directly, not fixed here) is available for organizations that specifically don't want that condition.
Why this over plain MIT or a Business Source License: MIT alone gives a well-funded competitor no reason not to just take this and sell a hosted version with nothing owed back. A Business Source License is NOT OSI-approved open source, which weakens the "real open-source project, real community credibility" story that's part of the plan here. AGPLv3 is OSI-approved open source (genuine stars, genuine community trust) while its network-use clause is exactly what creates a reason for a company that wants to avoid that clause to pay for a commercial license instead of just forking it.
Said plainly: this is a business judgment call, not a legal one — get
real legal review before actually relying on the commercial side to make
sales. No commercial contract has been drafted; COMMERCIAL.md explains
the model, it isn't a signable agreement.
Author
Maintained by Nulfied. Commercial licensing
inquiries: see COMMERCIAL.md, or open an issue on this repo.
This server cannot be deployed
Maintenance
Related MCP Connectors
- memnodeOAuthdev.memnode
Persistent, inspectable memory for AI agents with lineage, correction, and a hosted MCP endpoint.
Persistent memory for AI agents to retain, retrieve, and recall conversation context through MCP.
MCP-native Trust Infrastructure for AI Agents. Persistent encrypted memory with Trust Quotient.
Persistent personal memory for AI assistants — save, search, and recall across every MCP client.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceLocal-first AI memory layer with hybrid retrieval and brain-inspired namespaces. Enables agents to save, search, and manage memories directly via MCP tools.3 npmMIT
- AlicenseNot gradedqualityCmaintenanceProvides a local-first, source-cited memory layer for AI agents, with MCP tools to search, read, explain sources, and propose/apply memory updates.26 npm7Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to store, search, assemble, and manage local-first memories through seven MCP tools, including conversation turns, feedback, status, and dashboard access without cloud dependencies.AGPL 3.0
- FlicenseAqualityAmaintenanceShared fleet memory for AI agents — what one agent learns, the whole fleet knows. Nightly self-correction: stale facts rewritten in place, duplicates merged. Recall pushed into every prompt in supported coding agents. Self-hosted.8112-