Claude Code and the Fluree CLI
How an AI coding agent — Claude Code in particular, but the pattern generalizes — should drive the fluree CLI. This page ships inside the binary (fluree docs get ai/claude-code), so what it says is true for the exact version you are running; agent-side packaging (the fluree-cli Claude Code plugin, a stack's generated build prompt) deliberately defers to it rather than copying it.
Setup
Register the CLI's MCP server with your agent:
fluree mcp init --ide claude-code # or cursor / vscode / windsurf / zed
This wires fluree mcp serve with the docs toolset (ranked search over this documentation, version-exact) and the memory toolset (persistent project memory). Use --toolsets docs to skip memory. Without MCP, the same corpus is available as plain commands: fluree docs search, fluree docs get, fluree docs examples, fluree docs tree.
Probe, don't assume
The CLI's surface varies by version and by compiled features — and an agent's trained knowledge of it is always stale. Before composing a nontrivial invocation:
- Check the docs or
--helpfirst.fluree docs search "<topic>"/fluree <cmd> --helpare authoritative for the running binary. - A missing command usually means a feature-gated build, not a typo.
validate(SHACL) andcluster(server) vanish entirely from--helpin builds without their features. The hiddenfluree manifestcommand emits a machine-readable JSON of the full surface, including afeaturesarray that distinguishes "not compiled in" from "does not exist". - Check the version when a server is involved.
fluree --version; a stack that advertisescli.min_versionin its/.well-known/fluree.jsontriggers a warning atfluree remote addwhen your binary is older than what its docs teach (governancefluree modelcommands exist only in 4.1.3+).
Machine-readable output
Support is per-command, not global:
queryandmulti-querytake--format json(plus CSV/TSV/NDJSON variants);query --format ndjson --envelopeadds a self-describing head/rows/end wrapper (--envelopepairs with ndjson only).graph list,branch diff,branch revert --preview, and the fourdocssubcommands take boolean--json.list,info, andshoware human-formatted only (as of 4.1.x).- Errors are human text; the only machine signal is the exit code (
0ok,1error,2usage). Parse stderr only as a last resort.
Working against a remote (Fluree Solo / Fluree AI stacks)
--remote <name>takes a configured alias, never a URL. Set one up withfluree remote add <name> <url>; the compound positionalname/ledgerform is equivalent on data commands.- Passing the stack's API base (
https://<stack>/v1/fluree) as<url>is robust: discovery of/.well-known/fluree.jsonignores the input path, and if discovery is unreachable an input already ending in/flureeis stored as-is. fluree auth loginneeds the human. It prints a device code and opens the stack's/activatepage — the user approves it in their browser while the CLI polls. Run the command, then tell the user to approve; continue only afterfluree auth statusshows a configured token. There are no environment-variable credentials.- Scripting a token:
fluree auth tokenprints exactly the access token (for.envfiles,curl).fluree config listmasks credentials as[redacted];--revealprints them raw and its output must never be pasted into logs, commits, or chat. .fluree/contains the remote config including live access and refresh tokens — it must be gitignored in any project where an agent runsfluree init.
Destructive operations — confirm with the user first
fluree drop --forceis a hard delete (storage removed, not recoverable), andfluree branch drophas no confirmation flag at all — on a leaf branch it permanently deletes storage and cascades into retracted ancestors.mainhas no special protection. Name the exact target and get explicit user confirmation before running either.- Never drop and recreate a ledger underneath a running server — the server keeps stale index pointers and fails partially (some queries work, others 404 on leaf files). Stop the server first.
Resource limits on shared machines
--memory-budget-mb 0 (the default) auto-sizes to 80% of system RAM and assumes it owns the box; a large create --from import on a machine also running an IDE, Docker, or a browser can OOM the machine. On anything but a dedicated host, pass an explicit budget and modest --parallelism (2–4). Note FLUREE_IMPORT_THREADS silently overrides --parallelism.
Policy work
Author policy as a single where (object, or array of patterns correlated by shared variables) that constrains ?$this; unknown keys in f:query are silently ignored, and a policy whose where never touches ?$this matches everything — silently allowing what it was meant to restrict. Verify with --track-policy on direct/local execution (its allowed/evaluated counts expose an uncorrelated policy immediately); server-routed --track-policy is unreliable. See the policy cookbook.
Query hygiene for agents
- Prefer
--explainto inspect a plan without executing. --attime travel on server-routed queries injects aFROMclause by scanning for the literalwheresubstring — keepWHEREon the same line asSELECT, and never combine--atwith an explicitFROM.- Auto-routing silently targets a detected local server (a stderr notice is the only sign);
--directforces local execution when behavior differs.