MCP-native, self-hosted memory for AI agents — with the governance an enterprise will actually ask for.
One static binary. Local embeddings. No cloud, no graph database, no Python stack.
Redaction happens before anything is written; every read is audited.
./memalyze # MCP over stdio, for Claude Code / Cline / any harness
v0.1.0 is out — static
binaries for linux/darwin/windows, checksums published alongside.
The problem
Every agent framework ships its own memory: a vector table here, a JSON file there, a
"notes" folder somewhere else. Three things follow, and all three hurt in production:
You cannot audit it. "Which customer's data did the agent read last Tuesday?" has no
answer, so security review stops the project.
You cannot deploy it offline. Most options either call a cloud API or download model
weights from HuggingFace at runtime — both fail inside a bank, a hospital, or a factory.
You cannot keep it small. Twenty-three tools, a graph database, and a Python
dependency tree later, the "memory feature" is a second product to operate.
memalyze is the middleware that fixes those three, and nothing else.
What is different
Cloud memory APIs
Framework built-ins
Personal note apps
memalyze
Where data lives
vendor cloud
inside the framework
local Markdown
your server / your laptop
How to connect
proprietary API
tied to one framework
MCP
MCP, any harness, stdio or HTTP
Redaction before write
❌
❌
❌
✅ 8 rule families, configurable, irreversible by default
Read audit
partial
❌
❌
✅ append-only*, per-actor, exportable
Offline
❌
partial
⚠️ model download needed
✅ local embeddings, no network
Deployment
SaaS
with the framework
173 Python packages
✅ one static binary / one compose file
Tool surface
—
—
23 tools
4 tools
* A database trigger rejects UPDATE on audit_log; DELETE is not blocked, so anyone
with the database file can remove rows. It is append-only at the SQL level, not WORM — export
to object-lock or syslog storage if deletions are inside your threat model
(SECURITY.md).
Not another mem0, and not Basic Memory either: those are good at remembering. memalyze
assumes remembering is becoming a commodity and competes on governance, offline
operation, and a deliberately small surface.
30-second demo
No Ollama, no network, no MCP client:
./examples/demo/demo.sh
# or: go run ./cmd/memalyze demo
It writes a memory containing a phone number, an e-mail and a resident ID, then shows:
what is actually stored ([REDACTED:phone], not 13800138000);
that searching for the original number returns 0 hits;
that a business-word search still hits, returning the redacted text;
the audit rows for the two writes and the two reads.
Prebuilt, checksum-verified (Linux/macOS; Windows: take the .exe from the release page):
curl -fsSL https://raw.githubusercontent.com/mahaoboy/memalyze/main/scripts/install.sh | sh
ollama pull qwen3-embedding:0.6b # ~640 MB, 1024-dim, strong on Chinese
memalyze --version
From source (Go 1.27+): make build, then ./memalyze --version.
2. Wire it into a harness
Claude Code (project scope):
claude mcp add --scope project memalyze -- "$(pwd)/memalyze"
cp examples/claude-code/CLAUDE.md ./CLAUDE.md # makes Claude search before answering
Cline: copy examples/cline/cline_mcp_settings.json and .clinerules.
Generic harness: examples/custom-harness/ — one prompt contract
plus pseudocode. All options: examples/README.md.
3. Or one-click in Claude Desktop (MCPB)
Download the bundle for your platform from the
v0.1.0 release and open it.
Claude Desktop shows an install sheet and asks where to keep memalyze.db.
Platform
File
macOS Apple Silicon
memalyze-0.1.0-darwin-arm64.mcpb
macOS Intel
memalyze-0.1.0-darwin-amd64.mcpb
Windows x64
memalyze-0.1.0-windows-amd64.mcpb
Linux x64
memalyze-0.1.0-linux-amd64.mcpb
The binary inside is the same v0.1.0 build as above. These bundles are new and have not
been opened on a real macOS/Windows desktop yet — if the install sheet does not appear,
use the plain binary. The server is also listed in the
MCP Registry.
4. Or run it in Docker (memalyze + Ollama + model pull)
Point a Streamable-HTTP MCP client at http://127.0.0.1:8080/mcp with
Authorization: Bearer $MEMALYZE_HTTP_TOKEN. See docs/s16-docker.md.
Tools
Four, on purpose. Every extra tool is a decision the model has to make.
Tool
What it does
Notable semantics
memory_add
store a memory
duplicates return the existing id; embedding failure keeps the memory (embedding_failed=true); returns redacted + rule names
memory_search
retrieve
vector first, keyword backfill, degraded + degrade_reason when the vector path is unavailable; empty query lists recent
memory_delete
soft delete
idempotent for already-deleted ids; unknown id returns a tool error
echo
wiring check
proves the MCP link works; no business logic
There is nomemory_context tool: memory_search already returns text you can paste
into a prompt, and two overlapping tools make model choice worse (D-017).
Governance
Redaction (write path). Rules run in memory.Service.Addbefore dedup, FTS and
embedding — so plaintext never reaches the main table, the full-text index or a vector.
Modes: enforce (default), dry-run (count only, for tuning), off (debugging).
Custom rule packs are JSON: examples/redaction-rules.json.
Audit (read path). Append-only audit_log (a database trigger rejects UPDATE):
actor, tenant, scope, action, memory id, timestamp, result count, degraded, redaction
count. The search text itself is stored as SHA-256 + length unless you explicitly set
MEMALYZE_AUDIT_QUERY_PLAIN=1.
What is not here yet: per-user authentication (one token per process, actor from
env), audit retention/purge, reversible redaction, audit UI.
Retrieval, measured
Numbers from S8 on a 60-memory Chinese corpus, 16 queries, measured not assumed
(docs/s8-retrieval-report.md):
Approach
recall@3
MRR
qwen3-embedding:0.6b (default)
0.94
0.92
CJK bigram FTS5 (keyword backfill)
0.88
—
nomic-embed-text
0.47
—
Two counter-intuitive findings that shaped the design: SQLite FTS5's default tokenizer
cannot search Chinese at all (0.19 recall until we stored bigram text), and RRF fusion
scored worse than vector-only, so v0.1 does not fuse. See D-012.
Latency (S14, cold start fixed): warmup 37.8 s in background, then search 1.14 s with
degraded=false; after five idle minutes a fresh process answers in 1.52 s. If the vector
path is unavailable, search degrades to keyword in ≤3 s instead of hanging (D-015/D-018).
Known gaps: no per-user auth, no audit retention, the Docker image has not been built in
CI (no daemon in the dev environment), brute-force vector scan, Chinese-first defaults
(English works, but the tokenizer is tuned for CJK).
threat model: what is defended, what is out of scope
Pilot
Two-week pilot: we install memalyze in your environment, tune the redaction rules to your
data, review the audit export with you, and write down the threat-model gaps we find. No fee;
you keep the deployment and the notes.