Local code exploration with progressive zoom and measured token budgets.
Search your local code graph, then zoom from a map to structure and source.
The new explore interface keeps its entire response inside a measured token
budget, including metadata, and reuses unchanged views the client still retains.
Find definitions, inspect static references and verify source freshness.
Local-first · progressive zoom · measured tokens · CLI + MCP
Explore the FastAPI code galaxy in motion. Watch the video or open the interactive galaxy.
Code galaxy · Token zoom demo · Quickstart · Exploration · MCP
Install v1.3.0 from PyPI or GitHub Releases. See release status.
# Windows
python -m pip install --upgrade droste-memory
# macOS / Linux
python3 -m pip install --upgrade droste-memory
droste index . # index the current repo
droste view # open the fractal galaxy in your browser
Install once, then index and view. droste view opens a full-screen, zoomable map of your
code — scroll to dive from the project star into folder orbits, down to the
individual functions and their indexed relationships.
Need it for an agent instead of your eyes?
droste explore "checkout flow" --tokens 1500
Use returned node IDs as --focus and choose --level map, structure or
source to navigate the same region at different detail. used measures the
complete compact response under the selected tokenizer. Source bodies downgrade
explicitly when they cannot fit. Prepare the small token vocabularies once with
droste explore --prepare-tokenizers for later offline use. See
the workflow, receipts and measured limits.
The older droste context --budget interface still budgets characters.
For everyday code investigation:
droste check # verify source hashes and index coverage
droste find calculate # find symbol IDs, paths and line numbers
droste references calculate --direction both
droste references helper --file src/math.py --direction callers --depth 3
droste watch . # refresh after additions, edits, renames or deletions
references returns candidates for ambiguous names; choose a file or symbol ID
instead of guessing. Python links include the call expression and source line.
Other language links report their heuristic resolution method. check exits
with status 1 for stale, partial or unverifiable indexes. Context responses warn
about stale/partial coverage using a quick size/mtime check; check additionally
verifies SHA-256 hashes. Run it before relying on an old index.
Indexing respects nested .gitignore rules and a project-root .drosteignore
(Git ignore syntax; applied last). Symlinks, generated bundles, dependency
directories and Droste's own storage are excluded. Use an explicit --db per
project when running independent writers. watch batches root refreshes and
reuses unchanged extraction/embeddings; view remains a snapshot, so reopen it
to see a refreshed graph.
Running droste with no arguments prints the command palette:
.-----------------------.
.----' | '----.
.---' .-----+-----. '---.
.' .----' | '----. '.
/ .---' .---+---. '---. \
/ .-' .-' | '-. '-. \
| .' .-' .---+---. '-. '. |
| / .' .' | '. '. \ |
| | | | .--+--. | | | |
| --+--------+-----+---+ @ +---+-----+--------+-- |
| | | | '--+--' | | | |
| \ '. '. | .' .' / |
| '. '-. '---+---' .-' .' |
\ '-. '-. | .-' .-' /
\ '---. '---+---' .---' /
'. '----. | .----' .'
'---. '-----+-----' .---'
'----. | .----'
'-----------------------'
DROSTE-MEMORY // RIGID FRACTAL RADIAL LAYOUT
Local Graph Engine v1.3.0-Alpha-Sharded
Commands
droste index <path> [--reset]
droste status
droste zoom <symbol_name>
droste context [query] --budget 1500
droste explore [query] --tokens 2000 --level map|structure|source
droste mcp
Fast path: droste context hub_core --budget 1000 | clip
Droste combines lexical and semantic retrieval with a static code graph and an interactive map. A graph can bring callers and callees into context even when they share few words with the query. Other tools also offer graph-based MCP retrieval; see the dated ecosystem review.
Droste focuses on a small Python CLI, budgeted context, and visual exploration. The graph is a static approximation: name matching and cross-language bridges can produce false positives and do not prove runtime behavior.
The useful building blocks are:
self/cls members. Dynamic receivers remain unresolved.
Other languages use local/unique-name matching; ambiguous candidates are skipped..rpc('x'), .from('table')),
to edge functions, and same-name handlers between any two languages. Your
Dart/TS/Python frontend and your database stop being two separate worlds on the
map.Polyglot: Python (AST) + tree-sitter for Dart, TypeScript/JavaScript, Go, Rust, Java, C#, C/C++, Kotlin, Swift, Ruby, PHP, SQL — symbols and edges.
Honest scope: the measured advantage is structural / causal retrieval. On pure semantic "concept" queries it's competitive with a vector baseline, not a leap. Cross-language bridges are strongest where the target is actually defined in the indexed repo (e.g. SQL schema in your migrations).
The public source validation uses pinned Requests and CPython revisions with manually labelled edge assertions. It currently passes 19 of 20 assertions: 15/16 expected edges found, 0/4 forbidden edges emitted. The missed edge is documented; this small corpus is not an agent-task benchmark or a comparison against competing products.
python eval/public_corpus.py --output public-results.json
The evaluation script compares structural retrieval against lexical and vector baselines, using caller/callee relations extracted from the same code as the reference. This measures graph-neighbor retrieval, not agent task completion or superiority over another product. Previous headline numbers are omitted until we publish a fixed public corpus, pinned revisions and complete result files.
python eval/comparative_eval.py --repos /path/to/public/repo --sample 60 --seed 7 --json results.json
Use the real embedding backend for semantic comparisons; the offline hash mode is deterministic but does not provide semantic similarity.
bge-small-en-v1.5, 384-dim), then the graph
expands the seed bidirectionally (callees and callers).explore budgets its complete response in reference
tokenizer tokens, including metadata. Navigate map, structure and source by
node ID; acknowledge exact retained views to avoid resending their bodies.context --budget is characters, with a minimum of 500. Full
source, contracts or explicit source stubs fit that effective limit, including
separators. That legacy interface does not promise tokenizer-specific counts..droste/ directory, blake2b
dirty-tracking so a re-index rewrites only what changed; atomic file replacement with metadata
written last. Multi-file updates are not transactions; use one writer per DB
and re-index after an interrupted write.Droste is a drop-in MCP server — an AI agent can call it as primary code memory instead of doing blind file reads. Add this to your client configuration file (e.g., Cursor, Claude Desktop, or Codex):
First install or upgrade to the current PyPI release:
# Windows
python -m pip install --upgrade droste-memory
# macOS / Linux
python3 -m pip install --upgrade droste-memory
droste mcp --help
For Codex, add this to C:\Users\<you>\.codex\config.toml on Windows, or ~/.codex/config.toml on macOS/Linux:
[mcp_servers.droste]
command = "droste"
args = ["mcp"]
startup_timeout_sec = 120
Installed packages store their default database in %LOCALAPPDATA%/Droste on
Windows, ~/Library/Application Support/Droste on macOS, or
${XDG_DATA_HOME:-~/.local/share}/droste on Linux. Source checkouts preserve
their repository-local database. Set DROSTE_DB or pass --db to override.
Existing databases inside an older installation are not moved automatically;
point --db at the old file to continue using it, or re-index your source.
For explicitly offline operation, set DROSTE_EMBEDDING_BACKEND=hash.
The default auto backend may download an embedding model on first use;
code is processed locally. Hash mode trades semantic retrieval for deterministic,
network-free embedding. droste view serves a snapshot; rerun it after indexing.
By default, droste mcp uses Droste's global local database. That is fine for
quick use and small workflows. For serious multi-repo work, use one database per
repository so each project has isolated memory and agents can safely re-index
that project with reset=true.
The --db option is global, so keep it before mcp:
# Windows example
[mcp_servers.droste]
command = "droste"
args = ["--db", "C:/Users/you/AppData/Local/Droste/my-project/droste_memory_db.json", "mcp"]
startup_timeout_sec = 120
# macOS / Linux example
[mcp_servers.droste]
command = "droste"
args = ["--db", "/Users/you/.local/share/droste/my-project/droste_memory_db.json", "mcp"]
startup_timeout_sec = 120
For JSON-based MCP clients:
{
"mcpServers": {
"droste": {
"command": "droste",
"args": ["mcp"]
}
}
}
The same isolated-DB pattern works in JSON clients:
{
"mcpServers": {
"droste": {
"command": "droste",
"args": [
"--db",
"/absolute/path/to/droste_memory_db.json",
"mcp"
]
}
}
}
Restart your client after changing the MCP config. Index the project, call
droste_check_index, then use symbol lookup and references before retrieving
context. Inspect the real source before making changes.
Primary tools: droste_index_project, droste_check_index,
droste_find_symbols, droste_references, droste_explore, droste_get_context, droste_status.
Supporting canvas tools: inject_concept, move_camera_and_zoom, get_space_status.
droste_explore is the progressive token-budget path. Existing open MCP
connections keep their earlier process until reconnection; a new connection
loads the upgraded tool list. Retained-view handles are valid only while the
client still retains the corresponding text; clear them after compaction.
Droste also ships agent skill templates for Codex and Claude. They teach an
agent how to use Droste safely: isolated DBs, indexing, droste context, MCP
config, and root-contamination guardrails.
Codex skill:
integrations/codex-skill/droste-code-memory/
Claude-compatible skill:
integrations/claude-skill/droste-code-memory/
Install the Codex skill by copying the folder into your Codex skills directory:
# macOS / Linux
mkdir -p ~/.codex/skills
cp -R integrations/codex-skill/droste-code-memory ~/.codex/skills/
# Windows PowerShell
New-Item -ItemType Directory -Force "$env:USERPROFILE\.codex\skills" | Out-Null
Copy-Item -Recurse -Force integrations\codex-skill\droste-code-memory "$env:USERPROFILE\.codex\skills\"
Then ask Codex:
Use $droste-code-memory to index this repository and retrieve causal context before editing.
For Claude, import or copy the Claude skill folder as a Claude Skill package and
keep its SKILL.md, references/, and scripts/ together.
pip install -e ".[dev]"
pytest # deterministic regression suite (tests/)
python eval/comparative_eval.py # retrieval benchmark vs lexical & vector cores
tests/ = invariants + concurrency (round-trip, dirty-oracle, packer guardrail,
cross-process shard race). eval/ = performance/quality benchmarks.
v1.3.0 (alpha). Progressive token-budget exploration, tested CLI/MCP workflows, source freshness checks and an explicitly limited static graph. Dynamic dispatch, receiver-type inference and complete cross-language resolution remain outside the current guarantees. Use one writer per database. See validation and limitations.
map → structure → source with droste explore and droste_explore.o200k_base / cl100k_base token counts.find, references, check and matching MCP tools, with source evidence.--reset.droste --db ... view to visualize the requested database.DROSTE_DB overrides it.droste view by shipping the visualizer
HTML/templates and public demo graph inside the installed package.pip install droste-memory, droste index ., droste view..droste/, .tmp/,
and *.egg-info directories from project scans.Path.walk() usage.server.json for official MCP Registry publishing.graph.json,
status.json, context.json) are excluded from source distributions, while
the public visualizer/demo_graph.json remains included.droste_index_project records the active repo,
and droste_get_context / droste_status filter to that root unless an agent
passes another root explicitly.UnicodeEncodeError
crashes on older terminal encodings.MIT — see LICENSE.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
uvx droste-memoryMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"io-github-lorismascio17-droste-memory": {
"command": "uvx",
"args": [
"droste-memory"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referencedroste-memorypypiDroste works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.