Surreal-Memory MCP server
Commit Nov 13, 2026Provides AI agents with persistent graph-based memory using SurrealDB to enable multi-hop reasoning and spreading activation recall.
Also known as acidkill/surreal-memory
- Stars
- 7
- Tools
- 3
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Nov 13, 2026
- License
- MIT
What is Surreal-Memory MCP?
Surreal-Memory provides AI agents with persistent graph-based memory using SurrealDB to enable multi-hop reasoning and spreading activation recall. It exposes 3 tools, such as smem_remember, smem_recall, smem_health.
Summary generated from the project's README
About Surreal-Memory MCP server
Surreal-Memory provides AI agents with a persistent, graph-based memory system using SurrealDB as its multi-model backend. Unlike standard vector databases that rely solely on similarity scores, this server treats memories as interconnected neurons linked by explicit synapse types like CAUSED_BY or LEADS_TO. This architecture enables multi-hop reasoning and spreading activation recall, allowing agents to trace complex chains of causality rather than just finding keyword matches.
Developers can set this up locally via pip or through Docker, requiring SurrealDB version 3.2.0 or higher. The system is designed to work fully offline without mandatory embedding APIs, though it supports OpenAI-compatible credentials for enhanced semantic search. It offers a specialized set of tools including smem_remember for storing knowledge, smem_recall for retrieving it through association, and smem_health to monitor the state of the agent's brain. Users can also sync their memory across devices using a personal Cloudflare Worker setup.
What you can do with it
- 1Trace causal relationshipsAsk the agent to explain the root cause of a specific technical failure by traversing the memory graph.
- 2Ingest large document setsTrain the agent's memory by uploading various file formats like PDF or JSON to build permanent knowledge.
Written from the project's README. Every use case is checked against a quote from it.
Surreal-Memory MCP tools 3
Detected from the READMEsmem_remembersmem_recallsmem_health
| smem_remember | — | |
| smem_recall | — | |
| smem_health | — |
Configuration
GEMINI_API_KEY
| Name | Description | |
|---|---|---|
| GEMINI_API_KEY | — |
Automated checks
Ran Nov 14, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work
- Source repository linked and reachableacidkill/surreal-memory is public and reachablegithub.com/acidkill/surreal-memory ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-11-12github.com/acidkill/surreal-memory ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model3 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNo tool named like delete, drop or execPass
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubSurreal-Memory
Persistent graph memory for AI agents, powered by SurrealDB.
All features are free and open source. No license keys. No paywalls. No embedding API required for basic usage.
pip install surreal-memory[surrealdb]
smem init --full
Restart your AI tool. Your agent now remembers.
What's new in 3.12.2
- Safer consolidation recovery: resumable summarization, scoped pruning and change-log cleanup, and compression safeguards for pinned/shared neurons, original content, later edits and completed replay receipts.
- Less work per database round trip: native record targets, neuron reads in batches of 100, and optional verified acceleration for semantic checkpoint hashing.
- Quieter memory:
recall,context,recapandexplainno longer feed their queries or results back into passive memory capture. Explicit memory writes remain available; normal recall reinforcement still occurs. - More reliable operations: failed WebSocket queries are surfaced without unsafe replay, busy changefeeds are paged correctly, and completed-run semantic snapshots can be removed under a configurable retention policy.
- The dashboard command palette now filters page entries and Pro hints by query.
For an unfinished consolidation, use smem consolidate --resume --brain default.
For a new run, use smem consolidate --brain default. Existing strategy budgets
still apply; this release does not guarantee a large brain completes in one call.
Read the upgrade and consolidation guide before
maintenance, especially the backup and downgrade notes.
Previously in 3.12.1
smem consolidate --resumeresumes the saved incomplete strategy set and reference time after validating the checkpoint. Invalid or replaced checkpoints are refused without changing their stored state.- Fiber-census retries account for nullable fields omitted by SurrealDB while preserving page fingerprints and conflict checks.
Previously in 3.12.0
- Consolidation now advances through bounded, durable work units. Interrupted runs can resume from committed checkpoints, including semantic-link discovery, deduplication, fiber censuses, compression, and lifecycle work.
- Semantic-link discovery limits candidate memory and records source revisions so stale or repeatedly changing source data can be detected and recovered safely instead of replaying unbounded work.
- Pruning and retention resume between committed substeps after errors, and indexed keyset scans keep large graph operations bounded.
- The schema migration carries compatible unfinished v3.11 checkpoints
forward while preserving their phase data and
3.11.0:checkpoint-v1compatibility marker. Package-version bumps do not invalidate this v1 checkpoint epoch; incompatible formats, schema state, or run parameters remain fenced off from resume. - Reranker requests that exceed context limits are split without losing candidate scores, and OpenAI-compatible embedding credentials are isolated from unrelated provider requests.
See CHANGELOG.md for migration details and the complete list of changes. For earlier releases, see the changelog.
Why Surreal-Memory?
Most AI memory tools are vector databases with a search API bolted on. Surreal-Memory is a graph that thinks — memories are stored as interconnected neurons and recalled through spreading activation, backed by SurrealDB's multi-model engine (document + graph + vector in one database).
Query: "Why did Tuesday's outage happen?"
Surreal-Memory traces the chain:
outage ← CAUSED_BY ← JWT expiry ← SUGGESTED_BY ← Alice's review
Relationships are explicit — CAUSED_BY, LEADS_TO, RESOLVED_BY, CONTRADICTS — so your agent doesn't just find memories, it reasons through them.
| RAG / Vector Search | Surreal-Memory | |
|---|---|---|
| Backend | Pinecone / Chroma | SurrealDB (doc + graph + vector) |
| Retrieval | Similarity score | Graph traversal + vector search |
| Relationships | None | 41 explicit synapse types |
| LLM required | Yes (embeddings) | No — works fully offline |
| Multi-hop reasoning | Multiple queries | One traversal |
| Memory lifecycle | Static | Decay, reinforcement, consolidation |
| Cost per 1K queries | ~$0.02 | $0.00 |
What's Different From NeuralMemory?
Surreal-Memory builds on NeuralMemory's graph memory architecture but replaces the SQLite + paid-Pro model with SurrealDB + free community plugin:
| NeuralMemory (upstream) | Surreal-Memory | |
|---|---|---|
| Storage engine | SQLite (limited) | SurrealDB (all features free) |
| Vector search | Paid Pro feature | Built-in via SurrealDB HNSW |
| Semantic recall | Paid Pro feature | Free via community plugin |
| Smart consolidation | Paid Pro feature | Free via community plugin |
| Compression | Paid Pro feature | Free via community plugin |
| License required | Yes for Pro features | No — everything is free |
| Multi-model | No | Yes — document + graph + vector |
Quick Start
Automated Setup (Claude Code)
Give this to Claude Code on any machine and it handles everything — prerequisites, Docker, MCP registration, and verification:
Please read INSTALL_PROMPT.md and follow the instructions to set up Surreal-Memory on this machine.
Or clone and point Claude Code at the file:
git clone https://github.com/acidkill/surreal-memory.git
# then in Claude Code:
# "Read INSTALL_PROMPT.md and follow the setup instructions"
Docker (manual)
cp .env.example .env # edit with your keys
docker compose -f docker-compose.surrealdb.yml up -d
Dashboard at http://localhost:8000/ui, SurrealDB at localhost:8001.
Requires SurrealDB ≥ 3.2.0 (the compose file uses
surrealdb/surrealdb:v3.2.0). Upgrading from an older SurrealDB? Back up thesurrealdb_datavolume first — the synapse graph auto-migrates to native RELATE edges on the first connect after the upgrade.
Manual
pip install surreal-memory[surrealdb]
smem init --full
First Memory
smem remember "Fixed auth bug with null check in login.py:42"
smem recall "auth bug"
# → "Fixed auth bug with null check in login.py:42"
3 Tools. That's It.
57 MCP tools are available, but you only need three:
| Tool | What it does |
|---|---|
smem_remember |
Store a memory — auto-detects type, tags, and connections |
smem_recall |
Recall through spreading activation + vector search |
smem_health |
Brain health score (A–F) with actionable fix suggestions |
Everything else — sessions, context loading, habit tracking, maintenance — works transparently in the background.
Architecture
┌──────────────────────────────┐
│ MCP Server (57 tools) │
└──────────┬───────────────────┘
│
┌──────────▼───────────────────┐
│ Engine (encoding + │
│ retrieval pipeline) │
└──────────┬───────────────────┘
│
┌────────────────▼────────────────┐
│ SurrealDB Backend │
│ ┌─────────┬─────────┬────────┐ │
│ │ Document │ Graph │ Vector │ │
│ │ Store │ Queries │ HNSW │ │
│ └─────────┴─────────┴────────┘ │
└─────────────────────────────────┘
Core Data Model
- Brain — top-level container with configuration
- Neuron — atomic knowledge node (entity, concept, time, action, intent, state)
- Synapse — typed, directed edge between neurons (41 types:
CAUSED_BY,LEADS_TO, etc.) - Fiber — a memory record: typed content with metadata, priority, tags, lifecycle stage
Engine
- Encoding Pipeline — composable async steps: extract entities → create neurons → link synapses → bundle into fibers
- Reflex Retrieval — spreading activation through the neuron graph, combined with SurrealDB vector search when available
- Reranking — optional cross-encoder pass over-fetches SA candidates and blends relevance score with activation level for higher recall precision
- Consolidation — merges similar neurons, reinforces strong paths, prunes weak ones
- Compression — 5-tier lifecycle: full → summary → essence → ghost → metadata
Community Plugin
The built-in CommunityPlugin unlocks the Pro-tier capabilities at no cost:
- Directional Compression — multi-axis semantic preservation, used by the compression pass
- Auto-tier during consolidation — gated behind a registered plugin, which ships by default
Cloud Sync
Sync your brain across every machine through your own Cloudflare Worker:
Laptop ←→ Your Cloudflare Worker ←→ Desktop
↕
Your Phone
You deploy the sync hub to your own Cloudflare account. Your D1 database, your encryption key, your data.
smem sync sync --direction both # bi-directional sync (also: push, pull)
Set SURREAL_MEMORY_SYNC_AUTO=true (or auto_sync under [sync] in
config.toml) to sync automatically after every remember/recall.
Sync uses Merkle delta — only diffs travel, not the full brain.
Features
Memory & Recall
- 15 memory types — fact, decision, error, insight, preference, workflow, instruction, and more
- Spreading activation — memories surface by association, not keyword match
- Vector search — SurrealDB HNSW for semantic similarity (when embeddings are configured)
- Cross-encoder reranking — optional config-driven precision pass, HTTP (shared inference server) or in-process, blended with the activation score
- Cognitive reasoning — hypothesize, submit evidence, make predictions, verify with Bayesian confidence
- Per-fact supersession — when a new memory replaces an old one, recall automatically resolves the conflict (the old fact is superseded, not deleted); recall the state of the world as of a past moment with
valid_at - Trust & recency scoring — weight recall by how much you trust a source and how fresh a memory is, instead of treating everything as equally reliable forever
- Uncertainty surfacing — ask
smem_uncertaintyhow much to trust an answer: contradictions, drift, soon-expiring memories, low-evidence facts - Queryable retrieval traces — opt-in record of why a recall returned what it did, for debugging and auditing
- Geospatial recall — attach a location to a memory and filter recall to a radius around a point (
near)
Knowledge Ingestion
-
Train from documents — PDF, DOCX, PPTX, HTML, JSON, XLSX, CSV ingested into permanent brain knowledge
-
Train from database schemas — extract table structures and FK relationships
-
Fast bulk training —
smem trainbatches DB writes (one round-trip per N synapses viaadd_synapses_batch) and thefind_neuronsbrain_id index is now used, so large docs stay cheap per chunk even on big brains (previously 7–15 s/chunk on a 68k-neuron brain; ~10× fewer DB ops/chunk). Shows livetqdmprogress. -
Import adapters — migrate from ChromaDB, Mem0, Cognee, Graphiti, LlamaIndex
-
Reasoning training (opt-in) — mine a model's own
thinkingfrom~/.claudetranscripts, distill it into reusable reasoning-pattern fibers, and inject the learned strategies into other models' sessions (dashboard +smem reasoningCLI +smem_reasoningMCP tool). Off by default; traces are redacted before storage. Per-model category coverage — how many of the 8 categories hold enough patterns — is the number to watch;pattern_targetscaps how many patterns each model may accumulate, though a model's own trace backlog usually runs out first. -
Rebuilding lost patterns — distillation marks every trace it consumes as processed, including the ones it discards, so patterns cannot normally be re-derived from a backlog that has already been mined.
reprocessre-opens it: a checkbox beside Backfill in the dashboard,smem reasoning mine --reprocess, orreprocess: trueonsmem_reasoning. Repeating it is safe — pattern signatures make a second pass a no-op rather than a duplicate-maker. It respectsmining_models(globs are resolved against the models actually present, and a filter matching nothing re-opens nothing), anddry_runstill wins, since re-opening the backlog is a write. Traces already dropped byretention_daysneed--backfillto be re-ingested from the transcripts first. -
LLM pattern naming and quality gating (opt-in, local-only) — by default a distilled pattern is named after its own mechanics (
debugging: restate-goal, gather-evidence, verify) and described by a raw slice of the medoid trace. Pointdistill_use_llmat a loopback OpenAI-compatible endpoint and a local model rewrites the title, description and strategy, marks whether it is reusable, and scores its quality. Injection requires bothmin_confidence(cluster support) andinjection_min_quality(transferable prose); each pattern can also be disabled reversibly in the dashboard. Legacy patterns without quality metadata remain eligible until rebuilt or disabled. A non-loopback endpoint is refused outright — reasoning traces never leave the machine — and any failure falls back to mechanical naming, which new patterns retain for inspection but do not auto-inject.distill_llm_load_cmdloads the model once before the first request, so you control how it loads (context size, GPU layers, no vision projector) instead of accepting whatever the endpoint does implicitly;distill_llm_unload_cmdreleases it when the run ends, so it does not sit in VRAM between runs. Both are argv lists run without a shell,{model}is substituted, and either one being absent or failing degrades silently to the old behavior:[reasoning_training] distill_use_llm = true distill_llm_model = "<a chat model your server serves>" distill_llm_endpoint = "http://127.0.0.1:PORT/v1" # loopback only distill_llm_load_cmd = ["<your-launcher>", "load", "{model}", "--n-gpu-layers", "99"] distill_llm_unload_cmd = ["<your-launcher>", "stop", "{model}"] -
Clustering threshold travels with the embedder — two traces become one pattern when their embeddings exceed
cluster_cosine(default0.75). Embedding models do not share a similarity scale, so a value borrowed from another model can sit above the 99th percentile of your corpus and cluster nothing at all, silently leaving the move-set fallback to outperform the embedding path it is meant to back up. If mining reports patterns learned but categories stay empty, compare the threshold against your own pairwise distribution before raisingpattern_targets:[reasoning_training] cluster_cosine = 0.75 # lower = more merging; too low collapses everything into one cluster
Lifecycle & Storage
- Memory consolidation — episodic memories mature into semantic knowledge through spaced recall, not through a command. A fiber reaches
semanticafter 7 days inepisodicplus reinforcement spread across 3+ distinct days (or 15+ rehearsals across 5+ time windows) — recalling a memory is what advances it;smem consolidatecannot move it on its own.smem healthshows where every memory sits (stage_distribution) and what each one is still waiting on (semantic_gate_blockers: dwell time, recall spacing, or already eligible), so a flatconsolidation_ratiois diagnosable instead of mysterious. Recall rehearses the memories it actually surfaced — raisebrain.reinforcement_neuron_limit(default 15) to widen that reach at the cost of some recall latency. - Compression tiers — full → summary → essence → ghost → metadata
- Brain versioning — snapshot, rollback, diff, transplant memories between brains
Ecosystem
- Web dashboard — multi-page React UI at
/ui(overview, health radar, graph, timeline, evolution, storage, sync, diagrams, reasoning, oracle, tool-stats, visualize, settings, uncertainty) — every page free, no Pro gate - VS Code extension — memory tree, graph explorer, CodeLens, WebSocket sync
- LangChain adapter — optional extra (
pip install surreal-memory[langchain]) exposing aBaseRetrieverand chat message history backed by a brain — see Python API - Safety — Fernet encryption, sensitive content auto-detection, input firewall
- Plugin system — extend with custom MCP tools and a compression function
Embeddings
The keyword + graph core works with no embedding API at all. Embeddings are
optional — they add semantic recall (vector search via SurrealDB HNSW) so memories
surface even when the wording differs. Configure interactively with smem setup embeddings
or via SURREAL_MEMORY_EMBEDDING_* env vars.
Recommended — Google Gemini (gemini-embedding-001, 3072-dim, multilingual, free tier):
pip install "surreal-memory[surrealdb,embeddings-gemini]"
export GEMINI_API_KEY=... # free key: https://aistudio.google.com/apikey
No API key? Run it locally — the same on-device model class ChromaDB/MemPalace use,
via sentence-transformers (offline, no key):
pip install "surreal-memory[surrealdb,embeddings]"
smem setup embeddings # choose "Sentence Transformers"
| Provider | Default model | Key | Notes |
|---|---|---|---|
| Gemini (recommended) | gemini-embedding-001 |
GEMINI_API_KEY |
3072-dim, multilingual, free tier |
| Local (sentence-transformers) | all-MiniLM-L6-v2 · paraphrase-multilingual-MiniLM-L12-v2 |
— | offline, no key, ~440MB download |
| Ollama | nomic-embed-text · bge-m3 |
— | local server (ollama serve) |
| Local OpenAI-compatible (e.g. llamastash) | bge-m3 |
— | any server exposing /v1/embeddings; pairs with bge-reranker-v2-m3 on the same host |
| OpenAI | text-embedding-3-small |
OPENAI_API_KEY |
paid |
| OpenRouter | openai/text-embedding-3-small |
OPENROUTER_API_KEY |
OpenAI-compatible |
Running bge-m3 on your own OpenAI-compatible server (llama.cpp, llamastash, vLLM …) — this is
the local pairing for the bge-reranker-v2-m3 cross-encoder described under Reranking, so both
halves of retrieval stay on one host and nothing leaves the machine:
[embedding]
enabled = true
provider = "openai" # the wire format, not the vendor
model = "bge-m3-FP16" # whatever name your server serves it under
dimension = 1024 # bge-m3 is 1024-dim; drives the HNSW index
endpoint = "http://127.0.0.1:11435/v1"
endpoint may also come from SURREAL_MEMORY_EMBEDDING_ENDPOINT; the config key wins, matching
[reranker] endpoint. Only a loopback host is accepted for reasoning-trace work — a remote base is
refused with a warning rather than silently downgrading, because those traces never leave the machine.
The endpoint that passes that check is the one handed to the client as its base URL, so "the check
passed" means the requests really went there — a provider's own hosted default cannot override it.
Set the provider to auto to pick the best available option at runtime
(order: Ollama → local sentence-transformers → Gemini → OpenAI → OpenRouter).
The combination is validated. Every provider assumes a dimension for a model it does
not recognise, so aiming one at another provider's model name yields vectors of the wrong
width — which the vector index then rejects on every write. smem doctor, smem_health
and MCP startup report two impossible cases instead of passing them: a model outside a
hosted provider's catalogue (the report lists the models it does serve), and a known model
whose dimension contradicts the configured one. The check stays quiet where it cannot
know — a local OpenAI-compatible server serves whatever files it was pointed at, so an
unfamiliar model name there is normal, and only an exact catalogue match counts as knowing
a dimension.
Embeddings use one model per brain — switching models changes vector dimensions and invalidates existing vectors. Pick a provider before ingesting at scale.
Reranking
Spreading activation over-fetches candidates; an optional cross-encoder reranker then
scores each (query, memory) pair for relevance and blends that score with the
activation level (blend_weight, default 0.7) for a final precision pass. Off by
default — recall works the same without it.
[reranker]
enabled = true
endpoint = "http://127.0.0.1:11435/v1" # OpenAI-compatible /rerank (e.g. llamastash)
model_name = "BAAI/bge-reranker-v2-m3"
blend_weight = 0.7
- HTTP mode (
endpointset) — runs on a shared inference server (e.g. llama.cpp / llamastash on GPU), notorchdependency needed locally. Falls back to theSURREAL_MEMORY_RERANKER_ENDPOINTenv var whenendpointis unset. For endpoints that require auth, setSURREAL_MEMORY_RERANKER_API_KEYand requests carry aBearerheader (an empty key sends none, so llamastash needs no extra config). - In-process mode (no endpoint) — loads a local
sentence-transformersCrossEncoder. Install withpip install "surreal-memory[reranker]". - Reranking never breaks recall, but it never fails quietly either. A failed rerank
is retried once; if it still cannot run, recall returns the spreading-activation
ordering and says so —
rerank_degradedin the MCP response,rerank_degraded_warningin the CLI. Un-reranked results look exactly like reranked ones, so a silent fallback would hide a real drop in precision.
Surreal-Memory MCP questions
What tools does Surreal-Memory MCP provide?
It exposes 3 tools, including smem_remember, smem_recall, smem_health.
Does Surreal-Memory require an embedding API for basic usage?
No, it works fully offline and does not require an embedding API for basic usage.
How does Surreal-Memory differ from standard RAG or vector search?
Unlike standard RAG which relies on similarity scores, Surreal-Memory uses graph traversal and 41 explicit synapse types for multi-hop reasoning.
Can I sync my memory across different devices?
Yes, you can sync your brain across machines using your own Cloudflare Worker and D1 database.