CLI guide
The whole product is meant to be two commands - init and dev - and everything else serves them.
The authoritative, machine-generated full reference (every subcommand and flag, rendered from clap’s
own metadata and drift-gated in CI) ships in the repo as
skills/nuthatch-builder/cli-reference.md.
If a flag isn’t there, it doesn’t exist. This page is the guided tour: use it to understand the
workflow, then use the generated reference when you need the exact spelling of an option.
Almost every command that operates on a nest takes --dir (default .). The exception is
nest bundle, which takes the directory as a positional argument: nuthatch nest bundle <dir>.
The two commands
nuthatch init <address>…- scaffold a nest from one or more contract addresses: resolve each ABI (Sourcify → Blockscout → Etherscan), detect the deployment block, and write the project. Omit--chain- init probes the known chains for the contract’s bytecode and picks the one it lives on.--aliasnames the contracts (default: the contract name from the ABI, elsec0, c1, …);--rpcuses your own endpoints; paired with a--chainname nuthatch does not ship, it scaffolds any other EVM chain, reading the chain id from the endpoint.--abisupplies a local ABI (the escape hatch for a proxy),--explorernames a Blockscout instance to resolve from,--start-blockskips the deploy-block probe, and--no-timestampsdropsblock_timestampfor good.--from <git-url|dir>initialises from a published nest instead of addresses (nothing is resolved - ABIs are vendored, so it’s cloned, copied, and validated);--from-subgraph <cid|url>scaffolds from a subgraph manifest.initrefuses a directory that already holds a nest (grow it withadd, or pass a new--dir), and refuses a flag its mode would ignore, such as--chainwith--from.nuthatch dev- run it: backfill, follow the tip, serve the API.--listen(default127.0.0.1:8288),--rpcruntime overrides,--backfill N(recent-history mode),--seal-direct(backfill finalized history straight to Parquet, bypassing the hot store),--concurrency(concurrent window fetches; 8-16 against your own node),--window(override thegetLogsblock-window - large for sparse contracts),--no-admin. Also--rpc-fallback(endpoints asked only while every other one is failing),--poll-interval(default: the chain’s block time, never under 2 s),--finality-only(never index the unfinalised tip),--cors, and--state-rpc(archive endpoints for declared[[calls]]).
Everyday companions
nuthatch add <address>…- grow an existing nest with another contract; no re-init.nuthatch sql [query]- query the live tip ∪ sealed history; prints a table. No query opens a REPL (.tables,.schema <t>, history).--jsonemits NDJSON for piping tojq.nuthatch schema- regenerate the derived artifacts (schema.json,llms.txt, thesemantic.tomlfootguns) after hand-editingnuthatch.toml.nuthatch mcp- serve MCP over stdio, bridging to a runningdev(--url).--print-configprints a copy-paste client config instead. See MCP.nuthatch check [name]- run the nest’s invariant/parity checks (checks/*.sql) against recorded expected results;--updaterecords current results as the fixtures.nuthatch doctor- probe an RPC endpoint before trusting a backfill to it: widesteth_getLogsrange, batch limit, archive depth, and the largest safe--window.--cataloguechecks the sealed segment catalogue instead.nuthatch serve- serve a nest without indexing it;--hot-storereads a Postgres hot store in a scaled-mode build.
entities.toml needs no special command: dev loads and maintains it. A nest declaring an entity
must use the normal ingest path; dev --seal-direct is refused because direct sealing bypasses the
entity circuit.
Derive-first reads (RFC-0023)
nuthatch recipe list/recipe add <name>- add a derived view that computes a read (e.g.total_supply) from indexed events instead of aneth_call. No archive node, deterministic, free.nuthatch metadata fetch- fetch and cache a token’s immutabledecimals/symbol/nameonce; remembered inmetadata.json.
Packaging & lifecycle (RFC-0012, 0019, 0020)
-
nuthatch nest bundle- package a nest’s authored inputs into one portable, content-addressed.bundle; prints the content address.--as-dirwrites an inspectable directory instead. -
nuthatch nest load <bundle|url|dir>- verify a bundle (manifest format, every file’s hash, and that the regenerated decode registry matches) and install it as a runnable nest.--expectasserts the hash;--registryresolves aname[@version]reference instead, or a NID, whose bundle must compute to that NID. -
nuthatch nest publish <bundle> --registry <store>- publish undername@version, advancinglatest, and index it by NID; prints the hash and the NID. -
nuthatch nest rename-alias <old> <new>- re-key a contract alias innuthatch.toml, the ABI file andsemantic.toml. -
nuthatch seed --from <mirror>- fill a nest that has not indexed from a published mirror (a path,s3://bucket/prefixor a publichttps://address) instead of backfilling over RPC. -
nuthatch nest nid --dir <nest>- print the NID the nest’s data is stored under (data/<nid>/), without running it. -
nuthatch publish sync|status|verify|finalise --target <prefix>- mirror sealed segments to a directory ors3://bucket/prefix;dev --publish-targetdoes it as they seal, andfinalisemarks each table’s provisional tail final so a seed can trust it. -
nuthatch migrate --dir <dir>- move a pre-2.0 directory to identity-keyed datasets, and apply a staged nest upgrade. Classifies the change and refuses a breaking one by name (--allow-breakingto accept). Moves data and never re-indexes;--dry-runprints the plan. -
nuthatch prune --dir <dir>- reclaim datasets and shared segments nothing mounts any more. Lists by default;--yesdeletes, and refuses while a runtime holds the directory (runtime.lock). -
nuthatch dev- run many nests behind one listener;--fail-fastexits on the first fault instead of quarantining it (RFC-0026);--registry <store>lets a live mount fetch a NID the runtime does not hold.--ipfsand--state-rpcreach every nest it runs;--state-rpcis refused when the runtime declares more than one chain. See Run a runtime and Host nests for others.
Offchain data (RFC-0045)
nuthatch offchain drop <file> --table <name>- seal a local CSV, JSON array or Parquet file as an immutable snapshot underoffchain__<name>.nuthatch offchain pull <url> --table <name> --format json- fetch a JSON-array feed once and seal it the same way; schedule it on the host. An authored entity can readoffchain__<name>.
Scaled mode (RFC-0022)
nuthatch control/nuthatch worker- the control plane and a writer worker. Both need the scaled build (--features postgres-store, or the-scaledrelease artifacts). See Scaled mode.
The compliance pack (RFC-0008)
nuthatch labels import|list- labeled address sets as content-addressed snapshots.nuthatch lists fetch|list- sanctions/watch lists as pinned address snapshots (ofac-sdn,eu-consolidatedhave default URLs; any other name takes--urlor--file).nuthatch pack keygen|build|verify- the signed compliance-pack manifest (ed25519).keygenwrites its secret owner-only, by default under~/.nuthatch;verifyneeds--pubkey, the signer’s public key as 64 hex characters or a file holding them.nuthatch audit report- summarise the threshold flags over a range (--json).nuthatch audit sealed --rpc <url>- re-fetch a sample of sealed ranges from a second endpoint and compare them row by row;dev --audit-rpcdoes the same in the background.
Measurement
nuthatch bench backfill --from N --to N- events/sec, wall-clock, peak RSS over a pinned range (--runs 3; the report is the median).--seal-directmeasures the direct-to-Parquet path. A nest declaring[[calls]]also needs--state-rpc; both benchmark arms resolve the calls, and the command refuses to under-measure them when the endpoint is absent. State RPC URLs are redacted in output because they often contain credentials.nuthatch bench query- the read path: entity point-read p50/p99 and the/sqlhot∪cold scan cost. Run offline against an already-indexed nest (stopdevfirst).
Checked against Nuthatch 5.8.2. Verify a release-specific command with the CLI reference before running it in production.