Graphiti Local: A Local-First Temporal Knowledge Graph with Human-Gated Writes
Problem: Memory servers for agents usually hand the model a write tool, often a delete tool too. The graph then holds whatever the model decided was true, and nobody can say who put a fact there or take it back cleanly.
Solution: Graphiti Local splits the two paths. Agents read through six MCP tools and a kg command line that cannot write. Facts enter through a proposal queue, a person approves them, and a separate command lands them in the graph.
Business value: The same read-first interface runs a company's context layer on its own tenant and my own working graphs, on FalkorDB, Neo4j or a single LadybugDB file, with OpenAI, Azure OpenAI or a local model through Ollama.
Frame: The rule I build into client systems, published as a tool: the model reads, a person signs. The tool is the evidence, not the offer.
Why the agent only reads
An agent with a write tool on its own memory will use it. It records a guess as a fact, merges two customers that share a name, or deletes the fact that contradicted its plan. None of that is malicious. It is what the tool invites.
Graphiti Local removes the invitation. The MCP server registers exactly six tools, search_nodes, search_memory_facts, get_entity_edge, get_episodes, get_episode_entities and get_status, and has no write, delete, clear, approval or maintenance tools at all. It is built on Graphiti, so every fact keeps its validity window and its source episode. The guide on temporal knowledge graphs explains that model.
How a fact gets in
kg propose GROUP "fact" --type source-fact --provenance "source"appends a proposal to a local queue. It does not touch the graph.- A person approves it with
kg-workspace approve, reviews the dry run ofkg-workspace drain, and adds--applywhen it is ready. - A proposal is archived only after it actually lands. A failed ingest leaves it approved, so the next drain retries it.
- The configured groups form an allow-list on reads and on proposals. A fact addressed to an unknown group is refused, not queued.
Bulk ingestion is a separate command, kg-ingest. It is a dry run by default, resumes through a content-keyed ledger instead of duplicating records, and stops at a record boundary when it receives SIGTERM.
Built for unattended use
Every kg command prints JSON on stdout and exits non-zero when it refuses, so a scheduled job or an agent can consume the result without scraping text. Every graph call has a timeout, so a hanging backend makes kg exit with a reason instead of leaving an agent waiting.
Two commands prove a setup before anything depends on it. kg doctor checks versions, configuration, the workspace, the backend and a live probe of the embedding width. kg verify checks the six read tools, the absence of write tools, and live retrieval. The embedding probe exists because a width mismatch corrupts every vector without an error, and so does a model change at the same width: Graphiti Local records the embedder of the first write and refuses a later ingest under a different one.
Portability
kg export writes a snapshot from Graphiti’s models rather than from backend rows, so it reads the same whichever backend produced it. kg-ingest --restore replays it into another backend and re-embeds every name and fact under the configured model, which is also the path to a new embedder. Records keep their ids, so restoring twice updates instead of duplicating.
Running without a cloud provider
With a local model through Ollama, a local embedder and the embedded LadybugDB backend, the graph runs entirely on one machine: no API key, and no data leaving the host. On the embedded backend the readers open the file read-only, so an ingest can run while the MCP server is up.
Where it is used
In client work, Graphiti Local is the read interface of the context layer for AI agents on the company’s own tenant. The case study shows the layer with its approvals and its audit trail.
Start here
- Repository: github.com/renezander030/graphiti-local, Apache-2.0
- Install:
uv sync, copy one of the example configurations, thenuv run kg doctor - Running it: Graphiti in production covers backends, models, embeddings and ingestion
- Related tools: agent-approval-gate for the same propose, approve and apply boundary without a graph, and agentic-task-system, a task layer that reads this graph through the same
kgcommand line
Graphiti Local is an independent community project built on Graphiti. It is not affiliated with or endorsed by Zep. Details read from the repository on 11 September 2026.
Stack Stack
- Python 3.10+, built on graphiti-core
- FalkorDB or Neo4j as a server, LadybugDB embedded in one file
- MCP over stdio, or streamable HTTP with a bearer token
- OpenAI, Azure OpenAI or any OpenAI-compatible endpoint such as Ollama
- Apache-2.0
Ähnliches Projekt auf dem Tisch? Similar project on your desk?
Am schnellsten klärt das ein Gespräch. Termin direkt hier wählen: The fastest way to scope it is a conversation. Pick a slot right here:
Your agents answer from whatever the retriever finds, and too often that is last quarter's truth. I build the context layer they answer and act from: a temporal knowledge graph that keeps every fact with its source and the time it held, reads with each person's own permissions, and writes nothing without a person's approval. On your own tenant, billed by the hour, step by step.