{
  "markdown": "<div align=\"center\">\n\n# Droste\n\n<!-- mcp-name: io.github.lorismascio17/droste-memory -->\n\n### See your codebase as a living galaxy — and give your agents causal memory of it.\n\nDroste indexes any repo into a fractal, zoomable map of its symbols, wires them\ntogether with their real call / import / DB edges across languages, and serves an\nagent the *causal* slice of code it actually needs — not just keyword matches.\n\n**Local-first · zero-config · polyglot · MCP-native**\n\n[![PyPI](https://img.shields.io/pypi/v/droste-memory.svg?cacheSeconds=300)](https://pypi.org/project/droste-memory/)\n[![Python](https://img.shields.io/pypi/pyversions/droste-memory.svg)](https://pypi.org/project/droste-memory/)\n[![CI](https://github.com/lorismascio17/droste-memory/actions/workflows/ci.yml/badge.svg)](https://github.com/lorismascio17/droste-memory/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\n![Droste fractal code galaxy](docs/assets/hero.gif)\n\n*Zooming out reveals the causal web — every cyan arc is a real `syntax_dependency`\nedge. [Full flythrough (FastAPI)](docs/assets/demo.mp4)*\n\n[Quickstart](#quickstart) · [Why it's different](#why-its-different) · [How it works](#how-it-works) · [MCP](#use-it-as-an-mcp-server) · [Benchmarks](#benchmarks)\n\n</div>\n\n---\n\n## Quickstart\n\n```bash\n# Windows\npython -m pip install --upgrade droste-memory\n\n# macOS / Linux\npython3 -m pip install --upgrade droste-memory\n\ndroste index . # index the current repo\ndroste view    # open the fractal galaxy in your browser\n```\n\nInstall once, then index and view. `droste view` opens a full-screen, 60fps zoomable map of your\ncode — scroll to dive from the project star into folder orbits, down to the\nindividual functions, with the causal edges glowing between them.\n\nNeed it for an agent instead of your eyes?\n\n```bash\ndroste context \"checkout flow\" --budget 1500   # causal context slice for an LLM\n```\n\nRunning `droste` with no arguments prints the command palette:\n\n```text\n                  .-----------------------.\n             .----'           |           '----.\n         .---'          .-----+-----.          '---.\n       .'          .----'     |     '----.          '.\n      /        .---'      .---+---.      '---.        \\\n     /      .-'        .-'    |    '-.        '-.      \\\n    |     .'        .-'   .---+---.   '-.        '.     |\n    |    /        .'    .'    |    '.    '.        \\    |\n    |   |        |     |   .--+--.   |     |        |   |\n    | --+--------+-----+---+  @  +---+-----+--------+-- |\n    |   |        |     |   '--+--'   |     |        |   |\n    |    \\        '.    '.    |    .'    .'        /    |\n    |     '.        '-.   '---+---'   .-'        .'     |\n     \\      '-.        '-.    |    .-'        .-'      /\n      \\        '---.      '---+---'      .---'        /\n       '.          '----.     |     .----'          .'\n         '---.          '-----+-----'          .---'\n             '----.           |           .----'\n                  '-----------------------'\n\nDROSTE-MEMORY // RIGID FRACTAL RADIAL LAYOUT\nLocal Graph Engine v1.1.6-Alpha-Sharded\n\nCommands\n  droste index <path> [--reset]\n  droste status\n  droste zoom <symbol_name>\n  droste context [query] --budget 1500\n  droste mcp\n\nFast path: droste context hub_core --budget 1000 | clip\n```\n\n---\n\n## Why it's different\n\nMost \"code context\" tools rank by keyword (ctags / ripgrep / repo-maps) or by\nembedding cosine (vector-RAG). Both can only return what *resembles* your query.\nA caller that shares no tokens — or a database function in a different language —\nis invisible to them, yet it's exactly what you need to understand or change the\ncode.\n\nDroste's edge is the causal graph:\n\n- **Causal wormholes.** Real `syntax_dependency` edges (calls, imports,\n  inheritance) in both directions — Droste hands the caller and callees, ordered,\n  within a token budget.\n- **Cross-language bridges.** The part nobody else does well: Droste links across\n  languages — app code to SQL functions/tables (`.rpc('x')`, `.from('table')`),\n  to edge functions, and same-name handlers between any two languages. Your\n  Dart/TS/Python frontend and your database stop being two separate worlds on the\n  map.\n- **A map you actually want to look at.** The fractal galaxy isn't a gimmick —\n  it's how you see coupling, risk hotspots, and the blast radius of a change.\n- **Zero-config and local.** No cloud, no account, no API key. fastembed (ONNX,\n  no torch) gives real semantics; a deterministic fallback keeps it runnable\n  anywhere.\n\nPolyglot: Python (AST) + tree-sitter for Dart, TypeScript/JavaScript, Go, Rust,\nJava, C#, C/C++, Kotlin, Swift, Ruby, PHP, SQL — symbols *and* edges.\n\n> **Honest scope:** the measured advantage is structural / causal retrieval. On\n> pure semantic \"concept\" queries it's competitive with a vector baseline, not a\n> leap. Cross-language bridges are strongest where the target is actually defined\n> in the indexed repo (e.g. SQL schema in your migrations).\n\n---\n\n## Benchmarks\n\nSelf-supervised eval (gold = the true caller/callee set from the AST), equal\nretrieval breadth *k*, real embeddings, across Python + Dart repos\n(`eval/comparative_eval.py`):\n\n| structural retrieval | Droste | vector-RAG core | lexical core |\n| --- | --- | --- | --- |\n| neighbour-recall | **0.94** | 0.18 | 0.42 |\n| nDCG@k | **0.65** | 0.10 | 0.29 |\n\n…plus hundreds of true causal neighbours that both baselines structurally miss.\nThis is a retrieval-method comparison (the cores of vector-RAG and lexical\nsearch), not a head-to-head against the finished products that wrap them.\n\n---\n\n## How it works\n\n- **Causal graph.** Each definition is parsed (Python `ast`; tree-sitter for the\n  rest) into the names it calls / imports / inherits, becoming first-class\n  `syntax_dependency` edges. Cross-language edges add DB calls (`.rpc`, `.from`,\n  `.functions.invoke`) and string-literal name matches across languages.\n- **Hybrid seed.** A query is matched by a normalized blend of lexical score and\n  semantic cosine (fastembed `bge-small-en-v1.5`, 384-dim), then the graph\n  expands the seed bidirectionally (callees and callers).\n- **Token packer.** Results fit a budget with LOD-demotion (full to contract to\n  skeleton) and a hard guardrail that never cuts a line of code mid-token.\n- **Sharded persistence.** One shard per file under `.droste/`, blake2b\n  dirty-tracking so a re-index rewrites only what changed; atomic writes + meta\n  written last, so it is crash-safe and self-heals on the next run.\n\n---\n\n## Use it as an MCP server\n\nDroste 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):\n\nFirst install or upgrade the PyPI package:\n\n```bash\n# Windows\npython -m pip install --upgrade droste-memory\n\n# macOS / Linux\npython3 -m pip install --upgrade droste-memory\n\ndroste mcp --help\n```\n\nFor Codex, add this to `C:\\Users\\<you>\\.codex\\config.toml` on Windows, or `~/.codex/config.toml` on macOS/Linux:\n\n```toml\n[mcp_servers.droste]\ncommand = \"droste\"\nargs = [\"mcp\"]\nstartup_timeout_sec = 120\n```\n\nBy default, `droste mcp` uses Droste's global local database. That is fine for\nquick use and small workflows. For serious multi-repo work, use one database per\nrepository so each project has isolated memory and agents can safely re-index\nthat project with `reset=true`.\n\nThe `--db` option is global, so keep it before `mcp`:\n\n```toml\n# Windows example\n[mcp_servers.droste]\ncommand = \"droste\"\nargs = [\"--db\", \"C:/Users/you/AppData/Local/Droste/my-project/droste_memory_db.json\", \"mcp\"]\nstartup_timeout_sec = 120\n```\n\n```toml\n# macOS / Linux example\n[mcp_servers.droste]\ncommand = \"droste\"\nargs = [\"--db\", \"/Users/you/.local/share/droste/my-project/droste_memory_db.json\", \"mcp\"]\nstartup_timeout_sec = 120\n```\n\nFor JSON-based MCP clients:\n\n```json\n{\n  \"mcpServers\": {\n    \"droste\": {\n      \"command\": \"droste\",\n      \"args\": [\"mcp\"]\n    }\n  }\n}\n```\n\nThe same isolated-DB pattern works in JSON clients:\n\n```json\n{\n  \"mcpServers\": {\n    \"droste\": {\n      \"command\": \"droste\",\n      \"args\": [\n        \"--db\",\n        \"/absolute/path/to/droste_memory_db.json\",\n        \"mcp\"\n      ]\n    }\n  }\n}\n```\n\nRestart your client after changing the MCP config. In a repo, ask your agent to call `droste_index_project` first, then `droste_get_context` for causal context.\n\nKey tools: `droste_index_project`, `droste_get_context`, `droste_status`.\n\n---\n\n## Use it as an agent skill\n\nDroste also ships agent skill templates for Codex and Claude. They teach an\nagent how to use Droste safely: isolated DBs, indexing, `droste context`, MCP\nconfig, and root-contamination guardrails.\n\nCodex skill:\n\n```text\nintegrations/codex-skill/droste-code-memory/\n```\n\nClaude-compatible skill:\n\n```text\nintegrations/claude-skill/droste-code-memory/\n```\n\nInstall the Codex skill by copying the folder into your Codex skills directory:\n\n```bash\n# macOS / Linux\nmkdir -p ~/.codex/skills\ncp -R integrations/codex-skill/droste-code-memory ~/.codex/skills/\n```\n\n```powershell\n# Windows PowerShell\nNew-Item -ItemType Directory -Force \"$env:USERPROFILE\\.codex\\skills\" | Out-Null\nCopy-Item -Recurse -Force integrations\\codex-skill\\droste-code-memory \"$env:USERPROFILE\\.codex\\skills\\\"\n```\n\nThen ask Codex:\n\n```text\nUse $droste-code-memory to index this repository and retrieve causal context before editing.\n```\n\nFor Claude, import or copy the Claude skill folder as a Claude Skill package and\nkeep its `SKILL.md`, `references/`, and `scripts/` together.\n\n---\n\n## Development\n\n```bash\npip install -e \".[dev]\"\npytest                            # deterministic regression suite (tests/)\npython eval/comparative_eval.py   # retrieval benchmark vs lexical & vector cores\n```\n\n`tests/` = invariants + concurrency (round-trip, dirty-oracle, packer guardrail,\ncross-process shard race). `eval/` = performance/quality benchmarks.\n\n---\n\n## Status\n\n**v1.1.6 (alpha).** Engine, polyglot + cross-language graph, CLI, fractal\nvisualizer and MCP server are working and tested. Packaging/distribution are\nmaturing — issues and PRs welcome (see `CONTRIBUTING.md`).\n\n### What's new in v1.1.6\n\n- Fixed the PyPI wheel packaging for `droste view` by shipping the visualizer\n  HTML/templates and public demo graph inside the installed package.\n- Verified the three-command pitch from a clean install:\n  `pip install droste-memory`, `droste index .`, `droste view`.\n\n### What's new in v1.1.5\n\n- Fixed self-index contamination by excluding Droste's own `.droste/`, `.tmp/`,\n  and `*.egg-info` directories from project scans.\n- Improved small-budget context packing by pinning the focus node's direct\n  callers/callees before secondary lexical matches.\n- Guaranteed compact stubs for true causal neighbours so important wormholes do\n  not disappear when full context cannot fit.\n\n### What's new in v1.1.4\n\n- Fixed Python 3.10/3.11 compatibility by replacing Python 3.12-only\n  `Path.walk()` usage.\n- Hardened MCP Registry publishing so metadata is only published after the\n  matching PyPI release is live.\n- Improved CI diagnostics for faster multi-version release debugging.\n\n### What's new in v1.1.3\n\n- Added public Codex and Claude skill templates for agent-side Droste adoption.\n\n### What's new in v1.1.2\n\n- Added MCP Registry ownership metadata in the README/PyPI description.\n- Added `server.json` for official MCP Registry publishing.\n- Added manual and scheduled growth workflows for MCP registry publishing and\n  visibility checks.\n\n### What's new in v1.1.1\n\n- Packaging/privacy hardening: generated visualizer JSON files (`graph.json`,\n  `status.json`, `context.json`) are excluded from source distributions, while\n  the public `visualizer/demo_graph.json` remains included.\n\n### What's new in v1.1.0\n\n- MCP context is root-isolated: `droste_index_project` records the active repo,\n  and `droste_get_context` / `droste_status` filter to that root unless an agent\n  passes another `root` explicitly.\n- Multi-root databases no longer silently mix repositories when no safe root can\n  be inferred; Droste returns a clean warning instead.\n- Windows CLI output is guarded for UTF-8 consoles to avoid `UnicodeEncodeError`\n  crashes on older terminal encodings.\n- Retrieval ranking is now query-aware: runtime code gets a slight boost for\n  normal implementation queries, while tests/docs remain fully visible when the\n  query asks for them.\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n",
  "bytes": 12494,
  "sha": "8763fc8787864da72fd196a0e469aca8688c2097fd26c4cbdd4d2366bed02776",
  "repo_slug": "lorismascio17/droste-memory",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_lorismascio17_droste_memory_fc464bfd/readme"
}