Graphiti Local: A Local-First Temporal Knowledge Graph with Human-Gated Writes

September 11, 2026 · 3 min read · open-source, knowledge-graph, mcp
For decision-makers, in 20 seconds

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.

6
Lese-Werkzeuge über MCP Read-only MCP tools
Kein Schreiben, Löschen oder Leeren No write, delete or clear
0
Schreib-Werkzeuge über MCP Write tools over MCP
Schreiben erst nach Freigabe Writes wait for a person's approval
3
Graph-Backends Graph backends
FalkorDB, Neo4j, LadybugDB FalkorDB, Neo4j, LadybugDB
11
kg-Befehle kg commands
JSON auf stdout, Exit-Code bei Ablehnung JSON on stdout, non-zero exit on refusal

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 of kg-workspace drain, and adds --apply when 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

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:

Scope in 24h · Hourly rate agreed up front · Billed for the hours worked

The context layer for your AI agents

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.

Scope my automation in 24h

Two fields. I reply within 24h with a written scope: either “yes, about X hours over Y weeks” or “no, here’s why not”.

See what you get first: sample scope →

Your details are used only to answer this request — no sharing, no newsletter. Privacy

Not ready to write it up? Book a 30-min call instead →

Request received

You’ll hear from me within 24h with an honest assessment.

Prefer to talk? 30-min roadmap call →
Get your AI pilot checked