{"id":49438428,"url":"https://github.com/ousatov-ua/memgraph-ingester","last_synced_at":"2026-05-30T11:01:14.708Z","repository":{"id":352411210,"uuid":"1214962520","full_name":"ousatov-ua/memgraph-ingester","owner":"ousatov-ua","description":"Turns codebases into graph-based memory for AI agents using Memgraph","archived":false,"fork":false,"pushed_at":"2026-05-27T12:33:03.000Z","size":2602,"stargazers_count":8,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-27T14:27:50.410Z","etag":null,"topics":["ai","ai-agent","ai-agents","claude-code","codex","gemini","github-copilot","memgraph"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ousatov-ua.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-19T09:40:12.000Z","updated_at":"2026-05-27T14:11:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ousatov-ua/memgraph-ingester","commit_stats":null,"previous_names":["ousatov-ua/memgraph-ingester"],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/ousatov-ua/memgraph-ingester","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ousatov-ua%2Fmemgraph-ingester","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ousatov-ua%2Fmemgraph-ingester/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ousatov-ua%2Fmemgraph-ingester/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ousatov-ua%2Fmemgraph-ingester/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ousatov-ua","download_url":"https://codeload.github.com/ousatov-ua/memgraph-ingester/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ousatov-ua%2Fmemgraph-ingester/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33626142,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ai-agent","ai-agents","claude-code","codex","gemini","github-copilot","memgraph"],"created_at":"2026-04-29T19:00:31.429Z","updated_at":"2026-05-30T11:01:14.674Z","avatar_url":"https://github.com/ousatov-ua.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Memgraph Ingester\n\n[![Build](https://github.com/ousatov-ua/memgraph-ingester/actions/workflows/maven.yml/badge.svg)](https://github.com/ousatov-ua/memgraph-ingester/actions/workflows/maven.yml)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.ousatov-ua/memgraph-ingester)](https://central.sonatype.com/artifact/io.github.ousatov-ua/memgraph-ingester)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Visitors](https://visitor-badge.laobi.icu/badge?page_id=ousatov-ua.memgraph-ingester)](https://github.com/ousatov-ua/memgraph-ingester)\n[![GitHub commits](https://img.shields.io/github/commit-activity/t/ousatov-ua/memgraph-ingester)](https://github.com/ousatov-ua/memgraph-ingester/commits/main)\n[![GitHub last commit](https://img.shields.io/github/last-commit/ousatov-ua/memgraph-ingester)](https://github.com/ousatov-ua/memgraph-ingester/commits/main)\n[![Supports Java codebases](https://img.shields.io/badge/spec_support-Java-f89820?logo=openjdk\u0026logoColor=white)](#3-ingest-java)\n[![Supports JavaScript/TypeScript codebases](https://img.shields.io/badge/spec_support-JavaScript%20%2F%20TypeScript-3178c6?logo=typescript\u0026logoColor=white)](#4-ingest-javascript-or-typescript)\n[![Supports Python codebases](https://img.shields.io/badge/spec_support-Python-3776ab?logo=python\u0026logoColor=white)](#5-ingest-python)\n[![Supports any language](https://img.shields.io/badge/supports-any_language_by_ctags-blue)](#6-ingest-any-language)\n\n![memgraph-ingester-readme-banner-640x320.svg](image/memgraph-ingester-readme-banner-640x320.svg)\n\nMemgraph Ingester indexes source files into\n[Memgraph](https://memgraph.com/) so AI agents can query a real code graph instead of repeatedly\nscanning raw files.\n\nLanguages supported:\n- **Java**\n- **JavaScript/TypeScript**\n- **Python**\n- **Ctags-detected fallback languages** such as Ruby, Go, Rust, Kotlin, C, and C++ for structural\n  inventories when no first-class adapter owns the file extension.\n\nOptionally, it can also enable **memories** for durable project rules.\n\nUse it when you want your agent to quickly answer questions such as:\n\n- What classes, methods, files, and packages exist?\n- What extends or implements this type?\n- Who calls this method?\n- What durable project rules, decisions, findings, risks, and tasks should the agent remember?\n\nThe normal path is simple:\n\n1. Run Memgraph.\n2. Download one ingester executable.\n3. Run one command; the ingester selects Java, JS/TS, Python, or ctags fallback logic from each\n   source file extension.\n4. Connect your AI agent through MCP or `mgconsole`.\n\nNo source code is uploaded by the ingester. It reads local files, writes graph nodes to your\nMemgraph instance over Bolt, and exits.\n\n## Safety First\n\nThe ingester is designed to be safe to try.\n\n| Area | What happens |\n|---|---|\n| Project isolation | Every code and memory node is scoped by `--project`. Multiple repos can share one Memgraph instance. |\n| Normal re-ingestion | `--wipe-project-code` deletes only the code graph for that `--project`. Other projects stay untouched. |\n| Memory protection | Memory is not deleted unless you explicitly pass `--wipe-project-memories`. |\n| Full database wipe | `--wipe-all` deletes all Memgraph data. Use it only when you intentionally want an empty database. |\n| Schema setup | `--apply-schema` is safe to re-run. Existing constraints and indexes are skipped by Memgraph. |\n| Java parsing | Java source is parsed locally with JavaParser. Dependencies are optional and only improve symbol resolution. |\n| JS/TS parsing | The ingester can manage its own Node.js and TypeScript parser locally. You do not have to install Node.js. |\n| Python parsing | The ingester can manage its own standalone CPython runtime and private venv locally. You do not have to install Python. |\n| Ctags fallback | The ingester can manage its own Universal Ctags executable locally. You do not have to install ctags. |\n\nFor JS/TS, Python, and ctags fallback, managed runtime mode is explicit and controlled:\n\n- Default mode is `--js-runtime-mode managed`.\n- Default mode is `--python-runtime-mode managed`.\n- Default mode is `--ctags-runtime-mode managed`.\n- Managed mode downloads pinned Node.js `22.11.0` from `nodejs.org`.\n- It verifies Node.js with the official SHA-256 checksum before extracting.\n- It downloads pinned TypeScript `5.6.3` from the npm registry.\n- It verifies the TypeScript package with SHA-512 integrity metadata.\n- Managed Python downloads pinned standalone CPython `3.14.5` from python-build-standalone.\n- It verifies CPython with the release `SHA256SUMS` file before extracting.\n- It creates a private Python venv under `~/.cache/memgraph-ingester` by default.\n- Managed ctags downloads an official Universal Ctags release asset and verifies SHA-256 when the\n  release publishes a digest.\n- With `--ctags-version latest`, a ready cached ctags install is reused before checking GitHub\n  release metadata.\n- It caches parser runtimes under `~/.cache/memgraph-ingester` by default.\n- It never installs Node.js globally.\n- It never installs Python globally.\n- It never runs `npm install` in your project.\n- It never imports your Python project packages or runs your Python application code.\n- It never runs source files through ctags; ctags only reads files to emit tags.\n- It skips `node_modules` during source ingestion and watch registration.\n- The Python adapter skips common Python environment/cache directories such as `.venv`, `venv`,\n  `site-packages`, `__pycache__`, `build`, and `dist`.\n\nIf you do not want the ingester to download Node.js, use your own Node.js:\n\n```bash\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-js-project \\\n  --js-runtime-mode system \\\n  --wipe-project-code \\\n  --init-instructions \\\n  --apply-schema\n```\n\nIf you want no network access during JS/TS ingestion, warm the cache once and then use offline mode:\n\n```bash\n\u003cingester\u003e --check-js-runtime\n\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-js-project \\\n  --js-runtime-mode offline \\\n  --init-instructions \\\n  --wipe-project-code\n```\n\n## Requirements\n\nFor normal use:\n\n- Memgraph, either local, Docker, or an existing Bolt endpoint.\n- One ingester download from the release page.\n\nRuntime requirements by artifact:\n\n| Artifact | Java required? | Node.js required for JS/TS? | Python required for Python? | Ctags required for fallback? |\n|---|---:|---:|---:|---:|\n| Native executable | No | No, managed mode handles it | No, managed mode handles it | No, managed mode handles it |\n| Shaded JAR | Java 25 JRE | No, managed mode handles it | No, managed mode handles it | No, managed mode handles it |\n\nOptional tools:\n\n- `mgconsole`, if you want to query Memgraph directly without MCP (***produces much fewer tokens***)\n- Node.js, Python 3.9+, or Universal Ctags only when you explicitly choose\n  `--js-runtime-mode system`, `--python-runtime-mode system`, or `--ctags-runtime-mode system`.\n  Set `MEMGRAPH_INGESTER_PYTHON` to override the system Python executable, or\n  `MEMGRAPH_INGESTER_CTAGS` to override the system ctags executable.\n- Maven, only if you want a richer Java classpath or you want to build from source.\n- Java 25 SDK, only if you build from source.\n\n## Quick Start\n\n### 1. Start Memgraph\n\n```bash\ndocker run -p 7687:7687 -p 7444:7444 --name memgraph memgraph/memgraph-mage:3.9.0\n```\n\nMemgraph Bolt listens on `bolt://localhost:7687`.\n\n### 2. Download the Ingester\n\nVersion in this repository: `11.0.3`.\n\n| Platform | Download                                                                                                                                             |\n|---|------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Java shaded JAR | [memgraph-ingester.jar](https://github.com/ousatov-ua/memgraph-ingester/releases/download/v11.0.3/memgraph-ingester.jar)                             |\n| Linux AMD64 | [memgraph-ingester-linux-amd64.zip](https://github.com/ousatov-ua/memgraph-ingester/releases/download/v11.0.3/memgraph-ingester-linux-amd64.zip)     |\n| macOS ARM64 | [memgraph-ingester-macos-arm64.zip](https://github.com/ousatov-ua/memgraph-ingester/releases/download/v11.0.3/memgraph-ingester-macos-arm64.zip)     |\n| Windows AMD64 | [memgraph-ingester-windows-amd64.zip](https://github.com/ousatov-ua/memgraph-ingester/releases/download/v11.0.3/memgraph-ingester-windows-amd64.zip) |\n\nFor native downloads:\n\n```bash\nunzip memgraph-ingester-macos-arm64.zip\nchmod +x memgraph-ingester-macos-arm64\n./memgraph-ingester-macos-arm64 --help\n```\n\nFor the JAR:\n\n```bash\njava -jar /path/to/memgraph-ingester.jar --help\n```\n\nIn commands below, replace `\u003cingester\u003e` with either the native executable path or\n`java -jar /path/to/memgraph-ingester.jar`.\n\n### 3. Ingest Java\n\nSimple Java ingestion:\n\n```bash\ncd /path/to/your/java/project\n\n\u003cingester\u003e \\\n  --source src/main/java \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project \\\n  --init-instructions \\\n  --wipe-project-code \\\n  --apply-schema\n```\n\nNote: If you want to use memories too, then add `--with-memories`.\n\nBetter Java symbol resolution for Maven projects:\n\n```bash\ncd /path/to/your/java/project\n\nCP=$(mvn -q dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=/dev/stdout 2\u003e/dev/null)\n\n\u003cingester\u003e \\\n  --source src/main/java \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project \\\n  --init-instructions \\\n  --classpath \"$CP\" \\\n  --wipe-project-code \\\n  --apply-schema\n```\n\nWhat the classpath improves:\n\n- Fully qualified external types.\n- More complete `EXTENDS` and `IMPLEMENTS` edges.\n- More complete method signatures.\n- More complete best-effort `CALLS` edges.\n\n### 4. Ingest JavaScript or TypeScript\n\nManaged mode needs no user-installed Node.js:\n\n```bash\ncd /path/to/your/js/project\n\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-js-project \\\n  --wipe-project-code \\\n  --init-instructions \\\n  --apply-schema\n```\n\nOptional preflight check, without connecting to Memgraph:\n\n```bash\n\u003cingester\u003e --check-js-runtime\n```\n\nThis downloads and verifies the managed parser runtime if needed, then runs a local parser smoke\ntest against temporary JS files.\n\n### 5. Ingest Python\n\nManaged mode needs no user-installed Python:\n\n```bash\ncd /path/to/your/python/project\n\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-python-project \\\n  --wipe-project-code \\\n  --init-instructions \\\n  --apply-schema\n```\n\nOptional preflight check, without connecting to Memgraph:\n\n```bash\n\u003cingester\u003e --check-python-runtime\n```\n\nThis downloads and verifies the managed standalone CPython runtime if needed, creates the private\nparser venv, then runs a local parser smoke test against temporary Python files.\n\n### 6. Ingest Other Ctags-Detected Languages\n\nManaged ctags mode needs no user-installed ctags. It is a fallback after Java, JS/TS, and Python,\nso first-class adapters still own their extensions:\n\n```bash\ncd /path/to/your/mixed/project\n\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-mixed-project \\\n  --wipe-project-code \\\n  --init-instructions \\\n  --apply-schema\n```\n\nOptional preflight check, without connecting to Memgraph:\n\n```bash\n\u003cingester\u003e --check-ctags-runtime\n```\n\nCtags fallback writes files, packages, synthetic module owners, types, methods, and fields under the\ndetected graph language. It does not promise call graphs or language-specific semantic resolution.\n\n### 7. Verify the Graph\n\nWith MCP, run the same Cypher through your agent. With `mgconsole`:\n\n```bash\nmgconsole --host localhost --port 7687 --output-format=csv\n```\n\nThen:\n\n```cypher\nMATCH (p:Project)-[:CONTAINS]-\u003e(l:Language)-[:CONTAINS]-\u003e(c:Code)\nRETURN p.name, l.name, c.sourceRoots, c.lastIngested\nORDER BY c.lastIngested DESC;\n```\n\nYou should see your project name and a fresh `lastIngested` timestamp.\n\n## Common Commands\n\n### Re-ingest after code changes\n\n```bash\n\u003cingester\u003e \\\n  --source src/main/java \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project\n```\n\nRegular re-ingestion prunes graph state for source files that were deleted and for declarations or\nfile-local relationships removed from changed files. Use `--wipe-project-code` only when you want a\nfresh project code graph before ingestion starts.\nChanged-file cleanup and replacement writes are committed per file, including with `--threads \u003e 1`.\nRetained snapshots include active-source files, existing same-root graph files, and existing files\nfrom other source roots. Re-ingestion refreshes retained files after deletes with the retained\nfile's source root. Watch re-ingestion also skips delete cleanup after update failures, retries\nsnapshot-failed batches, and reconciles delete-only snapshot failures.\n\n### Faster re-runs\n\nUse `--incremental` to skip files whose filesystem `lastModified` timestamp matches the graph:\n\n```bash\n\u003cingester\u003e \\\n  --source src/main/java \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project \\\n  --incremental\n```\n\n### Watch mode\n\nUse `--watch` to keep the graph fresh while editing:\n\n```bash\n\u003cingester\u003e \\\n  --source src/main/java \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project \\\n  --watch\n```\n\nWatch mode recursively watches the source tree, debounces rapid saves, re-ingests changed files,\nand removes graph state for deleted files.\n\n### Fresh project code and memory\n\nThis is safe for the named project, but it deletes that project's memory:\n\n```bash\n\u003cingester\u003e \\\n  --source src/main/java \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project \\\n  --wipe-project-code \\\n  --wipe-project-memories \\\n  --apply-schema\n```\n\n### Multiple projects in one Memgraph instance\n\n```bash\n\u003cingester\u003e -s ~/code/repo-a/src/main/java -b bolt://localhost:7687 -P repo-a --wipe-project-code\n\u003cingester\u003e -s ~/code/repo-b/src/main/java -b bolt://localhost:7687 -P repo-b --wipe-project-code\n```\n\nList indexed projects:\n\n```cypher\nMATCH (p:Project)-[:CONTAINS]-\u003e(l:Language)-[:CONTAINS]-\u003e(c:Code)\nRETURN p.name, l.name, c.sourceRoots, c.lastIngested\nORDER BY c.lastIngested DESC;\n```\n\n## Java Guide\n\nThe Java adapter reads `.java` files using JavaParser with Java 25 syntax support. It should handle\nmost earlier Java versions as well.\n\nCaptured Java structure:\n\n- Packages and files.\n- Classes, interfaces, annotations, enums, records, and nested classes.\n- Methods, constructors, fields, visibility, return types, static flags, line ranges, and synthetic flags.\n- `EXTENDS`, `IMPLEMENTS`, `DECLARES`, `DEFINES`, `CONTAINS`, `ANNOTATED_WITH`, and best-effort `CALLS`.\n\nUse `--classpath` whenever you can. Without dependency JARs, the ingester still works, but external\ntypes may fall back to simple names and some call edges may be missing.\n\nFor Maven projects:\n\n```bash\nCP=$(mvn -q dependency:build-classpath -DincludeScope=test -Dmdep.outputFile=/dev/stdout 2\u003e/dev/null)\n```\n\nUse `-DincludeScope=test` when you ingest tests or test fixtures. It includes JUnit, Testcontainers,\nmocking libraries, and other test-scoped dependencies.\n\nGenerated code is indexed only if you ingest it:\n\n```bash\n\u003cingester\u003e \\\n  --source target/generated-sources/annotations \\\n  --bolt bolt://localhost:7687 \\\n  --project my-java-project\n```\n\nDo not pass `--wipe-project-code` on the generated-source pass unless you want to replace the\nprevious graph with generated sources only.\n\n## JavaScript and TypeScript Guide\n\nJS/TS files are detected from their extensions during the normal `--source` scan.\n\nAccepted source extensions:\n\n- `.js`\n- `.jsx`\n- `.ts`\n- `.tsx`\n- `.mts`\n- `.cts`\n- `.d.ts`\n- `.d.mts`\n- `.d.cts`\n- `.mjs`\n- `.cjs`\n\nOnly source files under `--source` are considered. Use the repository root as `--source` when you\nwant root JavaScript config files or support scripts indexed alongside application source.\n`tsconfig.json` and configs from its `extends` chain are read for TypeScript path aliases when\npresent, but they are not indexed as code nodes.\n\nSkipped paths:\n\n- Anything under `node_modules`.\n\nCaptured JS/TS structure:\n\n- Files and synthetic module owners.\n- Classes, named class expressions, and class expressions assigned to variables.\n- Interfaces and type aliases as graph interfaces.\n- Class/interface `EXTENDS` and class `IMPLEMENTS` relationships, including relative imports and\n  `tsconfig.json` path aliases, including those inherited from extended configs, that resolve under\n  `--source`.\n- Interface and object-literal type members as `:Field`/`:Method` declarations.\n- TypeScript enums as graph classes with `isEnum = true` and `kind = \"enum\"`, with enum members as\n  `:Field` declarations using `kind = \"enum-member\"`.\n- Top-level functions and variables under the module owner.\n- Exported callable aliases and class re-export aliases as graph-visible declarations for their\n  public export names.\n- Methods, constructors, function-valued class fields, fields, abstract class metadata, bodyless\n  abstract/optional method signatures, static flags, line ranges, and kinds.\n- Decorators as annotations, preserving namespace-qualified decorator FQNs when possible.\n- Angular decorators with framework metadata when detected.\n- Syntax-based best-effort call edges, including top-level IIFEs/callbacks, local function\n  constructors, typed `this.\u003cproperty\u003e` receivers for local classes, and deferred resolution for\n  resolvable relative imports.\n- Relative import and `tsconfig.json` path-alias resolution, including extended configs, prefers\n  TypeScript source files over emitted JavaScript when both exist for the same local module path.\n\nRuntime modes:\n\n| Mode | Use when | Network |\n|---|---|---|\n| `managed` | You want the ingester to own the parser runtime. This is the default. | Downloads once if cache is missing. |\n| `system` | You want to use `node` from `PATH`. | No Node download. TypeScript may still be managed unless already cached. |\n| `offline` | You want no downloads and the cache is already warm. | No downloads. Fails if cache is missing. |\n\nCustom cache:\n\n```bash\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-js-project \\\n  --js-runtime-cache /path/to/cache \\\n  --wipe-project-code\n```\n\nCustom pinned versions:\n\n```bash\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-js-project \\\n  --js-node-version 22.11.0 \\\n  --js-typescript-version 5.6.3 \\\n  --wipe-project-code\n```\n\nJS/TS caveat: JavaScript is dynamic. `CALLS` is not a complete raw AST call inventory; it records\nknown source call relationships when the helper can associate the site and target with graph\nmethods. Dynamic dispatch, dependency injection, monkey-patching, framework templates, and\ngenerated code can produce missing call edges. A missing JS/TS `CALLS` edge does not prove a call\nnever happens.\n\n## Python Guide\n\nPython files are detected from their extensions during the normal `--source` scan.\n\nAccepted source extensions:\n\n- `.py`\n- `.pyi`\n\nSkipped paths:\n\n- `__pycache__`\n- `.venv`\n- `venv`\n- `.tox`\n- `.nox`\n- `site-packages`\n- `build`\n- `dist`\n\nCaptured Python structure:\n\n- Files and synthetic module owners.\n- Classes and class `EXTENDS` relationships when relative imports resolve under `--source`.\n- Top-level functions and variables under the module owner.\n- Methods, constructors, fields, decorators, line ranges, and kinds.\n- Syntax-based best-effort call edges for local functions and deferred owner/name calls for\n  resolvable `self.method()` calls.\n\nRuntime modes:\n\n| Mode | Use when | Network |\n|---|---|---|\n| `managed` | You want the ingester to own the parser runtime. This is the default. | Downloads once if cache is missing. |\n| `system` | You want to use Python 3.9+ from `PATH` or `MEMGRAPH_INGESTER_PYTHON`. | No CPython download. |\n| `offline` | You want no downloads and the managed cache is already warm. | No downloads. Fails if cache is missing. |\n\nCustom cache:\n\n```bash\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-python-project \\\n  --python-runtime-cache /path/to/cache \\\n  --wipe-project-code\n```\n\nCustom pinned standalone CPython:\n\n```bash\n\u003cingester\u003e \\\n  --source . \\\n  --bolt bolt://localhost:7687 \\\n  --project my-python-project \\\n  --python-version 3.14.5 \\\n  --python-build 20260510 \\\n  --wipe-project-code\n```\n\nPython caveat: Python is dynamic. The ingester parses syntax with CPython `ast`; it does not import\nproject modules, install project dependencies, or execute application code. Dynamic dispatch,\nmonkey-patching, imports outside `--source`, and generated code can produce missing call or\ninheritance edges. A missing Python `CALLS` edge does not prove a call never happens.\n\n## Agent Setup\n\nThe graph is useful directly, but it becomes much more powerful when your agent is told to use it.\nThe executable can write project-scoped Memgraph instructions to the agent's local instruction file.\nIt replaces its own previously managed block when one already exists, so rerunning the command keeps\n`AGENTS.md`, `CLAUDE.md`, or another instruction file tidy.\n\nRun the command from the repo you just ingested, using the same `--project` value.\n\nCode graph guidance is installed by default:\n\n```bash\nmemgraph-ingester --init-instructions -P my-project\nmemgraph-ingester -P my-project --instructions-agent codex\n```\n\nAdd optional Memory workflow instructions when you want agents to create and maintain durable\nMemgraph Memories:\n\n```bash\nmemgraph-ingester --init-instructions -P my-project --with-memories\nmemgraph-ingester -P my-project --instructions-agent codex --with-memories\n```\n\nAgent presets choose the default target file:\n\n```bash\nmemgraph-ingester --init-instructions -P my-project --instructions-agent codex\nmemgraph-ingester --init-instructions -P my-project --instructions-agent claude\nmemgraph-ingester --init-instructions -P my-project --instructions-agent gemini\nmemgraph-ingester --init-instructions -P my-project --instructions-agent github\n```\n\nWhen `--instructions-agent` is present, `--init-instructions` is optional.\n\nUse `--instructions-file` to target a specific file:\n\n```bash\nmemgraph-ingester -P my-project --instructions-file .github/copilot-instructions.md\n```\n\nCommit the updated instruction file so future agent sessions get the same graph guidance.\n\n## MCP or mgconsole\n\nMCP is optional. Agents can query Memgraph through MCP or via\n`mgconsole`.\n\nUse MCP when you want the agent to query the graph automatically.\nUse `mgconsole` when you want direct, token-light Cypher output.\n\n### Claude MCP\n\nMinimal `.claude.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"memgraph\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"mcp-memgraph\"\n      ],\n      \"env\": {\n        \"MEMGRAPH_URL\": \"bolt://localhost:7687\",\n        \"MCP_READ_ONLY\": \"false\"\n      }\n    }\n  }\n}\n```\n\nVerify:\n\n```bash\nclaude mcp list\n```\n\n### Codex MCP\n\nMinimal `~/.codex/config.toml`:\n\n```toml\n[mcp_servers.memgraph]\ncommand = \"uv\"\nargs = [\n  \"run\",\n  \"--with\",\n  \"mcp-memgraph\",\n  \"--python\",\n  \"3.13\",\n  \"mcp-memgraph\"\n]\n\n[mcp_servers.memgraph.env]\nMCP_TRANSPORT = \"stdio\"\nMEMGRAPH_URL = \"bolt://localhost:7687\"\nMEMGRAPH_USER = \"memgraph\"\nMEMGRAPH_PASSWORD = \"\"\nMEMGRAPH_DATABASE = \"memgraph\"\nMCP_READ_ONLY = \"false\"\n\n[mcp_servers.memgraph.tools.run_query]\napproval_mode = \"approve\"\n```\n\nVerify:\n\n```bash\ncodex mcp list\n```\n\n### Gemini MCP\n\nMinimal `~/.gemini/settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"mcp-memgraph\": {\n      \"command\": \"uvx\",\n      \"args\": [\n        \"mcp-memgraph\"\n      ],\n      \"env\": {\n        \"MEMGRAPH_URL\": \"bolt://localhost:7687\",\n        \"MCP_READ_ONLY\": \"false\"\n      },\n      \"timeout\": 5000,\n      \"trust\": true\n    }\n  }\n}\n```\n\nVerify:\n\n```bash\ngemini mcp list\n```\n\n### GitHub Copilot MCP\n\nMinimal `~/.copilot/mcp-config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"mcp-memgraph\": {\n      \"type\": \"local\",\n      \"command\": \"uvx\",\n      \"args\": [\n        \"mcp-memgraph\"\n      ],\n      \"env\": {\n        \"MEMGRAPH_URL\": \"bolt://localhost:7687\",\n        \"MCP_READ_ONLY\": \"false\"\n      },\n      \"tools\": [\n        \"*\"\n      ]\n    }\n  }\n}\n```\n\nSet `MCP_READ_ONLY` to `\"true\"` if you only want the agent to read. Keep it `\"false\"` when you want\nthe agent to create or update Memory nodes.\n\n## CLI Reference\n\nExit codes:\n\n| Code | Meaning |\n|---:|---|\n| `0` | Success |\n| `1` | Invalid arguments or runtime setup failure |\n| `2` | One or more files failed to parse or ingest |\n\nOptions:\n\n| Option | Short | Required | Default | Description |\n|---|---|---:|---|---|\n| `--source` | `-s` | yes |  | Root directory to scan. |\n| `--bolt` | `-b` | yes |  | Memgraph Bolt URL, for example `bolt://localhost:7687`. |\n| `--project` | `-P` | yes |  | Logical project name. Namespaces all graph nodes. |\n| `--user` | `-u` | no | empty | Memgraph username. |\n| `--pass` | `-p` | no | empty | Memgraph password. |\n| `--threads` | `-t` | no | `1` | Parser threads. Each thread gets its own Bolt session. |\n| `--wipe-project-code` |  | no | `false` | Delete this project's code graph before ingesting. |\n| `--wipe-project-memories` |  | no | `false` | Delete this project's memory graph before ingesting. |\n| `--apply-schema` |  | no | `false` | Apply Memgraph constraints and indexes before ingesting. |\n| `--wipe-all` |  | no | `false` | Delete all data from Memgraph. |\n| `--incremental` |  | no | `false` | Skip files whose last-modified timestamp matches the graph. |\n| `--watch` | `-w` | no | `false` | Watch the source directory and re-ingest changes. |\n| `--classpath` |  | no | empty | Platform-separated JAR paths for Java symbol resolution. |\n| `--js-runtime-mode` |  | no | `managed` | `managed`, `system`, or `offline`. |\n| `--js-runtime-cache` |  | no | `~/.cache/memgraph-ingester` | Cache directory for managed Node.js and TypeScript downloads. |\n| `--js-node-version` |  | no | `22.11.0` | Pinned Node.js version for managed JS/TS parsing. |\n| `--js-typescript-version` |  | no | `5.6.3` | Pinned TypeScript compiler package version. A leading `v` is accepted. |\n| `--check-js-runtime` |  | no | `false` | Run a local JS runtime smoke check without connecting to Memgraph. |\n| `--python-runtime-mode` |  | no | `managed` | `managed`, `system`, or `offline`. |\n| `--python-runtime-cache` |  | no | `~/.cache/memgraph-ingester` | Cache directory for managed CPython downloads and private Python venvs. |\n| `--python-version` |  | no | `3.14.5` | Pinned CPython version for managed Python parsing. A leading `v` is accepted. |\n| `--python-build` |  | no | `20260510` | Pinned python-build-standalone release tag for managed Python parsing. |\n| `--check-python-runtime` |  | no | `false` | Run a local Python runtime smoke check without connecting to Memgraph. |\n| `--init-instructions` |  | no | `false` | Write or replace managed agent instructions and exit. Includes Code guidance by default. |\n| `--instructions-agent` |  | no | `codex` | Agent preset: `codex`, `claude`, `gemini`, `github`, or `copilot`. Implies `--init-instructions` when explicitly provided. |\n| `--instructions-file` |  | no | preset file | Instruction file to update. Overrides `--instructions-agent` and implies `--init-instructions`. |\n| `--with-memories` |  | no | `false` | Include optional Memory workflow instructions when initializing agents. |\n| `--help` |  | no |  | Print CLI help. |\n| `--version` |  | no |  | Print CLI version. |\n\nParallel ingestion:\n\n| Threads | Typical speedup | Bottleneck |\n|---:|---|---|\n| `1` | 1x | Sequential parse and write |\n| `4` | about 2.5x to 3x | Write serialization starts |\n| `8` | about 3x to 4x | Diminishing returns |\n| `16+` | about 3x to 4x | Writes saturated |\n\nUse 4 to 8 threads for large projects on most machines. Values higher than your CPU core count\nrarely help.\n\n## Graph Model\n\nMemgraph Ingester creates two project-scoped graph roots:\n\n- Code graph: `(:Project)-[:CONTAINS]-\u003e(:Language)-[:CONTAINS]-\u003e(:Code)`\n- Memory graph: `(:Project)-[:HAS_MEMORY]-\u003e(:Memory)`\n\nEvery code and memory node uses the same `project` namespace. Code is grouped by language nodes\nnamed `Java` and `Js`.\n\n### Code Nodes\n\n| Label | Identity | Key properties |\n|---|---|---|\n| `:Project` | `name` | Project anchor. |\n| `:Language` | `(project, name)` | `Java` or `Js` group. |\n| `:Code` | `(project, language)` | `sourceRoots`, `lastIngested`. |\n| `:Package` | `(name, project, language)` | Package name. |\n| `:File` | `(path, project)` | `lastModified`, `language`. |\n| `:Class` | `(fqn, project)` | `name`, `packageName`, type flags, `language`, `kind`, `modulePath`, `framework`. |\n| `:Interface` | `(fqn, project)` | `name`, `packageName`, `language`, `kind`, `modulePath`, `framework`. |\n| `:Annotation` | `(fqn, project)` | `name`, `packageName`, `language`, `kind`, `modulePath`, `framework`. |\n| `:Method` | `(signature, project)` | `name`, `returnType`, `visibility`, `isStatic`, `startLine`, `endLine`, `ownerFqn`, `ownerDisplayName`, `language`, `kind`. |\n| `:Field` | `(fqn, project)` | `name`, `type`, `visibility`, `isStatic`, `language`, `kind`. |\n| `:PendingCall` | `(project, callerSignature, calleeOwnerFqn, calleeName)` | Temporary owner/name call record resolved after ingestion. |\n\n### Code Relationships\n\n| Relationship | Meaning |\n|---|---|\n| `(:Project)-[:CONTAINS]-\u003e(:Language)-[:CONTAINS]-\u003e(:Code)` | Code graph anchor per language. |\n| `(:Code)-[:CONTAINS]-\u003e(:Package \\| :File)` | Top-level code membership. |\n| `(:Package)-[:CONTAINS]-\u003e(:Class \\| :Interface \\| :Annotation)` | Package contents. |\n| `(:File)-[:DEFINES]-\u003e(:Class \\| :Interface \\| :Annotation \\| :Method \\| :Field)` | Source location and file-owned members. |\n| `(:Class)-[:EXTENDS]-\u003e(:Class)` | Class inheritance. |\n| `(:Class)-[:IMPLEMENTS]-\u003e(:Interface)` | Interface implementation. |\n| `(:Interface)-[:EXTENDS]-\u003e(:Interface)` | Interface inheritance. |\n| `(:Class \\| :Interface \\| :Annotation)-[:DECLARES]-\u003e(:Method \\| :Field)` | Type members. |\n| `(:Method)-[:CALLS]-\u003e(:Method)` | Best-effort call graph. |\n| `(:Method)-[:PENDING_CALL]-\u003e(:PendingCall)` | Deferred owner/name call awaiting unique target resolution. |\n| `(:*)-[:ANNOTATED_WITH]-\u003e(:Annotation)` | Annotation or decorator usage. |\n\n### Memory Nodes\n\nMemory nodes are manually authored by agents or clients. They survive code re-ingestion when you do\nnot pass `--wipe-project-memories`.\n\nOnly the properties listed here should be used.\n\n| Label | Identity | Allowed properties |\n|---|---|---|\n| `:Memory` | `project` | `project` |\n| `:Decision` | `(id, project)` | `id`, `project`, `title`, `topic`, `status`, `rationale`, `consequences`, `createdAt`, `updatedAt` |\n| `:ADR` | `(id, project)` | `id`, `project`, `number`, `title`, `status`, `context`, `decision`, `consequences`, `createdAt`, `updatedAt` |\n| `:Rule` | `(id, project)` | `id`, `project`, `title`, `topic`, `severity`, `description`, `createdAt`, `updatedAt` |\n| `:Context` | `(id, project)` | `id`, `project`, `title`, `topic`, `content`, `source`, `createdAt`, `updatedAt` |\n| `:Finding` | `(id, project)` | `id`, `project`, `title`, `topic`, `type`, `status`, `summary`, `evidence`, `createdAt`, `updatedAt` |\n| `:Task` | `(id, project)` | `id`, `project`, `title`, `status`, `priority`, `description`, `createdAt`, `updatedAt` |\n| `:Risk` | `(id, project)` | `id`, `project`, `title`, `topic`, `severity`, `status`, `mitigation`, `createdAt`, `updatedAt` |\n| `:Question` | `(id, project)` | `id`, `project`, `title`, `status`, `answer`, `createdAt`, `updatedAt` |\n| `:Idea` | `(id, project)` | `id`, `project`, `title`, `topic`, `status`, `notes`, `createdAt`, `updatedAt` |\n| `:CodeRef` | `(project, targetType, key)` | `project`, `targetType`, `key` |\n\nControlled values:\n\n| Node | Property | Values |\n|---|---|---|\n| `:Decision` | `status` | `proposed`, `accepted`, `rejected`, `superseded` |\n| `:ADR` | `status` | `draft`, `accepted`, `rejected`, `superseded` |\n| `:Rule` | `severity` | `hard`, `soft`, `recommendation` |\n| `:Finding` | `type` | `bug`, `perf`, `constraint`, `security` |\n| `:Finding` | `status` | `open`, `resolved`, `obsolete` |\n| `:Task` | `status` | `todo`, `doing`, `done`, `blocked`, `cancelled` |\n| `:Task` | `priority` | `0` critical, `1` high, `2` medium, `3` low, `4` none |\n| `:Risk` | `severity` | `low`, `medium`, `high`, `critical` |\n| `:Risk` | `status` | `open`, `mitigated`, `accepted`, `obsolete` |\n| `:Question` | `status` | `open`, `answered`, `obsolete` |\n| `:Idea` | `status` | `proposed`, `accepted`, `rejected`, `obsolete` |\n\n### Memory Relationships\n\n| Relationship | Meaning |\n|---|---|\n| `(:Project)-[:HAS_MEMORY]-\u003e(:Memory)` | Memory graph anchor. |\n| `(:Memory)-[:HAS_DECISION \\| :HAS_ADR \\| :HAS_RULE \\| :HAS_CONTEXT]-\u003e(:*)` | Memory item ownership. |\n| `(:Memory)-[:HAS_FINDING \\| :HAS_TASK \\| :HAS_RISK \\| :HAS_QUESTION]-\u003e(:*)` | Memory item ownership. |\n| `(:Memory)-[:HAS_IDEA]-\u003e(:Idea)` | Memory item ownership. |\n| `(:Decision \\| :ADR \\| :Rule \\| :Context \\| :Finding \\| :Task \\| :Risk \\| :Idea)-[:REFERS_TO]-\u003e(:CodeRef)` | Stable memory-to-code reference. |\n| `(:CodeRef)-[:RESOLVES_TO]-\u003e(:Code \\| :Package \\| :File \\| :Class \\| :Interface \\| :Annotation \\| :Method \\| :Field)` | Current code node resolved after ingestion. |\n\nFor `:CodeRef`, use `key: 'java'`, `key: 'js'`, or `key: 'python'` for `targetType: 'Code'`,\nand `key: 'java:\u003cpackage\u003e'`, `key: 'js:\u003cpackage\u003e'`, or `key: 'python:\u003cpackage\u003e'` for\n`targetType: 'Package'`.\n\nSee [`doc/MEMORY.md`](doc/MEMORY.md) for Memory examples and Cypher recipes.\nSee [`doc/SCHEMA.md`](doc/SCHEMA.md) for the full graph model.\n\n## Useful Queries\n\nAll classes in a project:\n\n```cypher\nMATCH (:Project {name: 'my-project'})-[:CONTAINS]-\u003e(:Language {name: 'Java'})\n  -[:CONTAINS]-\u003e(:Code)-[:CONTAINS]-\u003e(:File)-[:DEFINES]-\u003e(c:Class)\nWHERE c.isExternal = false\nRETURN c.fqn\nORDER BY c.fqn;\n```\n\nWho calls a method:\n\n```cypher\nMATCH (caller:Method {project: 'my-project'})-[:CALLS]-\u003e(m:Method {project: 'my-project'})\nWHERE m.signature CONTAINS 'Widget.save('\nRETURN caller.signature\nORDER BY caller.signature;\n```\n\nAccepted decisions:\n\n```cypher\nMATCH (:Memory {project: 'my-project'})-[:HAS_DECISION]-\u003e(d:Decision {status: 'accepted'})\nRETURN d.id, d.title, d.rationale\nORDER BY d.updatedAt DESC;\n```\n\nMemory linked to a file:\n\n```cypher\nMATCH (file:File {path: 'src/main/java/com/example/Widget.java', project: 'my-project'})\nMATCH (memory {project: 'my-project'})-[:REFERS_TO]-\u003e(:CodeRef)-[:RESOLVES_TO]-\u003e(file)\nRETURN labels(memory), memory.id, memory.title;\n```\n\n## Caveats\n\n- JavaParser is not `javac`. It handles many projects well, but edge-case Java syntax and complex\n  symbol resolution can still fail.\n- Java `CALLS` edges are best-effort. Missing edges do not prove a call never happens.\n- Use `--classpath` for better Java FQN and call-edge coverage.\n- External Java parent types and annotations can appear as project-scoped nodes with\n  `isExternal = true`.\n- JS/TS `CALLS` edges are syntax-based and best-effort. Owner/name calls that cannot be\n  resolved in-file are stored as `:PendingCall` records and retried after the batch. Direct owner\n  methods are preferred, then the nearest superclass with exactly one matching method. Pending calls\n  for a reingested JS/TS file are cleared before the file's current calls are stored.\n- Re-ingestion refreshes file-local outgoing `CALLS`, `ANNOTATED_WITH`, `EXTENDS`, and `IMPLEMENTS`\n  relationships before writing the current file data, while preserving current method nodes so\n  incoming `CALLS` edges from unchanged files survive incremental runs.\n- Changed-file cleanup and replacement writes are per-file transactional. Retained snapshots include\n  active-source files, existing same-root graph files, and existing files from other source roots.\n- Re-ingestion refreshes retained files after deletes with the retained file's source root. Watch\n  re-ingestion also skips delete cleanup after update failures, retries snapshot-failed batches,\n  and reconciles delete-only snapshot failures.\n- Raw JS/TS `:Class` queries include synthetic module owners and TypeScript enums. Filter\n  `language = \"js\"` and `kind = \"class\"` when you only want JavaScript/TypeScript classes.\n- Generated code is indexed only when its generated source directory is passed to `--source`.\n- With `--threads \u003e 1`, log order is non-deterministic. Graph writes are idempotent.\n\n## Project Layout\n\n```text\n.\n├── .github/workflows/\n│   ├── maven.yml                               # Maven build/test workflow\n│   └── native-binaries.yml                     # GraalVM native binaries + JS runtime smoke tests\n├── doc/\n│   ├── MEMORY.md                               # Memory graph usage guide and recipes\n│   └── SCHEMA.md                               # Full code + memory graph schema reference\n├── image/                                      # README banners and social preview assets\n├── memgraph-platform/\n│   └── docker-compose.yml                      # Local Memgraph + Lab stack\n├── src/main/java/io/github/ousatov/tools/memgraph/\n│   ├── AgentInstructionsInstaller.java         # Agent instruction install/replace support\n│   ├── IngesterCli.java                        # picocli CLI entry point\n│   ├── def/\n│   │   └── Const.java                          # Shared parameter, label, and Cypher resource names\n│   ├── exception/\n│   │   └── ProcessingException.java            # Domain-level processing failure\n│   ├── exe/\n│   │   ├── adapter/\n│   │   │   ├── JavaLanguageAdapter.java        # JavaParser-backed Java ingestion adapter\n│   │   │   ├── JsLanguageAdapter.java          # Node/TypeScript-backed JS/TS ingestion adapter\n│   │   │   ├── LanguageAdapter.java            # Source-language adapter contract\n│   │   │   ├── SourceFileDefinitions.java      # Graph identities emitted for one source file\n│   │   │   └── SourceLanguage.java             # Supported source-language values\n│   │   ├── analyze/\n│   │   │   ├── JavaTypeNames.java              # Java type-name helpers\n│   │   │   ├── JsAnalysis.java                 # Neutral JS analyzer records\n│   │   │   ├── JsAnalyzer.java                 # Java wrapper around the bundled JS analyzer\n│   │   │   ├── ManagedNodeRuntime.java         # Downloaded/cached Node.js runtime management\n│   │   │   ├── ManagedPythonRuntime.java       # Downloaded/cached CPython and venv management\n│   │   │   ├── ManagedTypescriptPackage.java   # Downloaded/cached TypeScript compiler management\n│   │   │   ├── ParseService.java               # JavaParser setup and parsing\n│   │   │   ├── PythonAnalysis.java             # Neutral Python analyzer records\n│   │   │   ├── PythonAnalyzer.java             # Java wrapper around the bundled Python analyzer\n│   │   │   └── RuntimeMode.java                # Parser runtime mode values\n│   │   ├── ingestion/\n│   │   │   └── IngestionOrchestrator.java      # Ingestion, wipe, incremental, and watch workflow\n│   │   ├── metrics/\n│   │   │   ├── IngestionMetrics.java           # Metrics snapshot model\n│   │   │   ├── IngestionMetricsCollector.java  # Metrics collection from graph queries\n│   │   │   ├── IngestionPerformanceMetrics.java # Performance metrics table model\n│   │   │   ├── IngestionRunStats.java          # Per-run ingestion counters\n│   │   │   ├── MarkdownMetricsTable.java       # Shared Markdown metrics table renderer\n│   │   │   ├── MetricsSnapshotValidator.java   # Metrics snapshot comparison helper\n│   │   │   └── MetricsValidationCli.java       # CLI for validating metrics snapshots\n│   │   └── writer/\n│   │       ├── CallEdgeWriter.java             # Java call-edge extraction/writes\n│   │       ├── CommonGraphWriter.java          # Shared graph writer helpers for language writers\n│   │       ├── CypherExecutor.java             # Cypher execution and retry handling\n│   │       ├── GraphNodeWriter.java            # Batched low-level graph node/edge writes\n│   │       ├── GraphWrite.java                 # Shared graph write payload records\n│   │       ├── GraphWriter.java                # Stable writer facade over language-specific writers\n│   │       ├── java/\n│   │       │   └── JavaGraphWriter.java        # Java-specific graph writes\n│   │       ├── js/\n│   │       │   └── JsGraphWriter.java          # JavaScript/TypeScript-specific graph writes\n│   │       └── python/\n│   │           └── PythonGraphWriter.java      # Python-specific graph writes\n│   ├── schema/\n│   │   └── Memgraph.java                       # Schema loader and global wipe helpers\n│   └── vo/\n│       ├── Method.java                         # Method graph payload\n│       └── Settings.java                       # Ingestion settings payload\n├── src/main/resources/\n│   ├── META-INF/native-image/\n│   │   └── io.github.ousatov-ua/memgraph-ingester/\n│   │       ├── reflect-config.json             # GraalVM reflection metadata\n│   │       └── resource-config.json            # GraalVM bundled resource patterns\n│   ├── io/github/ousatov/tools/memgraph/cypher/\n│   │   ├── action/                             # Shared upsert, delete, and resolve Cypher\n│   │   │   ├── Js/                             # JS/TS-specific cleanup Cypher\n│   │   │   └── Python/                         # Python-specific cleanup Cypher\n│   │   ├── metrics/                            # Metrics snapshot Cypher queries\n│   │   ├── create-schema.cypher                # Constraints and indexes\n│   │   ├── drop-schema.cypher                  # Schema teardown\n│   │   └── wipe-all-data.cypher                # Full data wipe\n│   ├── io/github/ousatov/tools/memgraph/js/\n│   │   ├── js-analyzer-ast.cjs                 # TypeScript AST extraction helpers\n│   │   ├── js-analyzer-paths.cjs               # JS/TS import and tsconfig path resolution\n│   │   └── js-analyzer.cjs                     # Bundled TypeScript compiler-based JS/TS analyzer\n│   ├── io/github/ousatov/tools/memgraph/python/\n│   │   └── python-analyzer.py                  # Bundled CPython ast-based Python analyzer\n│   └── simplelogger.properties                 # Runtime logging defaults\n├── src/test/java/io/github/ousatov/tools/memgraph/\n│   ├── AgentInstructionsInstallerTest.java     # Agent instruction installer tests\n│   ├── CypherResourceTest.java                 # Bundled Cypher resource checks\n│   ├── IngesterCliInstructionsTest.java        # CLI instruction-generation tests\n│   ├── IngesterCliTest.java                    # CLI option and execution tests\n│   ├── exception/                              # Domain exception tests\n│   ├── extension/                              # Testcontainers Memgraph JUnit extension\n│   ├── exe/                                    # Parser, writer, orchestrator, and memory ITs\n│   └── schema/                                 # Schema loader tests\n├── template/\n│   ├── AI-memgraph-code-template.md            # Default code graph agent instructions\n│   └── AI-memgraph-memory-template.md          # Optional Memory workflow agent instructions\n├── .gitignore\n├── LICENSE\n├── pom.xml                                     # Maven build, release, and native-image configuration\n└── README.md                                   # User documentation\n```\n\n## License\n\nMIT. See [`LICENSE`](LICENSE).\n\n## Acknowledgements\n\n- [Evgeniy Voronyuk](https://github.com/brunneng) – testing support, propositions of use scenarios.\n\n## For Enthusiasts: Build It Yourself\n\nYou do not need this section to use the tool. Use the release downloads unless you want to hack on\nthe project.\n\n### Build the shaded JAR\n\nRequirements:\n\n- Java 25 SDK.\n- Maven 3.9+.\n\n```bash\ngit clone https://github.com/ousatov-ua/memgraph-ingester.git\ncd memgraph-ingester\nmvn clean package -Pshade -DskipTests\n```\n\nOutput:\n\n```text\ntarget/memgraph-ingester.jar\n```\n\nRun it:\n\n```bash\njava -jar target/memgraph-ingester.jar --help\n```\n\n### Validate a metrics snapshot\n\nAfter each ingestion run, the CLI prints Markdown tables for graph counts and performance counters\nsuch as elapsed milliseconds, file outcomes, and Cypher statement batching. The metrics validator is\nopt-in and compares only the graph-count table. It is not bound to the normal build, test, release,\nor native profiles. Run it after ingesting a project when you want to compare the current metrics\ntable with an expected snapshot file:\n\n```bash\nmvn compile exec:java@validate-metrics \\\n  -Dmetrics.expected=/path/to/expected-metrics.md \\\n  -Dmetrics.project=memgraph-ingester \\\n  -Dmetrics.bolt=bolt://localhost:7687\n```\n\nUse `-Dmetrics.user=...` and `-Dmetrics.pass=...` when the Bolt endpoint requires credentials.\n\n### Build a native executable\n\nNative builds use GraalVM Native Image and build for the OS where Maven runs.\n\n```bash\nmvn clean package -Pnative-macos -DskipTests\nmvn clean package -Pnative-linux -DskipTests\nmvn clean package -Pnative-windows -DskipTests\n```\n\nUse the profile that matches your operating system.\n\n### Use as a Maven dependency\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.github.ousatov-ua\u003c/groupId\u003e\n  \u003cartifactId\u003ememgraph-ingester\u003c/artifactId\u003e\n  \u003cversion\u003e11.0.3\u003c/version\u003e\n\u003c/dependency\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fousatov-ua%2Fmemgraph-ingester","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fousatov-ua%2Fmemgraph-ingester","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fousatov-ua%2Fmemgraph-ingester/lists"}