Graph Memory MCP
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., "@Graph Memory MCPRemember Alice manages Platform, then show related team facts."
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.
Agent memory turns into noise: duplicate facts, contradictions served as truth, stale decisions that look current, bloated context, and every session starts from scratch. Teams end up with a pile of unstructured notes nobody trusts.
Graph Memory MCP solves this:
Stays clean — near-duplicate writes refused on insert; mark facts outdated;
CONTRADICTSedges surfaced in search; TTL for temporary factsExact agent text — the text in the graph is what the agent wrote; no extraction model splits, rewrites, or drops it
Physical isolation — one
owner_id= one graph (FalkorDB) or one database (ArcadeDB); no query-time filteringFree, predictable writes — no LLM calls on the server; writes are fast, cost-free, and work offline
Compact recall —
search(..., compact=true)returns snippets under a token budget with suggested next steps
Quick start: docker compose up -d && uv run graph-memory-mcp — ready at http://127.0.0.1:8000/mcp
Quickstart · Comparison · Agent policies · Features
Quickstart (5 minutes)
Start the databases. FalkorDB is the default backend:
docker compose up -dInstall and start the server:
uv sync
uv run graph-memory-mcp --host 127.0.0.1 --port 8000Configure your MCP client. For Claude Desktop or Cursor, add this to your MCP servers config (see examples/mcp_servers_config.json):
{
"mcpServers": {
"graph-memory-mcp": {
"transport": "streamable_http",
"url": "http://127.0.0.1:8000/mcp"
}
}
}Try a smoke test. The server is now running at
http://127.0.0.1:8000/mcp:
uv run python examples/http_client_usage.pySee Configuration and Running the databases for environment setup and backend options.
Related MCP server: Graph-Mem MCP
What it provides
Fact storage with embeddings (semantic search; hybrid rank: cosine + identifier match + recency)
get_brief— project anchor and recent durable facts, separate from searchEntity and triplet graph (subject–predicate–object)
Context subgraph (
get_context) and paths (get_trace)recall_context— one-call search and expand on small graphsFact versioning and soft-deletion. Facts with
ttl_daysstay out of default search untilinclude_ttl=trueFact auto-linking —
auto_link=trueon a Fact addsMENTIONSto similar Entity nodes (default is false)Near-duplicate writes refused before insert (
memory_duplicate); a different fact usescheck_duplicates=falseMulti-tenant isolation via
owner_idBackground jobs (deduplication, archival)
MCP-native API (FastMCP)
Backed by FalkorDB by default. GRAPH_BACKEND=arcadedb uses ArcadeDB with the same tools.
Where it fits
Mem0 remembers facts. Graph Memory keeps them current.
This server is the store. The agent writes the fact, the owner_id, the TTL, and the edge. Search returns what was stored. Embeddings are the only model call inside the server.
Real graph you can traverse, in open source. Not a hidden ranking signal. Mem0 OSS has no graph. The Platform graph only changes search order. Here the agent walks the edges.
Outdated is marked. Mem0 keeps both facts and ranks the newer one higher.
mark_outdated,CONTRADICTS, and version snapshots say what is current.Near-duplicates are refused at write, without an LLM. Mem0 skips exact copies. Near-copies are stored.
Each owner_id is its own graph. Mem0 keeps every user_id in one store.
Graphiti (the library behind Zep) ingests episodes and keeps a bi-temporal graph: a new fact invalidates the old one, and the old one stays queryable by time.
Case | Graph Memory MCP | Mem0 | Graphiti |
The graph | Edges are readable ( | OSS: no graph. Platform: ranking only, | Temporal graph you can query |
A decision changed |
| Add-only. Both stay; the newer one ranks higher. No outdated mark. | The old edge is invalidated; history stays |
A near-duplicate write | Refused at write ( | Exact text skipped by hash. Near-copies stored | New edges |
The agent already has the sentence |
| An extraction model may split, rewrite, or drop it | An episode pipeline turns it into entities and edges |
"Remember this chat" and nobody chose the facts | The server does not read a transcript |
|
|
A debug note that should disappear |
|
| Validity windows, not a debug TTL |
Two agents, one project | Same |
|
|
No extraction model | Writes do not call an LLM |
| Several LLM calls per episode |
Agent policies
Any LLM agent that reads or writes Graph Memory — single-agent or multi-agent — should load the memory ritual from client rules / AGENTS.md and keep docs/memory_policies_for_LLM.md (or the shorter docs/memory_policy_cheatsheet.md) in context at the start of each session. That defines what to store, owner_id rules, and how to link facts; without it, memory tends to get noisy or mis-scoped. The same full policy is optionally exposed as MCP resource graph-memory://agent-policies (clients rarely auto-fetch it — prefer rules).
Install
uv syncuv sync installs runtime deps plus the dev group (pre-commit, pytest, …).
PyTorch is installed from the CPU-only index by default (no NVIDIA/CUDA wheels on Linux). Configured in pyproject.toml via [tool.uv.sources].
Check theexamples directory for code snippets demonstrating various usage patterns (embedded, HTTP, and MCP configuration).
Run (Development)
HTTP server
graph-memory-mcp --host 127.0.0.1 --port 8000Streamable HTTP MCP is at http://127.0.0.1:8000/mcp. Tools are MCP calls, not REST paths under /mcp.
Server profiles
Three processes, one handler layer. Tool names match. A client picks one and stays on it.
Start | Writes | |
Default |
| Nested |
Simple |
| Flat provenance ( |
Extended |
| Same as default, plus |
graph-memory-mcp --simple --host 127.0.0.1 --port 8000
graph-memory-mcp --extended --host 127.0.0.1 --port 8000See Server profiles.
Graph Explorer (local GUI)
Read-only web UI to inspect nodes, semantic search, similar facts, and graph context. Proxies read-only MCP tools to a separately running Graph Memory server.
# Terminal 1 — MCP server (FalkorDB must be running; uses .env)
uv run graph-memory-mcp --host 127.0.0.1 --port 8000
# Terminal 2 — Explorer GUI only
uv run graph-memory-explorer --host 127.0.0.1 --port 8088
# optional: --mcp-url http://127.0.0.1:8000/mcp (or GRAPH_MEMORY_MCP_URL)Open http://127.0.0.1:8088 — enter owner_id and a node_id, run search, expand neighbors with + on hover or +10 neighbors in the detail panel.
Configuration
Settings are loaded from environment variables and optional .env file.
You can start from env.example (copy it to .env).
Key defaults live in graph_memory_mcp/config.py within the MCPServerConfig class, including:
RELATION_POLICY_ENFORCE—off|warn(default) |enforceRELATION_ALLOWED_TYPES— comma-separated allowlist for new edgesOWNER_SCOPE—client(default) |header. See Owner isolation.JOBS_ENABLED— off by default. On runs archive and dedup.JOBS_OWNER_IDSlimits them to those owners; empty means every owner. See background jobs.Agent link guidance:
docs/memory_policies_for_LLM.md
Running the databases
Docker Compose starts both databases. It does not start the MCP server. The code default for FALKORDB_PASSWORD is empty, so copy env.example before connecting.
cp env.example .env # first time only
docker compose up -dPort | Credentials in | |
FalkorDB | 6379, UI at http://localhost:3000 | password |
ArcadeDB | 2480 | user |
FalkorDB is the default backend and is required for the default test run. ./scripts/falkordb-up.sh starts only FalkorDB. ArcadeDB tests: uv run pytest -m arcade.
With Password Authentication
docker run -p 6379:6379 -p 3000:3000 -it --rm \
-v ./data:/var/lib/falkordb/data \
-e REDIS_ARGS="--requirepass falkordb123" \
falkordb/falkordbNote: Replace falkordb123 with your desired password and make sure to set the same password in your .env file:
FALKORDB_PASSWORD=falkordb123Without Password (Development Only)
docker run -p 6379:6379 -p 3000:3000 -it --rm \
-v ./data:/var/lib/falkordb/data \
falkordb/falkordbAfter starting FalkorDB, you can access the web interface at http://localhost:3000.
Vector Indexes
The server uses two vector indexes (Fact and Entity):
Index | Used by |
Fact |
|
Entity | Fact |
Creation (pick one):
Automatic — indexes are created on first
search,find_similar, or Factauto_linkif missing.Startup —
AUTO_CREATE_INDEXES=truein.env.Admin —
POST /admin/ensure-indexes(or MCPensure_vector_indexeswhenMCP_EXPOSE_ADMIN_TOOLS=true).
FalkorDB keeps index data in sync when nodes change; you only need to recreate index definitions after changing embedding model dimension.
Changing EMBEDDING_MODEL invalidates the stored corpus. Old node embeddings were produced by the old model — new queries will not match them meaningfully. The full procedure is: (1) switch the model, (2) recreate vector index definitions if the dimension changed, (3) re-embed every node (currently manual: iterate nodes and update_node with the same text, or export/import with regenerate_embeddings=true). The same applies to changing prompt/prefix conventions of the same model.
Embedding prefixes
Some models are trained with prompt prefixes. The default intfloat/multilingual-e5-base expects "query: " for search queries and "passage: " for stored texts. The code default for both prefixes is empty; env.example sets them for e5. Enabling prefixes on an existing corpus counts as a model change — re-embed the corpus (see warning above).
Persistence & Backups
docker-compose.yml enables AOF persistence (--appendonly yes --appendfsync everysec) — a container crash loses at most ~1 second of writes. For point-in-time backups:
./scripts/backup.sh # BGSAVE + copy dump.rdb to ./backups (keeps last 14)
# cron example (hourly): 0 * * * * cd /path/to/repo && ./scripts/backup.shLogical per-owner backups (portable across instances/models): GET /admin/export/{owner_id} — supports ?limit=&offset=§ion=nodes|relations for large owners; restore with POST /admin/import.
Multi-Agent Usage
Use owner_id to isolate or share knowledge between agents. For example:
Shared team memory: Both your code-generation agent and your debugging agent use
owner_id="team_platform". One agent stores "Production Redis is at redis.internal"; the other searches and finds it.Isolated per-agent memory: Your agent uses
owner_id="agent_codegen"for implementation notes; another usesowner_id="agent_docs"for documentation drafts. Neither sees the other's memory.
Values must be alphanumeric plus -, _, and @ (see docs/memory_policies_for_LLM.md).
Owner Isolation
Isolation is physical on both backends. On FalkorDB, every owner_id lives in its own graph ({FALKORDB_GRAPH}_{owner_id}) with its own vector indexes. On ArcadeDB, every owner_id lives in its own database ({ARCADE_DATABASE}_{owner_id}) with its own vertices, edges, and HNSW indexes. One owner cannot see another's data.
Who picks that owner is OWNER_SCOPE (default client):
|
| |
When | Trusted network; clients pass the owner directly | A reverse proxy or other middleware in front of the server sets the owner per request |
Owner | Tool argument |
|
Missing owner | Server default | Call is rejected. It does not fall back to |
Tool names and arguments stay the same in both modes. Agents should still pass owner_id explicitly: in client that value is the graph; in header the HTTP header wins, so a client cannot name someone else's graph.
See docs/memory_policies_for_LLM.md and docs/memory_faq.md for operational guidance.
ArcadeDB
Optional second graph backend. Leave GRAPH_BACKEND unset (or falkordb) to keep FalkorDB. Set GRAPH_BACKEND=arcadedb and the ARCADE_* variables in .env. Each owner_id gets its own database, {ARCADE_DATABASE}_{owner_id}, with its own vertices, edges, and HNSW indexes. The embedding is a property on the vertex. Search inside that database uses vector.neighbors.
Development
The default test run requires FalkorDB (see Running the databases). ArcadeDB tests are marked arcade and use the Compose server on port 2480:
./scripts/test.sh
# or: docker compose up -d && uv run pytest -q
# ArcadeDB: uv run pytest -m arcadePre-commit hooks
Hooks are not global — run them via the project venv (dev group installed by uv sync):
uv run pre-commit run --all-files
uv run pre-commit install # optional: git hooksSmoke Test (Quick Verification)
The server uses Streamable HTTP MCP at http://127.0.0.1:8000/mcp. Tools are invoked with MCP call_tool — there is no REST API at /mcp/tools/....
Terminal 1 — start the server (FalkorDB must be running):
graph-memory-mcp --host 127.0.0.1 --port 8000Terminal 2 — run the HTTP MCP client example:
uv run python examples/http_client_usage.pyThat script calls health_check, create_node, and search over Streamable HTTP. See examples/ for embedded usage and MCP client configuration.
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent memory, knowledge graph, task management and more for AI agents via MCP.
- KogniteOAuthdev.kognite
Hosted agent memory: store, search, and recall facts across sessions from any MCP client.
Cross-vendor AI memory over MCP. One semantic store, readable and writeable from every MCP client.
An MCP memory server. One memory your agents share — across models, devices and apps.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceMCP server that gives AI agents and teams persistent, shared memory using a knowledge graph with vector embeddings, automatic consolidation of related facts, and hybrid search.3-
- AlicenseNot gradedqualityCmaintenanceA universal MCP server providing persistent, structured memory through a knowledge graph with graph storage, semantic vector search, and multi-hop traversal for AI agents and IDEs.19 PyPI1MIT
- AlicenseNot gradedqualityBmaintenanceKnowledge-graph memory server for MCP-compatible AI tools, providing persistent, connected memory with typed relationships and auto-consolidation.54 npmMIT
- AlicenseNot gradedqualityCmaintenanceA local-first compiled knowledge graph MCP server that provides structured memory for AI agents with full-text search, vector embeddings, and timeline tracking.55 npm8MIT