name: neo4j-cli description: Neo4j CLI. Runs and pipes Cypher, introspects the schema, generates a data model, and embeds text inline as a query parameter. Discovers and loads example datasets from GitHub repos into local Docker, Neo4j Desktop, or a new Aura instance. Manages local Neo4j Docker containers and Neo4j Desktop DBMSs; Aura instances, projects, and Agents; and Aura, Neo4j connection (dbms), and embedding-provider credentials. Installs, removes, and refreshes agent skills, and self-updates the binary. Skip for Cypher syntax help, Neo4j drivers, Kubernetes, Neo4j Browser, or other databases. version: {{VERSION}}
neo4j-cli
Allows you to manage Neo4j resources
Allows you to manage Neo4j resources. Write operations require --rw.
Global Flags
| Flag | Type | Default | Description |
|---|---|---|---|
--format |
string | - | Format to print console output in, from a choice of [default, json, table, toon]. (agents: prefer toon) |
--rw |
bool | false | Allow write operations. Auto-applied in interactive terminals; required when running under an agent harness or non-interactive script. |
Subcommands
| Command | Description |
|---|---|
admin |
Manage Neo4j databases, users, roles, and privileges |
agent-context |
Emit the full CLI shape as JSON for AI-agent discovery |
aura |
Allows you to programmatically provision and manage your Aura resources |
config |
Manage and view global configuration values |
credential |
Manage and view credential values |
dataset |
Discover example Neo4j datasets |
desktop |
Manage DBMSes under a local Neo4j Desktop 2 install |
docker |
Manage local Neo4j containers via Docker |
history |
View and manage the local command history log |
query |
Run Cypher, inspect the database schema (:schema), and embed text against a Neo4j database via the Bolt protocol |
skill |
Install agent skills for this CLI into supported AI agents |
update |
Self-update the neo4j-cli binary |
Tips & Gotchas
- Example datasets:
neo4j-cli dataset listsurfaces a curated suggestion set, but any GitHub<owner>/<repo>carrying arelate.project-install.jsonmanifest can be loaded — the suggestions are not a constraint. Load with the per-target verbs:docker load <owner/repo>(local container),desktop dbms load <owner/repo>(Neo4j Desktop),aura instance load <owner/repo>(new Aura instance). Loading defaults to the latest Neo4j;--databasetargets a database (defaultneo4j). Loads are writes, so pass--rwunder an agent. - Before generating ANY Cypher: run
neo4j-cli query :schema --format toonfirst to discover the real labels, relationship types, and properties. Do not guess the schema. Read query-additions.md for the full schema-first workflow, parameters, embeddings, and Cypher 25 vs 5. - The
aurasubcommand under neo4j-cli does NOT carry a nestedskillgroup — install agent skills vianeo4j-cli skill installat the top level. credentiallives at the top level of neo4j-cli (not nested underaura) so credentials apply across every subcommand that talks to Aura.- All read commands accept
--format json|table|toon. Write commands print confirmation text only; pipe-friendly output requires explicit--format jsonwhere supported. - Always pass
--format toonon read commands — toon uses ~40% fewer tokens than JSON while encoding the same data, so default to it for every list/get/show command. Only use--format jsonwhen piping into a JSON-aware tool that requires it; only use--format tablewhen the user explicitly asks for a human-readable table. - Async resource operations (instance create/resize/destroy) accept
--waitto block until the resource reaches a terminal state. - The
version:line in an installed SKILL.md reflects the binary (self-skill) or the cached catalogplugin.json.version(catalog skills). Runneo4j-cli skill checkto detect drift; re-runskill installto refresh. neo4j-cli skillinstalls either the embedded self-skill OR any skill from the curated catalog atgithub.com/neo4j-contrib/neo4j-skills(Cypher, modeling, drivers, GraphRAG, GDS, Aura, …). The self-skill is addressable asself(canonical) or by the binary nameneo4j-cli(alias) — both are reserved and shadowed catalog entries are rejected. The five leaves take an optional[skill-name]positional plus--agent <name>(case-insensitive) to scope to a single agent. Hard break: a positional that matches an agent name (e.g.claude-code) errors withunknown skill: <name>; did you mean '--agent <name>'?— no silent fall-through to the old positional-as-agent shape.install/removeaccept--all:install --allwrites the self-skill plus every catalog entry into every detected agent;remove --allremoves every catalog skill from every detected agent and never touches the self-skill (which is preserved).install,list, andcheckaccept--refreshto force a network fetch of the catalog before the operation; the newneo4j-cli skill refreshleaf does the same as a standalone command.- Catalog cache lives under
os.UserCacheDir()/neo4j-cli/skill-catalog/with a 24h TTL —list/install/checkauto-refresh when stale. Read commands (list,print,check) fall back to the cached copy on network failure with a stderr warning; cold cache plus a needed catalog install fails non-zero with a hint pointing atneo4j-cli skill refresh.printis strictly offline. - If you pass an HTTP-style URI (e.g.
http://host:7474) toqueryit is auto-rewritten toneo4j://host:7687(andhttps://toneo4j+s://host:7687); this command speaks the Bolt protocol. Useneo4j+ssc://for self-signed certs. - Write operations require
--rwwhen running under an agent harness. The CLI auto-detects known agents (Claude Code, Codex, Cursor, Gemini CLI, Replit, …) via environment variables, so agents always need--rwfor writes — interactive humans in a terminal do not.neo4j-cli query runadditionally runsEXPLAINover Bolt to detect write cypher when--rwis not set and blocks statements classified as writes before execution. - Do NOT preemptively add
--rw. Run write commands without it by default. If a command fails withthis command writes; pass --rw to allow it, surface the error and ask the user once to confirm the write, then re-run with--rw— do not add it on your own. neo4j-cli queryaccepts multiple statements in one string, split on a;at end of line (a mid-line;is kept verbatim; the terminating;is stripped). By default each runs in its own transaction, in order, failing fast on the first error;--atomicruns them all in one transaction that rolls back on any failure. When >1 statement runs,--format jsonemits a JSON array of result envelopes and--format table/toonprint stacked blocks; a single statement renders unchanged.- Use
--param NAME:embed=<text>onneo4j-cli queryto inject an embedding vector inline; the text is sent to the configured embedding provider and the resulting[]float32is bound to$NAMEfor both the EXPLAIN preflight and the real run. The siblingneo4j-cli query :embed [text]leaf computes a vector standalone (no Bolt connection opened). - Embedding config (
--embed-provider,--embed-model,--embed-base-url,--embed-dimensions) resolves with the same precedence as connection config: flag > OS env (NEO4J_EMBED_*) >.envwalk-up > stored embed credential. API keys layer per provider:OPENAI_API_KEY(openai),HF_TOKEN(huggingface),GEMINI_API_KEYthenGOOGLE_API_KEY(gemini) — all beatingNEO4J_EMBED_API_KEY(generic) and the stored credential'sapi-key. Ollama needs no API key. Vertex AI uses Application Default Credentials (gcloud auth application-default loginorGOOGLE_APPLICATION_CREDENTIALS), takes no--api-key, and requires--vertex-project+--vertex-location(stored on the credential — no per-query flag override). - Linking dbms→embed:
credential dbms add --embed-credential <name>orcredential dbms set-embed <dbms-name> [embed-name]attaches an embed cred to a dbms cred soquery --credential <dbms-name> --param NAME:embed=...picks up both connection and embed config in one selector. Removing an embed cred is non-cascading; stale links surface lazily at query time. - Updating the CLI: run
neo4j-cli updateto self-update the binary in place. Useneo4j-cli update checkto report whether a newer version is available without downloading (exits 1 when newer), and--pre-releasesto opt into alpha/beta/rc tags (default is stable-only). When the binary lives under a known package-manager prefix (Homebrew, npm-global, pipx, uv tool) the command refuses to overwrite and prints the channel-correct upgrade command; pass--forceto override. After a successful swap, any installed agent skill bundles are refreshed automatically — no manualskill installfollow-up needed. - Local Neo4j via Docker:
neo4j-cli docker(create/list/get/start/stop/delete) shells out to the hostdockerCLI. Docker itself is the source of truth — managed containers carry theorg.neo4j.cli.managed=truelabel plus a small set of metadata labels (edition, version, bolt-port, http-port, ephemeral); no separate state file is maintained.docker createdefaults to the enterprise image with the evaluation license (NEO4J_ACCEPT_LICENSE_AGREEMENT=eval); pass--accept-licensefor the commercial license, or--edition communityfor the community image. Host ports default to 7474 (HTTP) and 7687 (Bolt); override with--http-port/--bolt-port. When the requested pair is taken, both ports are auto-incremented by the same offset until a free pair is found. If--namecollides with an existing container or stored dbms credential, the chosen name is auto-suffixed (<name>-1,<name>-2, …) and the chosen name is logged to stderr. All--rw,--format json|table|toon, and--waitconventions from the aura tree apply equally here.
# Persistent flow: create stores a dbms credential, then query --credential connects with no further config
neo4j-cli docker create --name dev --wait --rw
neo4j-cli query --credential dev 'RETURN 1 AS n'
neo4j-cli docker delete dev --force --rw
The generated password appears in
docker create's rendered output; redirects and pipes capture it — pass--password <s>to pick your own,--no-print-passwordto keep the stored credential but omit the password from stdout (recover vianeo4j-cli credential dbms get <name>), or--no-store-credentialto suppress storage and rendering.Persistent volume mounts:
--data-dir <host>bind-mounts at/data(persist DB acrossdocker delete),--logs-dir <host>at/logs,--import-dir <host>at/import(forLOAD CSV). Paths support~and$VARexpansion; missing dirs are created at mode 0o755. All three are incompatible with--ephemeral. Neo4j adjusts ownership of the mounted dirs at container startup, so they appear under the container's neo4j UID on the host after first start.
# Persist data on the host so it survives delete + recreate
neo4j-cli docker create --name dev --data-dir ~/neo4j-dev/data --rw
neo4j-cli docker delete dev --force --rw
neo4j-cli docker create --name dev --data-dir ~/neo4j-dev/data --rw # reuses the same data
- Ephemeral runs:
neo4j-cli docker create --ephemeralshellsdocker run --rm, skips credential persistence, and emits a.envblob (NEO4J_URI/NEO4J_USERNAME/NEO4J_PASSWORD/NEO4J_DATABASE) to stdout. With--env-out-file <path>the blob is written to that path (mode 0600) and stdout stays silent so it can be piped intoneo4j-cli query --env <path>. The env-file write goes through a temp file in the same directory + atomic rename; a pre-existing symlink at the target path is replaced by a regular file (the symlink is not followed). Docker auto-removes the container when it stops — nothing to delete.
# Ephemeral flow: throwaway container + env-file consumed by query --env
neo4j-cli docker create --name tmp --ephemeral --env-out-file /tmp/n.env --wait --rw
neo4j-cli query --env /tmp/n.env 'RETURN 1 AS n'
neo4j-cli docker stop tmp --rw
- Aura Agents:
neo4j-cli aura agent(list/get/create/update/replace/delete/invoke) manages Aura Agents — LLM-backed assistants bound to an Aura database.--organization-id/--project-idhonour the default workspace, identical to every other aura command.invokeis dual-mode:--format jsonreturns the full server response verbatim (content blocks, usage, end_reason, errors), while the default table output joins the text content blocks and prints a single stats lineStatus: <S> | End reason: <ER> | Tool calls: <N> | Tokens: <req> req / <res> res / <total> total. HTTP 403 oninvokesurfaces asagent invocation forbidden: agent may be disabled or private; an HTTP 200 body withtype: "error"surfaces asagent invocation failed: <message>.
# List, create, and invoke an agent (workspace default already set)
neo4j-cli aura agent list --format toon
neo4j-cli aura agent create --name docs-bot --description "Docs assistant" --dbid <dbid> --tools '[{"type":"text2cypher","name":"ask","description":"Answer questions about the graph"}]' --rw
neo4j-cli aura agent invoke <agent-id> --input "hello" --rw
--toolsis a JSON array of tool objects. Every tool shares the envelope{type, name, description, config}(plus optionalenabled) —name≤64 chars,description≤2000 chars. Thetypediscriminator is camelCase (NOT snake_case):text2cypher,cypherTemplate,similaritySearch. Theconfigobject is type-specific; the four canonical shapes are:
[{"type":"text2cypher","name":"ask-graph","description":"Convert natural-language questions into Cypher and run them against the database."}]
[{"type":"cypherTemplate","name":"top-customers","description":"Return the top N customers by total order value.","config":{"template":"MATCH (c:Customer)-[:PLACED]->(o:Order) RETURN c.name AS name, sum(o.total) AS spent ORDER BY spent DESC LIMIT $limit","parameters":[{"name":"limit","data_type":"integer","description":"Maximum number of customers to return."}]}}]
[{"type":"similaritySearch","name":"doc-search","description":"Find docs most similar to the user question.","config":{"provider":"openai","model":"text-embedding-3-small","index":"docs_embedding_index","top_k":5}}]
[{"type":"similaritySearch","name":"doc-search-enriched","description":"Vector-search docs, then enrich each hit with its parent page.","config":{"provider":"openai","model":"text-embedding-3-small","index":"docs_embedding_index","top_k":5,"post_processing_cypher":"MATCH (node)<-[:HAS_CHUNK]-(page:Page) RETURN page.title AS title, page.url AS url, node.text AS chunk, score ORDER BY score DESC"}}]
Tool-config field reference (v2beta1):
text2cypher— noconfigfields required.cypherTemplate.config— requiredtemplate(Cypher string); optionalparameters[]of{name, data_type, description}withdata_type ∈ {string, number, boolean, integer}.similaritySearch.config— requiredprovider(openai|vertexai),model(provider-compatible embedding model),index(vector-index name, ≤100 chars),top_k(1–100); optionaldimensions(integer, when the provider/index needs an explicit size); optionalpost_processing_cypher— read-only Cypher appended to the vector search and run as a single query, withnodeandscoreexposed to the post-processing block (write queries are rejected server-side).