Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

The fluree-cli plugin in fluree/claude-plugins registers the docs MCP server (--toolsets docs — no memory toolset; run fluree mcp init yourself if you want that too) and adds skills for driving the CLI, which defer to this page rather than restating it. The same marketplace carries fluree-companion for stack-first workflows — connecting to a Fluree AI stack, authenticating against it, and working through the stack’s own surfaces.

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 --help first. fluree docs search "<topic>" / fluree <cmd> --help are authoritative for the running binary.
  • A missing command usually means a feature-gated build, not a typo. validate (SHACL) and cluster (server) vanish entirely from --help in builds without their features. The hidden fluree manifest command emits a machine-readable JSON of the full surface, including a features array that distinguishes “not compiled in” from “does not exist”.
  • Check the version when a server is involved. fluree --version; a stack that advertises cli.min_version in its /.well-known/fluree.json triggers a warning at fluree remote add when your binary is older than what its docs teach (governance fluree model commands exist only in 4.1.3+).

Machine-readable output

Support is per-command, not global:

  • query and multi-query take --format json (plus CSV/TSV/NDJSON variants); query --format ndjson --envelope adds a self-describing head/rows/end wrapper (--envelope pairs with ndjson only).
  • graph list, branch diff, branch revert --preview, and the four docs subcommands take boolean --json.
  • list, info, and show are human-formatted only (as of 4.1.x).
  • Errors are human text; the only machine signal is the exit code (0 ok, 1 error, 2 usage). 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 with fluree remote add <name> <url>; the compound positional name/ledger form is equivalent on data commands.
  • Passing the stack’s API base (https://<stack>/v1/fluree) as <url> is robust: discovery of /.well-known/fluree.json ignores the input path, and if discovery is unreachable an input already ending in /fluree is stored as-is.
  • fluree auth login needs the human. It prints a device code and opens the stack’s /activate page — the user approves it in their browser while the CLI polls. Run the command, then tell the user to approve; continue only after fluree auth status shows a configured token. There are no environment-variable credentials.
  • Scripting a token: fluree auth token prints exactly the access token (for .env files, curl). fluree config list masks credentials as [redacted]; --reveal prints 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 runs fluree init.
  • The stack documents itself, separately from this corpus. A Fluree AI stack serves an unauthenticated markdown index at https://<stack>/api/docs, with each page at /api/docs/{category}/{slug}. Those pages describe the stack — its UI, its HTTP surface, its provisioning; this corpus describes the binary. A task that spans both needs both.

Destructive operations — confirm with the user first

  • fluree drop --force is a hard delete (storage removed, not recoverable), and fluree branch drop has no confirmation flag at all — on a leaf branch it permanently deletes storage and cascades into retracted ancestors. main has 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 --explain to inspect a plan without executing.
  • --at time travel on server-routed queries injects a FROM clause by scanning for the literal where substring — keep WHERE on the same line as SELECT, and never combine --at with an explicit FROM.
  • Auto-routing silently targets a detected local server (a stderr notice is the only sign); --direct forces local execution when behavior differs.