A graph-memory MCP server for codebases. Delfos implements the active reconstruction model from "Memory is Reconstructed, Not Retrieved: Graph Memory for LLM Agents" (arXiv 2606.06036) over a code repository, and exposes it as tools any MCP-compatible agent (Claude Code, Cursor, etc.) can consume — no knowledge of the graph internals required.
Memory access is an iterative, LLM-driven traversal of a persistent
Cue → Tag → Content graph rather than one-shot retrieval. See
ARCHITECTURE.md for the architecture overview and
docs/decisions.md for the design decisions and rationale.
pip install delfos # or: uv add delfosDelfos ships prebuilt wheels for Python 3.12+ on Linux and macOS, so no C++
toolchain is required. To enable the SCIP cross-reference tools (references,
implementations, type_definition), also install
scip-python:
npm install -g @sourcegraph/scip-pythonDelfos needs an embedding endpoint (and, for reconstruct, a chat endpoint).
Create a .env at the root of the repo you want to index — it is loaded
automatically at startup, anchored to that repo. Copy
.env.example and edit.
Against hosted OpenAI, an API key is the only required setting (the model
and dimension default to nomic-embed-text / 768, or whatever your index was
built with):
DELFOS_EMBED_API_KEY=sk-...Against a local OpenAI-compatible server (llama.cpp, Ollama, LM Studio),
point the base URLs at it — see .env.example for a full
llama.cpp walkthrough. The complete list of DELFOS_* variables and their
precedence is in Configuration below.
delfos index /path/to/repo # build the .delfos/ workspace
delfos doctor --repo /path/to/repo # verify workspace + toolchain
delfos status --repo /path/to/repo # inspect the manifest and storeIndexing writes a .delfos/ workspace inside the repo: the graph store
snapshot, index.scip, and a manifest.json recording the embedding model and
dimension the index was built with. Queries against it need only credentials —
the model and dimension come from the manifest.
The primary way to consume Delfos is as an MCP server. Point your agent at the
delfos-mcp console script and set DELFOS_REPO to the repo you indexed. For
Claude Code / Cursor, add it to your mcpServers config:
{
"mcpServers": {
"delfos": {
"command": "delfos-mcp",
"env": { "DELFOS_REPO": "/absolute/path/to/repo" }
}
}
}The server runs read-only over stdio and exposes the walk tools (search,
traverse_forward, traverse_reverse, fetch), the SCIP tools, and the
reconstruct prompt that teaches the depth-first traversal discipline.
Credentials can live in the repo's .env (loaded automatically) rather than in
the config above.
You can also explore the graph directly, without an agent:
delfos search "how are edges deleted"
delfos reconstruct "the stale-file reindex flow" --budget 3search returns the semantic seed cues; reconstruct runs the LLM-driven
depth-first walk (and needs the DELFOS_LLM_* chat endpoint configured).
Two layers meet at a single boundary — the GraphStore ABC. No component ever
touches the C++ engine directly. The summary below is the short version; the
full contributor-facing walkthrough is ARCHITECTURE.md.
libdelfos/— the C++ storage engine: an in-memory CSR directed property graph (graph.hpp), an HNSW vector index over USearch (vector_index.hpp), and crash-safe snapshot persistence via FlatBuffers + USearch native format (snapshot.hpp). Exposed to Python as thedelfos._delfosextension through nanobind bindings.delfos.schema— the code-specific Cue-Tag-Content schema as Pydantic models (CueNode,TagNode,ContentNode), theEdgemodel, and the closed enum vocabularies. Cue and content nodes carrysource_file+git_shaprovenance (for delete-and-reindex; tags are shared across files and carry none) and optional embedding metadata (embedding_model) for embedding versioning.delfos.store— theGraphStoreabstract base class (the single database boundary every other component goes through) andNativeGraphStore, the concrete backend over the C++ engine.delfos.indexer— the construction pipeline (parser,extractor,embedder,pipeline) that turns a repository into graph nodes and edges.
Delfos is configured via DELFOS_* environment variables, resolved with this
precedence (highest first):
- Real environment variables
- A
.envfile at the repo root passed to--repo/DELFOS_REPO— loaded explicitly at startup (copy.env.exampleto.envand edit) .delfos/config.toml(non-secret settings only — keep API keys out of it).delfos/manifest.json, recorded at index time (embed.model/embed.dimonly — these must match what the index was built with)- Built-in defaults (
nomic-embed-text, dim 768)
| Variable | Purpose |
|---|---|
DELFOS_EMBED_MODEL |
Embedding model name |
DELFOS_EMBED_DIM |
Embedding output dimension (must match the model) |
DELFOS_EMBED_BASE_URL |
OpenAI-compatible embedding endpoint (unset = OpenAI) |
DELFOS_EMBED_API_KEY |
Embedding endpoint API key (required when DELFOS_EMBED_BASE_URL is unset) |
DELFOS_LLM_MODEL |
Chat model for the reconstruct hop planner |
DELFOS_LLM_BASE_URL |
OpenAI-compatible chat endpoint (unset = OpenAI) |
DELFOS_LLM_API_KEY |
Chat endpoint API key |
DELFOS_REPO |
Repo whose .delfos/ workspace to serve (delfos-mcp only) |
DELFOS_VERBOSE |
1 for per-file DEBUG logging |
A query against an already-indexed repo needs only credentials — the model and
dimension come from the manifest. DELFOS_EMBED_BASE_URL and
DELFOS_LLM_BASE_URL each point at their own endpoint independently; there is
no fallback between them.
This project uses uv.
uv sync # install Python deps + dev tools
uv pip install -e . # build + install the _delfos C++ extension
uv run ruff check . # lint
uv run ruff format . # format
uv run pyright # type-check (strict)
uv run pytest # run testsThe standalone C++ build/test flow uses the Ninja generator (brew install ninja):
cmake --preset debug # configure (ASan + UBSan)
cmake --build build/debug
ctest --test-dir build/debug --output-on-failureNote: CMake 4.x dropped compatibility with
cmake_minimum_required < 3.5, which the vendored USearch dependency still declares. The build passes-DCMAKE_POLICY_VERSION_MINIMUM=3.5(wired intopyproject.tomland the CMake presets) to configure under modern CMake.