Generated from
AGENTS.mdOn this page14
nf-claw agent guide
This repository is a library of nf-core pipelines. Each one lives in pipelines/<name>/:
upstream/ holds the pinned pipeline code (a git submodule) and skill.md says how to run it.
This guide is what an agent needs to find, run, follow, replay and chain a pipeline. The guarantees behind each step, and their limits, are in the guides it links to: inputs and preflight, replay and verification, chaining, timeouts, MCP and known issues.
Setup (first time)
Install once, from the repository root, so the nfclaw command is on PATH:
pip install -e .Use Python 3.11+ and a virtualenv on a path without spaces (on macOS, not in iCloud). For the
maintenance tests, install pip install -e ".[dev,yaml]", which adds pytest and YAML support.
Without installing: run python3 -m runner <cmd> from the repository root wherever this guide
shows nfclaw <cmd>.
To run a pipeline
- Find it:
nfclaw list <keywords>ranks the pipelines that match a request. Or grepcatalog.json(orcatalog.md) for a keyword; do NOT read it whole. - Read
pipelines/<name>/skill.md: the exact command, inputs and required parameters of the pinned release. - Run:
The direct upstream command isbashnfclaw run <name> --input samplesheet.csv --outdir results -profile docker
nextflow run pipelines/<name>/upstream -profile docker ..., with no-rbecause the submodule is already pinned to the release. It skips nfclaw's preflight, provenance and runtime corrections, so use nfclaw for releases that need those corrections. - Check status, in the foreground or the background:
It printsbashnfclaw status results # add --json for one machine-readable object
success,running, or how the run ended, with the error. Exit codes:0success,3running,1failed. For the logs, see where a run is logged.
[!NOTE]
nfclaw runruns the pipeline for real: there is no preview/dry-run default. To see the exactnextflowcommand without launching it, add--check. It validates inputs and parameters, prints the command (preceded by theNXF_*variables that--nxf-verand--nxf-envset, e.g.NXF_VER=25.10.4 nextflow run …) and exits. It writes nothing into--outdir, so you can use that directory for the real run. Add--demoto run the release's bundled test profile end to end. A run has no overall time limit unless you pass--timeout SECONDS.
- Options: Docker is the default profile;
-profile(or--profile) takes comma-separated profiles.--params-file PATHloads JSON (or YAML, with theyamlextra), and values given on the command line override the file. Pipeline flags accept hyphens or underscores (raw Nextflow needs the exact spelling from the schema).--no-provenanceskips the replay bundle and checksum records but keeps the parameter file and the run logs; without those records a later--resumecannot reuse cached tasks and recomputes them all (why). - What
--checkcovers: inputs, parameters and the environment (Git, Nextflow, Java, the profile's container engine and, for Docker, a daemon that answers), and whether the run's engine can parse the release's configuration (nextflow config). A release that Nextflow 26.04+'s strict parser rejects is refused, with the fix.--checkmay initialise submodules, fetch a requested version and download a pinned engine. Itspreflightlines say which checks ran, which are left to launch and which are not supported; conditional and complex schema constraints are left to the release's own validation (scope). - References: pass the references the chosen analysis needs, even when the schema does not mark them required. Each skill's reference section lists the options.
- Output directory: outside the repository or ignored by Git (
results/is ignored), and a new one per run. A second run into an--outdirthat is in use fails at once (a lock file sits beside it). Keep data, pipeline code and configuration outside the output directory: nfclaw refuses any overlap between what a run reads and where it writes, before writing anything.
Inputs
- Paths inside a samplesheet must be absolute. Nextflow resolves them against its launch
directory, which
nfclaw runsets to--outdir, so a relative path would not mean what it says, andnfclaw runrejects it.--inputitself may be relative (nfclaw makes it absolute). It is not always a samplesheet; the schema decides. It can be a directory or tarball (rangeland), an SDRF file or PRIDE accession (mhcquant), or--input falsewhere a pipeline documents running without one (sarek). TheInputssection ofskill.mdsays which. - No samplesheet yet? Pass the data files. Where
--inputis a samplesheet, it may instead name a directory (searched recursively), a quoted glob, or files (--inputonce per file), andnfclaw runwrites the sheet first:nfclaw run rnaseq --input /data/fastq --sheet-set strandedness=auto --outdir results. Sample names are the file names, never changed. FastQ mates pair by_R1/_R2, or by_1/_2only when their first read names show they are mates; lanes fill alanecolumn. Values that no file determines come from--sheet-set COLUMN=VALUEor from the schema's defaults; theInputssection ofskill.mdlists them.--sheet-setcan be repeated and takes a constant or a{sample}/{lane}template; an empty value leaves a column empty, which is also how to choose between groups of read columns. Missing values, ambiguous matches, unpaired mates and duplicates are refused. Files that match nothing are ignored with an advisory, so read the warnings. Add--checkto see the sheet first. It is staged as<outdir>/provenance/samplesheet.csvand replayed as recorded. In a chain, a stage takes the sameinputplus a"sheet_set"object. The rules and the list of supported pipelines: generation boundaries. - Safe file names and sample IDs. Task scripts put staged file names and sample identifiers into
shell commands. nfclaw therefore refuses input file names with whitespace, shell operators,
wildcards or a leading
-or~. It also refuses sample, patient and genome identifiers that do not start with a letter, digit or underscore, or that contain anything other than letters, digits, combining marks,.,_and-. Use a safely named copy or a safe alias; nfclaw never renames a sample. The full rules: inputs refused before launch. - Recorded runtime corrections. A few exact releases (fastqrepair 1.1.1, Bactmap, Createtaxdb and Funcscan) run with recorded corrections that leave the pinned source untouched. The run says so and records them (source corrections).
Where a run is logged and how to check it
Every nfclaw run logs itself to a fixed place, so there is no need to redirect its output. To find
out how a run stands, ask nfclaw:
nfclaw status <outdir>nfclaw status <outdir> --json # state, outcome, times, pids, logs, caveats, provenance gaps, error, last outputIt prints status: success, running (…), or the outcome the run ended with (failed (exit status N),
timed out after N s, interrupted, terminated by SIGTERM, refused before launch). If nfclaw
itself was killed with SIGKILL, ran out of memory, filled the disk or the machine restarted, it
prints stopped without an outcome; --resume then continues from the finished tasks. After the
status come the log's location and the recorded error or the run's last output. A log that exists
but cannot be read is unknown. Exit codes: 0 success, 3 running, 1 anything else. It also works
for replays and chains.
Success is not completeness. A pipeline can exit 0 without some of its samples or tasks. When
its completion summary says so (nf-core's "…, but with errored process(es)", rnaseq's skipped
samples and failed strandedness checks), when Nextflow ignored failed tasks, or when a profile or
--config runs every task as a stub (stubRun = true, as proteinfold's test profile does, so its
--demo computes nothing), nfclaw status reports
status: success — with caveats the pipeline reported about its results and quotes them.
nfclaw run prints them as warnings and records them in provenance/run_manifest.json
(completion_caveats). Read them before using the results.
A successful run may also have gaps in what it recorded for replay: an image without a digest, a task
with no container, no task records. The results are unaffected, but a replay can check less.
nfclaw status lists these under provenance gaps (provenance_gaps with --json), and
nfclaw chain status beside each stage.
<outdir>/provenance/logs/run.log: the whole launch in order. nfclaw's header (command, launch directory, Nextflow log path, host and pids, advisories), everything Nextflow printed (each line prefixed with|), gaps in the recorded environment (provenance: …) and, on failure, nfclaw's error. Its last line, written once nfclaw is done, is==> nfclaw run finished <time>: <outcome>.--resumeappends to it, so a failed attempt is never overwritten. No run log means nfclaw never launched there: run the command in the foreground to see why.<outdir>/.nextflow.log: Nextflow's own detailed log. Nextflow runs from--outdir, so its hint "Check '.nextflow.log'" means this file, not one in your working directory.stdout.txtandstderr.txtbesiderun.log: Nextflow's two raw streams. Engines up to 26.04 print error reports on stdout; from 26.10 the console log goes to stderr (migration notes). Look at both when diagnosing a failure.
Jobs started through MCP can also be managed from a shell on the same host, as the same user and
with the same NFCLAW_STATE_DIR: nfclaw jobs list, nfclaw jobs status <job-id> and
nfclaw jobs cancel <job-id>. Add --json for a versioned object. Job status exits 0 for success,
3 while running, and 1 for failed, cancelled, lost or unknown jobs. Cancelling returns without
waiting; check the status to confirm the job stopped.
Commands and JSON fields.
To run in the background, start nohup nfclaw run ... &, and stop it with kill <nfclaw pid> (the
pid: line of the run log). nfclaw then shuts Nextflow and its tasks down, removes the task
containers they left behind, writes the bundle and closes the log, as on Ctrl-C. On Linux, if
nfclaw is killed outright (SIGKILL), its Nextflow receives SIGTERM; scheduler jobs and other
detached work still depend on the executor's own cleanup.
When a run fails, nfclaw's error quotes what Nextflow reported, adds the Caused by: chain from
.nextflow.log when the console hides the reason, and gives the absolute paths of the run log,
.nextflow.log and the failing task's .command.err. Fix the cause and run the same command again
with --resume. docs/known-issues.md maps symptoms to fixes.
Replaying and verifying a run
<outdir>/provenance/commands.sh re-runs the recorded command into a fresh directory
(<outdir>.replay by default, or ./commands.sh /path/to/fresh-dir). It refuses a target that
already holds files, because an nf-core pipeline cannot publish over a previous run's files. A
replay runs the pipeline again; it is a reproduction, not a --resume. Before it starts, its guard
checks that the recorded pipeline source, local input bytes (samplesheet data paths included),
parameters and configs are unchanged, and refuses rather than produce results that silently differ.
It logs to <target>/provenance/logs/run.log (nfclaw status <target> reads it;
kill <replay pid> stops it). After Nextflow succeeds, it compares its execution environment
(image digests, plugins, container engine, remote inputs) with the recording. Keep the original
bundle.
nfclaw verify results.replay --against results # structure; pairs launch-stamped filesnfclaw verify results.replay --against results --strict # also identical bytes, and environment if both recorded onenfclaw verify results.replay --against results --require-environment # complete environment evidencenfclaw assess results.replay --contract runner/output_contracts/tumourevo-1.0.0-demo.jsonverify compares files and directories by path and reports them as identical, changed,
missing or extra. Changed bytes may be metadata or a different result, so inspect them with tools
that understand the format. assess checks sample coverage and the parsed scientific content against
an explicit output contract; two contracts for exact demo pins
are supplied. What the bundle holds, what the guard checks, how --resume treats changed local
inputs, and what each verification mode can and cannot show: replay and verification.
Trust skill.md and reference.md over your own memory: they are generated from the pinned commit.
To set a parameter beyond the essentials, look it up in pipelines/<name>/reference.md, which lists
every parameter with its allowed values and constraints. Do not invent a flag or a value.
nfclaw run rejects unknown flags, values outside the allowed set and clear type or shape errors
before it starts; nf-schema stays authoritative for the complete schema at run time. Numbers reach
Nextflow with their exact decimal value. Read upstream/ only for deep dives.
To chain pipelines (A, then B, then C)
A chain runs several pipelines in sequence. Each stage starts only after the previous one
succeeded, and its inputs are prepared from that stage's outputs (for fetchngs → rnaseq,
fetchngs's samplesheet becomes rnaseq's --input). Write a spec in JSON and run it:
{
"nxf_env": {"NXF_JVM_ARGS": "-Djava.net.preferIPv6Addresses=true"},
"stages": [
{"pipeline": "fetchngs", "input": "/abs/ids.csv", "retries": 2},
{"pipeline": "rnaseq", "params": {"genome": "GRCh38"}}
]
}Check it first:
nfclaw chain run spec.json --outdir /abs/chain --checkThis validates every stage and handoff and checks that each stage's config parses with its engine,
leaving --outdir untouched. Then run the same command without --check.
- Which pipeline can follow which:
nfclaw chain edges [name], or the## Chainingsection of askill.md. Without a rule there is no chain, unless you give the stage an inline"handoff". - Stage parameters: a stage's
paramsare its own flags (look them up in itsreference.md). An explicit stageinputorparamsvalue overrides the value a handoff would supply.demo: trueadds that release'stestprofile. - Run options:
profile,nxf_ver,nxf_env,configandlimitscan be set on the chain or on a stage, since releases of different ages can need different engines. A stage'snxf_envis merged over the chain's; itsconfigandlimitsreplace the chain's.--timeout SECONDSsets one deadline for the whole chain. - Logs and state: each stage is an ordinary run in
<outdir>/NN-<stage>/. The chain logs to<outdir>/chain/logs/chain.log, whose last line is==> nfclaw chain finished <time>: <outcome>;kill <pid>stops it cleanly. - Resuming:
nfclaw chain run [spec.json] --outdir /abs/chain --resumeskips the stages that succeeded and resumes the failed one (which you may change in the spec) with Nextflow's cache."retries": Nrelaunches a stage after a pipeline failure, never after a validation error. - Lineage:
nfclaw chain status <outdir>(add--jsonfor one object) checks by SHA-256 which run's outputs became which run's inputs. It exits 0 when the chain succeeded, 3 while it runs and 1 otherwise;--quickskips the hashing. Handoff checks, sample isolation, secrets innxf_envand failure handling:docs/chaining.md.
Using nf-claw through MCP
nfclaw mcp serves this library to MCP clients (Claude Code, Codex, Antigravity, Hermes and others)
on stdio; docs/mcp.md explains the setup for each client. Each tool runs the
nfclaw command it names, so everything in this guide applies unchanged:
- Find and read:
list_pipelines(query), thenshow_pipeline(pipeline)for itsskill.md, orshow_pipeline(pipeline, document="reference", grep="…")for any other parameter.read_doc(guide="known-issues", search="…")returns only the sections about an error or warning. - Run:
run_pipeline(pipeline, outdir, input, params={…}, check=true)validates and prints the command; withoutcheckit starts a detached job and returns itsjob_id. Pipeline parameters go inparamsunder their schema names; nfclaw's own options (profile,resume,nxf_env,limit_cpus, …) are separate arguments. - Follow:
get_job(job_id, wait_seconds=N)reportsrunning(preparingorlaunched),succeeded,failed,cancelledorlost, withnfclaw status's report and the latest output. A job outlives the client and the server: any later session can read it back (list_jobs).run_status(outdir)reports on any run directory, with the parsednfclaw status --jsonrecord. - Chain:
run_chain(spec, outdir)runsnfclaw chain runon a spec given as JSON;run_status(outdir, chain=true)checks the lineage. - Stop:
cancel_job(job_id)stops a job askill <nfclaw pid>does; continue later withresume=true.
Use absolute paths and a new outdir per run, as on the command line.
To run a specific (non-latest) version
By default a run uses the release pinned in this repository. Updates are checked before they are adopted, so a newer upstream release may not be pinned yet. To run another published release:
- List releases:
nfclaw versions <name>(the pinned release is marked). - Read that version's docs:
nfclaw show <name> --pipeline-version X.Y.Zfetches the tag, checks it out underpipelines/<name>/.versions/X.Y.Z/(ignored by Git) and prints theskill.mdgenerated from that release's schema, with areference.mdbeside it. Parameters, flags and validation all come from X.Y.Z. - Run it:
bashnfclaw run <name> --pipeline-version X.Y.Z --input samplesheet.csv --outdir results -profile docker
Only real release tags are accepted: X.Y.Z, or X.Y for older nf-core releases such as fetchngs
1.9, with or without a leading v, plus dev (below). An unknown version fails at once and lists
the available ones. Provenance records the exact version that ran.
Unreleased development code (dev)
--pipeline-version dev runs the dev branch (like nextflow run nf-core/<name> -r dev), which holds
changes not yet in any release:
nfclaw run fetchngs --pipeline-version dev --input ids.csv --outdir /path/to/out -profile dockerdev moves, so each run resolves it to the branch's current commit, checks that commit out under
pipelines/<name>/.versions/dev-<commit12>/, prints a warning naming it, and records it for replay.
Read its docs first (nfclaw show <name> --pipeline-version dev), because its parameters can differ
from the release. nfclaw versions <name> lists dev with its current commit. Offline, nfclaw uses
the last dev commit it fetched and says so, and --resume warns when dev has moved since the
run it continues. Prefer a release for results you need to reproduce from a version number.
Choosing the Nextflow engine and environment
nfclaw run passes your shell environment on to Nextflow. Two flags make the engine and its
environment explicit and reproducible; both are recorded in <outdir>/provenance/:
--nxf-ver X.Y.Zpins the Nextflow version for this run (it setsNXF_VER). Use it when a newer Nextflow breaks an older release, or to reproduce an earlier run exactly. Nextflow refuses an engine older than the release's declarednextflowVersion(seeskill.md); nfclaw's error then names the--nxf-verto pass, and--checkwarns about it instead.--nxf-env KEY=VALUEsets anNXF_*variable for this run (repeatable). Common uses:- on an IPv6-only host where the JVM cannot reach GitHub for remote configs:
--nxf-env NXF_JVM_ARGS=-Djava.net.preferIPv6Addresses=true - to skip remote config fetches entirely:
--nxf-env NXF_OFFLINE=true
- on an IPv6-only host where the JVM cannot reach GitHub for remote configs:
--config PATH(or-c, repeatable) passes an extra Nextflow config through as-c, for example a Docker host-network config (docker { runOptions = "--network host" }) or custom resources.
Each run launches Nextflow from its --outdir, so its .nextflow/ history belongs to that run and
--resume resumes it (use a separate --outdir per pipeline). Task work files go to the shared
<repo>/work/ directory by default; set --nxf-env NXF_WORK=/path/to/work to choose another, and
keep the work files that --resume and result symlinks need.
Running on a machine smaller than the pipeline assumes
nf-core usually sizes processes with labels from the pipeline's conf/base.config, which assume a
server. One step can request far more memory than a workstation has
(Process requirement exceeds available memory), and retry rules can raise requests further. Many
bundled test profiles set small ceilings, but real runs often need one. Set it with:
nfclaw run <name> ... --limit-cpus 4 --limit-memory 15.GB--limit-time DURATION also caps how long any one task may run. A task that needs longer is stopped,
and so is every retry, so set it only as a deliberate ceiling, never as a guess at how long the
analysis takes.
These become Nextflow's process.resourceLimits, applied to every process and every retry. They are
written to <outdir>/provenance/resource_limits.config and replayed by commands.sh.
resourceLimits needs Nextflow 24.04.0 or newer: older engines accept it but apply no ceiling. So
nfclaw run refuses --limit-* when the run would use an older engine or the engine version cannot
be identified; pin a newer engine with --nxf-ver, or use the release's own --max-* parameters
where it has them. Do not work around this with withName: overrides, which size only the processes
they name.
If a pipeline's upstream/ is empty, initialise it first:
git submodule update --init pipelines/<name>/upstreamnfclaw run refuses a pinned upstream/ that is not at the commit its skill.md documents (for
example after a git pull without a submodule update) or that has local edits to tracked files.
Restore it with git submodule update --force pipelines/<name>/upstream, or pass --pipeline-version
to run another release on purpose.
Requirements
- Linux or macOS (on Windows, run nfclaw inside WSL 2)
- Git
- Python 3.11+ (install nfclaw with
pip install -e .) - Nextflow (Java 17+)
- Docker or Singularity/Apptainer
[!IMPORTANT] Use paths without spaces. Many bioinformatics tools and Nextflow's work directory mishandle spaces in paths; on macOS, also avoid iCloud folders.
nfclaw runchecks the repository path, the work directory and--outdirbefore launch and fails with the offending path (--allow-spacesoverrides this).
Reference genomes
Some releases fetch a reference remotely by default. sarek, for example, defaults --genome to
GATK.GRCh38, which it looks up in AWS iGenomes at s3://ngi-igenomes/igenomes/, so a run that
passes no reference of its own reads from S3 and fails on a host without access to that bucket. Each
skill.md says which case its pipeline is in, under "Reference genome". Pass your own reference
(--fasta, …) for a self-contained run, or --igenomes-ignore true to turn the lookup off.
Warnings are not failures
A run or replay can print harmless upstream warnings. Examples: Nextflow reporting the validation.*
config scope as unrecognised (its linter does not see scopes that plugins add); a release setting a
parameter its own plugin removed (scrnaseq's validationSchemaIgnoreParams, which nfclaw run
neutralises in the config and announces); or a test profile that sets conflicting references on
purpose (rnaseq's --gtf with --gff). docs/known-issues.md lists them with
their real cause under "Warnings a run prints that are not faults"; check there before reporting one.
nfclaw run also announces measured run-to-run variation before launch (for example dada2
assignTaxonomy tie-breaking or unseeded QIIME2 rarefaction), so differences between runs or
replays are expected rather than treated as faults. nf-claw never modifies the pinned pipeline
source.