Skip to main content
Glama

OpenReadout

OpenReadout lets AI agents read and analyze raw files from lab instruments like microscopes, mass specs, flow cytometers, plate readers and NMR. It reads 120+ formats without vendor software, and runs as an MCP server, a CLI, or a Python or R package.

Related MCP server: file-analyzer-mcp

Get Started

Install it, then connect it to your agent:

brew install openreadout/tap/openreadout    # other ways under Installation below
openreadout mcp --install claude-desktop    # or claude, codex, cursor, vscode, gemini

Then ask your agent about a file, like "What's in cells.czi?" In Claude Code you can install it as a plugin instead (see AI Integration).

Or try the browser demo with no install. Your files never leave your computer.

With an Agent

Claude finds the cerebellum in a 3.7 GB slide scan and labels its layers.

https://github.com/user-attachments/assets/7ee0f9fe-e6e0-4378-a46d-5cdc04d57151

Claude checks a gene knockout with files from five instruments.

https://github.com/user-attachments/assets/658d300b-dc9d-4164-af84-bb48261fd33f

What It Does

  • Inspect images, channels, traces, spectra, tables, and metadata, in plain text or structured JSON

  • Check files for truncation, missing planes, and damaged structure, with exit code 4 when a file is corrupt

  • Export to OME-TIFF, OME-Zarr, mzML, NWB, CSV, Parquet, Arrow, JCAMP-DX, Allotrope ASM, and RDML, reading every export back to verify it

  • Preview image planes, traces, spectra, and plate heat maps as PNG

  • Analyze chromatographic peaks, plate assays (IC50, standard curves), qPCR (Cq, ΔΔCq), NMR peaks, patch-clamp features, spikes, and flow-cytometry gates, with documented methods

  • Batch over whole directories, index lab shares, and watch running acquisitions

On the Command Line

# Install (macOS / Linux; other ways under Installation)
curl -fsSL https://raw.githubusercontent.com/openreadout/openreadout/main/scripts/install.sh | sh

# What is in the file?
openreadout info cells.lif
# → format: Leica LIF (lif) v2  size: 16.0 MiB  images: 1  planes: 2
# →   [0] PEI_laminin_35k  2048x2048 z=1 c=2 t=1  uint16  px=0.3250 µm
# →       objective: HC PL FLUOTAR L 20x/0.40 DRY

# Is it complete?
openreadout check partial-copy.lif
# → error  truncated       block chain runs past end of file
# → error  missing_planes  geometry needs 16777216 bytes but only 8969789 are stored

# Integrate the peaks of a chromatogram
openreadout analyze peaks gc-run.ch --min-height 1
# → 4 peaks, area in pA·min
# → 1   4.852 min  area 0.2779  25.08 %
# → ...

# Structured JSON for scripts and agents
openreadout info cells.lif --json
{
  "ok": true,
  "schema_version": "2",
  "data": {
    "format": { "id": "lif", "name": "Leica LIF", "vendor": "Leica Microsystems" },
    "images": [
      {
        "size_x": 2048, "size_y": 2048, "size_c": 2,
        "pixel_type": "uint16",
        "physical_size": { "x": 0.325, "y": 0.325, "unit": "µm" }
      }
    ]
  }
}

Formats

Area

Formats

Export to

Light microscopy

Zeiss CZI, Nikon ND2, Leica LIF, Olympus OIR/VSI/OIB, Imaris, OME-TIFF and other TIFF variants, OME-Zarr, whole-slide images (including Philips iSyntax, Hamamatsu VMS and MIRAX)

OME-TIFF, OME-Zarr

High-content screening

Harmony (Opera Phenix, Operetta), ImageXpress, CellVoyager

OME-Zarr plate, OME-TIFF

Electron microscopy

MRC, Gatan DM3/DM4, FEI SER/EMI, Velox EMD, EER movies, SerialEM mdoc

OME-TIFF, OME-Zarr, MRC

Structural biology

CBF/miniCBF, SMV, EIGER NeXus (NXmx) diffraction images

MRC, OME-TIFF

Medical imaging

DICOM (files, series, studies, DICOMDIR), NIfTI, Analyze, Bruker ParaVision

NIfTI, OME-TIFF

Mass spectrometry

Thermo RAW, Bruker timsTOF and BAF, Agilent MassHunter, Waters MassLynx, Sciex WIFF, mzML

mzML, Parquet, Arrow

Chromatography

Agilent ChemStation and OpenLab, Shimadzu, Chromeleon, AIA/ANDI

CSV, JCAMP-DX, Parquet

Electrophysiology

Axon ABF, Intan, SpikeGLX, Open Ephys, Neuralynx, Blackrock, Plexon, HEKA, Spike2, TDT, Axona, NWB

NWB, CSV, Parquet

NMR and spectroscopy

Bruker TopSpin and OPUS, Varian, JEOL, Thermo OMNIC, Renishaw, JCAMP-DX, SPC

JCAMP-DX, CSV

Flow cytometry

FCS, FlowJo workspaces, Gating-ML

CSV, Parquet, Arrow

Plate readers and qPCR

Plate-reader exports, RDML, Applied Biosystems, LightCycler, Rotor-Gene

Allotrope ASM, RDML, CSV

DNA sequencing and electrophoresis

Illumina run folders, Oxford Nanopore POD5 and FAST5, FASTQ, BAM, ABIF Sanger and fragment-analysis files, Agilent Bioanalyzer and TapeStation

FASTQ, CSV, Parquet

Other

NanoDrop, Qubit, Incucyte, gel and blot imagers, ÄKTA, ITC, Biacore, Seahorse, Octet, Zetasizer, XRD, EPR, electrochemistry, thermal analysis

CSV, Parquet

The format list lists every format OpenReadout reads, with its known gaps.

Installation

Ships as a single self-contained binary. No Java, no Python, no vendor DLLs -- nothing else to install.

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/openreadout/openreadout/main/scripts/install.sh | sh

# Windows (PowerShell)
irm https://raw.githubusercontent.com/openreadout/openreadout/main/scripts/install.ps1 | iex

# Homebrew (macOS / Linux)
brew install openreadout/tap/openreadout

# npm (all platforms; installs the native binary for your platform as a dependency)
npm install -g openreadout

# Rust toolchain
cargo install openreadout --locked

Docker, Nix, cargo-binstall, and the other channels are on the install page.

Verify installation: openreadout --version

AI Integration

MCP Server

Built-in MCP server — register with one command:

openreadout mcp --install claude          # Claude Code
openreadout mcp --install claude-desktop  # Claude Desktop
openreadout mcp --install codex           # OpenAI Codex
openreadout mcp --install cursor          # Cursor
openreadout mcp --install vscode          # VS Code / Copilot
openreadout mcp --install gemini          # Gemini CLI

Windsurf, Zed, Continue, and Cline are supported too. The server exposes 28 tools (openreadout_info, openreadout_check, openreadout_preview, openreadout_export, openreadout_peaks, ...) over JSON-RPC, so the client doesn't need shell access.

Claude Code Plugin

Installs the MCP server and the skill together:

/plugin marketplace add openreadout/agent-plugins
/plugin install openreadout@openreadout

Gemini CLI Extension

gemini extensions install https://github.com/openreadout/agent-plugins

Codex Plugin

codex plugin marketplace add openreadout/agent-plugins
codex plugin add openreadout@openreadout

Each of these adds the skill and the MCP server from the openreadout/agent-plugins repository. The server runs the openreadout binary from your PATH, so install it first.

Agent Skill

openreadout self skill --install claude   # ~/.claude/skills/openreadout
openreadout self skill --install agents   # ~/.agents/skills/openreadout (Codex, Cursor, Copilot, Gemini CLI)

The skill source is in skills/openreadout.

Built for Agents

  • JSON output for every command, with published schemas.

  • Fixed exit codes: 0 ok, 1 error, 2 usage, 3 unknown format, 4 corrupt, 5 I/O, 6 unsupported.

  • Errors with a hint about what to try next.

  • Assurance on every result: whether that kind of file was checked against another reader. --strict refuses anything that wasn't.

  • Previews the agent can look at, as PNG.

  • Figures from plot: plate grids, dose-response fits, gated dot plots and more, as PNG, SVG or PDF.

  • Fast metadata: info reads headers only, so a 100 GB file is as quick as a small one.

  • Read-only and offline.

Python and R

Python — pip install openreadout returns metadata as dicts and pixels as NumPy, dask, or xarray arrays, with plugins for bioio and napari. See the Python guide.

import openreadout

with openreadout.File("cells.lif") as f:
    f.images[0]["channels"]     # same keys as `info --json`
    stack = f.to_xarray(0)      # labelled with channel names and µm
    f.preview(composite=True)   # shows itself in Jupyter

openreadout.plot(data={"file": "growth.pda"}, facet="plate").save("plate.pdf")

R — the R package returns arrays and data frames, and draws the same previews and figures. See the R guide.

Comparison

OpenReadout

Bio-Formats

bioio

czifile / nd2 / liffile

msconvert

Open source & free

✓ (MIT / Apache-2.0)

✓ (GPL)

✓ (plugins vary)

✓ (BSD)

✓ (vendor DLLs are not)

AI-native CLI + JSON + MCP

✓

✗

✗

✗

✗

Zero install (single binary)

✓

✗ (JVM)

✗ (Python)

✗ (Python)

✗

No vendor DLLs

✓

✓

✓

✓

✗

Integrity check

✓

✗

✗

✗

✗

Microscopy

✓

✓

✓

✓ (one format each)

✗

Mass spectrometry

✓

✗

✗

✗

✓

Ephys, flow, NMR, chromatography, plates, qPCR

✓

✗

✗

✗

✗

Cross-platform

✓

✓

✓

✓

Windows (or Wine)

Validation

Each reader is tested against other readers on public instrument files. See how we validate.

The readers were written from public files, published specifications and permissively licensed readers (credited in NOTICE), without vendor SDKs or DLLs. GPL readers such as Bio-Formats are only run as black boxes in tests. See the clean-room policy and the per-format provenance logs.

Documentation

The documentation has guides for every command and format:

Privacy

OpenReadout runs on your computer, makes no network connections and sends no telemetry. See PRIVACY.md.

License

Licensed under either the Apache License 2.0 or the MIT license, at your option. OpenReadout is not affiliated with any instrument vendor; see TRADEMARKS.md.

Bug reports and contributions are welcome on GitHub Issues. See CONTRIBUTING.md, and read the clean-room policy before working on a reader.

Demo files and README images come from the public test corpus (corpus/manifest.toml), used under their licences, and are credited in .github/assets/gallery/CREDITS.md. demo.tape regenerates the terminal demo.


If you find OpenReadout useful, please give it a star on GitHub — it helps others discover the project.

Available Tools

28 tools
openreadout_assayB
Read-onlyIdempotent

Plate-reader exports, with the layout the file stores or layout. analysis: wells (per-well values, blank subtraction, replicate mean/SD/CV, outliers), curve (standard curve, back-calculated concentrations, LLOQ/ULOQ), dose-response (IC50/EC50 per compound with CI and Hill slope), kinetics (Vmax, lag, AUC per well), growth (growth rate, doubling time, lag, logistic fit, and whether each well grew, crashed or regrew, with times), qc (Z′, S/B, S/N, SSMD). An argument that names analyses applies to those only.

NameRequiredDescriptionDefault
fileYesPath to the file or data-set directory.
lloqNocurve: lower limit of quantification (overrides the recovery rule).
plotNocurve, dose-response: also return a PNG of the points and the fitted curve.
uloqNocurve: upper limit of quantification (overrides the recovery rule).
modelNocurve, dose-response: the model. Default `4pl`. `linear` = y = slope · x + intercept; `4pl` = Four-parameter logistic: y = d + (a − d) / (1 + (x/c)^b); `5pl` = Five-parameter logistic: y = d + (a − d) / (1 + (x/c)^b)^g.
wellsNoOnly these wells (`A1:H6`); the layout's blanks and controls are still used.
fieldsNoRows show their main fields to 4 significant digits (growth: pattern, growth_rate_per_h, doubling_time_h, lag_time_s, max_value, time_to_max_s, crash_s, trough_s, regrowth_s). fields adds others, e.g. `["auc_h", "logistic_k"]`; `["all"]`: every field, full precision.
fit_onNocurve: fit every standard replicate or the level means. Default `replicates`. `replicates` = Every standard well (replicates as separate points); `means` = The mean of each standard level.
layoutNoPlate-layout file: CSV/TSV, a plate-map grid (blocks whose corner cell names the field: role, sample, compound, concentration, dilution) or a long table with a `well` column.
reduceNowells, curve, dose-response, qc on a kinetic read: how each well's time course becomes one value. `first` = first time point; `last` = last time point; `max` = largest value; `min` = smallest value; `mean` = mean over all time points; `max-slope` = largest slope over `window` points, per minute; `mean-slope` = least-squares slope over all time points, per minute; `auc` = area under the curve (value × s).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
windowNoPoints per sliding window (reduce=max-slope, kinetics, growth). Default: 5 or a tenth of the time points, whichever is larger.
analysisYesWhat to compute. `wells` = Per-well and per-replicate-group values: roles, blank subtraction, mean, SD, CV %, outliers; `curve` = Standard curve (linear, 4PL, 5PL) and back-calculated concentrations of every well; `dose-response` = Dose-response per compound: IC50/EC50 with confidence interval, Hill slope, top, bottom; `kinetics` = Per-well kinetic metrics: max slope (Vmax), lag time, time to max, AUC; `growth` = Per-well growth curves: growth rate, doubling time, lag, logistic fit; which wells grew, crashed or regrew and when (growth_summary); `qc` = Assay quality from control wells: Z′, signal/background, signal/noise, CVs.
normalizeNowells, dose-response, qc: percent effect from the controls. Default `none`. `none` = the (blank-subtracted) signal; `controls` = percent effect: 0 % = the negative control (vehicle) mean, 100 % = the positive control mean.
standardsNocurve: standards as `WELLS=CONCENTRATION` items separated by `;` (`A1,A2=100;B1:B2=50`). Default: the layout's.
weightingNocurve, dose-response: fit weighting. Default `none`. `none` = Every point weight 1 (ordinary least squares); `1/y` = w = 1/|y|; `1/y2` = w = 1/y²; `1/x` = w = 1/x (x > 0); `1/x2` = w = 1/x² (x > 0).
confidenceNocurve, dose-response: confidence level of intervals. Default 0.95.
blank_wellsNoWells to mark as blanks (`H1,H2`, `H1:H12`).
plate_optionsNoRarely needed plate options.
negative_wellsNoWells to mark as negative controls (no effect / vehicle).
positive_wellsNoWells to mark as positive controls (full effect / maximum signal).
growth_thresholdNogrowth: values at or below this are left out of the log-scale fit. Default 5 % of each well's maximum.

Output Schema

NameRequiredDescription
pathYesThe input file.
readYesThe read analysed.
blankNoBlank subtraction applied.
curveNoStandard-curve fit report (`curve`).
notesNoWhat was assumed or left out.
plateNoPlate (table) name.
tableYesTable (plate) index.
wellsNoOne row per well.
formatYesFormat id of the input (`plate`, or `long-csv`).
growthNoOne row per well (`growth`).
layoutYesWhere the layout came from and what it assigns.
reduceNoHow kinetic time courses were reduced to one value per well (endpoint analyses).
qualityNoAssay quality from control wells (whenever positive and negative controls exist).
samplesNoOne row per replicate group (sample, standard level, control, dose).
writtenNoFiles written (`--csv`, `--plot`).
analysisYesThe analysis run (`wells`, `curve`, `dose-response`, `kinetics`, `growth`, `qc`).
kineticsNoOne row per well (`kinetics`).
outliersYesOutlier rule and flagged wells.
warningsNoWhat may be wrong with the layout: role names read as samples, controls of unknown sign, role-map entries that matched no well.
compoundsNoOne row per compound (`dose-response`).
growth_summaryNoWells by growth pattern, with the range of crash and regrowth times (`growth`).

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered without the description. The description adds the analysis-scoping rule but says nothing about error behavior, layout-resolution conflicts, or what happens when required layout/standards are missing — context the schema only partially carries (e.g. strict/exit_code 6).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The analysis taxonomy is dense and useful, and the scoping sentence earns its place. But the opening fragment is confusingly terse (it states no action), and the whole enumeration duplicates the `analysis` parameter's enum description, so a meaningful portion is redundant for an agent that has the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not explain return values, and annotations cover safety, so what remains — orienting the agent on the six analysis families and the argument-scoping rule — is largely delivered. It falls short only on modality routing versus siblings and on failure/precondition behavior for a 22-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 22 parameters with enums, defaults and formulas. The description's analysis enumeration largely restates the `analysis` enum text (LLOQ/ULOQ, IC50/EC50, Z′/S/B/S/N/SSMD) rather than adding new meaning, so the baseline of 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (plate-reader exports) and enumerates the six analysis modes the tool computes, so an agent can tell it is the plate-reader assay analysis tool rather than the qPCR, chromatogram, or ephys siblings. However, the opening 'Plate-reader exports, with the layout the file stores or `layout`' is a verbless fragment that never states the action ('analyse/compute') outright, and no sibling is named for contrast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'An argument that names analyses applies to those only' gives real applicability guidance, telling the agent that e.g. `curve` or `plot` are scoped to the analyses named in `analysis`, and the analysis enumeration implies which mode to pick. But there is no when-to-use/when-not guidance and no naming of alternatives like `openreadout_stats`, `openreadout_extract` or `openreadout_summarize` that an agent might otherwise reach for.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_batchA
DestructiveIdempotent

One measure over many files as one tidy table, optionally joined to sample sheets or plate maps (the join key is chosen from the data and reported in joins[] with unmatched rows) and summarized by group (by; test against a control). Analyses (peaks, chromatogram, nmr-peaks, ephys-features, spikes, qpcr, gate, assay) take the arguments of their tools as options. Inputs (paths): files, directories, globs or an index query. Returns at most limit rows (page with offset; output writes them all to a file); a failing file is a row with error. openreadout_summarize regroups a table written by an earlier output.

NameRequiredDescriptionDefault
byNoSummarize by these columns (e.g. `["condition"]`): n, mean, sd, sem, median, min, max, cv_percent per group; channels/parameters/populations stay apart automatically.
keysNoFixed join keys `SHEET_COLUMN=FIELD` (path, file, stem, sample_id, sample_name, barcode, well, position, run_order, column:NAME).
testNo`welch` or `mann-whitney` against `control` (a value of the first `by` column).
limitNoRows to return (default 20, max 500; 0 with `output`: the rows are in the file).
pathsNoFiles, directories or glob patterns.
queryNo… and the query (search syntax, e.g. "format=fcs channel~CD4").
whereNoRow filters `COLUMN=VALUE` / `COLUMN!=VALUE` (e.g. "parameter=FITC-A").
fieldsNoColumns to keep (info: index field names, or `["all"]`).
offsetNoFirst row returned.
outputNoWrite the full table (or the summary, with `by`) to this .csv/.tsv/.jsonl/.json/.parquet file (verified; never overwrites without `overwrite`).
valuesNoValue columns to summarize (default: the measure's main values).
controlNoThe control group.
formatsNoOnly these format ids (e.g. `["fcs"]`).
measureYesWhat to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the other openreadout_assay arguments; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml).
optionsNoThe measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, openreadout_assay with its `analysis`, ...), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters.
exact_byNoGroup by exactly `by` (do not add the measurement columns that vary).
overwriteNoReplace an existing output file.
recursiveNoWalk sub-directories.
replicateNoAverage rows within each replicate first.
worksheetNoWorksheet of an XLSX sheet.
from_indexNoAlso take the data sets an index query selects: the index directory …
sample_sheetsNoSample sheets (CSV/TSV/XLSX) or plate layouts (plate-map grids) to join; the key is chosen from the data (file name, path, sample id recorded in the file, well, barcode, vial, run order) and reported under joins[].

Output Schema

NameRequiredDescription
rowsYesRows as arrays in column order.
grainYesColumns that identify a row within its data set.
joinsNoSample sheets and layouts joined, in order.
inputsYesHow the inputs became data sets.
offsetYesIndex of the first row in `rows`.
outputNoThe file the full table was written to (`-o`).
columnsYesColumns of `rows`, with type, unit and role (`id`, `key`, `metadata`, `annotation`, `value`, `error`).
measureYesMeasure (`stats`, `trace`, `table`, `gate`, `info`, …).
summaryNoThe group summary (`--by`).
warningsNoThings to check: skipped inputs, grouping, join results.
truncatedYesTrue when the table has rows after the last one returned (page with `offset`, or read the full table from `output`).
total_rowsYesRows in the whole table.
returned_rowsYesRows returned here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare the safety profile (destructiveHint=true, idempotentHint=true), and the description adds real behavior beyond that: a failing file becomes a row with error rather than aborting, limit defaults to 20/max 500 with offset paging, output writes all rows and never overwrites without overwrite, and the join key is chosen from the data and reported in joins[] with unmatched rows.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded: the core purpose, then joins/summarization, then inputs, then paging/output semantics. Every clause carries information, though the heavy parenthetical stacking (measure lists, option lists) makes it read as one long run-on rather than clearly separable statements.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the description still covers the non-obvious output contract (rows written to file vs returned, per-file errors as rows, joins[] reporting). For a 22-parameter tool with nested `options` this is nearly complete, missing only explicit prerequisites/permissions for writing output files.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 22 parameters in detail, including the per-measure semantics of `measure`. The description reinforces how `options` maps to sibling tools and how joins are keyed, but adds little syntax beyond what the schema provides — the baseline 3 for full coverage applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+scope: 'One measure over many files as one tidy table', then names the optional join and group-summarization behaviors. It explicitly distinguishes itself from the sibling openreadout_summarize, which only regroups a previously written table, so an agent can route without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear input-mode guidance ('files, directories, globs or an index query') and explains that analyses (peaks, chromatogram, nmr-peaks, ...) are invoked by passing their tool arguments as options. It also names openreadout_summarize as the follow-up alternative, but never states the when-not condition versus the singular openreadout_stats/table/trace tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_checkA
Read-onlyIdempotent

Integrity check: ok plus findings (severity, code, message) for truncation, missing planes or parts, bad blocks; a plate folder reports missing files per well; a file still being written reports acquisition_in_progress.

NameRequiredDescriptionDefault
fileYesPath to the file or data-set directory.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
headers_onlyNoCheck headers and structure only (offsets, declared sizes and counts, missing parts): no decompression, decoding or checksums over the data.

Output Schema

NameRequiredDescription
okYesTrue when no finding has severity `error`.
pathYesThe input file.
formatYesFormat id of the input file.
findingsYesEverything found, in the order checked.
assuranceNoWhether the file lies inside what its reader has been validated on (the same block as `info` → `assurance`). `ok` says the file is intact; `assurance` says whether its values can be trusted. Filled by the `check` command when the header can be read.
acquisitionNoPresent when the file is not finished: still being written (`in_progress`: findings about the unfinished tail are warnings and `ok` covers the complete part) or stopped before the end (`interrupted`). See `book/src/guides/lab-shares.md`.
checks_performedYesWhat was verified, in plain words, so the caller knows what "ok" covers.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower, and the description adds real behavioral detail: the shape of findings (severity, code, message), the plate-folder per-well reporting mode, and the acquisition_in_progress special case. It does not explain the strict/exit_code 6 behavior that only the schema hints at.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence that front-loads the outcome (ok plus findings) before enumerating detection categories. No filler, though the semicolon-chained clauses make it slightly harder to parse than it needs to be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, yet the description still usefully summarizes the finding structure and the folder-mode behavior. Complete enough to call correctly; the only gap is sibling differentiation and strict-mode behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters are already documented, making 3 the baseline. The description adds only slight context (a directory argument triggers per-well reporting) and does not elaborate on strict or headers_only semantics beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (integrity check) on a specific resource (file/data-set directory) and enumerates what it detects: truncation, missing planes or parts, bad blocks. An agent can tell it is a damage check, but the description never distinguishes it from the similarly-scoped sibling openreadout_health.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the content: the tool is for verifying file/folder integrity. There is no explicit when-to-use statement, no when-not-to, and no routing to alternatives such as openreadout_info or openreadout_health.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_chromatogramA
Read-onlyIdempotent

Chromatograms from mass spectra and detector signals: TIC, BPC, extracted-ion (mz with ppm or da), SRM/MRM transitions, stored chromatograms and UV/DAD/FID/TCD traces (traces). Per chromatogram: apex time and intensity, integral, and thinned arrays. Answers 'when does m/z X elute'.

NameRequiredDescriptionDefault
daNoXIC tolerance in m/z units instead of ppm.
mzNoExtracted-ion chromatograms at these m/z values (one streaming pass for all).
bpcNoBase-peak chromatogram.
ppmNoXIC tolerance (half-width) in ppm. Default 10.
runNoSpectra run. Default 0.
ticNoTotal-ion chromatogram (the default for mass-spectrometry files when nothing else is chosen).
fileYesPath to the file or data-set directory.
sweepNoSweep of the traces (one spectrum of a map or series, one injection). Default 0.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
tracesNoStored chromatograms or detector signals (UV/DAD, FID, TCD, stored TIC/SRM): trace indices from openreadout_info → traces[].
channelNoChannel of the traces (e.g. one DAD wavelength). Default: the first signal channel.
profileNoUse profile data where scans store both profile and centroids. Default false (the instrument's centroids).
ms_levelNoMS level of the scans. Default 1 (2 with `precursor`).
mz_rangeNoTIC/BPC over this m/z range only, `[low, high]`.
polarityNo`positive` or `negative`: only scans of this polarity.
rt_rangeNoRetention-time range `[start, end]`, minutes.
aggregateNo`sum` (default) or `max` of the points inside an XIC window.
precursorNoOnly MS/MS scans of this precursor m/z (product-ion XIC).
max_pointsNoPoints returned per chromatogram (the most intense point of each of N equal slices). Default 500, max 20000; the summary (apex, integral) always covers every point.
scan_filterNoOnly scans whose scan filter/description contains this text (case-insensitive).
transitionsNoSRM/MRM transitions as `"Q1>Q3"` strings, e.g. `"279.2>179.2"`.
precursor_tolNoPrecursor tolerance, m/z units. Default 0.5.
transition_tolNoQ1/Q3 tolerance of transitions, m/z units. Default 0.5.

Output Schema

NameRequiredDescription
runNoSpectra run used, when any chromatogram was computed from spectra.
pathYesThe input file.
notesNoAnything the caller should know.
formatYesFormat id of the input file.
outputNoFile written (`-o`), when any.
spectra_readYesSpectra decoded.
chromatogramsYesOne entry per requested chromatogram.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and a closed world, so the safety profile is fully covered. The description adds that output arrays are thinned while the apex/integral summary covers every point, which is useful behavioral context, but it discloses nothing about cost, streaming, or parameter interaction beyond what the schema's own parameter text already states.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, front-loaded with the supported chromatogram modes before the per-chromatogram output and the use-case question. Nothing is padded, though the mode enumeration and output summary run long for a single sentence, which keeps it just under a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a 23-parameter tool with an output schema and full annotation coverage, the description supplies the missing high-level framing: which chromatogram types exist and what each result contains. It does not explain how the many mode selectors (tic/bpc/mz/transitions/traces) interact or which combinations are mutually exclusive, which is the main residual gap for a tool this complex.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the 23 parameters is already documented in the schema, including tolerances, defaults, and the max_points thinning rule. The description only restates a handful of these (mz with ppm or da, transitions, traces) at a conceptual level without adding syntax or interaction semantics, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (chromatograms) and enumerates the specific modes it extracts — TIC, BPC, extracted-ion with ppm/da tolerance, SRM/MRM transitions, stored/detector traces — which lets an agent recognize the tool against siblings like openreadout_spectrum or openreadout_trace. The verb is only implied in the text (it lives in the annotation title 'Extract chromatograms'), and no sibling is named for contrast, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied through one concrete question it answers, "when does m/z X elute," which points at extracted-ion work, and through the mode list that hints which parameters select which behavior. There is no explicit when-to-use versus openreadout_spectrum/openreadout_trace/openreadout_peaks, and no stated exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_compareA
Read-onlyIdempotent

Compare two files, e.g. a raw file and its export: metadata differences, geometry, channel names, physical sizes, and per-plane hashes or the largest difference within tolerance. identical says whether they hold the same data.

NameRequiredDescriptionDefault
fileYesThe first file (e.g. the raw file).
imageNoOnly this image index (in both files).
levelNoPyramid level (0 = full resolution, the default).
ignoreNoJSON pointers (into openreadout_info output) to leave out of the metadata diff; `*` matches one segment.
selectNoPlane selection strings such as `c=0`, `z=2-5`, `t=0,3`. A second file holding only the selected planes (an export with the same selection) is matched to them in order.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
againstYesThe second file (e.g. an OME-TIFF export of `file`).
no_pixelsNoMetadata and geometry only, no pixels.
toleranceNoLargest absolute sample difference that still counts as equal. Default: bit-identical planes (same xxh3-128).

Output Schema

NameRequiredDescription
oursYesThe first file.
notesNoCaveats (e.g. formats that store different metadata for the same acquisition).
imagesYesGeometry, channel-name and physical-size comparison per image index.
planesYesThe plane-by-plane comparison.
theirsYesThe second file.
metadataYesThe normalized-metadata diff.
identicalYesNothing compared differs: metadata (unless skipped), geometry, channel names, physical sizes and planes (within the tolerance). The exit code is 0 when true, 1 when false.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds behavior beyond that: it discloses the default equality rule (bit-identical xxh3-128 planes unless tolerance is set), that strict mode refuses unvalidated values with exit_code 6, and what the 'identical' flag reports. It does not describe output shape or performance characteristics, but the output schema exists to carry that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with the core action front-loaded and the compared aspects following. Every clause carries information, though the enumerated list plus the trailing 'identical says...' sentence makes it slightly cramped rather than maximally scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter comparison tool, the definition plus a 100%-covered schema, an output schema, and safe-read annotations leave nothing an agent needs missing: purpose, what is compared, the equality default, and the return signal ('identical') are all present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the 9 parameters is already documented in the schema, including tolerance's xxh3-128 default and the ignore JSON-pointer syntax. The description only echoes these at a high level ('per-plane hashes or the largest difference within tolerance') without adding format or interaction details, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Compare two files') and enumerates exactly what dimensions are compared: metadata, geometry, channel names, physical sizes, per-plane hashes. That is far more specific than the title alone. It stops short of naming a sibling, so an agent cannot infer from the text alone why it would pick this over openreadout_check or openreadout_info.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical 'e.g. a raw file and its export' gives a concrete usage scenario and the required params reinforce it ('an OME-TIFF export of `file`'). There is no explicit when-not guidance and no naming of the alternative tools (openreadout_check, openreadout_info) whose output feeds the `ignore` pointers.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_ephys_featuresC
Read-onlyIdempotent

Patch-clamp features: action potentials per sweep, rheobase, f-I slope, input resistance, membrane time constant, capacitance, sag; in voltage clamp, holding current and access resistance.

NameRequiredDescriptionDefault
fileYesPath to the file or data-set directory.
traceNoTrace index (default 0).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
sweepsNoSweeps to analyse (default all).
channelNoChannel (default: the first voltage channel, else the first current channel).
max_spikesNoPer-spike rows returned (default 25, the first spikes in sweep order; counts stay complete).
min_rise_mvNoA spike's peak must rise this far above the lowest voltage since the previous spike, mV (default 15; 0 counts every crossing, as eFEL does).
dvdt_thresholdNodV/dt onset criterion, V/s (default 10).
peak_threshold_mvNoSpike voltage threshold, mV (default −20).

Output Schema

NameRequiredDescription
cellYesPer-cell features.
pathYesInput path.
notesNoRemarks.
traceYesTrace analysed.
formatYesFormat id.
spikesYesOne row per spike (at most `max_spikes`).
sweepsYesOne row per sweep.
channelYesChannel analysed.
settingsYesSpike detection settings.
stimulusNoStimulus from the protocol, when there is one.
clamp_modeYes`current_clamp`, `voltage_clamp` or `unknown` (from the channel and command units).
sample_rate_hzYesSampling rate, Hz.
spikes_truncatedYesTrue when `spikes` was cut at `max_spikes`.
spike_count_totalYesTotal spikes detected.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and non-destructive, so the safety profile is covered. The description adds no behavioral context beyond the domain split of current vs voltage clamp: nothing about required file/assurance preconditions, what happens when features cannot be computed, or how strict mode affects results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler; the topic leads and the clamp-mode distinction follows. It is efficient, though the semicolon-heavy feature list reads more like an output inventory than guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained — yet the description spends its length restating those outputs instead of covering the gaps: required input format, the meaning of strict/exit_code 6, and how it relates to openreadout_spikes. Adequate but with clear omissions for a 9-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter carries its own default and semantics, so the baseline of 3 applies. The description's enumerated quantities describe outputs rather than clarifying any parameter, adding no interpretive value for inputs like sweeps, channel or the spike-detection thresholds.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource (patch-clamp features) and enumerates the specific quantities computed, so an agent can tell this is an ephys feature-extraction tool. However, there is no explicit verb and no differentiation from neighbours like openreadout_spikes or openreadout_trace, which also operate on traces.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisite statement (e.g. what file kinds qualify), and no mention of alternatives such as openreadout_spikes for raw spike events. The agent must infer selection context entirely from the feature list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_exportA
DestructiveIdempotent

Convert to an open format, or save a figure, as a new file read back and verified; the source is never touched. format: ome-tiff (images, default; pyramidal when the source is), ome-zarr (multiscale; plates as OME-NGFF HCS), mzml (mass spectra, default), csv (one table or one sweep of a trace, default for tables and traces), parquet or arrow (tables, traces with every sweep, spectra=true for MS points), nwb (electrophysiology), jcamp (NMR, IR/Raman, chromatograms), asm (plate readers), rdml (qPCR), nifti (volumes: CT, MRI). Figures: plot or preview = the arguments of that call, output .png, .jpg, .tiff, .svg or .pdf (scale, dpi for print); the picture comes back too. Sends progress with a progressToken.

NameRequiredDescriptionDefault
dpiNoFigures: print resolution (e.g. 300), recorded in .png, .jpg and .tiff files; .svg and .pdf pages get the size the raster would print at.
runNomzML, Parquet, Arrow: spectra run index (default 0).
fileNoPath to the file (not with plot or preview).
plotNoSave a figure: the arguments of an openreadout_plot call. `output` names the file.
rowsNoCSV, Parquet, Arrow, NWB, JCAMP-DX: rows (samples of each sweep for traces) `A-B`, `A-` or `A`, zero-based and inclusive.
imageNoImages: only this image index.
levelNoImages: export this source pyramid level as the full resolution (default 0).
scaleNoFigures: pixels per figure pixel in .png, .jpg and .tiff files (default 2, up to 8); image previews are read again at max_size × scale.
sweepNoCSV, Parquet, Arrow, NWB, JCAMP-DX: only this sweep (CSV default 0; the others: every sweep).
tableNoCSV, Parquet, Arrow: this table index (FCS data set, plate read, event or peak table).
traceNoCSV, Parquet, Arrow, NWB, JCAMP-DX: this trace index (NWB default: every trace).
wellsNoOME-Zarr of a multi-well plate: only the fields of these wells (`C05`).
formatNo`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON), `rdml` (RDML 1.3; qPCR files), `fastq` (base calls: a Sanger read, its default, gives one file; an Illumina run folder gives a directory of gzip FASTQ, one file per lane and read, and rows `0-N` writes the first N+1 clusters of each lane), `nifti` (NIfTI-1 `.nii.gz`; one volume with voxel size and scanner orientation) or `mrc` (MRC2014; EM movies, stacks and diffraction images). Without it, the extension of `output` decides; it must not contradict `output`.
labelsNoCSV: add a second header line with column labels (FCS `$PnS`).
outputNoOutput path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.fastq`, `.parquet`, `.arrow`, `.nwb`, `.jdx`, `.nii.gz` or `.mrc`. Its extension sets the format when `format` is not given. Figures: .png, .jpg, .tiff, .svg or .pdf (default `<data file stem>.figure.png` or `.preview.png` next to the data).
regionNoImages: export only this rectangle `{x, y, width, height}` (pixels of `level`) of every plane, read tile by tile (cut a field out of a whole-slide image).
selectNoImages: plane selection strings such as `c=0`, `z=2-5`, `t=0,3`.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
previewNoSave a picture: the arguments of an openreadout_preview call (file, region, annotations, marks, dark, …); max_size up to 8192. Images are saved with a scale bar and no rulers (axes scale-bar; add title, caption) unless axes says otherwise.
spectraNoParquet, Arrow: export the mass spectra of `run` (one row per point, plus a `<name>.scans.parquet` per-scan summary) instead of a table or trace.
centroidNomzML, Parquet, Arrow: write the instrument's centroid lists instead of profiles where a scan has both.
overwriteNoReplace an existing output file or directory.
group_framesNoMRC: sum every N time points into one section (dose fractions of a movie).

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag a non-read-only, destructive, idempotent write confined to the local world. The description adds real value on top: the source is never touched, output is read back and verified, overwrite replaces an existing file or directory, strict mode can fail with exit_code 6, and progress is reported via progressToken. Minor gap: no mention of permissions or what is returned on success.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first clause, which is good. But the remainder is a single dense run-on that dumps the entire format list already present in the schema's format parameter, so a large fraction of the text duplicates structured data instead of earning its place. Structure suffers from being one unbroken block.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 23-parameter, no-required, nested-object tool with no output schema, the description covers conversion targets, figure saving, verification, overwrite and progress well. The main gap is the return value for the data-export path (only figures are said to come back), which with no output schema is left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every one of the 23 parameters is already documented inline, including the format enum-like list. The description largely restates the format options rather than adding interpretation, and the default-selection rule (extension of output decides unless format is given) is already in the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause gives a specific verb and resource: convert data to an open format or save a figure, written as a new file that is read back and verified, leaving the source untouched. This is clearly distinguishable from display-oriented siblings like openreadout_plot and openreadout_preview, whose arguments this tool reuses. An agent knows exactly what this tool produces.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: it lists per-source default formats and notes that plot/preview arguments are reused for figures, which hints at the boundary with those siblings. However, it never explicitly says when to choose export over plot/preview, nor states any prerequisites or exclusions. Guidance is present but left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_extractA
DestructiveIdempotent

Write one attachment a file embeds (a slide label or thumbnail, a preview image, time stamps) to a new file as stored, verified. openreadout_info view=structure lists them.

NameRequiredDescriptionDefault
fileYesAbsolute or working-directory-relative path to the file that holds the attachment.
outputNoOutput path. Default: `<input stem>.<attachment name>.<ext>` next to the input.
overwriteNoReplace an existing output file.
attachmentYesThe attachment: a name as openreadout_info view=structure lists it (a CZI's `Thumbnail`, `Label` or `SlidePreview` image, `TimeStamps`), or `#<index>`.

Output Schema

NameRequiredDescription
pathYesThe input file.
xxh3Yesxxh3-128 of the written bytes, 32 hex chars.
formatYesFormat id of the input file.
outputYesWhere the bytes were written.
verifiedYesTrue once the output was read back and matched.
attachmentYesThe attachment that was extracted.
bytes_writtenYesNumber of bytes written.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, readOnlyHint=false and openWorldHint=false, so the safety profile is covered structurally. The description adds a genuine behavioral note with 'as stored, verified' (bytes are written unmodified and checked), but says nothing about what overwriting destroys, permissions, or failure behavior when the attachment is absent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no padding; the action and its scope are front-loaded and the pointer to openreadout_info view=structure comes second as a discovery hint. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering the destructive/idempotent profile and an output schema present, the description need not explain return values; it correctly focuses on which attachment to pull and where listing lives. It is slightly thin on interaction between `output` and `overwrite` (what happens when the target already exists), which keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (file, output, overwrite, attachment) are already documented, including the `#<index>` form. The description only echoes the attachment concept and adds no syntax, default, or interaction detail beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (extract/write) and resource (an embedded attachment such as a slide label, thumbnail, preview image, or time stamps) and gives concrete examples of the attachment types, which separates it from generic siblings like openreadout_export. It lacks explicit verb+resource naming tied to other tools' scopes, but the purpose is clear without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Points the agent at openreadout_info view=structure as the way to discover valid attachment values, which is useful context, but never states when to use this tool versus alternatives like openreadout_export or openreadout_preview, nor any prerequisites or exclusions. Usage is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_gateA
Read-onlyIdempotent

Flow-cytometry gating from a FlowJo workspace (workspace) or Gating-ML 2.0 file (gatingml): the event count, percentage and medians of every population of the FCS file. Without workspace or gatingml, file is the gating file and the answer describes its samples and gate tree.

NameRequiredDescriptionDefault
fileYesPath to the file or data-set directory.
tableNoFCS data set index. Default 0.
sampleNoWorkspace sample name or id (default: matched by file name, then $FIL, then the only one).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
mediansNoParameters whose median over each population's events is reported under populations[].medians (`$PnN` or `$PnS`; `Comp-NAME` for compensated values), or `["all"]`: every parameter a gate uses, compensated as the gate reads it.
gatingmlNoGating-ML 2.0 document (instead of workspace).
workspaceNoFlowJo workspace (.wsp); `file` is then the FCS file to count events in.
populationsNoReport only these populations (paths or unique names) and their descendants.

Output Schema

NameRequiredDescription
pathNoThe FCS file gated; absent when only the gating file was described.
treeYesThe same populations as a tree (quadrant gates appear as grouping nodes without a count).
notesNoCaveats: skipped populations, disagreements with counts stored in the workspace, scaling.
tableNoFCS data set (table) gated.
sampleNoThe workspace sample whose gates were used (FlowJo only).
workspaceNoWorkspace-level facts (FlowJo only).
transformsYesTransforms by id (FlowJo: by parameter name).
event_countNoEvents in the data set.
gating_fileYesThe gating file (FlowJo workspace or Gating-ML document).
populationsYesOne row per population, parents before children.
compensationYesCompensation matrices the gating file defines (and whether any gate used them).
gating_formatYes`flowjo-wsp` or `gating-ml`.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: the fallback interpretation of `file` when both gating inputs are omitted, and the specific report contents per population. It does not mention failure modes such as the strict/exit_code 6 path (that only appears in the schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences, front-loaded with the core action and outputs. The second sentence's fallback rule is a little packed with clauses, but every clause carries actionable information and nothing is repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 8 parameters, an output schema present, and full schema coverage, the description supplies what the structured fields cannot: the operating-mode logic and the fallback behaviour. Minor gaps remain around error/strict handling and how `populations` and `medians` interact, but nothing essential for a correct call is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes further by describing cross-parameter coupling: `workspace` makes `file` the FCS file to count in, `gatingml` is an alternative to `workspace`, and the absence of both redefines `file`. That role-switching is not obvious from the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — flow-cytometry gating — and names the two input modes (FlowJo workspace, Gating-ML 2.0) plus the exact outputs (event count, percentage, medians per population). No sibling tool overlaps this domain, so an agent can select it unambiguously.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear mode-selection guidance: pass `workspace` or `gatingml` to compute gated counts, and if neither is supplied, `file` acts as the gating file and the answer degrades to a sample/gate-tree description. It does not point to any alternative tool for other flow-cytometry tasks, so exclusions are absent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_healthA
Read-onlyIdempotent

Storage health of a share indexed by openreadout_index: truncated or corrupt files, unreadable formats, duplicates (confirmed by content hash unless no_hash), the same experiment stored twice, files at risk, totals and personal-data findings.

NameRequiredDescriptionDefault
no_hashNoDo not confirm duplicate candidates by hashing their content (no file is read).
max_listNoMost entries listed per section (default 50; counts are complete).
index_dirYesIndex directory (from openreadout_index or `openreadout index`).

Output Schema

NameRequiredDescription
piiYesPersonal data.
rootsYesThe roots of the index.
totalsYesTotals.
at_riskYesVendor-only formats with no open export.
by_yearYesPer acquisition year.
by_familyYesPer family.
by_formatYesData sets and bytes per format.
index_dirYesThe index directory.
integrityYesTruncated and corrupt data sets.
duplicatesYesByte-identical copies.
unreadableYesUnreadable formats and unrecognised files.
generated_atYesWhen this report was made.
index_completeYesWhether the index covers every root to the end.
near_duplicatesYesThe same experiment stored more than once.
index_updated_atYesWhen the index was last written.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, closed-world, so the safety profile is covered. The description adds that duplicate confirmation reads file content unless no_hash is set, hinting at I/O cost, but it does not state how expensive a full hash pass is, whether progress is reported, or how sections behave on a partially indexed share.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that leads with the resource ('Storage health of a share indexed by openreadout_index') and then lists findings; the enumeration is dense but every item conveys a distinct output category. Slightly list-heavy but free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema and complete annotation coverage, the description only needs to convey purpose and scope, and it does so, including the results categories. The only gap is workflow guidance relative to sibling diagnostics, which is minor given the rich structured metadata.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter already carries a description, so the schema does the heavy lifting. The description only gestures at no_hash via 'unless no_hash' and says nothing extra about max_list or index_dir beyond the schema, which is an appropriate baseline-3 case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific resource and scope — storage health of a share produced by openreadout_index — and enumerates the concrete findings it reports (truncated/corrupt files, duplicates, files at risk, totals). This separates it from openreadout_stats, openreadout_info and openreadout_check well enough for selection, though the phrasing is a noun phrase rather than an explicit verb.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The tie to openreadout_index implies 'run after indexing', but there is no explicit when-to-use, when-not-to-use, or named alternative (e.g. openreadout_check vs openreadout_stats). The agent must infer the workflow position and the choice between this and sibling inspection tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_indexA
Idempotent

Catalog every data set under roots into index_dir (Parquet: one row per data set with format, size, sample, instrument, technique, method, operator, start, dimensions, channels, objective, events, scans, integrity status, personal-data flags). Headers only and resumable: a call stops after max_files/max_seconds with complete=false, and the same call again continues. openreadout_search queries the result. For one folder of files, openreadout_batch with measure info lists what each file is in one call.

NameRequiredDescriptionDefault
piiNoLook for personal data (default true).
checkNoIntegrity check per data set: `headers` (default; structure only), `full` or `none`.
rootsYesDirectories (or files) to crawl.
excludeNoGlob patterns of names or root-relative paths to skip.
restartNoDiscard an interrupted crawl instead of resuming it.
threadsNoWorker threads (default: the number of CPUs).
index_dirYesIndex directory to create or update (never inside a root).
max_filesNoStop after this many files in this call (default 20000); call again to continue.
full_rescanNoRead every file again instead of reusing unchanged records.
max_secondsNoStop after this many seconds in this call (default 45); call again to continue.
follow_symlinksNoCrawl directories behind symbolic links too (links to files are always read).

Output Schema

NameRequiredDescription
piiYesPersonal-data totals.
nextNoWhat to do next, when the crawl is not complete.
toolYesThe tool and version that wrote it.
bytesYesBytes of every file seen.
crawlYesCrawl counters, cumulative over resumed sessions.
filesYesRows of `files.parquet`.
rootsYesThe directories (or files) crawled, absolute.
yearsYesData sets per acquisition year (`unknown` when the file records no date).
tablesYesThe tables.
changesYesData sets per change (`new`, `changed`, `unchanged`, `moved`) and `removed`.
formatsYesData sets and bytes per format id.
completeYesTrue when the crawl walked every root to the end. False after a cap (`--max-files`, `--max-seconds`) or an interruption: the tables then hold what was read so far plus the previous run's records for the rest, and rerunning the same command continues.
datasetsYesData sets (rows of `experiments.parquet`) after multi-file grouping.
familiesYesData sets and bytes per family.
problemsYesProblems per category (`integrity`, `readability`, `walk`, `pii`).
settingsYesOptions of the crawl.
index_dirYesAbsolute path of the index directory.
started_atYesWhen this run started (ISO-8601 UTC).
updated_atYesWhen the tables were written.
files_per_sYesItems per second over the crawl's wall time.
check_statusYesData sets per check status.
schema_versionYes[`INDEX_SCHEMA_VERSION`].
unknown_extensionsYesFiles no reader recognises, per lower-case extension (`(none)` for no extension).

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations it discloses the substantive behavioral traits: headers-only scanning, resumability via max_files/max_seconds with complete=false, and the same call resuming an interrupted crawl. This resumption contract is not derivable from the annotations or schema and is exactly what the agent needs. It is consistent with idempotentHint=true and readOnlyHint=false (it writes an index).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then mechanics, then sibling routing; every sentence carries weight. The parenthetical column list is dense but informative. Slightly long, but no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, yet the description still outlines the index contents. Combined with annotations covering safety and idempotency, an agent has everything needed to invoke this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning: it enumerates the per-row fields produced and clarifies the stop-and-continue semantics of max_files/max_seconds. It also implies the roots/index_dir distinction ('never inside a root' contrast). Modest extra value over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Catalog every data set under roots into index_dir') and details the output shape (Parquet, one row per data set). It distinguishes itself from siblings by naming openreadout_search as the query path and openreadout_batch as the alternative for single folders.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It routes the agent explicitly: openreadout_search queries the index, and openreadout_batch should be used for one folder of files instead. It does not state when *not* to index or prerequisites (e.g. permission to write index_dir), but the alternative-tool guidance is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_infoA
Read-onlyIdempotent

What an instrument file or data-set directory holds, from its headers (fast on huge files): format, images[] (sizes, pixel type, µm/px, channels and dyes, objective), tables[], traces[], spectra[] (MS runs), plate, experiment (sample, instrument, method, operator, start) and assurance. view=summary attaches a ~384 px thumbnail of image 0 with full-resolution pixel rulers. ask answers a question in words, naming the fields it used.

NameRequiredDescriptionDefault
askNoA question in plain words ("what was the gradient?", "which channel is DAPI?", "how many MS/MS scans?"): answered under answers[] with the fields each came from. Implies view=explain.
fileYesPath to the file or data-set directory.
kindNoview=structure: list only elements of this kind (as entries_total names them), e.g. "attachment" or "subblock".
viewNoWhat to return. `summary` = the header summary (default); `full` = the summary with per-frame records (time stamps, stage positions, exposure) and per-field provenance; vendor=true adds the vendor's raw metadata tree; `structure` = the container: images, blocks/segments/chunks, attachments (label, thumbnail, previews), pyramid levels, with offsets and sizes; `explain` = a plain-English account with caveats and suggested next steps (ask answers questions); `format` = the format only, from the file's signature (cheapest; works on damaged files).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
vendorNoview=full: include the vendor's raw metadata tree (can be megabytes). Default false.
thumbnailNoview=summary: attach a small picture of image 0 (~384 px, with full-resolution pixel rulers) as image content. Default true; skipped (with a note) when it would decode too much.
max_framesNoview=full: per-frame records per image under images[].extra.frames. Default 100; 0 omits them; -1 embeds all.
max_imagesNoList at most this many images (0 = all). Default: all, except screening plates (16; their field images are all alike and plate.wells[].images indexes every field).
first_entryNoview=structure with kind: skip this many elements of that kind first (paging).
max_entriesNoview=structure: list at most this many elements of each kind (0 = all). Default 50.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, non-destructive), so the bar is lower, and the description still adds real behavior: header-only reads are fast on huge files, view=summary attaches a ~384 px thumbnail with pixel rulers, and it reports the 'assurance' field. It could go further on rate limits or how the server behaves on unsupported formats.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first clause, but the rest is a dense, parenthetical run-on enumerating return fields (images[], tables[], traces[], spectra[], plate, experiment) that partly duplicates the output schema. Given 11 parameters and 5 view modes, some length is justified, but it is not tightly structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, multi-view inspection tool with full schema coverage, annotations, and an output schema, the description supplies the core mental model: header-derived content, view modes, thumbnail behavior, and cheap format detection. Nothing essential for calling it correctly is missing, though the relationship to sibling inspection tools is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and an output schema exists, so the schema carries the parameter burden and 3 is the baseline. The description only lightly adds meaning — roughly that view=summary governs the thumbnail and that ask returns answers with the fields used — while most of the parameter detail lives in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening clause names a specific resource and action: reading what an instrument file or data-set directory holds from its headers. It conveys the 'inspect metadata' role clearly, but it never distinguishes itself from close siblings such as openreadout_check, openreadout_summarize, or openreadout_preview, which an agent must route between.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is implied rather than stated: 'fast on huge files' and 'works on damaged files' hint at when this tool is the right choice, and the view list implies mode selection. However, there is no explicit when-to-use vs when-not, and no routing to any of the many sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_nmr_peaksA
Read-onlyIdempotent

NMR peak list (ppm, height, width, S/N) and integrals of given regions or of every multiplet (auto_integrate), from the vendor's processed spectrum or a spectrum processed from the FID (from=fid: group delay, apodization, zero filling, FT, phase, baseline).

NameRequiredDescriptionDefault
lbNoExponential line broadening in Hz (0 = none; default stored, else 0.3 Hz 1H / 1 Hz other).
fileYesPath to the file or data-set directory.
fromNo`auto` (default: the vendor's processed spectrum if present, else process the FID), `fid` (always process the FID), `processed` (stored spectrum only).
sizeNoTransform size in complex points (power of two).
phaseNo`default` (stored phases, else automatic), `stored`, `auto`, `magnitude`, `none`, or `"P0,P1"` in degrees.
sweepNoRow of a ser/arrayed FID (default 0).
traceNoTrace index (default: chosen by `from`).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
min_snrNoMinimum peak height in noise SDs (default 10).
baselineNoBaseline: `default` (order-1 polynomial), `none`, `poly:N`. Stored spectra are used as stored unless this is given.
negativeNoAlso report negative peaks (DEPT/APT).
integrateNoRegions to integrate, `[[a, b], …]` in ppm.
max_peaksNoKeep at most this many peaks (tallest; default 200).
range_ppmNoOnly pick between two shifts, `[a, b]` ppm.
auto_integrateNoWithout integrate: integrate every multiplet (peaks closer than 15 Hz, ±10 Hz).
min_prominenceNoMinimum prominence in noise SDs (default 5).
integral_referenceNoNormalise integrals so region `[index, value]` has that value (default `[0, 1]`).
min_height_fractionNoMinimum height as a fraction of the tallest point (default 0; e.g. 0.01).

Output Schema

NameRequiredDescription
axisYesThe chemical-shift axis of the spectrum.
pathYesThe input path.
notesNoRemarks.
peaksYesPeaks, high shift first.
sweepYesSweep (row) used.
traceYesTrace used (see `info` → `traces[]`).
formatYesFormat id.
sourceYes`processed` (a spectrum the vendor software stored) or `fid` (processed here).
nucleusNoObserved nucleus, when known.
noise_sdYesRobust noise standard deviation (same units as `height`).
integralsNoIntegrals of the requested regions.
main_peakNoThe tallest positive peak (named like `analyze peaks` → `main_peak` for chromatograms).
peak_countYesNumber of peaks found.
processingNoHow the FID was processed (`source` = `fid` only).
trace_nameNoIts name.
peak_optionsYesThresholds used.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: the FID processing chain it will apply (group delay, apodization, zero filling, FT, phase, baseline) and the fact that a stored spectrum is used as-is unless processing is requested. It stops short of stating permissions or failure behavior, but this is solid added context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with the primary output (peak list) front-loaded and the processing options parenthesized after. No wasted words, though the nested parentheses make it harder to parse at a glance than a two-sentence split would.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and 100% schema coverage, the description need not explain return values or parameter details; it correctly focuses on scope and the processing modes. The one gap is the absence of any differentiation from the sibling openreadout_peaks, which an agent needs for correct tool selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 18 parameters, including defaults and enumerated string values. The description echoes only two of them (from=fid, auto_integrate) without adding syntax or constraints beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (NMR peak list plus integrals) and enumerates the returned quantities (ppm, height, width, S/N), so an agent knows exactly what it gets. However, it never distinguishes itself from the closely named sibling openreadout_peaks (or openreadout_spectrum), leaving ambiguity about which tool to pick for generic vs NMR-specific peak extraction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage contexts via 'from the vendor's processed spectrum or a spectrum processed from the FID (from=fid ...)' and 'integrals of given regions or of every multiplet (auto_integrate)', which hints at the two operating modes. But it gives no explicit when-to-use/when-not guidance and never names an alternative tool, so the agent must infer the routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_peaksB
Read-onlyIdempotent

Detect and integrate peaks: chromatograms (detector traces, TIC, XIC, SRM) with retention time, area, height, widths, tailing, plates, resolution, S/N and area % (purity); one peak near rt; a compound list; bands and regions of IR, Raman, UV-Vis and NMR spectra and peaks of sized electropherograms in bp (x_range, integrate). Takes the openreadout_chromatogram arguments to choose the signal.

NameRequiredDescriptionDefault
daNoXIC tolerance in m/z units instead of ppm.
mzNoExtracted-ion chromatograms at these m/z values (one streaming pass for all).
rtNoExpected retention time (minutes): also report the peak there as `picked`.
bpcNoBase-peak chromatogram.
ppmNoXIC tolerance (half-width) in ppm. Default 10.
runNoSpectra run. Default 0.
ticNoTotal-ion chromatogram (the default for mass-spectrometry files when nothing else is chosen).
fileYesPath to the file or data-set directory.
pickNo`largest` (default) or `nearest` peak in the window.
sweepNoSweep of the traces (one spectrum of a map or series, one injection). Default 0.
smoothNoSavitzky–Golay window in points (below 5: none). Default automatic.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
tracesNoStored chromatograms or detector signals (UV/DAD, FID, TCD, stored TIC/SRM): trace indices from openreadout_info → traces[].
windowNoHalf-width of the `rt` window (and of compounds without one), minutes. Default 0.5.
channelNoChannel of the traces (e.g. one DAD wavelength). Default: the first signal channel.
min_snrNoDetection threshold, height / noise σ. Default 3.
profileNoUse profile data where scans store both profile and centroids. Default false (the instrument's centroids).
x_rangeNoAxis windows `[[a, b], ...]` to integrate, in the axis's own units (either order): on a spectrum (IR/Raman cm⁻¹, UV nm, NMR ppm) each is a region under `spectra[].regions` (area with the `baseline`, area without it, maximum, centroid, the bands inside); on a chromatogram a manual integration in minutes.
baselineNoBaseline under detected peaks: `auto` (default), `drop`, `valley` or `tangent`; or the baseline under `x_range` windows and manual integrations: `linear` (default: a straight line between the window's ends) or `none` (area of the signal itself).
ms_levelNoMS level of the scans. Default 1 (2 with `precursor`).
mz_rangeNoTIC/BPC over this m/z range only, `[low, high]`.
polarityNo`positive` or `negative`: only scans of this polarity.
rt_rangeNoRetention-time range `[start, end]`, minutes.
aggregateNo`sum` (default) or `max` of the points inside an XIC window.
compoundsNoTargeted compounds: `[{name, mz? | q1+q3? | trace?, rt?, window?, ppm?, polarity?, ms_level?, precursor?}]`; one result row each under `compounds`.
integrateNoManual integrations `[[start, end], ...]` in minutes.
min_widthNoSmallest width at half height, minutes.
precursorNoOnly MS/MS scans of this precursor m/z (product-ion XIC).
min_heightNoDetection threshold in signal units.
scan_filterNoOnly scans whose scan filter/description contains this text (case-insensitive).
transitionsNoSRM/MRM transitions as `"Q1>Q3"` strings, e.g. `"279.2>179.2"`.
area_secondsNoAreas in signal × seconds instead of signal × minutes. Default false.
summary_onlyNoLeave out the full peak tables (keep compounds, picked and manual results). Default false.
precursor_tolNoPrecursor tolerance, m/z units. Default 0.5.
transition_tolNoQ1/Q3 tolerance of transitions, m/z units. Default 0.5.

Output Schema

NameRequiredDescription
pathYesThe input file.
notesNoAnything the caller should know.
formatYesFormat id of the input file.
outputsNoFiles written (`-o`, `--plot`).
spectraNoSpectra (traces whose axis is not time: wavenumber, wavelength, ppm, …): bands and integrated regions, one entry per analysed spectrum.
compoundsNoOne row per compound of the compound list.
chromatogramsYesOne entry per analysed chromatogram.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile is covered. The description adds genuine scope context (which instruments/domains it applies to and that signal selection mirrors openreadout_chromatogram), but much of the rest is a recitation of returned quantities that the output schema already carries, and it says nothing about errors, caveats, or cost for a 35-parameter call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Appropriately sized for a 35-parameter tool and front-loaded with the core verb phrase, but it is a single run-on sentence stitched together with semicolons and nested parentheses, which makes the modality-by-modality enumeration hard to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema documenting returns, 100% schema coverage, and annotations carrying the safety profile, the description is nearly sufficient: it establishes scope across chromatography, spectroscopy and electrophoresis. The main remaining gap is sibling disambiguation (openreadout_nmr_peaks, openreadout_chromatogram) that an agent needs in order to pick the right tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% across 35 parameters, so the baseline is 3 and the schema does the heavy lifting. The description only names a handful of parameters (x_range, integrate, rt) and cross-references openreadout_chromatogram for signal selection; it adds no tolerance, unit, or default semantics beyond what is already in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Detect and integrate peaks') and then enumerates the exact data types handled (detector traces, TIC, XIC, SRM, IR/Raman/UV-Vis/NMR bands, electropherogram peaks in bp) plus the reported quantities. This is well beyond a tautology. It does not, however, differentiate itself from the close sibling openreadout_nmr_peaks, which plausibly overlaps the NMR/spectral case.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the enumeration of applicable modalities tells the agent what kinds of inputs qualify, and 'Takes the openreadout_chromatogram arguments to choose the signal' links it to a sibling for signal selection. There is no explicit when-to-use / when-not-to-use statement and no routing away from openreadout_nmr_peaks or openreadout_chromatogram.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_plotA
Read-onlyIdempotent

A finished figure from lab files in one call, as image content plus what was drawn (series, data read, ranges, units, marked peaks). Name data by file and selector, never by pasting numbers: traces and sweeps, chromatograms (TIC, XIC) and the spectrum at an rt or the TIC apex, plate wells by range or layout group (curves per well, or mean ± spread per group), FCS dot plots coloured by gate population and histograms, f–I curves, dose-response and standard-curve fits, a table file's columns (openreadout_batch output); small inline values are allowed. Several files overlay; facet=series gives small multiples, facet=plate plate positions; panels side by side; annotate with bands, lines, labelled points, arrows. Draws only; openreadout_export saves the figure.

NameRequiredDescriptionDefault
xNoThe x axis.
yNoThe y axis.
dataNoWhat to draw: one series spec or a list of them, drawn in order (first at the back).
fileNoThe file of every series here that names no file, table or values. Alone, without `data`, it draws the file's default view.
facetNoSmall multiples: `series` = one small plot per series (sweeps, files, groups, wells); `plate` = plate wells in their plate positions.
shareNoPanels that share an axis range. Default none.
stackNoOffset each series upward by this fraction of the tallest one (stacked spectra).
themeNoColour scheme. Default light.
titleNoTitle over the figure.
widthNoWidth in px (default 1200, at most 3000).
heightNoHeight in px (default from the content, at most 3000).
legendNoHow series are named: `direct` labels at the line ends, a `key` row, or `none`. Default direct when it fits, else key.
panelsNoSeveral panels, side by side (see columns); instead of a top-level `data`.
strictNotrue: refuse values this file's assurance does not validate (exit_code 6, with a hint).
captionNoSmall print under the figure (a source credit, a method note).
columnsNoPanels (or facets of a single panel) per row. Default: all panels in one row; facets in a near-square grid.
annotateNoBands, lines, labelled points, arrows, boxes and notes, in the units the axes show: the same annotations as openreadout_preview (`facet` picks one small plot).
row_labelsNoRow headings of a plate facet, top to bottom. Default: the layout group of each block of rows, else the row letters.
column_labelsNoColumn headings of a plate facet (e.g. doses), left to right.

Output Schema

NameRequiredDescription
saveNoHow to save this figure to a file (MCP: the openreadout_export call).
filesYesFiles the data came from.
notesNoWhat was done to the data (subtractions, fits, transforms).
themeYes`light` or `dark`.
titleNoFigure title.
widthYesPicture size in px.
heightYesPicture size in px.
panelsYesOne entry per panel.
warningsNoData that could not be drawn as asked, or values to double-check.
inline_seriesYesSeries drawn from inline values (numbers the caller supplied, not read from a file).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered; the description adds real workflow context: the tool returns image content plus a record of what was drawn, and it will not persist anything (export is needed to save). The 'never paste numbers' rule is extra behavioral guidance beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is well front-loaded, but the middle is one very long run-on sentence listing every drawable data type with semicolons, which is hard to scan. Each clause carries information, yet the structure could be split or bulletted for the same content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 19-parameter tool with full schema coverage, annotations, and an output schema, the description covers the capability envelope, the draw-vs-save boundary, faceting/panels, and annotation support. Minor schema-level details (size caps, strict mode) are left entirely to the schema, which is acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds a conceptual map of the selector space (file+selector by data family) and the important rule that values must be referenced by file/selector rather than pasted, which is semantic guidance the schema does not state outright.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('a finished figure from lab files in one call') and enumerates exactly the data families it can draw (traces, chromatograms, plates, FCS, dose-response, tables). It explicitly routes the agent apart from siblings by naming what it does not do ('Draws only; openreadout_export saves the figure') and by relating itself to openreadout_preview.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete selection rule ('Name data by file and selector, never by pasting numbers' with inline values as the exception) and names the alternative tool for a related task (openreadout_export for saving). It does not, however, explicitly state when to choose this over openreadout_preview, which also draws.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_previewA
Read-onlyIdempotent

A picture of the data as image content plus what was drawn: an image plane (default channel 0, middle z), a composite, a max projection (mip=z), a region (only the tiles needed are read), a trace or spectrum plot (largest peaks labelled; marks=spikes marks action potentials; x_range zooms), a Sanger chromatogram with base calls and quality or a sized electropherogram with the ladder, a plate heat map or, for kinetic reads, per-well growth curves coloured by layout group, or a flow-cytometry density plot. Image pictures carry rulers in full-resolution pixels and a µm scale bar, so a region read off the rulers zooms in. annotations draw your own labelled points, boxes, outlines, arrows, lines and bands in the picture's coordinates, to show the user what you found. Draws only; openreadout_export saves the picture.

NameRequiredDescriptionDefault
fftNoImages: a power-spectrum (FFT) inset in the top-right corner: Thon rings of a cryo-EM micrograph, the spots of a lattice.
lutNoColour lookup. Default: gray for one channel (inverted on diffraction images), channel colours for composites. `gray` = black to white; `channel-color` = black to the channel's colour; `inverted` = white to black: dark marks on a light ground (diffraction images).
mipNoMaximum-intensity projection, over the selected range if any. `z` = along z (focal planes); `t` = along t (time points).
runNoSpectrum preview: run index.
sumNoSum projection, over the selected range if any: a movie's frames added up (e.g. sum t, select t=0-39). `z` = along z (focal planes); `t` = along t (time points).
axesNoImage previews: what frames the picture. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `scale-bar` = a figure for people: the picture with a scale bar, the title and the caption; no rulers; `none` = the bare downsampled plane.
darkNoDraw in the dark theme.
fileYesPath to the file.
scanNoSpectrum preview: instrument scan number instead of an index.
viewNoVolumes: the plane to show. `axial`, `coronal`, `sagittal` (radiological orientation), `orthogonal` (all three, crossing at the middle or the selected z), `xz`, `yz`, or `native` (as stored). Default: medical images in their acquisition plane, others native. With a view, `z` and `mip: z` count slices of that view. `native` = the planes as stored; `axial` = head-foot slices, patient's left on the right, anterior up; `coronal` = front-back slices, patient's left on the right, head up; `sagittal` = left-right slices, anterior on the left, head up; `orthogonal` = axial, coronal and sagittal planes through the volume's centre (or the selected z); `xz` = columns against z: a cut along the stack; `yz` = rows against z: a cut along the stack.
imageNoImage index (default 0).
lanesNoGels and blots: how lanes are found for `marks: lanes` (as `openreadout_stats` lanes).
levelNoPyramid level to read (default: the level nearest max_size, or the level at which `region` renders at about max_size).
marksNoMarks from the data. Default auto: the prominent peaks of spectra and chromatograms are labelled; diffraction images get resolution rings. `auto` = label the largest peaks of spectra and chromatograms (default); `peaks` = label the largest peaks of any trace; `spikes` = mark the action potentials of current-clamp sweeps; `objects` = images: outline and number the nuclei, cells or spots found (`stats` objects); `lanes` = gels and blots: box and number the lanes, draw their profiles and bands (`stats` lanes); `rings` = diffraction images: resolution rings and the beam centre (auto draws them when the geometry is known); `none` = no marks.
sweepNoTrace preview: sweep index.
tableNoPlate or flow-cytometry preview: table index.
titleNoImage previews with axes scale-bar: a title above the picture.
traceNoTrace preview: trace index (see openreadout_info traces[]).
formatNoEncoding. Default png (sent as JPEG when a PNG would be too large); svg also returns the vector drawing as text. `png` = lossless (default); `jpeg` = lossy and smaller; `svg` = vector: text stays text, image data is embedded as PNG.
regionNoZoom: only this rectangle, `{x, y, width, height}` in full-resolution pixels (or in the pixels of `level` when a level is given). Whole-slide images: look at the overview first, then at regions of it.
selectNoPlane selection such as `c=1`, `z=4`, `t=0` or combined `c=0,1,z=2`. Default: c=0, the middle z, t=0. Several channels imply a composite.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
captionNoImage previews with axes scale-bar: a caption under the picture (what it shows, the stain, the sample).
columnsNoTable columns: a plate's value column, or the x and y parameters of a flow-cytometry density plot (one gives a histogram; default FSC-A, SSC-A).
objectsNoImages: how objects are found for `marks: objects` (as `openreadout_stats` objects).
x_rangeNoTrace preview: only this window of the x axis, `[a, b]` in its units (bp of a sized electropherogram, base positions of a Sanger read, minutes, ppm, …).
centroidNoSpectrum preview: the instrument's centroid list instead of the profile.
channelsNoTrace preview: channel indices (default: the first 8).
contrastNo`auto` (default; the file's display window when it has one, `log:90,99.95` on diffraction images), `min-max`, `percentile:LO,HI` (e.g. `percentile:1,99`), `log` (`log:50,99.9`) or `log:LO,HI`, `raw`, or a display window `window:CENTER,WIDTH` (`window:40,400`), `window:file`, or a CT preset `window:soft-tissue`, `brain`, `subdural`, `stroke`, `bone`, `lung`, `mediastinum`, `liver`.
max_sizeNoLongest side in pixels, rulers included (MCP: default 768, at most 2048).
spectrumNoSpectrum preview: zero-based spectrum index.
compositeNoBlend all (or the selected) channels additively in their colours.
annotationsNoYour own marks, drawn on top and reported back with their pixel positions. Coordinates as the picture shows them: full-resolution pixels on images (the ruler numbers), axis units on plots, wells on plates.

Output Schema

NameRequiredDescription
hintNoWhat to do next with the picture (look at it; zoom with a region read off the rulers).
kindYes`image`, `trace`, `chromatogram`, `spectrum`, `plate` or `events`.
pathYesThe input file.
saveNoHow to save this picture to a file (MCP: the openreadout_export call).
xxh3Yesxxh3-128 of the encoded bytes, 32 hex chars (identical across runs for the same request).
bytesYesSize of the encoded image.
imageNoPresent for image previews.
lanesNo`marks: lanes`: the lanes and bands found in the area shown, as `stats` lanes.
marksNoMarks drawn from the data (labelled peaks, action potentials).
notesNoAnything the caller should know (fallbacks, caps, implied options).
plateNoPresent for plate previews.
traceNoPresent for trace previews.
widthYesImage width in pixels.
eventsNoPresent for event previews.
formatYesFormat id of the input file.
heightYesImage height in pixels.
outputNoThe written file (CLI); absent when the preview is returned inline (MCP image content).
panelsNoPlot panels (traces, spectra, plate curves, events): where each sits in the picture and the data range it shows.
objectsNo`marks: objects`: the objects counted in the area shown, as `stats` objects (the first 20 listed).
encodingYes`png`, `jpeg` or `svg`.
spectrumNoPresent for spectrum previews.
verifiedYesTrue once a written file was read back and matched.
annotationsNoThe caller's annotations as drawn: each as given, plus where it landed in PNG pixels.
chromatogramNoPresent for chromatogram previews (a mass-spectrometry run's total-ion chromatogram).

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/destructive=false, so the safety profile is covered. The description adds real behavioral context beyond that: images carry rulers in full-resolution pixels plus a µm scale bar, a region read off the rulers zooms in, and annotations are 'drawn on top and reported back with their pixel positions.' That the tool only draws (never writes files) is also usefully disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is buried in a single enormous run-on sentence that enumerates every picture modality; nothing is front-loaded, and several clauses ('region ... only the tiles needed are read', 'x_range zooms') simply repeat structured schema content. It is information-dense but structurally weak, so it is neither wasteful enough for a 2 nor clean enough for a 4.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 33-parameter, multi-modal tool with an output schema and annotations already present, the description covers the modality space, the drawing-only scope, and coordinate conventions well. Return-value detail is rightly left to the output schema, so the remaining gap is minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3; the description still adds cross-parameter meaning beyond the schema — the default plane ('channel 0, middle z'), that mip=z is a max projection, that marks=spikes marks action potentials, that x_range zooms the axis, and that a region taken from the rulers zooms in. Much of this is restated from the schema, keeping it out of the top band.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource (draws a picture of the data as image content) and enumerates the exact picture types it produces across modalities. It also explicitly distinguishes itself from a sibling: 'Draws only; openreadout_export saves the picture,' so an agent can tell preview from export without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternative that matters most (openreadout_export for saving) and gives the selecting condition ('Draws only'). It also frames the use case ('annotations ... to show the user what you found'), but never differentiates itself from other rendering-adjacent siblings such as openreadout_plot or openreadout_chromatogram, so guidance is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_qpcrA
Read-onlyIdempotent

Real-time PCR (RDML, .eds, .rex, ...): one record per well and target with sample, task, Cq and Tm; compute_cq recomputes Cq, ddcq gives 2^-ΔΔCq fold changes, standard_curve fits efficiency per target.

NameRequiredDescriptionDefault
runNoOnly this run.
ddcqNoΔΔCq relative quantification (rows: one per sample × target).
fileYesPath to the file or data-set directory.
wellNoOnly this well (`A1`).
fieldsNoRows show their main fields to 4 significant digits (records: well, sample, target, cq, tm; relative_quantities: cq means, delta_cq, delta_delta_cq, rq with rq_min and rq_max). fields adds others, e.g. `["threshold"]`; `["all"]`: every field, full precision.
sampleNoOnly this sample, case-insensitive.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
targetNoOnly this target, case-insensitive.
cq_methodNoHow `compute_cq` computes Cq; default: `second-derivative` for LightCycler 480 `.ixo` files without a threshold or baseline window, else `threshold`. `threshold` = Where the baseline-corrected curve crosses a threshold; `stored-threshold` = A threshold crossing with only the threshold and baseline the file stores; `second-derivative` = The maximum of the second derivative, as the LightCycler 480 places its Cp.
thresholdNoThreshold for `compute_cq`.
compute_cqNoAlso compute our own Cq.
max_recordsNoAt most this many records (default 500).
baseline_endNoBaseline window for `compute_cq`, last cycle.
baseline_startNoBaseline window for `compute_cq`, first cycle.
control_sampleNoΔΔCq control (calibrator) sample; default: the file's.
standard_curveNoStandard curve per target (rows: one per target).
undetermined_cqNoCq for undetermined results in means and ΔΔCq; default: left out and counted.
reference_targetsNoΔΔCq reference targets; default: the file's.

Output Schema

NameRequiredDescription
pathYesThe input file.
notesYesWhat to keep in mind.
cyclesNoNumber of PCR cycles in the program.
formatYesFormat id.
dialectYesDialect (`rdml`, `eds-sds`, `eds-7500`, `eds-json`, `rex`).
recordsYesThe records.
targetsYesPer target: counts by Cq status and the mean Cq without the undetermined results.
cq_countsYesCq statuses over every record that matches the filters (not cut by `max_records`).
truncatedYesTrue when `max_records` cut the list.
experimentNoExperiment or run name.
instrumentNoInstrument model.
record_countYesRecords matching the filters.
cq_comparisonNoOur Cq against the vendor's (with `compute_cq`).
control_sampleNoControl (calibrator) sample used or recorded.
standard_curvesNoStandard curves (with `standard_curve`).
undetermined_cqNoCq used for undetermined results in the aggregates, when the request gave one.
reference_targetsYesReference targets used or recorded (endogenous controls).
relative_quantitiesNoΔΔCq results (with `relative`).
acquisition_temperature_cNoTemperature of the step that reads fluorescence during cycling (the annealing / extension temperature of a two-step PCR), °C.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and a closed world, so the safety profile is fully covered without the description. The description adds output-format context (one record per well and target; 2^-ΔΔCq; per-target efficiency) but says nothing about permissions, rate limits, or failure behavior beyond what annotations give.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence, front-loaded with the assay type and file formats, then the record structure and the three mode flags. Nothing is wasted, though the mode list is crammed into one clause that would read better as a short enumeration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and annotations carry the safety profile. For an 18-parameter tool the description still conveys the core analysis modes and record shape; the only real gap is that it does not say when to prefer ddcq versus standard_curve or when compute_cq should be enabled.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 18 parameters (including the cq_method enum values and every analysis flag). The description restates compute_cq, ddcq and standard_curve at a high level but adds no syntax or semantics beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific domain (real-time PCR), the supported file formats (RDML, .eds, .rex), and the output granularity (one record per well and target with sample, task, Cq and Tm). That is clear enough to distinguish it from the other domain-specific siblings, but it never explicitly names an alternative or positions itself relative to them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what the three analysis modes do (compute_cq recomputes Cq, ddcq gives 2^-ΔΔCq fold changes, standard_curve fits efficiency), which implicitly tells the agent when each flag is relevant. However it gives no explicit when-to-use guidance, no prerequisites, and no routing away from sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_reportB
Idempotent

A privacy-reviewed diagnostic bundle for a file that is refused, fails or is not validated, for a new-variant issue: no data values, free text only with include_text, and the issue_url to file it at. Nothing is sent; the user files it.

NameRequiredDescriptionDefault
fileYesThe file (or data-set directory) that is refused, fails or is not validated.
outputNoAlso write the bundle to this new local file. Default: only return it.
include_textNoKeep free text from the file (sample, image and channel names, comments); the path and personal data are still replaced. Default false: only with the user's consent.

Output Schema

NameRequiredDescription
bytesNoSize of the written bundle.
outputNoWhere the bundle was written; `None` with `--dry-run` (or from MCP without `output`).
reportYesThe bundle, exactly as written.
issue_urlYesWhere to file it (never contacted by the program).

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, openWorldHint=false, idempotentHint=true, destructiveHint=false), the description discloses meaningful behavior: 'Nothing is sent; the user files it' confirms no network transmission, 'privacy-reviewed' signals a sanitization step, 'no data values' states the data-minimization posture, and the include_text mention ties free-text retention to consent. These add real context an agent would not infer from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single compact sentence, which is good, but the structure is a run-on with multiple colons and an ambiguous clause ('for a new-variant issue: no data values, free text only with include_text') that forces re-reading. Front-loading the bundle concept is fine; the rest is dense rather than efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description covers the operative context for this tool: the trigger condition, the privacy/consent behavior, and the fact that nothing is transmitted. An agent could call it correctly; only the missing verb and confusing 'new-variant issue' phrasing leave minor ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents file, output and include_text with descriptions, making the baseline 3. The description only restates the include_text consent rule and references 'the issue_url to file it at' (an output field, not a parameter), adding no parameter syntax or format detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the deliverable (a 'privacy-reviewed diagnostic bundle') and its trigger ('a file that is refused, fails or is not validated'), so the resource is identifiable, but it never states a verb like 'produce' or 'write' and the colon-laden phrasing ('for a new-variant issue: no data values, free text only...') muddies what the tool actually does. No sibling is named or differentiated, though the purpose is distinctive enough to stand apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a usable trigger condition — use it when a file is refused, fails validation, or is a 'new-variant issue' — which is better than nothing. However, it names no alternative sibling (e.g. openreadout_check or openreadout_info) and gives no when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_scansA
Read-onlyIdempotent

The scans of a mass-spectrometry run, without decoding peaks: scan number, MS level, retention time, polarity, precursor m/z and charge, isolation window, activation, collision energy, filter, stored TIC; filtered and paged, and every match counted (matched, ms_level_counts). IR, Raman, UV-Vis and NMR spectra are traces: openreadout_trace.

NameRequiredDescriptionDefault
runNoRun index for files with several runs (Sciex samples; default 0).
fileYesPath to the mass-spectrometry file.
countNoOnly count the matching scans (matched, ms_level_counts); list none.
limitNoList at most this many matching scans (default 100, at most 5000); all are counted.
chargeNoOnly precursors of this charge state.
offsetNoSkip this many matching scans (paging; default 0).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
ms_levelNoOnly scans of this MS level (1 = full scans, 2 = MS/MS).
polarityNoOnly `positive` or `negative` scans.
rt_rangeNoRetention-time window `[start, end]` in minutes.
precursorNoOnly MS/MS scans whose precursor m/z is within the tolerance of this.
activationNoOnly this activation: HCD, CID, ETD, ... (case-insensitive).
scan_filterNoOnly scans whose filter string contains this text (case-insensitive).
precursor_ppmNoPrecursor tolerance in ppm instead.
precursor_tolNoPrecursor tolerance in m/z units (default 0.01).

Output Schema

NameRequiredDescription
runYesRun index.
pathYesThe input file.
scansYesThe listed scans, in spectrum-index order.
filterNoThe conditions applied (omitted when every scan is listed).
formatYesFormat id of the input file.
offsetYesPosition of the first listed scan among the matching ones (0-based; `--offset`).
sourceYes`headers` when the reader listed scan headers without decoding peaks, `spectra` when every spectrum had to be decoded to list it.
matchedYesScans matching the conditions (all of them are counted, not only the page listed).
returnedYesNumber of scans listed.
truncatedYesTrue when more matching scans follow the page (`offset + returned < matched`).
rt_range_sNoRetention-time range of the matching scans in seconds.
scan_countYesSpectra in the run.
ms_level_countsYesCounts of the matching scans per MS level (`"1"`, `"2"`, ...).

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive, so the safety profile is covered. The description adds useful behavior beyond that: it lists the exact fields returned, notes that results are filtered/paged, and discloses that every match is counted (matched, ms_level_counts) even when paging. No auth or rate-limit context, hence not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with semicolons, front-loaded with the resource and field list before the routing note. Every clause carries information (fields, filtering/paging, counting, sibling routing), though the field enumeration makes it heavier than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not required, and the annotations carry the safety profile. For a 15-parameter filtered-list tool, the description supplies the resource scope, the returned fields, and sibling routing, leaving only minor gaps like prerequisites or run semantics that the schema covers.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all 15 parameters thoroughly (rt_range, precursor_tol, strict, count, limit, etc.). The description only summarizes 'filtered and paged' and the counting behavior; it adds no parameter syntax or format detail beyond the schema. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('scans of a mass-spectrometry run') and immediately scopes it with 'without decoding peaks', enumerating the fields it returns. It also distinguishes itself from openreadout_trace by naming the modalities (IR, Raman, UV-Vis, NMR) that belong to the sibling, so an agent can tell the two apart without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear routing: this tool is for MS scans, and the final sentence directs the agent to openreadout_trace for IR/Raman/UV-Vis/NMR. 'Without decoding peaks' implies openreadout_peaks is the alternative for peak data. There is no explicit when-not statement, but the alternative is named, which is strong guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_spectrumA
Read-onlyIdempotent

One mass spectrum, picked by retention time (rt, minutes: the scan nearest it), scan number or zero-based spectrum index: metadata, peaks[] (the most intense, with charge from the isotope spacing and neutral mass) and mz[]/intensity[].

NameRequiredDescriptionDefault
rtNoThe MS scan (of ms_level, default 1) nearest this retention time, minutes: the spectrum at a chromatogram's apex.
runNoRun index for files with several runs (Sciex samples; default 0).
fileYesPath to the mass-spectrometry file.
scanNoThe scan number as the instrument counts it (1-based in Thermo files; mzML `scan=N` native ids, mzXML `num`, timsTOF spectrum position + 1).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
centroidNoThe stored centroid list instead of the profile when a scan has both.
ms_levelNoCount spectrum among the spectra of this MS level only (1 = full scans, 2 = MS/MS). MS1 and MS/MS scans interleave, and ms_level=2 with spectrum=0 is the first MS/MS scan.
spectrumNoThe zero-based spectrum index, counted within ms_level when it is given.
lock_massNoWaters .raw: correct m/z with the lock-spray reference scans, given the lock compound's m/z (e.g. 556.2771), or "auto" for the Lock Mass the file records. Default: m/z as stored.
top_peaksNoMost intense peaks listed under peaks[] with charge and neutral mass (default 20).
max_pointsNoAt most this many points, the most intense kept (default 1000; point_count reports the full size).

Output Schema

NameRequiredDescription
runYesRun index the spectrum belongs to.
pathYesThe input file.
viewYes`primary` (profile when recorded) or `centroid` (the instrument's centroid list).
peaksNoThe most intense peaks of the whole spectrum, with charges from their isotope patterns.
formatYesFormat id of the input file.
spectrumYesThe spectrum, with its arrays.
truncatedYesTrue when `mz`/`intensity` were shortened to `max_points` (the most intense points are kept, in m/z order).
point_countYesNumber of points in the full spectrum (the arrays may be shortened by `max_points`).

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, openWorldHint=false and destructiveHint=false, so the safety profile is fully covered. The description adds little beyond structured fields: the 'nearest scan' rt behavior and the peak/charge/neutral-mass output details are already in the schema and output schema respectively. No mention of errors, cost, or the strict/exit_code 6 refusal behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence, front-loaded with the resource and the selection keys before listing outputs. It is run-on and packs three selectors plus output shape into one clause, but every element earns its place and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, and with 100% schema coverage the parameters are covered. It adequately frames the selection keys and the shape of the result for a read-only single-record tool; only alternative-routing guidance is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 11 parameters in detail (rt, run, scan, spectrum, ms_level, top_peaks, max_points, etc.). The description restates only rt, scan and spectrum and adds no format or default semantics beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource ('One mass spectrum') and the three mutually exclusive selectors (retention time, scan number, zero-based spectrum index), which is enough to distinguish it from siblings like openreadout_chromatogram, openreadout_scans and openreadout_peaks. An agent can tell what it retrieves and how to address the target without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: read a single spectrum when you can name it by rt, scan or index. There is no explicit when-to-use / when-not-to-use guidance and no routing to alternatives such as openreadout_scans (enumerate scans) or openreadout_peaks (peak lists), so the agent must infer the boundaries.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_spikesA
Read-onlyIdempotent

Extracellular spike detection per channel: band-pass, threshold at K x MAD noise, spike counts, rates and times.

NameRequiredDescriptionDefault
fileYesPath to the file or data-set directory.
signNo`neg` (default), `pos` or `both`.
traceNoTrace index (default 0; pick the broadband stream).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
sweepsNoSweeps/segments (default all).
band_hzNoBand-pass `[low, high]` Hz (default [300, 6000]).
channelsNoChannels (default all).
max_timesNoSpike times per channel returned (default 200).
thresholdNoThreshold in MAD noise units (default 5).
max_secondsNoOnly the first N seconds of each sweep.

Output Schema

NameRequiredDescription
pathYesInput path.
notesNoRemarks.
traceYesTrace analysed.
formatYesFormat id.
sweepsYesSweeps analysed.
channelsYesOne entry per channel.
settingsYesSettings used (the high edge after clamping to 0.45 × the sampling rate).
sample_rate_hzYesSampling rate, Hz.
spike_count_totalYesSpikes on all channels.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent and non-destructive behavior, so the bar is low; the description still adds real value by disclosing the processing pipeline (band-pass, K x MAD thresholding) and the outputs produced (counts, rates, times). It does not mention cost, data-size limits, or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that names the domain first and then enumerates the pipeline stages and outputs. No filler, no restatement of the title or name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema and complete annotation set, the description only needs to frame the computation, which it does. The main residual gap is the absence of any statement about prerequisites (e.g. broadband trace selection, assurance/strict validation) that an agent would need before calling it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with 10 well-documented parameters, so the schema already carries parameter meaning. The description echoes band-pass, threshold and time outputs but adds no syntax, units or default information beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Extracellular spike detection per channel') plus the algorithm used, so an agent knows exactly what computation is performed. It contrasts implicitly with generic siblings like openreadout_peaks by naming the extracellular-spike domain, but never names an alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the domain phrase 'extracellular spike detection per channel' plus the mention of picking a broadband stream, which tells the agent the expected input. There is no explicit when-to-use/when-not guidance and no routing to sibling tools such as openreadout_peaks or openreadout_ephys_features.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_statsA
Read-onlyIdempotent

Pixel statistics per channel and image: count, min, max, mean, std, percentiles p1–p99, zero and saturated fractions (at the detector's 2^bits−1 when recorded), histogram; RGB images also per component. per=plane adds every plane; per=well or field gives rows per well of a screening plate. mip='z' measures the maximum-intensity projection; whole slides: a coarser level and/or a region. Measurements on one plane: line (intensity profile, FWHM), polygon (statistics inside), objects (count nuclei, cells or spots; preview marks=objects shows them), lanes (gel and blot lanes, band volumes and sizes; preview marks=lanes).

NameRequiredDescriptionDefault
mipNoMaximum-intensity projection first: `z` (per image, channel and time point: the largest value of each pixel over the selected z planes) or `t`; the statistics are of the projections. `z` = Along z: one projected plane per image, channel and time point; `t` = Along t: one projected plane per image, channel and z.
perNoRows. `channel` = channel and image aggregates (default); `plane` = also one entry per plane (image, c, z, t); `well` = a screening plate (pass the plate folder or index, never one TIFF): one row per well × channel over the well's fields; `field` = a screening plate: one row per well × field × channel.
binsNoHistogram bins (0 = none). Default 32, at most 65536.
fileYesAbsolute or working-directory-relative path to the instrument file, or a plate's index file or folder (Harmony `Index.idx.xml`, ImageXpress `.HTD`, CellVoyager `MeasurementData.mlf`, OME-Zarr plate).
lineNoIntensity profile along the line `[x0, y0, x1, y1]` (pixels of `level`, as on the preview rulers): values per channel, peak position and FWHM in px and µm.
imageNoOnly this image index.
lanesNoLanes and bands of a gel or blot in `region` or the whole plane: each lane's total and each band's row and background-subtracted volume (with `ladder`, its size). `{}` finds the lanes; preview marks=lanes draws them.
levelNoPyramid level: 0 = full resolution (default).
scaleNoHistogram spacing: `linear` (default) or `log`. `linear` = Equal-width bins from `min` to `max` (integer data: to `max + 1`, so each bin holds whole values); `log` = Geometrically spaced bins from the smallest positive value to `max`; values ≤ 0 are counted in `nonpositive`. Suited to data spanning decades (photon counts, spectra).linear
wellsNoper=well|field: only these wells (`C05`, `c5`).
regionNoOnly this rectangle of each plane, `{x, y, width, height}` in the pixel coordinates of `level` (e.g. the 512 x 512 centre of a whole-slide image).
selectNoPlane selection strings such as `c=0`, `z=2-5`, `t=0,3`. The aggregates cover exactly the selection.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
objectsNoCount objects in `region`, `polygon` or the whole plane: count, density, sizes, centroids, each object's mean in every channel and how many are positive per channel. `{}` counts nuclei with settings taken from the image (size, threshold, H&E colour deconvolution). Found in a DNA-stain channel unless `select` names one.
polygonNoStatistics inside this polygon `[[x, y], ...]` (pixels of `level`): area, mean, std, median, sum per channel.
line_widthNoProfile width in pixels, averaged across the line. Default 1.

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the read-only/idempotent/non-destructive profile, so the bar is lower, and the description still adds real behavior: 'strict ... refuses values the file's assurance does not validate (exit_code 6)', that 'the counts cover all' objects while only max_objects are listed, and that with a ladder 'bands then get sizes'. No rate limits, cost, or failure modes beyond exit_code 6 are described.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a single very long run-on passage with semicolon-separated clauses and no structure, so the key 'what it computes' idea competes with a dense feature dump. Nothing is truly wasted, but it is not front-loaded by importance and is hard to scan, which weakens selection speed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter tool this is a thorough description: it covers the output statistics, every measurement mode, projection and pyramid handling, plate/slide scoping, and selection semantics. With annotations and an existing output schema carrying the safety and return-shape burden, almost nothing an agent needs in order to call it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 16 parameters, and the description largely mirrors that content (mip, per, line, polygon, objects, lanes are all restated rather than extended). It does tie modes together usefully ('preview marks=objects shows them'), but adds little semantic detail the schema lacks, so the baseline 3 is right.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource (pixel statistics per channel/image) and immediately enumerates the measurement families it covers (count, min/max/mean/std, percentiles, histogram), so an agent knows exactly what the tool produces. It does not, however, name or contrast itself with any sibling such as openreadout_preview or openreadout_extract, leaving the boundary to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Embedded conditional guidance is present: 'per=plane adds every plane; per=well or field gives rows per well of a screening plate', 'mip=z measures the maximum-intensity projection', and 'Measurements on one plane: line..., polygon..., objects..., lanes...'. This tells the agent when each mode applies, but there are no explicit exclusions or pointer to an alternative tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_summarizeA
DestructiveIdempotent

Group statistics of a table written by an earlier openreadout_batch output (or any CSV, TSV, JSON Lines, JSON or Parquet table): n, mean, sd, sem, median, min, max and CV % per group of by, optionally averaging replicates first and testing every group against a control.

NameRequiredDescriptionDefault
byYesGroup by these columns.
testNo`welch` or `mann-whitney` against `control`.
tableYesA table file written by an openreadout_batch `output` (or any CSV, TSV, JSON Lines, JSON or Parquet table).
whereNoRow filters `COLUMN=VALUE` / `COLUMN!=VALUE`.
outputNoWrite the summary to this file.
valuesNoValue columns (default: the measure's main values).
controlNoThe control group (a value of the first `by` column).
exact_byNoGroup by exactly `by`.
overwriteNoReplace an existing output file.
replicateNoAverage rows within each replicate first.

Output Schema

NameRequiredDescription
inputYesThe table summarized.
outputNoWhere it was written.
summaryYesThe summary.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare a non-read-only, destructive, idempotent operation, and the description is consistent with that by noting the `output` write target and the ability to overwrite an existing output file. It also adds genuinely useful context beyond the annotations, such as accepted input formats and that replicates can be averaged before summarization. It does not discuss failure modes or what happens to prior results beyond the overwrite flag.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action (group statistics of a table) and the enumerated outputs, followed by the optional behaviors. It is a single dense sentence with nested parentheticals, which makes it slightly run-on but still economical with no wasted clauses.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a ten-parameter statistical tool with an output schema (so return values need no explanation) and annotations covering the safety profile, the description supplies enough to call it correctly: input formats, the grouping key, and the optional replicate/control behaviors. It is close to complete, with only minor gaps around filtering and value-column selection.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all ten parameters are already documented in the schema and this is the baseline case. The description reinforces `by` grouping, replicate averaging, and control testing, but says nothing about `where`, `exact_by`, or `values`, adding little meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource (group summary statistics of a table) and enumerates exactly what is computed (n, mean, sd, sem, median, min, max, CV%), plus the accepted input sources. It does not explicitly differentiate itself from potentially overlapping siblings such as openreadout_stats or openreadout_compare, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer it should call this when it wants per-group descriptive statistics, optionally with replicate averaging or a control comparison. No when-not-to-use conditions, prerequisites, or alternative tools are named, and the relationship to openreadout_stats is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_tableA
Read-onlyIdempotent

Rows of a table {columns, labels, rows, total_rows, truncated}: FCS events ($PnN columns), plate reads (well, row, col, read, wavelength_nm, time_s, value), event, spike or peak tables (including the vendor's own integration results). Values are raw; FCS can be compensated, transformed and given 0/1 population columns from a workspace or Gating-ML file. filter with count=true counts the events meeting conditions.

NameRequiredDescriptionDefault
fileYesPath to the file.
countNoReturn only the count (`filter.matched_rows`, `total_rows`, `percent`), no rows.
tableNoTable index (FCS data set or plate read; see openreadout_info → tables[]). Default 0.
filterNoRow conditions `COLUMN OP NUMBER` (OP: > >= < <= == !=; COLUMN: $PnN, $PnS or `gate:<path>`), all of which must hold, e.g. `["FITC-A > 1000"]`. Tested on the values returned (after compensate/transform when given) over the whole table; `filter.matched_rows` counts every match and first_row/max_rows page through them.
sampleNoWorkspace sample name or id (default: matched by file name or $FIL).
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
gatingmlNoFCS only: Gating-ML 2.0 file (same uses as workspace).
max_rowsNoMaximum rows to return. Default 100 (fewer for wide tables: about 5000 values), capped at 10000.
first_rowNoZero-based first row. Default 0.
transformNoFCS only: transform after compensation: `logicle`, `arcsinh`, `hyperlog`, `log`, `linear`, `biex`, `flowjo-log`, `arcsinh-cofactor`, with parameters as `NAME:K=V,…` (`logicle:T=262144,W=0.5,M=4.5,A=0`, `arcsinh-cofactor:5`), or `workspace` for the FlowJo sample's per-parameter transforms.
workspaceNoFCS only: FlowJo workspace (.wsp) for compensate=gating, transform=workspace and populations.
compensateNoFCS only: compensate the values: `auto` (the gating file's matrix when one is given, else the file's $SPILLOVER/$SPILL/SPILL), `fcs` or `gating`. Values become FCS scale values first ($PnE, $PnG, $TIMESTEP).
parametersNoFCS only: parameters ($PnN) to transform; default every fluorescence parameter.
populationsNoFCS only: populations (paths like `/Lymphocytes/Singlets` or unique names) whose 0/1 membership is appended as `gate:<path>` columns.

Output Schema

NameRequiredDescription
pathYesThe input file.
rowsYesRow-major values; `rows[r][c]`. Non-finite values serialize as `null`. A text column holds codes here; `texts` has its text.
tableYesTable index (see `info` → `tables[]`).
textsNoText columns (`info` → `tables[].columns[].extra.categories`) by column name: the text of each returned row, so `texts[name][r]` is what `rows[r][c]` codes. Absent when the table has no text column.
filterNoPresent with `--where`/`--count`: the row conditions and how many rows of the whole table meet them. `rows`, `first_row` and `truncated` then page through the matching rows.
formatYesFormat id of the input file.
labelsYesColumn labels (FCS `$PnS`), `null` where absent.
columnsYesColumn names (FCS `$PnN`).
first_rowYesZero-based index of the first row returned.
truncatedYesTrue when more rows follow the returned slice.
processingNoPresent when the values were processed (FCS scale values, compensation, transforms, population membership columns); absent for raw values.
total_rowsYesRows in the whole table.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry readOnly/idempotent/no-destructive, but the description adds real behavior: values are raw unless compensate/transform/workspace/populations are applied, FCS scaling ($PnE, $PnG, $TIMESTEP) is applied first, and strict can refuse values (exit_code 6). Those are substantive traits beyond the annotation set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences that front-load the return shape and table kinds, with no filler. The colon-separated noun lists are terse to the point of being hard to parse, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 14-parameter tool the description covers the important axes — table selection, raw vs compensated/transformed values, workspace/Gating-ML population columns, and filter/count behavior — and an output schema exists so return format need not be repeated. Only the interaction between first_row/max_rows paging and filtering is left to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description restates the filter semantics ('tested on the values returned after compensate/transform', matched_rows counting) that the schema already documents, and adds little independent meaning for the other 13 parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the resource precisely (rows of a table) and enumerates the concrete table kinds it returns — FCS events, plate reads, event/spike/peak tables — plus the return shape {columns, labels, rows, total_rows, truncated}. That is a clear specific operation, though it never explicitly contrasts itself with preview/export/extract siblings, only deferring to openreadout_info for table indices.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: it points to openreadout_info → tables[] for choosing a table index and notes that filter+count=true yields counts. There is no explicit 'use this when you need actual row values, use openreadout_preview/summarize otherwise' routing, so an agent must infer the boundary from siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_traceB
Read-onlyIdempotent

One window of one sweep of a sampled signal or 1-D spectrum in physical units: electrophysiology sweeps, chromatography detector traces, ÄKTA curves, ITC thermograms, SPR sensorgrams, NMR FIDs and spectra (process=true turns an FID into a spectrum), IR/Raman/UV-Vis/CD spectra (each spectrum of a map is a sweep), qPCR curves, EPR, XRD, electrochemistry, thermal analysis. Per channel: min, max, mean, std and argmax_axis_value (the maximum's position on the axis: retention time, ppm, cm⁻¹, °2θ) over the window, plus the first max_samples values.

NameRequiredDescriptionDefault
fileYesPath to the file.
countNoWindow length in samples (statistics cover the whole window). Default: to the end of the sweep.
sweepNoSweep (episode or segment) index. Default 0.
traceNoTrace index (see openreadout_info → traces[]). Default 0.
strictNoRefuse values the file's assurance does not validate (exit_code 6). Default: the server's.
processNoNMR: return FID traces as spectra processed by OpenReadout (group delay, apodization, zero filling, FT, stored or automatic phase, baseline, ppm axis).
x_rangeNoWindow on the trace's own axis instead of first_sample/count, `[a, b]` either order: cm⁻¹, nm, ppm, a chromatogram's retention time in its axis unit; seconds for signals without an axis.
channelsNoChannel indices to return. Default: all channels.
max_samplesNoSamples returned per channel. Default 200, capped at 10000.
first_sampleNoFirst sample of the window, zero-based within the sweep. Default 0.

Output Schema

NameRequiredDescription
axisNoThe trace's abscissa (`info` → `traces[].extra.axis`: `{quantity, unit, first, step, …}`), e.g. the ppm axis of an NMR spectrum or a chromatogram's retention time in minutes; sample `i` of the sweep is at `first + i * step`. For a time axis this agrees with `start_s` and `sample_rate_hz` (`first` = `start_s` at `first_sample` 0, `step` = 1 / `sample_rate_hz`, in `unit`). Irregular axes (`irregular: true`) name the channel holding each sample's abscissa instead.
pathYesThe input file.
sweepYesSweep index.
traceYesTrace index (see `info` → `traces[]`).
formatYesFormat id of the input file.
start_sYesTime of the first window sample in seconds. Single-sweep traces use the trace's own clock: `info.traces[].start_s + first_sample / sample_rate_hz` (a chromatogram's retention time, negative when acquisition began before injection; an electrophysiology recording's clock). Multi-sweep traces are timed from the start of the sweep (`first_sample / sample_rate_hz`; `sweep_start_s` places the sweep in the recording). Irregularly sampled traces (`sample_rate_hz` 0 with a `time` channel) report that channel's first window value; traces without a time base (spectra) report 0.
x_rangeNoThe axis window asked for (`x_range`, low to high): axis units, or seconds for signals without an axis. `first_sample`/`sample_count` are the samples inside it.
channelsYesOne entry per requested channel.
truncatedYesTrue when fewer samples are returned than the window holds.
sweep_countYesSweeps in the trace.
first_sampleYesFirst sample of the window (zero-based, within the sweep).
sample_countYesSamples in the window (statistics cover all of them).
sweep_start_sNoTime of the sweep's first sample on the recording clock, seconds, when the file records it (`info.traces[].start_s` for a single sweep, `extra.sweep_starts_s[sweep]` for multi-sweep traces).
sample_rate_hzYesSamples per second.
sweep_sample_countYesSamples in this sweep.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered by structured data. The description's remaining behavioral contribution is the NMR process=true transform, which is notable, but the return contents it lists (min/max/mean/std/argmax) are already covered by the output schema. Error behavior (strict/exit_code 6) is left entirely to the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is front-loaded, but the first sentence is a very long catalogue of ~14 instrument domains whose tail entries add little for an agent that already knows its data type. The second sentence stacks output fields and axis-unit clarifications into a single run-on. Information-dense, but not tightly edited.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and 100% parameter description coverage, the description does not need to explain return values; it still usefully frames what a window/sweep/spectrum means, which the schema alone would not convey. The main gap is the absence of any when-to-use or alternative-tool guidance given 27 sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description reinforces the units used by argmax_axis_value and by x_range (retention time, ppm, cm⁻¹, °2θ) and clarifies that a map's each spectrum counts as a sweep, but it adds no syntax or default information beyond what the parameter descriptions already state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a precise definition of the resource: 'one window of one sweep of a sampled signal or 1-D spectrum in physical units', and enumerates the data domains it covers (electrophysiology, chromatography, NMR, ITC, SPR, qPCR, etc.). It is clear the tool reads a sub-window of a series, but it never explicitly names the sibling it replaces or differs from (e.g. openreadout_spectrum, openreadout_scans, openreadout_stats), so sibling differentiation must be inferred.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the domain enumeration — the agent can infer this is the general-purpose trace/sweep reader for any sampled signal. There is no explicit when-to-use statement, no exclusions, and no routing to alternatives such as openreadout_spectrum or openreadout_scans. The 'process=true turns an FID into a spectrum' note is the closest thing to a mode-selection hint.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

openreadout_watchA
Read-only

Follow directories an instrument writes to: each call looks once and returns events since cursor (dataset_new, plane_new, scan_new, frame_new, dataset_complete, dataset_stalled, qc with qc=true: saturation, focus drift, dropped frames, TIC drop, error). Poll with the returned cursor; files are never locked.

NameRequiredDescriptionDefault
qcNoFirst call only: evaluate the built-in live QC rules on each new plane or scan.
dirsYesDirectories (or files) to watch. The same list (in any order) continues the same watcher across calls.
limitNoMost events returned (default 200, max 5000); call again with the new cursor for more.
sinceNoFirst call only: report data sets modified since then (`10m`, `2h`, `1d`, an ISO-8601 time, or `all`). Default: the live window (5 minutes) back from now.
cursorNoReturn events with a sequence number greater than this (the `cursor` of the previous call); 0 or absent on the first call.
stall_afterNoFirst call only: seconds without growth before `dataset_stalled` (default 120).
follow_symlinksNoFirst call only: walk into directories behind symbolic links too (links to files are always followed).

Output Schema

NameRequiredDescription
moreYesTrue when more events are waiting (raise `limit` or call again).
notesNoWhat the watcher left out and how to include it.
cursorYesPass back as `cursor` to get only newer events.
eventsYesEvents after the given cursor, oldest first (the same objects `openreadout watch` prints under `data`).
droppedYesTrue when events after the cursor were dropped (the server keeps the last 10000).
trackedYesData sets the watcher remembers.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, non-destructive, not idempotent), and the description adds genuinely useful behavior beyond that: each call is a single non-blocking look, continuation is by cursor, and watching never locks files. It does not explain backpressure or what happens when a watched directory disappears.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, with the core purpose front-loaded before the event-type parenthetical. The embedded enumeration of event names is dense but earns its place by telling the agent what to expect to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail is not required, yet the description still names the event vocabulary the agent will need for routing. Combined with the polling/cursor guidance, an agent has enough to invoke and loop correctly; only edge behavior (missing dirs, error recovery) is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all seven parameters including the first-call-only nature of qc/since/stall_after/follow_symlinks. The description adds only the cursor/polling linkage, which the schema's cursor description already carries, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Follow directories an instrument writes to') plus the operational model ('each call looks once and returns events since cursor'), and enumerates the returned event types. It is clearly distinguishable from read-once siblings like openreadout_scans or openreadout_check.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear operational context: poll repeatedly using the returned cursor, and 'files are never locked' signals it is safe to call alongside a running acquisition. It does not name an alternative sibling or state an explicit when-not-to-use, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 34 tool updatesv0.4.0
    • Addedopenreadout_assay
    • Removedopenreadout_assay_curve
    • Removedopenreadout_assay_qc
    • Removedopenreadout_assay_wells
    • Changedopenreadout_batch17 fields changed
      • removedInput schema / properties / by / default
        Removed value: -[]
      • removedInput schema / properties / exact_by / default
        Removed value: -false
      • removedInput schema / properties / fields / default
        Removed value: -[]
      • removedInput schema / properties / formats / default
        Removed value: -[]
      • removedInput schema / properties / keys / default
        Removed value: -[]
      • removedInput schema / properties / limit / minimum
        Removed value: -0
      • changedInput schema / properties / measure / description
        Previous value: -"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the arguments of that openreadout_assay_* tool; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml)."New value: +"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the other openreadout_assay arguments; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml)."
      • removedInput schema / properties / offset / default
        Removed value: -0
      • removedInput schema / properties / offset / minimum
        Removed value: -0
      • changedInput schema / properties / options / description
        Previous value: -"The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, ...; assay: `analysis` = wells, curve, dose-response, kinetics, growth or qc, plus the arguments of that openreadout_assay_* tool), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters."New value: +"The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, openreadout_assay with its `analysis`, ...), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters."
      • removedInput schema / properties / overwrite / default
        Removed value: -false
      • removedInput schema / properties / paths / default
        Removed value: -[]
      • removedInput schema / properties / recursive / default
        Removed value: -false
      • removedInput schema / properties / sample_sheets / default
        Removed value: -[]
      • removedInput schema / properties / values / default
        Removed value: -[]
      • removedInput schema / properties / where / default
        Removed value: -[]
      • changedOutput schema / $defs / Value / anyOf
        Previous value: -[
        -  {
        -    "description": "No value (JSON `null`, an empty CSV field).",
        -    "type": "null"
        -  },
        -  {
        -    "description": "`true` / `false`.",
        -    "type": "boolean"
        -  },
        -  {
        -    "description": "A whole number.",
        -    "format": "int64",
        -    "type": "integer"
        -  },
        -  {
        -    "description": "A real number (NaN and infinities are written as `null`).",
        -    "format": "double",
        -    "type": "number"
        -  },
        -  {
        -    "description": "Text.",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "description": "No value (JSON `null`, an empty CSV field).",
        +    "type": "null"
        +  },
        +  {
        +    "description": "`true` / `false`.",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "A whole number.",
        +    "format": "int64",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "A real number (NaN and infinities are written as `null`).",
        +    "format": "double",
        +    "type": [
        +      "number",
        +      "null"
        +    ]
        +  },
        +  {
        +    "description": "Text.",
        +    "type": "string"
        +  }
        +]
    • Changedopenreadout_check5 fields changed
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / headers_only / default
        Removed value: -false
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • changedOutput schema / $defs / Acquisition / properties / modified_ago_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Acquisition / properties / window_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_chromatogram20 fields changed
      • removedInput schema / properties / bpc / default
        Removed value: -false
      • removedInput schema / properties / channel / minimum
        Removed value: -0
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / max_points / minimum
        Removed value: -0
      • removedInput schema / properties / ms_level / minimum
        Removed value: -0
      • removedInput schema / properties / mz / default
        Removed value: -[]
      • removedInput schema / properties / profile / default
        Removed value: -false
      • removedInput schema / properties / run / default
        Removed value: -0
      • removedInput schema / properties / run / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / sweep / minimum
        Removed value: -0
      • removedInput schema / properties / tic / default
        Removed value: -false
      • removedInput schema / properties / traces / default
        Removed value: -[]
      • removedInput schema / properties / traces / items / minimum
        Removed value: -0
      • removedInput schema / properties / transitions / default
        Removed value: -[]
      • changedOutput schema / $defs / Chromatogram / properties / intensity / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Chromatogram / properties / mz_range / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Chromatogram / properties / mz_window / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Chromatogram / properties / rt_min / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Chromatogram / required
        Previous value: -[
        -  "label",
        -  "kind",
        -  "source",
        -  "points",
        -  "rt_min",
        -  "intensity"
        -]New value: +[
        +  "label",
        +  "kind",
        +  "source",
        +  "points",
        +  "rt_min",
        +  "intensity",
        +  "decimated"
        +]
    • Changedopenreadout_compare10 fields changed
      • removedInput schema / properties / ignore / default
        Removed value: -[]
      • removedInput schema / properties / image / minimum
        Removed value: -0
      • removedInput schema / properties / level / default
        Removed value: -0
      • removedInput schema / properties / level / minimum
        Removed value: -0
      • removedInput schema / properties / no_pixels / default
        Removed value: -false
      • removedInput schema / properties / select / default
        Removed value: -[]
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • changedOutput schema / $defs / ImageComparison / required
        Previous value: -[
        -  "image",
        -  "geometry_equal",
        -  "channel_names_equal",
        -  "ours_channels",
        -  "theirs_channels",
        -  "physical_size_equal"
        -]New value: +[
        +  "image",
        +  "geometry_equal",
        +  "channel_names_equal",
        +  "physical_size_equal"
        +]
      • changedOutput schema / $defs / PlaneComparison / required
        Previous value: -[
        -  "compared",
        -  "planes",
        -  "identical",
        -  "within_tolerance",
        -  "mismatched",
        -  "skipped_images",
        -  "mismatches"
        -]New value: +[
        +  "compared",
        +  "planes",
        +  "identical",
        +  "within_tolerance",
        +  "mismatched",
        +  "mismatches"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "identical",
        -  "ours",
        -  "theirs",
        -  "metadata",
        -  "images",
        -  "planes",
        -  "notes"
        -]New value: +[
        +  "identical",
        +  "ours",
        +  "theirs",
        +  "metadata",
        +  "images",
        +  "planes"
        +]
    • Removedopenreadout_dose_response
    • Changedopenreadout_ephys_features35 fields changed
      • removedInput schema / properties / channel / minimum
        Removed value: -0
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / max_spikes / minimum
        Removed value: -0
      • addedInput schema / properties / min_rise_mv
        Added value: +{
        +  "description": "A spike's peak must rise this far above the lowest voltage since the previous spike, mV (default 15; 0 counts every crossing, as eFEL does).",
        +  "type": "number"
        +}
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / sweeps / items / minimum
        Removed value: -0
      • removedInput schema / properties / trace / default
        Removed value: -0
      • removedInput schema / properties / trace / minimum
        Removed value: -0
      • changedOutput schema / $defs / ApSettings / properties / dvdt_threshold_v_per_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / ApSettings / properties / min_rise_mv
        Added value: +{
        +  "description": "Rise of a spike's peak above the lowest voltage since the previous spike's peak, mV.",
        +  "format": "double",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • changedOutput schema / $defs / ApSettings / properties / peak_threshold_mv / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ApSettings / required
        Previous value: -[
        -  "peak_threshold_mv",
        -  "dvdt_threshold_v_per_s",
        -  "dvdt_window_samples"
        -]New value: +[
        +  "peak_threshold_mv",
        +  "dvdt_threshold_v_per_s",
        +  "dvdt_window_samples",
        +  "min_rise_mv"
        +]
      • changedOutput schema / $defs / CellFeatures / properties / fi_slope_hz_per_pa / description
        Previous value: -"Least-squares slope of rate vs current over steps that fire, Hz/pA."New value: +"Least-squares slope of rate vs current from the rheobase to the step with the highest\nrate (steps past it, where firing fails, are left out), Hz/pA."
      • changedOutput schema / $defs / CellFeatures / properties / rheobase_pa / description
        Previous value: -"Smallest depolarising step that evokes at least one spike during the stimulus, pA."New value: +"Smallest depolarising step that evokes at least one spike during the stimulus, pA.\nAbsent when the cell also fires during a step of 0 pA or less (it fires without\ndepolarising current, so a rheobase is not defined; `notes` says so)."
      • addedOutput schema / $defs / CellFeatures / properties / spontaneous_rate_hz
        Added value: +{
        +  "description": "Firing rate before the stimulus, over every sweep, Hz: above 0 the cell fires on its own.",
        +  "format": "double",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • changedOutput schema / $defs / CellFeatures / required
        Previous value: -[
        -  "fi_curve"
        -]New value: +[
        +  "resting_mv",
        +  "rheobase_pa",
        +  "rheobase_sweep",
        +  "fi_curve",
        +  "fi_slope_hz_per_pa",
        +  "max_firing_rate_hz",
        +  "input_resistance_mohm",
        +  "tau_ms",
        +  "capacitance_pf",
        +  "sag_ratio",
        +  "holding_current_pa",
        +  "access_resistance_mohm",
        +  "membrane_resistance_mohm",
        +  "membrane_capacitance_pf"
        +]
      • changedOutput schema / $defs / ChannelRef / required
        Previous value: -[
        -  "index",
        -  "name"
        -]New value: +[
        +  "index",
        +  "name",
        +  "unit"
        +]
      • changedOutput schema / $defs / FiPoint / properties / current_pa / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / FiPoint / properties / rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / amplitude_mv / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / peak_mv / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / peak_time_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / rise_time_ms / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / threshold_mv / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / threshold_time_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / properties / upstroke_v_per_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spike / required
        Previous value: -[
        -  "sweep",
        -  "index",
        -  "peak_sample",
        -  "peak_time_s",
        -  "peak_mv",
        -  "threshold_time_s",
        -  "threshold_mv",
        -  "threshold_from_dvdt",
        -  "amplitude_mv",
        -  "rise_time_ms",
        -  "upstroke_v_per_s"
        -]New value: +[
        +  "sweep",
        +  "index",
        +  "peak_sample",
        +  "peak_time_s",
        +  "peak_mv",
        +  "threshold_time_s",
        +  "threshold_mv",
        +  "threshold_from_dvdt",
        +  "amplitude_mv",
        +  "half_width_ms",
        +  "rise_time_ms",
        +  "decay_time_ms",
        +  "ahp_mv",
        +  "ahp_depth_mv",
        +  "upstroke_v_per_s",
        +  "downstroke_v_per_s",
        +  "isi_ms"
        +]
      • addedOutput schema / $defs / StepResponse / required
        Added value: +[
        +  "baseline_mv",
        +  "steady_state_mv",
        +  "extreme_mv",
        +  "input_resistance_mohm",
        +  "tau_ms",
        +  "sag_ratio",
        +  "steady_fraction"
        +]
      • changedOutput schema / $defs / StimulusInfo / properties / holding / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / StimulusInfo / required
        Previous value: -[
        -  "output",
        -  "holding"
        -]New value: +[
        +  "output",
        +  "unit",
        +  "holding",
        +  "epoch"
        +]
      • addedOutput schema / $defs / SweepFeatures / properties / spike_count_before
        Added value: +{
        +  "description": "Spikes whose peak comes before the stimulus starts.",
        +  "format": "uint",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • changedOutput schema / $defs / SweepFeatures / required
        Previous value: -[
        -  "sweep",
        -  "spike_count"
        -]New value: +[
        +  "sweep",
        +  "stimulus_start_s",
        +  "stimulus_end_s",
        +  "stimulus_pa",
        +  "stimulus_mv",
        +  "spike_count",
        +  "spike_count_stimulus",
        +  "firing_rate_hz",
        +  "first_spike_latency_ms",
        +  "isi_mean_ms",
        +  "isi_cv",
        +  "adaptation_index",
        +  "half_width_mean_ms",
        +  "amplitude_mean_mv"
        +]
      • changedOutput schema / $defs / TestPulse / properties / delta_mv / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / TestPulse / required
        Previous value: -[
        -  "delta_mv"
        -]New value: +[
        +  "delta_mv",
        +  "holding_current_pa",
        +  "peak_current_pa",
        +  "steady_current_pa",
        +  "access_resistance_mohm",
        +  "membrane_resistance_mohm",
        +  "total_resistance_mohm",
        +  "tau_ms",
        +  "capacitance_pf"
        +]
      • changedOutput schema / properties / sample_rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_export28 fields changed
      • removedInput schema / $defs / Region / properties / height / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / width / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / x / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / y / minimum
        Removed value: -0
      • removedInput schema / properties / centroid / default
        Removed value: -false
      • addedInput schema / properties / dpi
        Added value: +{
        +  "description": "Figures: print resolution (e.g. 300), recorded in .png, .jpg and .tiff files; .svg and .pdf pages get the size the raster would print at.",
        +  "type": "integer"
        +}
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file (not with plot or preview)."
      • changedInput schema / properties / format / description
        Previous value: -"`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON) or `rdml` (RDML 1.3; qPCR files). Without it, the extension of `output` decides; it must not contradict `output`."New value: +"`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON), `rdml` (RDML 1.3; qPCR files), `fastq` (base calls: a Sanger read, its default, gives one file; an Illumina run folder gives a directory of gzip FASTQ, one file per lane and read, and rows `0-N` writes the first N+1 clusters of each lane), `nifti` (NIfTI-1 `.nii.gz`; one volume with voxel size and scanner orientation) or `mrc` (MRC2014; EM movies, stacks and diffraction images). Without it, the extension of `output` decides; it must not contradict `output`."
      • addedInput schema / properties / group_frames
        Added value: +{
        +  "description": "MRC: sum every N time points into one section (dose fractions of a movie).",
        +  "type": "integer"
        +}
      • removedInput schema / properties / image / minimum
        Removed value: -0
      • removedInput schema / properties / labels / default
        Removed value: -false
      • removedInput schema / properties / level / default
        Removed value: -0
      • removedInput schema / properties / level / minimum
        Removed value: -0
      • changedInput schema / properties / output / description
        Previous value: -"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.parquet`, `.arrow`, `.nwb` or `.jdx`. Its extension sets the format when `format` is not given."New value: +"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.fastq`, `.parquet`, `.arrow`, `.nwb`, `.jdx`, `.nii.gz` or `.mrc`. Its extension sets the format when `format` is not given. Figures: .png, .jpg, .tiff, .svg or .pdf (default `<data file stem>.figure.png` or `.preview.png` next to the data)."
      • removedInput schema / properties / overwrite / default
        Removed value: -false
      • addedInput schema / properties / plot
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Save a figure: the arguments of an openreadout_plot call. `output` names the file.",
        +  "type": "object"
        +}
      • addedInput schema / properties / preview
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "Save a picture: the arguments of an openreadout_preview call (file, region, annotations, marks, dark, …); max_size up to 8192. Images are saved with a scale bar and no rulers (axes scale-bar; add title, caption) unless axes says otherwise.",
        +  "type": "object"
        +}
      • removedInput schema / properties / run / default
        Removed value: -0
      • removedInput schema / properties / run / minimum
        Removed value: -0
      • addedInput schema / properties / scale
        Added value: +{
        +  "description": "Figures: pixels per figure pixel in .png, .jpg and .tiff files (default 2, up to 8); image previews are read again at max_size × scale.",
        +  "type": "number"
        +}
      • removedInput schema / properties / select / default
        Removed value: -[]
      • removedInput schema / properties / spectra / default
        Removed value: -false
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / sweep / minimum
        Removed value: -0
      • removedInput schema / properties / table / minimum
        Removed value: -0
      • removedInput schema / properties / trace / minimum
        Removed value: -0
      • removedInput schema / properties / wells / default
        Removed value: -[]
      • removedInput schema / required
        Removed value: -[
        -  "file"
        -]
    • Changedopenreadout_extract1 field changed
      • removedInput schema / properties / overwrite / default
        Removed value: -false
    • Changedopenreadout_gate10 fields changed
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / medians / default
        Removed value: -[]
      • changedInput schema / properties / medians / description
        Previous value: -"Parameters whose median over each population's events is reported under populations[].medians (`$PnN` or `$PnS`; `Comp-NAME` for compensated values)."New value: +"Parameters whose median over each population's events is reported under populations[].medians (`$PnN` or `$PnS`; `Comp-NAME` for compensated values), or `[\"all\"]`: every parameter a gate uses, compensated as the gate reads it."
      • removedInput schema / properties / populations / default
        Removed value: -[]
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / table / default
        Removed value: -0
      • removedInput schema / properties / table / minimum
        Removed value: -0
      • changedOutput schema / $defs / CompensationSummary / properties / matrix / items / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PopulationRow / properties / medians / additionalProperties / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / TransformSummary / properties / parameters / additionalProperties / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Removedopenreadout_growth
    • Changedopenreadout_health4 fields changed
      • removedInput schema / properties / max_list / minimum
        Removed value: -0
      • removedInput schema / properties / no_hash / default
        Removed value: -false
      • changedOutput schema / $defs / DuplicateGroup / required
        Previous value: -[
        -  "size_bytes",
        -  "paths"
        -]New value: +[
        +  "size_bytes",
        +  "sha256",
        +  "paths"
        +]
      • changedOutput schema / $defs / IntegrityEntry / required
        Previous value: -[
        -  "path",
        -  "status",
        -  "codes"
        -]New value: +[
        +  "path",
        +  "format",
        +  "status",
        +  "codes"
        +]
    • Changedopenreadout_index11 fields changed
      • removedInput schema / properties / exclude / default
        Removed value: -[]
      • addedInput schema / properties / follow_symlinks
        Added value: +{
        +  "description": "Crawl directories behind symbolic links too (links to files are always read).",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / full_rescan / default
        Removed value: -false
      • removedInput schema / properties / max_files / minimum
        Removed value: -0
      • removedInput schema / properties / restart / default
        Removed value: -false
      • removedInput schema / properties / threads / minimum
        Removed value: -0
      • changedOutput schema / $defs / CrawlStats / properties / elapsed_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / IndexSettings / required
        Previous value: -[
        -  "check",
        -  "follow_symlinks",
        -  "pii"
        -]New value: +[
        +  "check",
        +  "follow_symlinks",
        +  "exclude",
        +  "pii"
        +]
      • addedOutput schema / $defs / TableManifest / properties / columns
        Added value: +{
        +  "description": "Columns (name, type, unit class, description). Always in `index.json`; left out of the\nMCP tool's answer (listed in `index.json` and `book/src/guides/lab-shares.md`).",
        +  "items": true,
        +  "readOnly": true,
        +  "type": "array"
        +}
      • changedOutput schema / $defs / WalkStats / properties / symlinks_skipped / description
        Previous value: -"Symbolic links skipped (not followed)."New value: +"Symbolic links to directories skipped (not followed)."
      • changedOutput schema / properties / files_per_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_info21 fields changed
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • addedInput schema / properties / first_entry
        Added value: +{
        +  "description": "view=structure with kind: skip this many elements of that kind first (paging).",
        +  "type": "integer"
        +}
      • addedInput schema / properties / kind
        Added value: +{
        +  "description": "view=structure: list only elements of this kind (as entries_total names them), e.g. \"attachment\" or \"subblock\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / max_entries
        Added value: +{
        +  "description": "view=structure: list at most this many elements of each kind (0 = all). Default 50.",
        +  "type": "integer"
        +}
      • removedInput schema / properties / max_images / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate (assurance.strict_refuses). Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / vendor / default
        Removed value: -false
      • changedOutput schema / $defs / Acquisition2 / properties / modified_ago_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Acquisition2 / properties / window_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChannelInfo / properties / emission_range_nm / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ColumnInfo / properties / range / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / Listing / properties / entries_total
        Added value: +{
        +  "additionalProperties": {
        +    "format": "uint64",
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "description": "How many elements of each kind the container holds, when `entries` lists only some.",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Listing / properties / notes
        Added value: +{
        +  "description": "What was left out of `entries` and how to list it.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / $defs / PlateSummary / required
        Previous value: -[
        -  "rows",
        -  "columns",
        -  "wells",
        -  "field_count",
        -  "planes_expected",
        -  "complete"
        -]New value: +[
        +  "rows",
        +  "columns",
        +  "wells",
        +  "field_count",
        +  "planes_expected",
        +  "planes_absent",
        +  "planes_missing",
        +  "complete"
        +]
      • changedOutput schema / $defs / PlateWell / required
        Previous value: -[
        -  "well",
        -  "row",
        -  "column",
        -  "row_index",
        -  "column_index",
        -  "images"
        -]New value: +[
        +  "well",
        +  "row",
        +  "column",
        +  "row_index",
        +  "column_index",
        +  "images",
        +  "planes_missing"
        +]
      • changedOutput schema / $defs / ResolutionLevel / properties / downsample_x / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ResolutionLevel / properties / downsample_y / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SignalChannelInfo / properties / offset / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SignalChannelInfo / properties / scale / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SpectraInfo / properties / rt_range_s / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / TraceInfo / properties / sample_rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Removedopenreadout_kinetics
    • Changedopenreadout_link4 fields changed
      • removedInput schema / properties / formats / default
        Removed value: -[]
      • removedInput schema / properties / no_recursive / default
        Removed value: -false
      • removedInput schema / properties / paths / default
        Removed value: -[]
      • changedOutput schema / $defs / LinkMember / required
        Previous value: -[
        -  "path"
        -]New value: +[
        +  "path",
        +  "format"
        +]
    • Changedopenreadout_nmr_peaks37 fields changed
      • addedInput schema / properties / auto_integrate
        Added value: +{
        +  "description": "Without integrate: integrate every multiplet (peaks closer than 15 Hz, ±10 Hz).",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • changedInput schema / properties / integral_reference / prefixItems
        Previous value: -[
        -  {
        -    "minimum": 0,
        -    "type": "integer"
        -  },
        -  {
        -    "type": "number"
        -  }
        -]New value: +[
        +  {
        +    "type": "integer"
        +  },
        +  {
        +    "type": "number"
        +  }
        +]
      • removedInput schema / properties / integrate / default
        Removed value: -[]
      • removedInput schema / properties / max_peaks / minimum
        Removed value: -0
      • removedInput schema / properties / negative / default
        Removed value: -false
      • removedInput schema / properties / size / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / sweep / default
        Removed value: -0
      • removedInput schema / properties / sweep / minimum
        Removed value: -0
      • removedInput schema / properties / trace / minimum
        Removed value: -0
      • changedOutput schema / $defs / Apodization / oneOf
        Previous value: -[
        -  {
        -    "description": "No window.",
        -    "properties": {
        -      "kind": {
        -        "const": "none",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "kind"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "description": "`e^{−π·LB·t}`: Lorentzian lines broadened by `line_broadening_hz`.",
        -    "properties": {
        -      "kind": {
        -        "const": "exponential",
        -        "type": "string"
        -      },
        -      "line_broadening_hz": {
        -        "description": "Added Lorentzian full width at half height, Hz.",
        -        "format": "double",
        -        "type": "number"
        -      }
        -    },
        -    "required": [
        -      "kind",
        -      "line_broadening_hz"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "description": "`e^{−(π·GB·t)²/(4 ln 2)}`: multiplies each line by a Gaussian of `line_broadening_hz`\nfull width at half height.",
        -    "properties": {
        -      "kind": {
        -        "const": "gaussian",
        -        "type": "string"
        -      },
        -      "line_broadening_hz": {
        -        "description": "Gaussian full width at half height, Hz.",
        -        "format": "double",
        -        "type": "number"
        -      }
        -    },
        -    "required": [
        -      "kind",
        -      "line_broadening_hz"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "description": "No window.",
        +    "properties": {
        +      "kind": {
        +        "const": "none",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "kind"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "description": "`e^{−π·LB·t}`: Lorentzian lines broadened by `line_broadening_hz`.",
        +    "properties": {
        +      "kind": {
        +        "const": "exponential",
        +        "type": "string"
        +      },
        +      "line_broadening_hz": {
        +        "description": "Added Lorentzian full width at half height, Hz.",
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "line_broadening_hz"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "description": "`e^{−(π·GB·t)²/(4 ln 2)}`: multiplies each line by a Gaussian of `line_broadening_hz`\nfull width at half height.",
        +    "properties": {
        +      "kind": {
        +        "const": "gaussian",
        +        "type": "string"
        +      },
        +      "line_broadening_hz": {
        +        "description": "Gaussian full width at half height, Hz.",
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      }
        +    },
        +    "required": [
        +      "kind",
        +      "line_broadening_hz"
        +    ],
        +    "type": "object"
        +  }
        +]
      • changedOutput schema / $defs / FidParameters / properties / carrier_frequency_mhz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / FidParameters / properties / group_delay_points / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / FidParameters / properties / reference_frequency_mhz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / FidParameters / properties / spectral_width_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Integral / properties / from_ppm / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Integral / properties / to_ppm / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Integral / properties / value / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Integral / required
        Previous value: -[
        -  "from_ppm",
        -  "to_ppm",
        -  "value",
        -  "points"
        -]New value: +[
        +  "from_ppm",
        +  "to_ppm",
        +  "value",
        +  "normalized",
        +  "points"
        +]
      • changedOutput schema / $defs / Peak / properties / height / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / ppm / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / required
        Previous value: -[
        -  "ppm",
        -  "hz",
        -  "index",
        -  "height"
        -]New value: +[
        +  "ppm",
        +  "hz",
        +  "index",
        +  "height",
        +  "width_hz",
        +  "width_ppm",
        +  "snr"
        +]
      • changedOutput schema / $defs / PeakOptions / properties / min_height_fraction / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PeakOptions / properties / min_prominence_snr / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PeakOptions / properties / min_snr / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PeakOptions / properties / range_ppm / prefixItems
        Previous value: -[
        -  {
        -    "format": "double",
        -    "type": "number"
        -  },
        -  {
        -    "format": "double",
        -    "type": "number"
        -  }
        -]New value: +[
        +  {
        +    "format": "double",
        +    "type": [
        +      "number",
        +      "null"
        +    ]
        +  },
        +  {
        +    "format": "double",
        +    "type": [
        +      "number",
        +      "null"
        +    ]
        +  }
        +]
      • changedOutput schema / $defs / PpmAxis / properties / first_ppm / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PpmAxis / properties / reference_frequency_mhz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PpmAxis / properties / step_ppm / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ProcessingRecord / properties / group_delay_points / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ProcessingRecord / properties / phase0_deg / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ProcessingRecord / properties / phase1_deg / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ProcessingRecord / required
        Previous value: -[
        -  "steps",
        -  "fid_points",
        -  "size",
        -  "apodization_source",
        -  "group_delay_points",
        -  "phase_mode",
        -  "phase0_deg",
        -  "phase1_deg",
        -  "baseline",
        -  "parameters",
        -  "stored"
        -]New value: +[
        +  "steps",
        +  "fid_points",
        +  "size",
        +  "apodization",
        +  "apodization_source",
        +  "group_delay_points",
        +  "phase_mode",
        +  "phase0_deg",
        +  "phase1_deg",
        +  "baseline",
        +  "parameters",
        +  "stored"
        +]
      • addedOutput schema / $defs / StoredProcessing / required
        Added value: +[
        +  "spectrum_stored"
        +]
      • changedOutput schema / properties / noise_sd / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_peaks64 fields changed
      • removedInput schema / $defs / Compound / properties / channel / minimum
        Removed value: -0
      • removedInput schema / $defs / Compound / properties / ms_level / minimum
        Removed value: -0
      • changedInput schema / $defs / Compound / properties / polarity / description
        Previous value: -"Scan polarity. Polarity filter. `positive` = Positive-ion scans; `negative` = Negative-ion scans."New value: +"Scan polarity. `positive` = Positive-ion scans; `negative` = Negative-ion scans."
      • removedInput schema / $defs / Compound / properties / trace / minimum
        Removed value: -0
      • removedInput schema / properties / area_seconds / default
        Removed value: -false
      • removedInput schema / properties / bpc / default
        Removed value: -false
      • removedInput schema / properties / channel / minimum
        Removed value: -0
      • removedInput schema / properties / compounds / default
        Removed value: -[]
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / integrate / default
        Removed value: -[]
      • removedInput schema / properties / ms_level / minimum
        Removed value: -0
      • removedInput schema / properties / mz / default
        Removed value: -[]
      • removedInput schema / properties / profile / default
        Removed value: -false
      • removedInput schema / properties / run / default
        Removed value: -0
      • removedInput schema / properties / run / minimum
        Removed value: -0
      • removedInput schema / properties / smooth / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / summary_only / default
        Removed value: -false
      • removedInput schema / properties / sweep / minimum
        Removed value: -0
      • removedInput schema / properties / tic / default
        Removed value: -false
      • removedInput schema / properties / traces / default
        Removed value: -[]
      • removedInput schema / properties / traces / items / minimum
        Removed value: -0
      • removedInput schema / properties / transitions / default
        Removed value: -[]
      • removedInput schema / properties / x_range / default
        Removed value: -[]
      • changedOutput schema / $defs / Band / properties / area / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / area_percent / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / baseline_end / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / baseline_start / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / end / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / height / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / start / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Band / properties / x / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / BandMethod / properties / min_snr / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / BandMethod / properties / noise / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChromatogramPeaks / properties / mz_window / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChromatogramPeaks / properties / total_area / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / area / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / area_percent / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / baseline_end / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / baseline_start / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / end_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / height / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / rt_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / start_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Peak / properties / width_base_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PeakMethod / properties / min_snr / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PeakMethod / properties / noise / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PeakMethod / properties / rt_range_min / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PickedPeak / properties / expected_rt_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PickedPeak / properties / rt_window_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / area / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / area_no_baseline / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / baseline_end / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / baseline_start / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / from / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / max_height / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / max_value / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / max_x / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / peaks_area / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / to / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / x_first / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Region / properties / x_last / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SpectrumBands / properties / x_max / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SpectrumBands / properties / x_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Addedopenreadout_plot
    • Changedopenreadout_preview101 fields changed
      • addedInput schema / $defs / Annotation
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "One annotation, in the coordinates the picture shows: full-resolution pixels on images (as on the rulers), axis units on plots (as on the tick labels), and on plate curve grids the time and value axes every card shares.",
        +  "properties": {
        +    "channel": {
        +      "description": "Trace previews with several panels: the channel whose panel it goes in (default: the first panel).",
        +      "type": "integer"
        +    },
        +    "color": {
        +      "description": "`accent` (default, warm red), `ink`, `muted`, `white`, another colour name or `#RRGGBB`.",
        +      "type": "string"
        +    },
        +    "facet": {
        +      "description": "Plots with small multiples: the one small plot it goes in, by its title (e.g. `B3` or `sweep 6`; default: every one).",
        +      "type": "string"
        +    },
        +    "height": {
        +      "description": "box: height.",
        +      "type": "number"
        +    },
        +    "label": {
        +      "description": "Text drawn with the mark (the text itself for type text).",
        +      "type": "string"
        +    },
        +    "points": {
        +      "description": "polygon, line: the vertices, `[[x, y], ...]`.",
        +      "items": {
        +        "items": {
        +          "type": "number"
        +        },
        +        "maxItems": 2,
        +        "minItems": 2,
        +        "type": "array"
        +      },
        +      "type": "array"
        +    },
        +    "type": {
        +      "description": "What to draw. `point` = a dot at x, y (with its label beside it); `box` = a rectangle: corner x, y and width, height; `polygon` = a closed outline through points; `line` = an open line through points; `arrow` = an arrow from x, y (where the label goes) to x2, y2; `text` = the label alone, at x, y; `vline` = a vertical line at x; `hline` = a horizontal line at y; `vband` = a vertical band from x to x2; `hband` = a horizontal band from y to y2; `well` = a ring around a plate well (well; previews of plates only).",
        +      "enum": [
        +        "point",
        +        "box",
        +        "polygon",
        +        "line",
        +        "arrow",
        +        "text",
        +        "vline",
        +        "hline",
        +        "vband",
        +        "hband",
        +        "well"
        +      ],
        +      "type": "string"
        +    },
        +    "well": {
        +      "description": "Plate previews: the well (e.g. `B3`) for type well, or the one card a mark goes in on a curve grid (default: every card).",
        +      "type": "string"
        +    },
        +    "width": {
        +      "description": "box: width.",
        +      "type": "number"
        +    },
        +    "x": {
        +      "description": "point, text: position; box: corner; arrow: tail; vline, vband: x (vband from x to x2).",
        +      "type": "number"
        +    },
        +    "x2": {
        +      "description": "arrow: head; vband: other edge.",
        +      "type": "number"
        +    },
        +    "y": {
        +      "description": "point, text: position; box: corner; arrow: tail; hline, hband: y (hband from y to y2).",
        +      "type": "number"
        +    },
        +    "y2": {
        +      "description": "arrow: head; hband: other edge.",
        +      "type": "number"
        +    }
        +  },
        +  "required": [
        +    "type"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / $defs / LadderRequest
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "The marker lane and its sizes.",
        +  "properties": {
        +    "lane": {
        +      "description": "Lane number of the marker (1 = leftmost).",
        +      "type": "integer"
        +    },
        +    "sizes": {
        +      "description": "Marker sizes from the top of the lane down (largest first), e.g. kDa or bp.",
        +      "items": {
        +        "type": "number"
        +      },
        +      "type": "array"
        +    },
        +    "unit": {
        +      "description": "Unit of the sizes, e.g. `kDa` or `bp`.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "lane",
        +    "sizes"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / $defs / LanesRequest
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "How lanes and bands are found. Everything is optional.",
        +  "properties": {
        +    "count": {
        +      "description": "Number of lanes. Default: found from the image.",
        +      "type": "integer"
        +    },
        +    "ladder": {
        +      "$ref": "#/$defs/LadderRequest",
        +      "description": "The marker lane and its sizes; bands then get sizes."
        +    },
        +    "min_share": {
        +      "description": "Bands lower than this share of the lane's highest band are dropped. Default 0.05.",
        +      "type": "number"
        +    },
        +    "polarity": {
        +      "default": "auto",
        +      "description": "Bright bands (fluorescence, chemiluminescence) or dark ones (stains). Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).",
        +      "enum": [
        +        "auto",
        +        "bright",
        +        "dark"
        +      ],
        +      "type": "string"
        +    },
        +    "profiles": {
        +      "description": "Return each lane's profile (200 values from the top down). Default false.",
        +      "type": "boolean"
        +    },
        +    "width_px": {
        +      "description": "Lane width in pixels. Default 0.7 lane pitches.",
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / $defs / ObjectsRequest
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "How objects are found. Everything is optional; the defaults suit nuclei.",
        +  "properties": {
        +    "diameter_px": {
        +      "description": "The same in pixels, for images without a pixel size.",
        +      "type": "number"
        +    },
        +    "diameter_um": {
        +      "description": "Expected object diameter in µm. Default: measured from the image (spots: 0.5 µm).",
        +      "type": "number"
        +    },
        +    "kind": {
        +      "default": "nuclei",
        +      "description": "Default nuclei. `nuclei` = nuclei (default): touching nuclei are split; `cells` = whole cells stained throughout (larger; touching cells are split); `spots` = small bright spots (puncta, foci, single molecules), found by a Laplacian of Gaussian.",
        +      "enum": [
        +        "nuclei",
        +        "cells",
        +        "spots"
        +      ],
        +      "type": "string"
        +    },
        +    "max_area_um2": {
        +      "description": "Largest object kept in µm². Default: no limit.",
        +      "type": "number"
        +    },
        +    "max_objects": {
        +      "description": "Objects listed (in reading order). Default 100; the counts cover all.",
        +      "type": "integer"
        +    },
        +    "method": {
        +      "default": "auto",
        +      "description": "Default auto. `auto` = Otsu's, or the triangle method when objects are sparse; `otsu` = Otsu's (two classes of similar spread); `triangle` = the triangle method (a big background peak, few objects); `local` = each pixel against its neighbourhood (uneven staining).",
        +      "enum": [
        +        "auto",
        +        "otsu",
        +        "triangle",
        +        "local"
        +      ],
        +      "type": "string"
        +    },
        +    "min_area_um2": {
        +      "description": "Smallest object kept in µm². Default: a fifth of the expected area.",
        +      "type": "number"
        +    },
        +    "polarity": {
        +      "default": "auto",
        +      "description": "Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).",
        +      "enum": [
        +        "auto",
        +        "bright",
        +        "dark"
        +      ],
        +      "type": "string"
        +    },
        +    "split": {
        +      "description": "Cut touching objects apart (seeded watershed). Default true.",
        +      "type": "boolean"
        +    },
        +    "stain": {
        +      "default": "auto",
        +      "description": "RGB images. Default auto. `auto` = hematoxylin for brightfield (stained tissue); for fluorescence, blue for nuclei when the blue component holds signal, else the brightest component; `hematoxylin` = the nuclear stain of H&E and IHC, by colour deconvolution; `eosin` = eosin, by colour deconvolution; `dab` = the brown IHC chromogen, by colour deconvolution; `red` = one component; `green` = one component; `blue` = one component; `luminance` = the mean of the components.",
        +      "enum": [
        +        "auto",
        +        "hematoxylin",
        +        "eosin",
        +        "dab",
        +        "red",
        +        "green",
        +        "blue",
        +        "luminance"
        +      ],
        +      "type": "string"
        +    },
        +    "threshold": {
        +      "description": "Threshold in raw units of what is measured (spots: the height above the local background). Default: chosen by `method`.",
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • removedInput schema / $defs / Region / properties / height / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / width / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / x / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / y / minimum
        Removed value: -0
      • addedInput schema / properties / annotations
        Added value: +{
        +  "description": "Your own marks, drawn on top and reported back with their pixel positions. Coordinates as the picture shows them: full-resolution pixels on images (the ruler numbers), axis units on plots, wells on plates.",
        +  "items": {
        +    "$ref": "#/$defs/Annotation"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / axes / description
        Previous value: -"Image previews: what frames the picture. What frames an image preview. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `none` = the bare downsampled plane."New value: +"Image previews: what frames the picture. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `scale-bar` = a figure for people: the picture with a scale bar, the title and the caption; no rulers; `none` = the bare downsampled plane."
      • changedInput schema / properties / axes / enum
        Previous value: -[
        -  "rulers",
        -  "grid",
        -  "none"
        -]New value: +[
        +  "rulers",
        +  "grid",
        +  "scale-bar",
        +  "none"
        +]
      • addedInput schema / properties / caption
        Added value: +{
        +  "description": "Image previews with axes scale-bar: a caption under the picture (what it shows, the stain, the sample).",
        +  "type": "string"
        +}
      • removedInput schema / properties / centroid / default
        Removed value: -false
      • removedInput schema / properties / channels / default
        Removed value: -[]
      • removedInput schema / properties / channels / items / minimum
        Removed value: -0
      • removedInput schema / properties / column
        Removed value: -{
        -  "description": "Plate preview (long layout): value column name.",
        -  "type": "string"
        -}
      • addedInput schema / properties / columns
        Added value: +{
        +  "description": "Table columns: a plate's value column, or the x and y parameters of a flow-cytometry density plot (one gives a histogram; default FSC-A, SSC-A).",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedInput schema / properties / composite / default
        Removed value: -false
      • changedInput schema / properties / contrast / description
        Previous value: -"`auto` (default), `min-max`, `percentile:LO,HI` (e.g. `percentile:1,99`) or `raw`."New value: +"`auto` (default; the file's display window when it has one, `log:90,99.95` on diffraction images), `min-max`, `percentile:LO,HI` (e.g. `percentile:1,99`), `log` (`log:50,99.9`) or `log:LO,HI`, `raw`, or a display window `window:CENTER,WIDTH` (`window:40,400`), `window:file`, or a CT preset `window:soft-tissue`, `brain`, `subdural`, `stroke`, `bone`, `lung`, `mediastinum`, `liver`."
      • addedInput schema / properties / dark
        Added value: +{
        +  "description": "Draw in the dark theme.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / fft
        Added value: +{
        +  "description": "Images: a power-spectrum (FFT) inset in the top-right corner: Thon rings of a cryo-EM micrograph, the spots of a lattice.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file."
      • changedInput schema / properties / format / description
        Previous value: -"Encoding. Default png (sent as JPEG when a PNG would be too large). Output encoding. `png` = lossless (default); `jpeg` = lossy and smaller."New value: +"Encoding. Default png (sent as JPEG when a PNG would be too large); svg also returns the vector drawing as text. `png` = lossless (default); `jpeg` = lossy and smaller; `svg` = vector: text stays text, image data is embedded as PNG."
      • changedInput schema / properties / format / enum
        Previous value: -[
        -  "png",
        -  "jpeg"
        -]New value: +[
        +  "png",
        +  "jpeg",
        +  "svg"
        +]
      • removedInput schema / properties / image / minimum
        Removed value: -0
      • addedInput schema / properties / lanes
        Added value: +{
        +  "$ref": "#/$defs/LanesRequest",
        +  "description": "Gels and blots: how lanes are found for `marks: lanes` (as `openreadout_stats` lanes)."
        +}
      • removedInput schema / properties / level / minimum
        Removed value: -0
      • changedInput schema / properties / lut / description
        Previous value: -"Colour lookup. Default: gray for one channel, channel colours for composites. Colour lookup for a single channel. `gray` = black to white; `channel-color` = black to the channel's colour."New value: +"Colour lookup. Default: gray for one channel (inverted on diffraction images), channel colours for composites. `gray` = black to white; `channel-color` = black to the channel's colour; `inverted` = white to black: dark marks on a light ground (diffraction images)."
      • changedInput schema / properties / lut / enum
        Previous value: -[
        -  "gray",
        -  "channel-color"
        -]New value: +[
        +  "gray",
        +  "channel-color",
        +  "inverted"
        +]
      • addedInput schema / properties / marks
        Added value: +{
        +  "description": "Marks from the data. Default auto: the prominent peaks of spectra and chromatograms are labelled; diffraction images get resolution rings. `auto` = label the largest peaks of spectra and chromatograms (default); `peaks` = label the largest peaks of any trace; `spikes` = mark the action potentials of current-clamp sweeps; `objects` = images: outline and number the nuclei, cells or spots found (`stats` objects); `lanes` = gels and blots: box and number the lanes, draw their profiles and bands (`stats` lanes); `rings` = diffraction images: resolution rings and the beam centre (auto draws them when the geometry is known); `none` = no marks.",
        +  "enum": [
        +    "auto",
        +    "peaks",
        +    "spikes",
        +    "objects",
        +    "lanes",
        +    "rings",
        +    "none"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / max_size / description
        Previous value: -"Longest side in pixels, rulers included (default 768, max 2048)."New value: +"Longest side in pixels, rulers included (MCP: default 768, at most 2048)."
      • removedInput schema / properties / max_size / minimum
        Removed value: -0
      • changedInput schema / properties / mip / description
        Previous value: -"Maximum-intensity projection, over the selected range if any. Axis of a maximum-intensity projection. `z` = along z (focal planes); `t` = along t (time points)."New value: +"Maximum-intensity projection, over the selected range if any. `z` = along z (focal planes); `t` = along t (time points)."
      • addedInput schema / properties / objects
        Added value: +{
        +  "$ref": "#/$defs/ObjectsRequest",
        +  "description": "Images: how objects are found for `marks: objects` (as `openreadout_stats` objects)."
        +}
      • removedInput schema / properties / run / minimum
        Removed value: -0
      • removedInput schema / properties / scan / minimum
        Removed value: -0
      • removedInput schema / properties / select / default
        Removed value: -[]
      • removedInput schema / properties / spectrum / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • addedInput schema / properties / sum
        Added value: +{
        +  "description": "Sum projection, over the selected range if any: a movie's frames added up (e.g. sum t, select t=0-39). `z` = along z (focal planes); `t` = along t (time points).",
        +  "enum": [
        +    "z",
        +    "t"
        +  ],
        +  "type": "string"
        +}
      • removedInput schema / properties / sweep / minimum
        Removed value: -0
      • changedInput schema / properties / table / description
        Previous value: -"Plate preview: table index."New value: +"Plate or flow-cytometry preview: table index."
      • removedInput schema / properties / table / minimum
        Removed value: -0
      • addedInput schema / properties / title
        Added value: +{
        +  "description": "Image previews with axes scale-bar: a title above the picture.",
        +  "type": "string"
        +}
      • removedInput schema / properties / trace / minimum
        Removed value: -0
      • addedInput schema / properties / view
        Added value: +{
        +  "description": "Volumes: the plane to show. `axial`, `coronal`, `sagittal` (radiological orientation), `orthogonal` (all three, crossing at the middle or the selected z), `xz`, `yz`, or `native` (as stored). Default: medical images in their acquisition plane, others native. With a view, `z` and `mip: z` count slices of that view. `native` = the planes as stored; `axial` = head-foot slices, patient's left on the right, anterior up; `coronal` = front-back slices, patient's left on the right, head up; `sagittal` = left-right slices, anterior on the left, head up; `orthogonal` = axial, coronal and sagittal planes through the volume's centre (or the selected z); `xz` = columns against z: a cut along the stack; `yz` = rows against z: a cut along the stack.",
        +  "enum": [
        +    "native",
        +    "axial",
        +    "coronal",
        +    "sagittal",
        +    "orthogonal",
        +    "xz",
        +    "yz"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / x_range
        Added value: +{
        +  "description": "Trace preview: only this window of the x axis, `[a, b]` in its units (bp of a sized electropherogram, base positions of a Sanger read, minutes, ppm, …).",
        +  "items": {
        +    "type": "number"
        +  },
        +  "maxItems": 2,
        +  "minItems": 2,
        +  "type": "array"
        +}
      • addedOutput schema / $defs / AnnotationType
        Added value: +{
        +  "description": "What an annotation draws.",
        +  "oneOf": [
        +    {
        +      "const": "point",
        +      "description": "a dot at x, y (with its label beside it)",
        +      "type": "string"
        +    },
        +    {
        +      "const": "box",
        +      "description": "a rectangle: corner x, y and width, height",
        +      "type": "string"
        +    },
        +    {
        +      "const": "polygon",
        +      "description": "a closed outline through points",
        +      "type": "string"
        +    },
        +    {
        +      "const": "line",
        +      "description": "an open line through points",
        +      "type": "string"
        +    },
        +    {
        +      "const": "arrow",
        +      "description": "an arrow from x, y (where the label goes) to x2, y2",
        +      "type": "string"
        +    },
        +    {
        +      "const": "text",
        +      "description": "the label alone, at x, y",
        +      "type": "string"
        +    },
        +    {
        +      "const": "vline",
        +      "description": "a vertical line at x",
        +      "type": "string"
        +    },
        +    {
        +      "const": "hline",
        +      "description": "a horizontal line at y",
        +      "type": "string"
        +    },
        +    {
        +      "const": "vband",
        +      "description": "a vertical band from x to x2",
        +      "type": "string"
        +    },
        +    {
        +      "const": "hband",
        +      "description": "a horizontal band from y to y2",
        +      "type": "string"
        +    },
        +    {
        +      "const": "well",
        +      "description": "a ring around a plate well (well; previews of plates only)",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedOutput schema / $defs / ChromatogramPreview
        Added value: +{
        +  "description": "Details of a chromatogram preview of a mass-spectrometry run (its first look).",
        +  "properties": {
        +    "apex_intensity": {
        +      "description": "Its intensity.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "apex_rt_min": {
        +      "description": "Retention time of the tallest point, minutes.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "ms1_scans": {
        +      "description": "MS1 scans drawn.",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "run": {
        +      "description": "Run index.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "scans": {
        +      "description": "Scans in the run (all MS levels).",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "signal": {
        +      "description": "`tic` (the total ion current each scan header records) or `bpc` (base-peak intensity).",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "run",
        +    "signal",
        +    "ms1_scans",
        +    "scans",
        +    "apex_rt_min",
        +    "apex_intensity"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / DataMark
        Added value: +{
        +  "description": "A mark drawn from the data: a labelled peak or a detected action potential.",
        +  "properties": {
        +    "channel": {
        +      "description": "Trace previews: the channel.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "kind": {
        +      "description": "`peak`, `spike`, `resolution_ring` (x: resolution in Å, y: radius in full-resolution\npixels) or `beam_center` (x, y: full-resolution pixels).",
        +      "type": "string"
        +    },
        +    "label": {
        +      "description": "The label drawn (e.g. the m/z or ppm), if any.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "x": {
        +      "description": "Position along the x axis, in its unit.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y": {
        +      "description": "Value there, in the panel's unit.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "kind",
        +    "x",
        +    "y"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / DrawnAnnotation
        Added value: +{
        +  "description": "An annotation as drawn: the request, plus where it landed in PNG pixels.",
        +  "properties": {
        +    "channel": {
        +      "description": "Trace previews with several panels: the channel whose panel it goes in (default: the\nfirst panel).",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "color": {
        +      "description": "`accent` (default, warm red), `ink`, `muted`, `white`, another colour name or `#RRGGBB`.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "drawn_color": {
        +      "description": "The colour drawn, `#RRGGBB`.",
        +      "type": "string"
        +    },
        +    "facet": {
        +      "description": "Plots with small multiples: the one small plot it goes in, by its title (e.g. `B3` or\n`sweep 6`; default: every one).",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "height": {
        +      "description": "box: height.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "label": {
        +      "description": "Text drawn with the mark (the text itself for type text).",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "label_px": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/PxRect"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Where the label went, in PNG pixels."
        +    },
        +    "outside": {
        +      "description": "True when part of the mark lies outside what the picture shows (it is clipped).",
        +      "type": "boolean"
        +    },
        +    "points": {
        +      "description": "polygon, line: the vertices, `[[x, y], ...]`.",
        +      "items": {
        +        "items": {
        +          "format": "double",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        },
        +        "maxItems": 2,
        +        "minItems": 2,
        +        "type": "array"
        +      },
        +      "type": "array"
        +    },
        +    "px": {
        +      "description": "The mark's key points in PNG pixels: the point, the box corners, the vertices, the\narrow's tail and head, a line's or band's ends (one pair per card on a curve grid).",
        +      "items": {
        +        "items": {
        +          "format": "double",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        },
        +        "maxItems": 2,
        +        "minItems": 2,
        +        "type": "array"
        +      },
        +      "type": "array"
        +    },
        +    "type": {
        +      "$ref": "#/$defs/AnnotationType",
        +      "description": "What to draw."
        +    },
        +    "well": {
        +      "description": "Plate previews: the well (e.g. `B3`) for type well, or the one card a mark goes in on a\ncurve grid (default: every card).",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "width": {
        +      "description": "box: width.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "x": {
        +      "description": "point, text: position; box: corner; arrow: tail; vline, vband: x (vband from x to x2).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "x2": {
        +      "description": "arrow: head; vband: other edge.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y": {
        +      "description": "point, text: position; box: corner; arrow: tail; hline, hband: y (hband from y to y2).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y2": {
        +      "description": "arrow: head; hband: other edge.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "type",
        +    "drawn_color",
        +    "px"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / EventsPreview
        Added value: +{
        +  "description": "Details of an event (flow cytometry) preview.",
        +  "properties": {
        +    "events": {
        +      "description": "Events drawn.",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "scales": {
        +      "description": "`linear` or `asinh` (each axis, x first).",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "table": {
        +      "description": "Table index.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "total_events": {
        +      "description": "Events in the table.",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "x": {
        +      "description": "Parameter on the x axis.",
        +      "type": "string"
        +    },
        +    "y": {
        +      "description": "Parameter on the y axis (absent for a histogram).",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "table",
        +    "x",
        +    "events",
        +    "total_events",
        +    "scales"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / ImagePreview / properties / crosshair
        Added value: +{
        +  "description": "Orthogonal views: the voxel (x, y, z of the stored planes) the three planes cross at.",
        +  "items": {
        +    "format": "uint32",
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "maxItems": 3,
        +  "minItems": 3,
        +  "type": [
        +    "array",
        +    "null"
        +  ]
        +}
      • changedOutput schema / $defs / ImagePreview / properties / downsample / description
        Previous value: -"Block size of the averaging downsample (1 = none)."New value: +"Pixels of the plane at `level` per drawn pixel, horizontally: above 1 when the plane was\nmade smaller (an area average), below 1 when it was enlarged (each source pixel drawn as\na square), 1 when drawn as is."
      • changedOutput schema / $defs / ImagePreview / properties / downsample / format
        Previous value: -"uint32"New value: +"double"
      • removedOutput schema / $defs / ImagePreview / properties / downsample / minimum
        Removed value: -0
      • changedOutput schema / $defs / ImagePreview / properties / downsample / type
        Previous value: -"integer"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / ImagePreview / properties / fft_inset
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/Region"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Where the power-spectrum inset is drawn (`fft`), in PNG pixels."
        +}
      • changedOutput schema / $defs / ImagePreview / properties / lut / description
        Previous value: -"`gray`, `channel-color` or `rgb`."New value: +"`gray`, `inverted`, `channel-color` or `rgb`."
      • changedOutput schema / $defs / ImagePreview / properties / projection / description
        Previous value: -"`max-z` or `max-t` for a maximum-intensity projection."New value: +"`max-z` or `max-t` for a maximum-intensity projection, `sum-z` or `sum-t` for a sum."
      • changedOutput schema / $defs / ImagePreview / properties / source_per_pixel / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ImagePreview / properties / source_per_pixel_y / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / ImagePreview / properties / view
        Added value: +{
        +  "description": "The plane of the volume shown, when it is not the stored planes: `axial`, `coronal`,\n`sagittal`, `orthogonal`, `xz` or `yz`. Rulers, regions and annotations then count the\npixels of that view.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / $defs / ImagePreview / properties / view_slices
        Added value: +{
        +  "description": "With a view: how many slices it has (the range of `z`).",
        +  "format": "uint32",
        +  "minimum": 0,
        +  "type": [
        +    "integer",
        +    "null"
        +  ]
        +}
      • changedOutput schema / $defs / ImagePreview / required
        Previous value: -[
        -  "image",
        -  "level",
        -  "source_width",
        -  "source_height",
        -  "downsample",
        -  "c",
        -  "z",
        -  "t",
        -  "composite",
        -  "rgb",
        -  "contrast",
        -  "lut",
        -  "channels"
        -]New value: +[
        +  "image",
        +  "level",
        +  "source_width",
        +  "source_height",
        +  "downsample",
        +  "c",
        +  "z",
        +  "t",
        +  "composite",
        +  "rgb",
        +  "contrast",
        +  "lut",
        +  "channels",
        +  "axes",
        +  "plot_area",
        +  "source_origin",
        +  "source_per_pixel",
        +  "source_per_pixel_y",
        +  "full_res_region"
        +]
      • addedOutput schema / $defs / PlateGroup
        Added value: +{
        +  "description": "One layout group of a plate preview (a SoftMax Pro group, a sample name, …).",
        +  "properties": {
        +    "blank": {
        +      "description": "True for blank wells (drawn faint).",
        +      "type": "boolean"
        +    },
        +    "color": {
        +      "description": "Colour it is drawn in, `#RRGGBB`.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "Group name as the file records it.",
        +      "type": "string"
        +    },
        +    "wells": {
        +      "description": "Wells in the group.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "name",
        +    "color",
        +    "wells"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / $defs / PlatePreview / description
        Previous value: -"Details of a plate heat map."New value: +"Details of a plate preview."
      • addedOutput schema / $defs / PlatePreview / properties / grouped_by
        Added value: +{
        +  "description": "The layout field the colours follow (e.g. `SoftMax group`).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / $defs / PlatePreview / properties / groups
        Added value: +{
        +  "description": "The groups, in the order of the key.",
        +  "items": {
        +    "$ref": "#/$defs/PlateGroup"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / $defs / PlatePreview / properties / max / description
        Previous value: -"Value shown at the yellow end of the scale."New value: +"Heat map: value at the dark end of the colour scale; curves: top of every card's y axis."
      • changedOutput schema / $defs / PlatePreview / properties / min / description
        Previous value: -"Colour-scale ends (dark = min, yellow = max)."New value: +"Heat map: value at the light end of the colour scale; curves: bottom of every card's y\naxis."
      • addedOutput schema / $defs / PlatePreview / properties / time
        Added value: +{
        +  "description": "Curves: the time axis every card shares, in `time_unit`.",
        +  "items": {
        +    "format": "double",
        +    "type": [
        +      "number",
        +      "null"
        +    ]
        +  },
        +  "maxItems": 2,
        +  "minItems": 2,
        +  "type": [
        +    "array",
        +    "null"
        +  ]
        +}
      • addedOutput schema / $defs / PlatePreview / properties / time_unit
        Added value: +{
        +  "description": "Curves: `s`, `min` or `h`.",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
      • addedOutput schema / $defs / PlatePreview / properties / view
        Added value: +{
        +  "description": "`heatmap` (one value per well) or `curves` (a kinetic read, one small plot per well).",
        +  "type": "string"
        +}
      • changedOutput schema / $defs / PlatePreview / required
        Previous value: -[
        -  "table",
        -  "layout",
        -  "rows",
        -  "columns",
        -  "wells",
        -  "value"
        -]New value: +[
        +  "table",
        +  "layout",
        +  "view",
        +  "rows",
        +  "columns",
        +  "wells",
        +  "value"
        +]
      • addedOutput schema / $defs / PlotPanel
        Added value: +{
        +  "description": "One plot panel inside the picture, for mapping PNG pixels to data values and back: the\nvalue at the panel's left edge is `x[0]`, at its right edge `x[1]`, at its bottom `y[0]`\nand at its top `y[1]`, along the scale named in `x_scale` / `y_scale`.",
        +  "properties": {
        +    "channel": {
        +      "description": "Trace previews: the channel drawn in this panel.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "plot_area": {
        +      "$ref": "#/$defs/PxRect",
        +      "description": "The panel's rectangle in PNG pixels."
        +    },
        +    "well": {
        +      "description": "Plate curve previews: the well of this card.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "x": {
        +      "description": "Values at the left and right edges.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "maxItems": 2,
        +      "minItems": 2,
        +      "type": "array"
        +    },
        +    "x_scale": {
        +      "description": "`linear`, `log` or `asinh`.",
        +      "type": "string"
        +    },
        +    "y": {
        +      "description": "Values at the bottom and top edges.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "maxItems": 2,
        +      "minItems": 2,
        +      "type": "array"
        +    },
        +    "y_scale": {
        +      "description": "`linear`, `log` or `asinh`.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "plot_area",
        +    "x",
        +    "y",
        +    "x_scale",
        +    "y_scale"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / $defs / PreviewChannel / properties / display_max / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / PreviewChannel / properties / display_min / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / PxRect
        Added value: +{
        +  "description": "A rectangle in PNG pixels (fractional).",
        +  "properties": {
        +    "height": {
        +      "description": "Height.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "width": {
        +      "description": "Width.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "x": {
        +      "description": "Left edge.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y": {
        +      "description": "Top edge.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "x",
        +    "y",
        +    "width",
        +    "height"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / $defs / ScaleBar / properties / length / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ScaleBar / properties / length_um / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SourcePoint / properties / x / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SourcePoint / properties / y / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SpectrumPreview / properties / max_intensity / description
        Previous value: -"Largest intensity (the top of the plot)."New value: +"Largest intensity."
      • changedOutput schema / $defs / SpectrumPreview / required
        Previous value: -[
        -  "run",
        -  "index",
        -  "scan_number",
        -  "ms_level",
        -  "style",
        -  "point_count",
        -  "x_axis"
        -]New value: +[
        +  "run",
        +  "index",
        +  "scan_number",
        +  "ms_level",
        +  "rt_s",
        +  "style",
        +  "point_count",
        +  "x_axis"
        +]
      • changedOutput schema / $defs / TracePreview / properties / channels / description
        Previous value: -"One panel per channel, top to bottom."New value: +"One panel per channel, top to bottom (one shared panel for overlays)."
      • changedOutput schema / $defs / TracePreview / properties / sample_rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / TracePreviewChannel / properties / min / description
        Previous value: -"Bottom and top of the panel's y axis (the channel's finite range, padded by 5 %)."New value: +"Bottom of the panel's y axis."
      • changedOutput schema / $defs / XAxis / description
        Previous value: -"The horizontal axis of a trace or spectrum preview (the labels at its two ends)."New value: +"The horizontal axis of a trace or spectrum preview."
      • changedOutput schema / $defs / XAxis / properties / first / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / XAxis / properties / last / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / properties / annotations
        Added value: +{
        +  "description": "The caller's annotations as drawn: each as given, plus where it landed in PNG pixels.",
        +  "items": {
        +    "$ref": "#/$defs/DrawnAnnotation"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / chromatogram
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/ChromatogramPreview"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Present for chromatogram previews (a mass-spectrometry run's total-ion chromatogram)."
        +}
      • changedOutput schema / properties / encoding / description
        Previous value: -"`png` or `jpeg`."New value: +"`png`, `jpeg` or `svg`."
      • addedOutput schema / properties / events
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/EventsPreview"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Present for event previews."
        +}
      • changedOutput schema / properties / kind / description
        Previous value: -"`image`, `trace`, `spectrum` or `plate`."New value: +"`image`, `trace`, `chromatogram`, `spectrum`, `plate` or `events`."
      • addedOutput schema / properties / lanes
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "`marks: lanes`: the lanes and bands found in the area shown, as `stats` lanes.",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / marks
        Added value: +{
        +  "description": "Marks drawn from the data (labelled peaks, action potentials).",
        +  "items": {
        +    "$ref": "#/$defs/DataMark"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / objects
        Added value: +{
        +  "additionalProperties": true,
        +  "description": "`marks: objects`: the objects counted in the area shown, as `stats` objects (the first\n20 listed).",
        +  "type": [
        +    "object",
        +    "null"
        +  ]
        +}
      • addedOutput schema / properties / panels
        Added value: +{
        +  "description": "Plot panels (traces, spectra, plate curves, events): where each sits in the picture and\nthe data range it shows.",
        +  "items": {
        +    "$ref": "#/$defs/PlotPanel"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / save
        Added value: +{
        +  "description": "How to save this picture to a file (MCP: the openreadout_export call).",
        +  "type": [
        +    "string",
        +    "null"
        +  ]
        +}
    • Changedopenreadout_qpcr25 fields changed
      • removedInput schema / properties / baseline_end / minimum
        Removed value: -0
      • removedInput schema / properties / baseline_start / minimum
        Removed value: -0
      • removedInput schema / properties / compute_cq / default
        Removed value: -false
      • changedInput schema / properties / cq_method / description
        Previous value: -"How `compute_cq` computes Cq; default: `second-derivative` for LightCycler 480 `.ixo` files without a threshold or baseline window, else `threshold`. How our Cq is computed (none of the methods reads the vendor's Cq or call). `threshold` = Where the baseline-corrected curve crosses a threshold; `stored-threshold` = A threshold crossing with only the threshold and baseline the file stores; `second-derivative` = The maximum of the second derivative, as the LightCycler 480 places its Cp."New value: +"How `compute_cq` computes Cq; default: `second-derivative` for LightCycler 480 `.ixo` files without a threshold or baseline window, else `threshold`. `threshold` = Where the baseline-corrected curve crosses a threshold; `stored-threshold` = A threshold crossing with only the threshold and baseline the file stores; `second-derivative` = The maximum of the second derivative, as the LightCycler 480 places its Cp."
      • removedInput schema / properties / ddcq / default
        Removed value: -false
      • addedInput schema / properties / fields
        Added value: +{
        +  "description": "Rows show their main fields to 4 significant digits (records: well, sample, target, cq, tm; relative_quantities: cq means, delta_cq, delta_delta_cq, rq with rq_min and rq_max). fields adds others, e.g. `[\"threshold\"]`; `[\"all\"]`: every field, full precision.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / max_records / minimum
        Removed value: -0
      • removedInput schema / properties / reference_targets / default
        Removed value: -[]
      • removedInput schema / properties / standard_curve / default
        Removed value: -false
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • changedOutput schema / $defs / CqComparison / required
        Previous value: -[
        -  "cq_method",
        -  "method",
        -  "curves",
        -  "both_cq",
        -  "both_undetermined",
        -  "only_vendor",
        -  "only_ours",
        -  "vendor_threshold_used"
        -]New value: +[
        +  "cq_method",
        +  "method",
        +  "curves",
        +  "both_cq",
        +  "both_undetermined",
        +  "only_vendor",
        +  "only_ours",
        +  "vendor_threshold_used",
        +  "mean_difference",
        +  "mean_abs_difference",
        +  "median_abs_difference",
        +  "max_abs_difference",
        +  "within_0_1",
        +  "within_0_5",
        +  "pearson_r"
        +]
      • changedOutput schema / $defs / QpcrAssayRecord / properties / tm / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / $defs / QpcrAssayRecord / required
        Removed value: -[
        -  "run",
        -  "well",
        -  "row",
        -  "col",
        -  "cq_undetermined",
        -  "cq_status",
        -  "tm",
        -  "flags",
        -  "cycles"
        -]
      • changedOutput schema / $defs / RelativeQuantity / properties / cq_mean / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / RelativeQuantity / properties / delta_cq / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / RelativeQuantity / properties / reference_cq_mean / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • removedOutput schema / $defs / RelativeQuantity / required
        Removed value: -[
        -  "sample",
        -  "target",
        -  "replicates",
        -  "undetermined",
        -  "cq_mean",
        -  "reference_cq_mean",
        -  "delta_cq"
        -]
      • changedOutput schema / $defs / StandardCurveFit / properties / efficiency_percent / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / StandardCurveFit / properties / intercept / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / StandardCurveFit / properties / r2 / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / StandardCurveFit / properties / slope / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / StandardCurveFit / required
        Previous value: -[
        -  "target",
        -  "points",
        -  "levels",
        -  "slope",
        -  "intercept",
        -  "r2",
        -  "efficiency_percent"
        -]New value: +[
        +  "target",
        +  "points",
        +  "levels",
        +  "slope",
        +  "intercept",
        +  "r2",
        +  "efficiency_percent",
        +  "vendor_slope",
        +  "vendor_efficiency_percent",
        +  "vendor_r2"
        +]
      • changedOutput schema / $defs / TargetCqSummary / required
        Previous value: -[
        -  "target",
        -  "counts",
        -  "averaged"
        -]New value: +[
        +  "target",
        +  "counts",
        +  "averaged",
        +  "cq_mean",
        +  "cq_sd",
        +  "cq_min",
        +  "cq_max"
        +]
      • changedOutput schema / required
        Previous value: -[
        -  "path",
        -  "format",
        -  "dialect",
        -  "reference_targets",
        -  "record_count",
        -  "truncated",
        -  "records",
        -  "cq_counts",
        -  "targets",
        -  "relative_quantities",
        -  "standard_curves",
        -  "notes"
        -]New value: +[
        +  "path",
        +  "format",
        +  "dialect",
        +  "reference_targets",
        +  "record_count",
        +  "truncated",
        +  "records",
        +  "cq_counts",
        +  "targets",
        +  "notes"
        +]
    • Changedopenreadout_report1 field changed
      • removedInput schema / properties / include_text / default
        Removed value: -false
    • Changedopenreadout_scans13 fields changed
      • removedInput schema / properties / count / default
        Removed value: -false
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the mass-spectrometry file."New value: +"Path to the mass-spectrometry file."
      • removedInput schema / properties / limit / minimum
        Removed value: -0
      • removedInput schema / properties / ms_level / minimum
        Removed value: -0
      • removedInput schema / properties / offset / default
        Removed value: -0
      • removedInput schema / properties / offset / minimum
        Removed value: -0
      • removedInput schema / properties / run / default
        Removed value: -0
      • removedInput schema / properties / run / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • changedOutput schema / $defs / ScanHeader / properties / isolation_window_mz / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ScanHeader / properties / scan_window_mz / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ScanHeader / required
        Previous value: -[
        -  "index",
        -  "scan_number",
        -  "ms_level",
        -  "polarity",
        -  "centroided"
        -]New value: +[
        +  "index",
        +  "scan_number",
        +  "ms_level",
        +  "rt_s",
        +  "polarity",
        +  "centroided"
        +]
      • changedOutput schema / properties / rt_range_s / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_search3 fields changed
      • removedInput schema / properties / fields / default
        Removed value: -[]
      • removedInput schema / properties / limit / minimum
        Removed value: -0
      • removedInput schema / properties / query / default
        Removed value: -""
    • Changedopenreadout_spectrum20 fields changed
      • removedInput schema / properties / centroid / default
        Removed value: -false
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the mass-spectrometry file."New value: +"Path to the mass-spectrometry file."
      • changedInput schema / properties / max_points / description
        Previous value: -"At most this many points (default 2000; point_count reports the full size)."New value: +"At most this many points, the most intense kept (default 1000; point_count reports the full size)."
      • removedInput schema / properties / max_points / minimum
        Removed value: -0
      • removedInput schema / properties / ms_level / minimum
        Removed value: -0
      • addedInput schema / properties / rt
        Added value: +{
        +  "description": "The MS scan (of ms_level, default 1) nearest this retention time, minutes: the spectrum at a chromatogram's apex.",
        +  "type": "number"
        +}
      • removedInput schema / properties / run / default
        Removed value: -0
      • removedInput schema / properties / run / minimum
        Removed value: -0
      • removedInput schema / properties / scan / minimum
        Removed value: -0
      • removedInput schema / properties / spectrum / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • addedInput schema / properties / top_peaks
        Added value: +{
        +  "description": "Most intense peaks listed under peaks[] with charge and neutral mass (default 20).",
        +  "type": "integer"
        +}
      • addedOutput schema / $defs / MsPeak
        Added value: +{
        +  "description": "One of the most intense peaks of a mass spectrum, with its charge from the isotope pattern.",
        +  "properties": {
        +    "charge": {
        +      "description": "Charge from the spacing of the isotope peaks above it (1.00336/z), when at least one\nis found.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "intensity": {
        +      "description": "Intensity.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "isotopes": {
        +      "description": "Isotope peaks found in a row above this one at that spacing.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": [
        +        "integer",
        +        "null"
        +      ]
        +    },
        +    "monoisotopic_mz": {
        +      "description": "m/z of the lowest peak of the same isotope pattern (the monoisotopic ion when it is\nseen), when it is below this one.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "mz": {
        +      "description": "m/z.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "neutral_mass_da": {
        +      "description": "Neutral monoisotopic mass (z · (m/z ∓ proton)), Da, when the charge and polarity are\nknown.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "mz",
        +    "intensity"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / $defs / Spectrum / properties / intensity / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spectrum / properties / isolation_window_mz / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spectrum / properties / mz / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spectrum / properties / scan_window_mz / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Spectrum / required
        Previous value: -[
        -  "index",
        -  "scan_number",
        -  "ms_level",
        -  "polarity",
        -  "centroided",
        -  "mz",
        -  "intensity"
        -]New value: +[
        +  "index",
        +  "scan_number",
        +  "ms_level",
        +  "rt_s",
        +  "polarity",
        +  "centroided",
        +  "mz",
        +  "intensity"
        +]
      • addedOutput schema / properties / peaks
        Added value: +{
        +  "description": "The most intense peaks of the whole spectrum, with charges from their isotope patterns.",
        +  "items": {
        +    "$ref": "#/$defs/MsPeak"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / properties / truncated / description
        Previous value: -"True when `mz`/`intensity` were shortened to `max_points`."New value: +"True when `mz`/`intensity` were shortened to `max_points` (the most intense points are\nkept, in m/z order)."
    • Changedopenreadout_spikes20 fields changed
      • removedInput schema / properties / channels / default
        Removed value: -[]
      • removedInput schema / properties / channels / items / minimum
        Removed value: -0
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file or data-set directory."New value: +"Path to the file or data-set directory."
      • removedInput schema / properties / max_times / minimum
        Removed value: -0
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / sweeps / items / minimum
        Removed value: -0
      • removedInput schema / properties / trace / default
        Removed value: -0
      • removedInput schema / properties / trace / minimum
        Removed value: -0
      • changedOutput schema / $defs / ChannelSpikes / properties / duration_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChannelSpikes / properties / noise / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChannelSpikes / properties / rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChannelSpikes / properties / threshold / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / ChannelSpikes / required
        Previous value: -[
        -  "channel",
        -  "name",
        -  "noise",
        -  "threshold",
        -  "spike_count",
        -  "rate_hz",
        -  "duration_s",
        -  "times",
        -  "times_truncated"
        -]New value: +[
        +  "channel",
        +  "name",
        +  "unit",
        +  "noise",
        +  "threshold",
        +  "spike_count",
        +  "rate_hz",
        +  "duration_s",
        +  "times",
        +  "times_truncated"
        +]
      • changedOutput schema / $defs / DetectSettings / properties / exclude_ms / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / DetectSettings / properties / high_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / DetectSettings / properties / low_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / DetectSettings / properties / threshold / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SpikeTime / properties / amplitude / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SpikeTime / properties / time_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / properties / sample_rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_stats46 fields changed
      • addedInput schema / $defs / LadderRequest
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "The marker lane and its sizes.",
        +  "properties": {
        +    "lane": {
        +      "description": "Lane number of the marker (1 = leftmost).",
        +      "type": "integer"
        +    },
        +    "sizes": {
        +      "description": "Marker sizes from the top of the lane down (largest first), e.g. kDa or bp.",
        +      "items": {
        +        "type": "number"
        +      },
        +      "type": "array"
        +    },
        +    "unit": {
        +      "description": "Unit of the sizes, e.g. `kDa` or `bp`.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "lane",
        +    "sizes"
        +  ],
        +  "type": "object"
        +}
      • addedInput schema / $defs / LanesRequest
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "How lanes and bands are found. Everything is optional.",
        +  "properties": {
        +    "count": {
        +      "description": "Number of lanes. Default: found from the image.",
        +      "type": "integer"
        +    },
        +    "ladder": {
        +      "$ref": "#/$defs/LadderRequest",
        +      "description": "The marker lane and its sizes; bands then get sizes."
        +    },
        +    "min_share": {
        +      "description": "Bands lower than this share of the lane's highest band are dropped. Default 0.05.",
        +      "type": "number"
        +    },
        +    "polarity": {
        +      "default": "auto",
        +      "description": "Bright bands (fluorescence, chemiluminescence) or dark ones (stains). Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).",
        +      "enum": [
        +        "auto",
        +        "bright",
        +        "dark"
        +      ],
        +      "type": "string"
        +    },
        +    "profiles": {
        +      "description": "Return each lane's profile (200 values from the top down). Default false.",
        +      "type": "boolean"
        +    },
        +    "width_px": {
        +      "description": "Lane width in pixels. Default 0.7 lane pitches.",
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / $defs / ObjectsRequest
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "How objects are found. Everything is optional; the defaults suit nuclei.",
        +  "properties": {
        +    "diameter_px": {
        +      "description": "The same in pixels, for images without a pixel size.",
        +      "type": "number"
        +    },
        +    "diameter_um": {
        +      "description": "Expected object diameter in µm. Default: measured from the image (spots: 0.5 µm).",
        +      "type": "number"
        +    },
        +    "kind": {
        +      "default": "nuclei",
        +      "description": "Default nuclei. `nuclei` = nuclei (default): touching nuclei are split; `cells` = whole cells stained throughout (larger; touching cells are split); `spots` = small bright spots (puncta, foci, single molecules), found by a Laplacian of Gaussian.",
        +      "enum": [
        +        "nuclei",
        +        "cells",
        +        "spots"
        +      ],
        +      "type": "string"
        +    },
        +    "max_area_um2": {
        +      "description": "Largest object kept in µm². Default: no limit.",
        +      "type": "number"
        +    },
        +    "max_objects": {
        +      "description": "Objects listed (in reading order). Default 100; the counts cover all.",
        +      "type": "integer"
        +    },
        +    "method": {
        +      "default": "auto",
        +      "description": "Default auto. `auto` = Otsu's, or the triangle method when objects are sparse; `otsu` = Otsu's (two classes of similar spread); `triangle` = the triangle method (a big background peak, few objects); `local` = each pixel against its neighbourhood (uneven staining).",
        +      "enum": [
        +        "auto",
        +        "otsu",
        +        "triangle",
        +        "local"
        +      ],
        +      "type": "string"
        +    },
        +    "min_area_um2": {
        +      "description": "Smallest object kept in µm². Default: a fifth of the expected area.",
        +      "type": "number"
        +    },
        +    "polarity": {
        +      "default": "auto",
        +      "description": "Default auto. `auto` = from the image: dark objects on a bright background (brightfield) or bright ones; `bright` = objects brighter than the background (fluorescence); `dark` = objects darker than the background (brightfield).",
        +      "enum": [
        +        "auto",
        +        "bright",
        +        "dark"
        +      ],
        +      "type": "string"
        +    },
        +    "split": {
        +      "description": "Cut touching objects apart (seeded watershed). Default true.",
        +      "type": "boolean"
        +    },
        +    "stain": {
        +      "default": "auto",
        +      "description": "RGB images. Default auto. `auto` = hematoxylin for brightfield (stained tissue); for fluorescence, blue for nuclei when the blue component holds signal, else the brightest component; `hematoxylin` = the nuclear stain of H&E and IHC, by colour deconvolution; `eosin` = eosin, by colour deconvolution; `dab` = the brown IHC chromogen, by colour deconvolution; `red` = one component; `green` = one component; `blue` = one component; `luminance` = the mean of the components.",
        +      "enum": [
        +        "auto",
        +        "hematoxylin",
        +        "eosin",
        +        "dab",
        +        "red",
        +        "green",
        +        "blue",
        +        "luminance"
        +      ],
        +      "type": "string"
        +    },
        +    "threshold": {
        +      "description": "Threshold in raw units of what is measured (spots: the height above the local background). Default: chosen by `method`.",
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • removedInput schema / $defs / Region / properties / height / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / width / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / x / minimum
        Removed value: -0
      • removedInput schema / $defs / Region / properties / y / minimum
        Removed value: -0
      • removedInput schema / properties / bins / minimum
        Removed value: -0
      • removedInput schema / properties / image / minimum
        Removed value: -0
      • addedInput schema / properties / lanes
        Added value: +{
        +  "$ref": "#/$defs/LanesRequest",
        +  "description": "Lanes and bands of a gel or blot in `region` or the whole plane: each lane's total and each band's row and background-subtracted volume (with `ladder`, its size). `{}` finds the lanes; preview marks=lanes draws them."
        +}
      • removedInput schema / properties / level / default
        Removed value: -0
      • removedInput schema / properties / level / minimum
        Removed value: -0
      • addedInput schema / properties / line
        Added value: +{
        +  "description": "Intensity profile along the line `[x0, y0, x1, y1]` (pixels of `level`, as on the preview rulers): values per channel, peak position and FWHM in px and µm.",
        +  "items": {
        +    "type": "number"
        +  },
        +  "maxItems": 4,
        +  "minItems": 4,
        +  "type": "array"
        +}
      • addedInput schema / properties / line_width
        Added value: +{
        +  "description": "Profile width in pixels, averaged across the line. Default 1.",
        +  "type": "integer"
        +}
      • changedInput schema / properties / mip / description
        Previous value: -"Maximum-intensity projection first: `z` (per image, channel and time point: the largest value of each pixel over the selected z planes) or `t`; the statistics are of the projections. The axis of a maximum-intensity projection (`stats --mip z`). `z` = Along z: one projected plane per image, channel and time point; `t` = Along t: one projected plane per image, channel and z."New value: +"Maximum-intensity projection first: `z` (per image, channel and time point: the largest value of each pixel over the selected z planes) or `t`; the statistics are of the projections. `z` = Along z: one projected plane per image, channel and time point; `t` = Along t: one projected plane per image, channel and z."
      • addedInput schema / properties / objects
        Added value: +{
        +  "$ref": "#/$defs/ObjectsRequest",
        +  "description": "Count objects in `region`, `polygon` or the whole plane: count, density, sizes, centroids, each object's mean in every channel and how many are positive per channel. `{}` counts nuclei with settings taken from the image (size, threshold, H&E colour deconvolution). Found in a DNA-stain channel unless `select` names one."
        +}
      • addedInput schema / properties / polygon
        Added value: +{
        +  "description": "Statistics inside this polygon `[[x, y], ...]` (pixels of `level`): area, mean, std, median, sum per channel.",
        +  "items": {
        +    "items": {
        +      "type": "number"
        +    },
        +    "maxItems": 2,
        +    "minItems": 2,
        +    "type": "array"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / scale / description
        Previous value: -"Histogram spacing: `linear` (default) or `log`. Spacing of histogram bin edges. `linear` = Equal-width bins from `min` to `max` (integer data: to `max + 1`, so each bin holds whole values); `log` = Geometrically spaced bins from the smallest positive value to `max`; values ≤ 0 are counted in `nonpositive`. Suited to data spanning decades (photon counts, spectra)."New value: +"Histogram spacing: `linear` (default) or `log`. `linear` = Equal-width bins from `min` to `max` (integer data: to `max + 1`, so each bin holds whole values); `log` = Geometrically spaced bins from the smallest positive value to `max`; values ≤ 0 are counted in `nonpositive`. Suited to data spanning decades (photon counts, spectra)."
      • removedInput schema / properties / select / default
        Removed value: -[]
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / wells / default
        Removed value: -[]
      • addedOutput schema / $defs / Band
        Added value: +{
        +  "description": "One band.",
        +  "properties": {
        +    "fraction_of_lane": {
        +      "description": "Share of the lane's band volume.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "height": {
        +      "description": "Height of the maximum above the background, in stored units.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "number": {
        +      "description": "Band number in its lane, from the top.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "relative": {
        +      "description": "Volume relative to the strongest band of the image (1 = the strongest band).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "saturated_px": {
        +      "description": "Pixels of the band at the saturation level: its volume is a lower bound.",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "size": {
        +      "description": "Size from the ladder, in its unit.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "volume": {
        +      "description": "Background-subtracted volume: stored units × pixels.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y": {
        +      "description": "Row of the band's maximum (full-resolution pixels).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y_range": {
        +      "description": "First and last row of the band.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "maxItems": 2,
        +      "minItems": 2,
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "number",
        +    "y",
        +    "y_range",
        +    "height",
        +    "volume",
        +    "fraction_of_lane",
        +    "relative"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / CountConfidence
        Added value: +{
        +  "description": "How far a count can be trusted.",
        +  "oneOf": [
        +    {
        +      "const": "high",
        +      "description": "the objects look like what was asked for",
        +      "type": "string"
        +    },
        +    {
        +      "const": "low",
        +      "description": "many objects are irregular or of the wrong size: check a picture before quoting the count",
        +      "type": "string"
        +    }
        +  ]
        +}
      • changedOutput schema / $defs / Histogram / properties / edges / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / Kind
        Added value: +{
        +  "description": "What to count.",
        +  "oneOf": [
        +    {
        +      "const": "nuclei",
        +      "description": "nuclei (default): touching nuclei are split",
        +      "type": "string"
        +    },
        +    {
        +      "const": "cells",
        +      "description": "whole cells stained throughout (larger; touching cells are split)",
        +      "type": "string"
        +    },
        +    {
        +      "const": "spots",
        +      "description": "small bright spots (puncta, foci, single molecules), found by a Laplacian of Gaussian",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedOutput schema / $defs / Lane
        Added value: +{
        +  "description": "One lane.",
        +  "properties": {
        +    "background": {
        +      "description": "Its background, at the same rows.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "type": "array"
        +    },
        +    "band_volume": {
        +      "description": "Sum of the band volumes.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "bands": {
        +      "description": "The bands, top first.",
        +      "items": {
        +        "$ref": "#/$defs/Band"
        +      },
        +      "type": "array"
        +    },
        +    "empty": {
        +      "description": "True when no band was found (or the lane was placed in a gap between found lanes).",
        +      "type": "boolean"
        +    },
        +    "number": {
        +      "description": "Lane number, 1 = leftmost.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "profile": {
        +      "description": "The profile from the top down, `profile_step_px` apart (with `profiles: true`).",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "type": "array"
        +    },
        +    "total_volume": {
        +      "description": "Background-subtracted volume of the whole lane (stored units × pixels): the total\nsignal, e.g. for normalising to a total-protein stain.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "x": {
        +      "description": "Centre column (full-resolution pixels).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "x_range": {
        +      "description": "Left and right edges.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "maxItems": 2,
        +      "minItems": 2,
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "number",
        +    "x",
        +    "x_range",
        +    "total_volume",
        +    "band_volume",
        +    "bands"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Lanes
        Added value: +{
        +  "description": "Lanes and bands of one plane.",
        +  "properties": {
        +    "band_count": {
        +      "description": "Bands found over all lanes.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "bin": {
        +      "description": "Full-resolution pixels per analysed pixel (1 unless the plane was binned).",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "c": {
        +      "description": "The channel measured.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "count": {
        +      "description": "Lanes found.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "lane_contrast": {
        +      "description": "How far the lanes stand out from the gaps between them: 1 − gap signal / lane signal of\nthe column profile (0 = not at all; below 0.15 the lanes are a guess).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "lanes": {
        +      "description": "The lanes, left to right.",
        +      "items": {
        +        "$ref": "#/$defs/Lane"
        +      },
        +      "type": "array"
        +    },
        +    "pitch_px": {
        +      "description": "Distance between neighbouring lane centres, pixels.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "polarity": {
        +      "description": "`bright` or `dark` bands, as measured.",
        +      "type": "string"
        +    },
        +    "profile_step_px": {
        +      "description": "Distance between profile values, pixels (with `profiles: true`).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "saturation_level": {
        +      "description": "The value counted as saturated, when the pixel type has one.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "size_unit": {
        +      "description": "Unit of band sizes (from the ladder).",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "width_px": {
        +      "description": "Lane width, pixels.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y_range": {
        +      "description": "Rows the lanes span: first and last (full-resolution pixels).",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "maxItems": 2,
        +      "minItems": 2,
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "count",
        +    "polarity",
        +    "pitch_px",
        +    "width_px",
        +    "y_range",
        +    "c",
        +    "bin",
        +    "band_count",
        +    "lanes"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / MeasureOutput
        Added value: +{
        +  "description": "Measurements on one plane: a line profile, statistics inside a polygon or an object count.",
        +  "properties": {
        +    "downsample": {
        +      "description": "Level-0 pixels per pixel of this level (1 at level 0).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "format": {
        +      "description": "Format id.",
        +      "type": "string"
        +    },
        +    "image": {
        +      "description": "Image index.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "lanes": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Lanes"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Lanes and bands."
        +    },
        +    "level": {
        +      "description": "Pyramid level read; coordinates are its pixels.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "notes": {
        +      "description": "What was assumed.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "objects": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Objects"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Objects."
        +    },
        +    "path": {
        +      "description": "The file.",
        +      "type": "string"
        +    },
        +    "pixel_size_um": {
        +      "description": "Pixel size at this level in µm, when recorded.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "profile": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Profile"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Profile along `line`."
        +    },
        +    "roi": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Roi"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Statistics inside `polygon`."
        +    },
        +    "t": {
        +      "description": "The time point read.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "z": {
        +      "description": "The z plane read.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "path",
        +    "format",
        +    "image",
        +    "level",
        +    "downsample",
        +    "z",
        +    "t"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Object
        Added value: +{
        +  "description": "One object.",
        +  "properties": {
        +    "area_px": {
        +      "description": "Pixels.",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "area_um2": {
        +      "description": "Area in µm².",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "diameter_um": {
        +      "description": "Diameter of a disc of the same area, in µm.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "edge": {
        +      "description": "True when the object touches the edge of the area searched (it may be cut).",
        +      "type": "boolean"
        +    },
        +    "height": {
        +      "description": "Spots: height above the local background in what was measured.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "id": {
        +      "description": "Number, in reading order (the label on a picture of the objects).",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "mean": {
        +      "description": "Mean raw value in each channel of `channels`, in that order.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "type": "array"
        +    },
        +    "solidity": {
        +      "description": "Area over the area of its convex hull (1 = convex; low values suggest merged objects).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "x": {
        +      "description": "Centroid column, in pixels of the level read.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "y": {
        +      "description": "Centroid row.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "x",
        +    "y",
        +    "area_px",
        +    "mean"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / ObjectChannel
        Added value: +{
        +  "description": "One channel measured in every object.",
        +  "properties": {
        +    "background": {
        +      "description": "Median value outside the objects.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "c": {
        +      "description": "Channel index (`c`), or the RGB component or stain index.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "mean": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Spread"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Object means."
        +    },
        +    "name": {
        +      "description": "Channel, component or stain name.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "positive": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Positive"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Objects clearly brighter than the rest (or than the background)."
        +    }
        +  },
        +  "required": [
        +    "c",
        +    "background"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Objects
        Added value: +{
        +  "description": "Objects found in one plane.",
        +  "properties": {
        +    "area_fraction": {
        +      "description": "Fraction of the area searched covered by objects.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "area_px": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Spread"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Object areas in pixels (objects off the edge, or all when every one touches it)."
        +    },
        +    "area_um2": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Spread"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Object areas in µm²."
        +    },
        +    "channels": {
        +      "description": "Every channel measured in the objects, in the order of each object's `mean`.",
        +      "items": {
        +        "$ref": "#/$defs/ObjectChannel"
        +      },
        +      "type": "array"
        +    },
        +    "confidence": {
        +      "$ref": "#/$defs/CountConfidence",
        +      "description": "`high`, or `low` when less than half of the objects' area is in compact objects of the\nexpected size (`fit`), when most objects are under a third of the expected area, or\nwhen more objects were found than the area holds: the image may not suit the count, or\nthe threshold cut noise into pieces (see `notes`)."
        +    },
        +    "count": {
        +      "description": "Objects found, including those touching the edge.",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "density_per_mm2": {
        +      "description": "Objects per mm² (edge objects count half).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "diameter_um": {
        +      "anyOf": [
        +        {
        +          "$ref": "#/$defs/Spread"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "description": "Diameters (of a disc of the same area) in µm."
        +    },
        +    "expected_diameter_from": {
        +      "description": "`given`, `measured` (from the image) or `default`.",
        +      "type": "string"
        +    },
        +    "expected_diameter_px": {
        +      "description": "Object diameter expected, in pixels: it sets the smoothing, the background scale, how\nclose two objects may be and the smallest object kept.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "expected_diameter_um": {
        +      "description": "The same in µm.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "fit": {
        +      "description": "Share of the objects' area in compact objects (solidity at least 0.85) of the expected\nsize (a third to three times the area of its disc), 0 to 1. Not for spots.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "kind": {
        +      "$ref": "#/$defs/Kind",
        +      "description": "What was counted."
        +    },
        +    "large": {
        +      "description": "Objects more than twice the median area: possibly several objects together.",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "measured": {
        +      "description": "What objects were found in: a channel (`c=0 DAPI`), an RGB component, `luminance` or a\nstain (`hematoxylin`, `eosin`, `dab`).",
        +      "type": "string"
        +    },
        +    "objects": {
        +      "description": "The objects in reading order (top to bottom, then left to right).",
        +      "items": {
        +        "$ref": "#/$defs/Object"
        +      },
        +      "type": "array"
        +    },
        +    "polarity": {
        +      "$ref": "#/$defs/Polarity",
        +      "description": "`bright` or `dark`."
        +    },
        +    "region": {
        +      "$ref": "#/$defs/Region",
        +      "description": "The rectangle searched, in pixels of the level read."
        +    },
        +    "searched_um2": {
        +      "description": "Area searched (the region, or the polygon) in µm².",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "split": {
        +      "description": "Whether touching objects were cut apart.",
        +      "type": "boolean"
        +    },
        +    "threshold": {
        +      "description": "Threshold, in units of what was measured after background subtraction (spots: height\nabove the local background).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "threshold_method": {
        +      "description": "`otsu`, `otsu-3`, `triangle`, `local`, `sparse` (a few objects on a large background:\nhalf way from the background to the objects), `noise` (spots: five robust standard\ndeviations of the background) or `given`.",
        +      "type": "string"
        +    },
        +    "touching_edge": {
        +      "description": "Objects touching the edge of the area searched.",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "truncated": {
        +      "description": "True when `objects` lists fewer than `count`.",
        +      "type": "boolean"
        +    }
        +  },
        +  "required": [
        +    "kind",
        +    "measured",
        +    "region",
        +    "expected_diameter_px",
        +    "expected_diameter_from",
        +    "polarity",
        +    "threshold",
        +    "threshold_method",
        +    "split",
        +    "count",
        +    "confidence",
        +    "touching_edge",
        +    "area_fraction",
        +    "large",
        +    "channels",
        +    "objects",
        +    "truncated"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / $defs / Percentiles / properties / p1 / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Percentiles / properties / p5 / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Percentiles / properties / p50 / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Percentiles / properties / p95 / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / Percentiles / properties / p99 / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / $defs / Polarity
        Added value: +{
        +  "description": "Bright or dark objects.",
        +  "oneOf": [
        +    {
        +      "const": "auto",
        +      "description": "from the image: dark objects on a bright background (brightfield) or bright ones",
        +      "type": "string"
        +    },
        +    {
        +      "const": "bright",
        +      "description": "objects brighter than the background (fluorescence)",
        +      "type": "string"
        +    },
        +    {
        +      "const": "dark",
        +      "description": "objects darker than the background (brightfield)",
        +      "type": "string"
        +    }
        +  ]
        +}
      • addedOutput schema / $defs / Positive
        Added value: +{
        +  "description": "Objects above a threshold in one channel.",
        +  "properties": {
        +    "count": {
        +      "description": "Objects whose mean is above it.",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "fraction": {
        +      "description": "The same as a fraction of all objects.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "method": {
        +      "description": "`otsu` (the object means fall in two groups), `background` (the channel's background\nplus five robust standard deviations) or `none` (no object is clearly brighter).",
        +      "type": "string"
        +    },
        +    "threshold": {
        +      "description": "Threshold on the object mean.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "threshold",
        +    "method",
        +    "count",
        +    "fraction"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Profile
        Added value: +{
        +  "description": "An intensity profile along a line.",
        +  "properties": {
        +    "channels": {
        +      "description": "One entry per channel.",
        +      "items": {
        +        "$ref": "#/$defs/ProfileChannel"
        +      },
        +      "type": "array"
        +    },
        +    "length_px": {
        +      "description": "Line length in pixels.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "length_um": {
        +      "description": "Line length in µm, when the pixel size is recorded.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "line": {
        +      "description": "`[x0, y0, x1, y1]` in pixels of the level read.",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "maxItems": 4,
        +      "minItems": 4,
        +      "type": "array"
        +    },
        +    "samples": {
        +      "description": "Samples taken along the line (one per pixel up to 20 000).",
        +      "format": "uint",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "step_px": {
        +      "description": "Distance between the returned values in pixels (the first is at the start, the last\nat the end).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "step_um": {
        +      "description": "Distance between the returned values in µm.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "width_px": {
        +      "description": "Pixels averaged across the line.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "line",
        +    "width_px",
        +    "length_px",
        +    "step_px",
        +    "samples",
        +    "channels"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / ProfileChannel
        Added value: +{
        +  "description": "One channel of a profile.",
        +  "properties": {
        +    "c": {
        +      "description": "Channel index (`c`), or the RGB component for RGB images.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "fwhm_px": {
        +      "description": "Full width at half maximum of the highest peak above the line's minimum, in pixels.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "fwhm_um": {
        +      "description": "The same in µm.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "max": {
        +      "description": "Largest value along the line.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "max_at_px": {
        +      "description": "Distance of the largest value from the start, in pixels.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "max_at_um": {
        +      "description": "The same in µm, when the pixel size is recorded.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "mean": {
        +      "description": "Mean value along the line.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "min": {
        +      "description": "Smallest value along the line.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "name": {
        +      "description": "Channel or component name.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "values": {
        +      "description": "The profile, one value every `step_px` from the start (at most 200; each the mean of the\nsamples it covers).",
        +      "items": {
        +        "format": "double",
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "c",
        +    "min",
        +    "max",
        +    "mean",
        +    "max_at_px",
        +    "values"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Roi
        Added value: +{
        +  "description": "Statistics inside a polygon.",
        +  "properties": {
        +    "area_px": {
        +      "description": "Pixels inside.",
        +      "format": "uint64",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "area_um2": {
        +      "description": "Area in µm², when the pixel size is recorded.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "channels": {
        +      "description": "One entry per channel.",
        +      "items": {
        +        "$ref": "#/$defs/RoiChannel"
        +      },
        +      "type": "array"
        +    },
        +    "polygon": {
        +      "description": "The vertices, in pixels of the level read.",
        +      "items": {
        +        "items": {
        +          "format": "double",
        +          "type": [
        +            "number",
        +            "null"
        +          ]
        +        },
        +        "maxItems": 2,
        +        "minItems": 2,
        +        "type": "array"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "polygon",
        +    "area_px",
        +    "channels"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / $defs / RoiChannel
        Added value: +{
        +  "description": "Statistics of one channel inside a polygon.",
        +  "properties": {
        +    "c": {
        +      "description": "Channel index (`c`), or the RGB component.",
        +      "format": "uint32",
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "max": {
        +      "description": "Largest value.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "mean": {
        +      "description": "Mean value.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "median": {
        +      "description": "Median value.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "min": {
        +      "description": "Smallest value.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "name": {
        +      "description": "Channel or component name.",
        +      "type": [
        +        "string",
        +        "null"
        +      ]
        +    },
        +    "std": {
        +      "description": "Standard deviation.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "sum": {
        +      "description": "Sum of the values (integrated intensity).",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "c",
        +    "min",
        +    "max",
        +    "mean",
        +    "std",
        +    "median",
        +    "sum"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / $defs / SampleStats / properties / zero_fraction / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / SampleStats / required
        Previous value: -[
        -  "count",
        -  "non_finite",
        -  "exact",
        -  "zero_fraction"
        -]New value: +[
        +  "count",
        +  "exact",
        +  "zero_fraction"
        +]
      • addedOutput schema / $defs / Spread
        Added value: +{
        +  "description": "Minimum, median, mean and maximum.",
        +  "properties": {
        +    "max": {
        +      "description": "Largest.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "mean": {
        +      "description": "Mean.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "median": {
        +      "description": "Median.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    },
        +    "min": {
        +      "description": "Smallest.",
        +      "format": "double",
        +      "type": [
        +        "number",
        +        "null"
        +      ]
        +    }
        +  },
        +  "required": [
        +    "min",
        +    "median",
        +    "mean",
        +    "max"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / anyOf
        Previous value: -[
        -  {
        -    "$ref": "#/$defs/StatsOutput",
        -    "description": "per=channel|plane."
        -  },
        -  {
        -    "$ref": "#/$defs/WellStatsOutput",
        -    "description": "per=well|field."
        -  }
        -]New value: +[
        +  {
        +    "$ref": "#/$defs/StatsOutput",
        +    "description": "per=channel|plane."
        +  },
        +  {
        +    "$ref": "#/$defs/WellStatsOutput",
        +    "description": "per=well|field."
        +  },
        +  {
        +    "$ref": "#/$defs/MeasureOutput",
        +    "description": "line, polygon, objects or lanes."
        +  }
        +]
    • Changedopenreadout_summarize5 fields changed
      • removedInput schema / properties / exact_by / default
        Removed value: -false
      • removedInput schema / properties / overwrite / default
        Removed value: -false
      • removedInput schema / properties / values / default
        Removed value: -[]
      • removedInput schema / properties / where / default
        Removed value: -[]
      • changedOutput schema / $defs / Value / anyOf
        Previous value: -[
        -  {
        -    "description": "No value (JSON `null`, an empty CSV field).",
        -    "type": "null"
        -  },
        -  {
        -    "description": "`true` / `false`.",
        -    "type": "boolean"
        -  },
        -  {
        -    "description": "A whole number.",
        -    "format": "int64",
        -    "type": "integer"
        -  },
        -  {
        -    "description": "A real number (NaN and infinities are written as `null`).",
        -    "format": "double",
        -    "type": "number"
        -  },
        -  {
        -    "description": "Text.",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "description": "No value (JSON `null`, an empty CSV field).",
        +    "type": "null"
        +  },
        +  {
        +    "description": "`true` / `false`.",
        +    "type": "boolean"
        +  },
        +  {
        +    "description": "A whole number.",
        +    "format": "int64",
        +    "type": "integer"
        +  },
        +  {
        +    "description": "A real number (NaN and infinities are written as `null`).",
        +    "format": "double",
        +    "type": [
        +      "number",
        +      "null"
        +    ]
        +  },
        +  {
        +    "description": "Text.",
        +    "type": "string"
        +  }
        +]
    • Changedopenreadout_table15 fields changed
      • removedInput schema / properties / count / default
        Removed value: -false
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file."
      • removedInput schema / properties / filter / default
        Removed value: -[]
      • removedInput schema / properties / first_row / default
        Removed value: -0
      • removedInput schema / properties / first_row / minimum
        Removed value: -0
      • removedInput schema / properties / max_rows / minimum
        Removed value: -0
      • removedInput schema / properties / parameters / default
        Removed value: -[]
      • removedInput schema / properties / populations / default
        Removed value: -[]
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / table / default
        Removed value: -0
      • removedInput schema / properties / table / minimum
        Removed value: -0
      • changedOutput schema / $defs / AppliedTransform / properties / parameters / additionalProperties / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / CompensationSummary / properties / matrix / items / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / TableFilterSummary / properties / percent / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / properties / rows / items / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_trace18 fields changed
      • removedInput schema / properties / channels / default
        Removed value: -[]
      • removedInput schema / properties / channels / items / minimum
        Removed value: -0
      • removedInput schema / properties / count / minimum
        Removed value: -0
      • changedInput schema / properties / file / description
        Previous value: -"Absolute or working-directory-relative path to the instrument file."New value: +"Path to the file."
      • removedInput schema / properties / first_sample / default
        Removed value: -0
      • removedInput schema / properties / first_sample / minimum
        Removed value: -0
      • removedInput schema / properties / max_samples / minimum
        Removed value: -0
      • removedInput schema / properties / process / default
        Removed value: -false
      • changedInput schema / properties / strict / description
        Previous value: -"true: refuse (an error with exit_code 6 and a hint) values this file's assurance does not validate. Default: the server's setting (OPENREADOUT_STRICT; off)."New value: +"Refuse values the file's assurance does not validate (exit_code 6). Default: the server's."
      • removedInput schema / properties / sweep / default
        Removed value: -0
      • removedInput schema / properties / sweep / minimum
        Removed value: -0
      • removedInput schema / properties / trace / default
        Removed value: -0
      • removedInput schema / properties / trace / minimum
        Removed value: -0
      • changedOutput schema / $defs / TraceChannelSlice / properties / samples / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / TraceStats / required
        Previous value: -[
        -  "count",
        -  "finite"
        -]New value: +[
        +  "count",
        +  "finite",
        +  "min",
        +  "max",
        +  "mean",
        +  "std",
        +  "argmin",
        +  "argmax"
        +]
      • changedOutput schema / properties / sample_rate_hz / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / properties / start_s / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / properties / x_range / items / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
    • Changedopenreadout_watch7 fields changed
      • removedInput schema / properties / cursor / minimum
        Removed value: -0
      • addedInput schema / properties / follow_symlinks
        Added value: +{
        +  "description": "First call only: walk into directories behind symbolic links too (links to files are always followed).",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / limit / minimum
        Removed value: -0
      • removedInput schema / properties / qc / default
        Removed value: -false
      • changedOutput schema / $defs / QcFinding / properties / threshold / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • changedOutput schema / $defs / QcFinding / properties / value / type
        Previous value: -"number"New value: +[
        +  "number",
        +  "null"
        +]
      • addedOutput schema / properties / notes
        Added value: +{
        +  "description": "What the watcher left out and how to include it.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
  2. 31 tool updatesv0.3.0
    • Removedopenreadout_analyze
    • Addedopenreadout_assay_curve
    • Addedopenreadout_assay_qc
    • Addedopenreadout_assay_wells
    • Changedopenreadout_batch10 fields changed
      • removedInput schema / properties / inputs
        Removed value: -{
        -  "default": [],
        -  "description": "Files, directories or glob patterns (summarize: the one table file).",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • changedInput schema / properties / measure / description
        Previous value: -"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `spectra` = one row per MS scan header (options: the openreadout_spectra filters); `peaks` = openreadout_analyze kind peaks (options); `chromatogram` = openreadout_analyze kind chromatogram (options); `assay` = openreadout_analyze kind assay (options); `nmr-peaks` = openreadout_analyze kind nmr-peaks (options); `ephys-features` = openreadout_analyze kind ephys-features (options); `spikes` = openreadout_analyze kind spikes (options); `qpcr` = openreadout_analyze kind qpcr (options); `gate` = population counts, percentages and medians (workspace or gatingml); `summarize` = group statistics (by) of the one table file in inputs, written by an earlier output."New value: +"What to measure per data set. `stats` = pixel statistics per image × channel (per=well for screening plates); `trace` = statistics per trace × sweep × channel; `table` = FCS: events, median, mean, sd, min, max per parameter; plate reads: one row per well; `info` = one row of header metadata per data set (fields); `scans` = one row per MS scan header (options: the openreadout_scans filters); `peaks` = openreadout_peaks (its arguments as options); `chromatogram` = openreadout_chromatogram (its arguments as options); `assay` = a plate-reader assay: options `analysis` (wells, curve, dose-response, kinetics, growth, qc) and the arguments of that openreadout_assay_* tool; `nmr-peaks` = openreadout_nmr_peaks (its arguments as options); `ephys-features` = openreadout_ephys_features (its arguments as options); `spikes` = openreadout_spikes (its arguments as options); `qpcr` = openreadout_qpcr (its arguments as options); `gate` = population counts, percentages and medians (workspace or gatingml)."
      • changedInput schema / properties / measure / enum
        Previous value: -[
        -  "stats",
        -  "trace",
        -  "table",
        -  "info",
        -  "spectra",
        -  "peaks",
        -  "chromatogram",
        -  "assay",
        -  "nmr-peaks",
        -  "ephys-features",
        -  "spikes",
        -  "qpcr",
        -  "gate",
        -  "summarize"
        -]New value: +[
        +  "stats",
        +  "trace",
        +  "table",
        +  "info",
        +  "scans",
        +  "peaks",
        +  "chromatogram",
        +  "assay",
        +  "nmr-peaks",
        +  "ephys-features",
        +  "spikes",
        +  "qpcr",
        +  "gate"
        +]
      • changedInput schema / properties / options / description
        Previous value: -"The measure's options. Analyses: the openreadout_analyze options of that kind, plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. spectra: the openreadout_spectra filters."New value: +"The measure's options. Analyses: the arguments of that analysis's tool (openreadout_peaks, openreadout_nmr_peaks, ...; assay: `analysis` = wells, curve, dose-response, kinetics, growth or qc, plus the arguments of that openreadout_assay_* tool), plus `rows` (which record list becomes rows: peaks peak|compound|chromatogram|band|region, nmr-peaks peak|integral|spectrum, ephys-features sweep|cell|spike, qpcr record|rq|standard_curve, assay wells|samples|compounds|kinetics|growth|quality). stats: image, select, level, per (channel|image|plane|well|field), wells, mip (z|t). trace: trace, sweep, channels. table: table, parameters, compensate, transform, workspace or gatingml, sample. gate: workspace or gatingml, sample, populations, medians, table. info: fields. scans: the openreadout_scans filters."
      • addedInput schema / properties / paths
        Added value: +{
        +  "default": [],
        +  "description": "Files, directories or glob patterns.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedOutput schema / $defs / BatchOutput
        Removed value: -{
        -  "description": "Output of a batch command in table mode.",
        -  "properties": {
        -    "columns": {
        -      "description": "Columns of `rows`, with type, unit and role (`id`, `key`, `metadata`, `annotation`,\n`value`, `error`).",
        -      "items": {
        -        "$ref": "#/$defs/Column"
        -      },
        -      "type": "array"
        -    },
        -    "grain": {
        -      "description": "Columns that identify a row within its data set.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "inputs": {
        -      "$ref": "#/$defs/InputReport",
        -      "description": "How the inputs became data sets."
        -    },
        -    "joins": {
        -      "description": "Sample sheets and layouts joined, in order.",
        -      "items": {
        -        "$ref": "#/$defs/JoinReport"
        -      },
        -      "type": "array"
        -    },
        -    "measure": {
        -      "description": "Measure (`stats`, `trace`, `table`, `gate`, `info`, …).",
        -      "type": "string"
        -    },
        -    "offset": {
        -      "description": "Index of the first row in `rows`.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "output": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/WrittenFile"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "The file the full table was written to (`-o`)."
        -    },
        -    "returned_rows": {
        -      "description": "Rows returned here.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "rows": {
        -      "description": "Rows as arrays in column order.",
        -      "items": {
        -        "items": {
        -          "$ref": "#/$defs/Value"
        -        },
        -        "type": "array"
        -      },
        -      "type": "array"
        -    },
        -    "summary": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/SummaryOutput"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "The group summary (`--by`)."
        -    },
        -    "total_rows": {
        -      "description": "Rows in the whole table.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "truncated": {
        -      "description": "True when the table has rows after the last one returned (page with `offset`, or read\nthe full table from `output`).",
        -      "type": "boolean"
        -    },
        -    "warnings": {
        -      "description": "Things to check: skipped inputs, grouping, join results.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    }
        -  },
        -  "required": [
        -    "measure",
        -    "grain",
        -    "inputs",
        -    "columns",
        -    "total_rows",
        -    "offset",
        -    "returned_rows",
        -    "truncated",
        -    "rows"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / SummarizeToolOutput
        Removed value: -{
        -  "description": "A summary of a saved table.",
        -  "properties": {
        -    "input": {
        -      "description": "The table summarized.",
        -      "type": "string"
        -    },
        -    "output": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/WrittenFile"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Where it was written."
        -    },
        -    "summary": {
        -      "$ref": "#/$defs/SummaryOutput",
        -      "description": "The summary."
        -    }
        -  },
        -  "required": [
        -    "input",
        -    "summary"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / anyOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/BatchOutput",
        -    "description": "A batch table."
        -  },
        -  {
        -    "$ref": "#/$defs/SummarizeToolOutput",
        -    "description": "The summary of a saved table."
        -  }
        -]
      • addedOutput schema / properties
        Added value: +{
        +  "columns": {
        +    "description": "Columns of `rows`, with type, unit and role (`id`, `key`, `metadata`, `annotation`,\n`value`, `error`).",
        +    "items": {
        +      "$ref": "#/$defs/Column"
        +    },
        +    "type": "array"
        +  },
        +  "grain": {
        +    "description": "Columns that identify a row within its data set.",
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  "inputs": {
        +    "$ref": "#/$defs/InputReport",
        +    "description": "How the inputs became data sets."
        +  },
        +  "joins": {
        +    "description": "Sample sheets and layouts joined, in order.",
        +    "items": {
        +      "$ref": "#/$defs/JoinReport"
        +    },
        +    "type": "array"
        +  },
        +  "measure": {
        +    "description": "Measure (`stats`, `trace`, `table`, `gate`, `info`, …).",
        +    "type": "string"
        +  },
        +  "offset": {
        +    "description": "Index of the first row in `rows`.",
        +    "format": "uint64",
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "output": {
        +    "anyOf": [
        +      {
        +        "$ref": "#/$defs/WrittenFile"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "description": "The file the full table was written to (`-o`)."
        +  },
        +  "returned_rows": {
        +    "description": "Rows returned here.",
        +    "format": "uint64",
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "rows": {
        +    "description": "Rows as arrays in column order.",
        +    "items": {
        +      "items": {
        +        "$ref": "#/$defs/Value"
        +      },
        +      "type": "array"
        +    },
        +    "type": "array"
        +  },
        +  "summary": {
        +    "anyOf": [
        +      {
        +        "$ref": "#/$defs/SummaryOutput"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "description": "The group summary (`--by`)."
        +  },
        +  "total_rows": {
        +    "description": "Rows in the whole table.",
        +    "format": "uint64",
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "truncated": {
        +    "description": "True when the table has rows after the last one returned (page with `offset`, or read\nthe full table from `output`).",
        +    "type": "boolean"
        +  },
        +  "warnings": {
        +    "description": "Things to check: skipped inputs, grouping, join results.",
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "measure",
        +  "grain",
        +  "inputs",
        +  "columns",
        +  "total_rows",
        +  "offset",
        +  "returned_rows",
        +  "truncated",
        +  "rows"
        +]
    • Changedopenreadout_check41 fields changed
      • removedInput schema / properties / against
        Removed value: -{
        -  "description": "Compare with this second file instead (e.g. an OME-TIFF export of `file`): metadata differences, geometry, channels, physical sizes and per-plane hashes.",
        -  "type": "string"
        -}
      • addedInput schema / properties / headers_only
        Added value: +{
        +  "default": false,
        +  "description": "Check headers and structure only (offsets, declared sizes and counts, missing parts): no decompression, decoding or checksums over the data.",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / ignore
        Removed value: -{
        -  "default": [],
        -  "description": "against: JSON pointers (into openreadout_info output) to leave out of the metadata diff; `*` matches one segment.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / image
        Removed value: -{
        -  "description": "against: only this image index (in both files).",
        -  "minimum": 0,
        -  "type": "integer"
        -}
      • removedInput schema / properties / include_text
        Removed value: -{
        -  "default": false,
        -  "description": "report: keep free text from the file (sample, image and channel names, comments); the path and personal data are still replaced. Default false: only with the user's consent.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / no_pixels
        Removed value: -{
        -  "default": false,
        -  "description": "against: metadata and geometry only, no pixels.",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / output
        Removed value: -{
        -  "description": "report: also write the bundle to this new local file. Default: only return it.",
        -  "type": "string"
        -}
      • removedInput schema / properties / report
        Removed value: -{
        -  "default": false,
        -  "description": "Build a privacy-reviewed diagnostic bundle for the maintainers instead (for a file that is refused, fails, or is not validated).",
        -  "type": "boolean"
        -}
      • removedInput schema / properties / select
        Removed value: -{
        -  "default": [],
        -  "description": "against: plane selection strings such as `c=0`, `z=2-5`, `t=0,3`. A second file holding only the selected planes (an export with the same selection) is matched to them in order.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • removedInput schema / properties / tolerance
        Removed value: -{
        -  "description": "against: largest absolute sample difference that still counts as equal. Default: bit-identical planes (same xxh3-128).",
        -  "type": "number"
        -}
      • changedOutput schema / $defs / Acquisition / description
        Previous value: -"`acquisition` in `info`, `info --view structure`, `check` and `check --planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`."New value: +"`acquisition` in `info`, `info --view structure`, `check` and `planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`."
      • removedOutput schema / $defs / CheckReport
        Removed value: -{
        -  "description": "Output of `check`.",
        -  "properties": {
        -    "acquisition": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/Acquisition"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Present when the file is not finished: still being written (`in_progress`: findings\nabout the unfinished tail are warnings and `ok` covers the complete part) or stopped\nbefore the end (`interrupted`). See `book/src/guides/lab-shares.md`."
        -    },
        -    "assurance": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/Assurance"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Whether the file lies inside what its reader has been validated on (the same block as\n`info` → `assurance`). `ok` says the file is intact; `assurance` says whether its values\ncan be trusted. Filled by the `check` command when the header can be read."
        -    },
        -    "checks_performed": {
        -      "description": "What was verified, in plain words, so the caller knows what \"ok\" covers.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "findings": {
        -      "description": "Everything found, in the order checked.",
        -      "items": {
        -        "$ref": "#/$defs/Finding"
        -      },
        -      "type": "array"
        -    },
        -    "format": {
        -      "description": "Format id of the input file.",
        -      "type": "string"
        -    },
        -    "ok": {
        -      "description": "True when no finding has severity `error`.",
        -      "type": "boolean"
        -    },
        -    "path": {
        -      "description": "The input file.",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "path",
        -    "format",
        -    "ok",
        -    "checks_performed",
        -    "findings"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / CompareOutput
        Removed value: -{
        -  "description": "Output of `check --against`.",
        -  "properties": {
        -    "identical": {
        -      "description": "Nothing compared differs: metadata (unless skipped), geometry, channel names,\nphysical sizes and planes (within the tolerance). The exit code is 0 when true, 1\nwhen false.",
        -      "type": "boolean"
        -    },
        -    "images": {
        -      "description": "Geometry, channel-name and physical-size comparison per image index.",
        -      "items": {
        -        "$ref": "#/$defs/ImageComparison"
        -      },
        -      "type": "array"
        -    },
        -    "metadata": {
        -      "$ref": "#/$defs/MetadataComparison",
        -      "description": "The normalized-metadata diff."
        -    },
        -    "notes": {
        -      "description": "Caveats (e.g. formats that store different metadata for the same acquisition).",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "ours": {
        -      "$ref": "#/$defs/CompareSide",
        -      "description": "The first file."
        -    },
        -    "planes": {
        -      "$ref": "#/$defs/PlaneComparison",
        -      "description": "The plane-by-plane comparison."
        -    },
        -    "theirs": {
        -      "$ref": "#/$defs/CompareSide",
        -      "description": "The second file."
        -    }
        -  },
        -  "required": [
        -    "identical",
        -    "ours",
        -    "theirs",
        -    "metadata",
        -    "images",
        -    "planes",
        -    "notes"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / CompareSide
        Removed value: -{
        -  "description": "One file of the pair.",
        -  "properties": {
        -    "format": {
        -      "description": "Its format id.",
        -      "type": "string"
        -    },
        -    "images": {
        -      "description": "Number of images.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "path": {
        -      "description": "The file as given.",
        -      "type": "string"
        -    },
        -    "tables": {
        -      "description": "Number of tables.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "traces": {
        -      "description": "Number of traces.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "path",
        -    "format",
        -    "images",
        -    "tables",
        -    "traces"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / DetectionSummary
        Removed value: -{
        -  "description": "The reader that claimed the input.",
        -  "properties": {
        -    "confidence": {
        -      "description": "`definite`, `likely` or `extension_only`.",
        -      "type": "string"
        -    },
        -    "format": {
        -      "description": "Format id.",
        -      "type": "string"
        -    },
        -    "note": {
        -      "description": "Why the match is less than definite.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "reader_confidence": {
        -      "description": "The reader's confidence level (`high`, `medium`, `low`).",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "format",
        -    "confidence",
        -    "reader_confidence"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Difference
        Removed value: -{
        -  "description": "A value that differs, at an RFC 6901 JSON pointer into `info --json` `data`.",
        -  "properties": {
        -    "ours": {
        -      "description": "Value in the first file; absent when the first file lacks the field."
        -    },
        -    "pointer": {
        -      "description": "RFC 6901 JSON pointer to the value, e.g. `/images/0/physical_size/x`.",
        -      "type": "string"
        -    },
        -    "theirs": {
        -      "description": "Value in the second file; absent when the second file lacks the field."
        -    }
        -  },
        -  "required": [
        -    "pointer"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Generator
        Removed value: -{
        -  "description": "Program name and version.",
        -  "properties": {
        -    "name": {
        -      "description": "`openreadout`.",
        -      "type": "string"
        -    },
        -    "version": {
        -      "description": "Its version.",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "name",
        -    "version"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Geometry
        Removed value: -{
        -  "description": "Geometry of one image.",
        -  "properties": {
        -    "pixel_type": {
        -      "$ref": "#/$defs/PixelType",
        -      "description": "Sample type."
        -    },
        -    "samples_per_pixel": {
        -      "description": "1 for grayscale, 3 for interleaved RGB.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "size_c": {
        -      "description": "Number of channels.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "size_t": {
        -      "description": "Number of time points.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "size_x": {
        -      "description": "Width in pixels.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "size_y": {
        -      "description": "Height in pixels.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "size_z": {
        -      "description": "Number of Z planes.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "size_x",
        -    "size_y",
        -    "size_z",
        -    "size_c",
        -    "size_t",
        -    "pixel_type",
        -    "samples_per_pixel"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / HexSample
        Removed value: -{
        -  "description": "A hex excerpt.",
        -  "properties": {
        -    "at": {
        -      "description": "`head` or the structure entry (`kind name`).",
        -      "type": "string"
        -    },
        -    "hex": {
        -      "description": "Space-separated bytes; masked text bytes are `__`.",
        -      "type": "string"
        -    },
        -    "offset": {
        -      "description": "Byte offset.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "at",
        -    "offset",
        -    "hex"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / ImageComparison
        Removed value: -{
        -  "description": "One image index present in either file.",
        -  "properties": {
        -    "channel_names_equal": {
        -      "description": "Channel names agree.",
        -      "type": "boolean"
        -    },
        -    "geometry_equal": {
        -      "description": "Both files have the image and their geometries agree (with `selected`, after the\nselection).",
        -      "type": "boolean"
        -    },
        -    "image": {
        -      "description": "Image index.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "ours": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/Geometry"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Absent when the first file has no image with this index."
        -    },
        -    "ours_channels": {
        -      "description": "Channel names of the first file (listed only when they differ).",
        -      "items": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "type": "array"
        -    },
        -    "ours_physical_size": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/PhysicalSize"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Physical pixel size in the first file (listed only when the sizes differ)."
        -    },
        -    "physical_size_equal": {
        -      "description": "Physical sizes agree to a relative 1e-6 (both absent counts as equal).",
        -      "type": "boolean"
        -    },
        -    "selected": {
        -      "description": "The second file holds only the selected planes of this image (an export made with the\nsame selection): planes, channels and the metadata diff were matched in selection\norder, and `ours` is the geometry after the selection.",
        -      "type": "boolean"
        -    },
        -    "theirs": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/Geometry"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Absent when the second file has no image with this index."
        -    },
        -    "theirs_channels": {
        -      "description": "Channel names of the second file (listed only when they differ).",
        -      "items": {
        -        "type": [
        -          "string",
        -          "null"
        -        ]
        -      },
        -      "type": "array"
        -    },
        -    "theirs_physical_size": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/PhysicalSize"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Physical pixel size in the second file (listed only when the sizes differ)."
        -    }
        -  },
        -  "required": [
        -    "image",
        -    "geometry_equal",
        -    "channel_names_equal",
        -    "ours_channels",
        -    "theirs_channels",
        -    "physical_size_equal"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / InputSummary
        Removed value: -{
        -  "description": "The input without its name.",
        -  "properties": {
        -    "extension": {
        -      "description": "Lower-case extension without the dot (`nd2`, `raw`, `d`), when there is one.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "kind": {
        -      "description": "`file` or `directory`.",
        -      "type": "string"
        -    },
        -    "member_extensions": {
        -      "additionalProperties": {
        -        "format": "uint64",
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "description": "Member counts per extension.",
        -      "type": "object"
        -    },
        -    "members": {
        -      "description": "A directory's members: relative paths with names that are not plain tokens replaced.",
        -      "items": {
        -        "$ref": "#/$defs/Member"
        -      },
        -      "type": "array"
        -    },
        -    "members_omitted": {
        -      "description": "Members not listed (more than 2000).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "sha256": {
        -      "description": "SHA-256 of the whole file (files up to 1 GiB).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "sha256_first_64mib": {
        -      "description": "SHA-256 of the first 64 MiB (larger files).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "signature_hex": {
        -      "description": "The first 16 bytes in hex; printable runs that are not a plain token are masked (`__`).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "signature_text": {
        -      "description": "The same bytes as text where they are a plain token (`ZISRAWFILE`, `ABF2`).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "size_bytes": {
        -      "description": "Bytes (a directory: the sum over its members).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "text_like": {
        -      "description": "The file looks like text (a delimited export, XML, JSON).",
        -      "type": "boolean"
        -    }
        -  },
        -  "required": [
        -    "kind",
        -    "size_bytes"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Integrity
        Removed value: -{
        -  "description": "Integrity findings.",
        -  "properties": {
        -    "checks_performed": {
        -      "description": "What was verified.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "findings": {
        -      "description": "Findings: severity, code, message (scrubbed), offset.",
        -      "items": true,
        -      "type": "array"
        -    },
        -    "mode": {
        -      "description": "`headers` (`check --headers-only`) or `full`.",
        -      "type": "string"
        -    },
        -    "ok": {
        -      "description": "No finding of severity error.",
        -      "type": "boolean"
        -    }
        -  },
        -  "required": [
        -    "mode",
        -    "ok",
        -    "checks_performed",
        -    "findings"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / KindCount
        Removed value: -{
        -  "description": "Count and bytes of one entry kind.",
        -  "properties": {
        -    "bytes": {
        -      "description": "Their total size, where sizes are known.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "count": {
        -      "description": "How many.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "kind": {
        -      "description": "Entry kind.",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "kind",
        -    "count",
        -    "bytes"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Member
        Removed value: -{
        -  "description": "One member of a directory data set.",
        -  "properties": {
        -    "path": {
        -      "description": "Path relative to the data set, `/`-separated.",
        -      "type": "string"
        -    },
        -    "size": {
        -      "description": "Bytes.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "path",
        -    "size"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / MetadataComparison
        Removed value: -{
        -  "description": "The normalized-metadata diff.",
        -  "properties": {
        -    "compared": {
        -      "description": "False with `--no-metadata`.",
        -      "type": "boolean"
        -    },
        -    "difference_count": {
        -      "description": "Total number of differences (the list holds at most 1000).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "differences": {
        -      "description": "The differences, at most 1000.",
        -      "items": {
        -        "$ref": "#/$defs/Difference"
        -      },
        -      "type": "array"
        -    },
        -    "equal": {
        -      "description": "True when no difference was found.",
        -      "type": "boolean"
        -    },
        -    "ignored": {
        -      "description": "Pointers left out (defaults plus `--ignore`); `extra` objects are also left out unless\n`include_extra`.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "include_extra": {
        -      "description": "Whether `extra` objects were compared.",
        -      "type": "boolean"
        -    }
        -  },
        -  "required": [
        -    "compared",
        -    "equal",
        -    "ignored",
        -    "include_extra",
        -    "difference_count",
        -    "differences"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / PhysicalSize
        Removed value: -{
        -  "description": "Physical pixel size in micrometres (the OME default unit). Every present value is > 0.",
        -  "properties": {
        -    "unit": {
        -      "description": "Always `µm` in this schema version.",
        -      "type": "string"
        -    },
        -    "x": {
        -      "description": "Pixel width in µm (the distance between neighbouring columns).",
        -      "format": "double",
        -      "type": [
        -        "number",
        -        "null"
        -      ]
        -    },
        -    "y": {
        -      "description": "Pixel height in µm (the distance between neighbouring rows).",
        -      "format": "double",
        -      "type": [
        -        "number",
        -        "null"
        -      ]
        -    },
        -    "z": {
        -      "description": "Spacing between Z planes (focal slices) in µm.",
        -      "format": "double",
        -      "type": [
        -        "number",
        -        "null"
        -      ]
        -    }
        -  },
        -  "required": [
        -    "unit"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / PixelType
        Removed value: -{
        -  "description": "Sample type of one channel value. Names follow OME-XML `PixelType` values.",
        -  "oneOf": [
        -    {
        -      "const": "int8",
        -      "description": "Signed 8-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "int16",
        -      "description": "Signed 16-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "int32",
        -      "description": "Signed 32-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "uint8",
        -      "description": "Unsigned 8-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "uint16",
        -      "description": "Unsigned 16-bit integer (the usual microscope camera output).",
        -      "type": "string"
        -    },
        -    {
        -      "const": "uint32",
        -      "description": "Unsigned 32-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "float",
        -      "description": "32-bit IEEE 754 floating point.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "double",
        -      "description": "64-bit IEEE 754 floating point.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "int64",
        -      "description": "Signed 64-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "uint64",
        -      "description": "Unsigned 64-bit integer.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "complex",
        -      "description": "Complex number of two 32-bit floats (real, then imaginary): OME `complex`.",
        -      "type": "string"
        -    },
        -    {
        -      "const": "double-complex",
        -      "description": "Complex number of two 64-bit floats (real, then imaginary): OME `double-complex`.",
        -      "type": "string"
        -    }
        -  ]
        -}
      • removedOutput schema / $defs / PlaneComparison
        Removed value: -{
        -  "description": "Plane-by-plane comparison.",
        -  "properties": {
        -    "compared": {
        -      "description": "False with `--no-pixels`.",
        -      "type": "boolean"
        -    },
        -    "identical": {
        -      "description": "Planes with identical xxh3-128.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "mismatched": {
        -      "description": "Planes that differ beyond the tolerance (or at all, without one).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "mismatches": {
        -      "description": "At most 1000 entries, in plane order.",
        -      "items": {
        -        "$ref": "#/$defs/PlaneMismatch"
        -      },
        -      "type": "array"
        -    },
        -    "planes": {
        -      "description": "Planes read from both files.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "skipped_images": {
        -      "description": "Image indices not compared plane by plane (missing on one side or geometry differs).",
        -      "items": {
        -        "format": "uint32",
        -        "minimum": 0,
        -        "type": "integer"
        -      },
        -      "type": "array"
        -    },
        -    "tolerance": {
        -      "description": "The `--tolerance` used, if any.",
        -      "format": "double",
        -      "type": [
        -        "number",
        -        "null"
        -      ]
        -    },
        -    "within_tolerance": {
        -      "description": "Planes that differ but within the tolerance.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "compared",
        -    "planes",
        -    "identical",
        -    "within_tolerance",
        -    "mismatched",
        -    "skipped_images",
        -    "mismatches"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / PlaneMismatch
        Removed value: -{
        -  "description": "A plane that differs.",
        -  "properties": {
        -    "c": {
        -      "description": "Channel index.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "differing_samples": {
        -      "description": "Samples that differ (absent when the planes' shapes differ).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "image": {
        -      "description": "Image index.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "max_abs_diff": {
        -      "description": "Largest absolute difference between corresponding samples.",
        -      "format": "double",
        -      "type": [
        -        "number",
        -        "null"
        -      ]
        -    },
        -    "note": {
        -      "description": "Why the samples could not be compared (e.g. the plane shapes differ).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "ours_xxh3": {
        -      "description": "xxh3-128 of the plane in the first file.",
        -      "type": "string"
        -    },
        -    "t": {
        -      "description": "Time index.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "theirs_xxh3": {
        -      "description": "xxh3-128 of the plane in the second file.",
        -      "type": "string"
        -    },
        -    "within_tolerance": {
        -      "description": "With a tolerance: whether `max_abs_diff` is within it (then the plane counts as equal).",
        -      "type": "boolean"
        -    },
        -    "z": {
        -      "description": "Z index.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "image",
        -    "c",
        -    "z",
        -    "t",
        -    "ours_xxh3",
        -    "theirs_xxh3",
        -    "within_tolerance"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Privacy
        Removed value: -{
        -  "description": "The privacy statement of a bundle.",
        -  "properties": {
        -    "excluded": {
        -      "description": "What it leaves out.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "included": {
        -      "description": "What the bundle contains, in plain words.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "mode": {
        -      "description": "`structure_only` (default) or `with_text` (`--include-text`).",
        -      "type": "string"
        -    },
        -    "personal_data": {
        -      "description": "Personal-data flags (kind and rule, never the value) found in the metadata.",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "redacted_strings": {
        -      "description": "Distinct strings from the file replaced by `<redacted-N>` or `<text:LEN>` placeholders.",
        -      "format": "uint32",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "mode",
        -    "included",
        -    "excluded",
        -    "redacted_strings"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / Report
        Removed value: -{
        -  "description": "The diagnostic bundle.",
        -  "properties": {
        -    "assurance": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/Assurance"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "The assurance block (`info` → `assurance`), text scrubbed."
        -    },
        -    "candidates": {
        -      "description": "Readers registered for the input's extension (what the user probably expected).",
        -      "items": {
        -        "type": "string"
        -      },
        -      "type": "array"
        -    },
        -    "detection": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/DetectionSummary"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "The reader that claimed the input, when one did."
        -    },
        -    "generator": {
        -      "$ref": "#/$defs/Generator",
        -      "description": "The program that wrote it."
        -    },
        -    "input": {
        -      "$ref": "#/$defs/InputSummary",
        -      "description": "The input, without its name or path."
        -    },
        -    "integrity": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/Integrity"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Integrity findings (`check`)."
        -    },
        -    "metadata": {
        -      "description": "The normalized metadata (`info`) with numbers kept and free text replaced."
        -    },
        -    "privacy": {
        -      "$ref": "#/$defs/Privacy",
        -      "description": "What the bundle contains and leaves out; read before sharing."
        -    },
        -    "report_version": {
        -      "description": "Bundle layout version ([`REPORT_VERSION`]).",
        -      "type": "string"
        -    },
        -    "samples": {
        -      "description": "Hex excerpts (only with `hex_bytes`).",
        -      "items": {
        -        "$ref": "#/$defs/HexSample"
        -      },
        -      "type": "array"
        -    },
        -    "stages": {
        -      "description": "The decode path: each stage in order with its result.",
        -      "items": {
        -        "$ref": "#/$defs/Stage"
        -      },
        -      "type": "array"
        -    },
        -    "structure": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/StructureMap"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "The container's structure (`info --view structure`)."
        -    },
        -    "vendor_keys": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/VendorKeys"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "Key skeleton of the vendor metadata tree (`info --view full` → `vendor`): paths and value\ntypes."
        -    }
        -  },
        -  "required": [
        -    "report_version",
        -    "generator",
        -    "privacy",
        -    "input",
        -    "stages"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / ReportOutput
        Removed value: -{
        -  "description": "What `openreadout check FILE --report` prints under `--json`.",
        -  "properties": {
        -    "bytes": {
        -      "description": "Size of the written bundle.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "issue_url": {
        -      "description": "Where to file it (never contacted by the program).",
        -      "type": "string"
        -    },
        -    "output": {
        -      "description": "Where the bundle was written; `None` with `--dry-run` (or from MCP without `output`).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "report": {
        -      "$ref": "#/$defs/Report",
        -      "description": "The bundle, exactly as written."
        -    }
        -  },
        -  "required": [
        -    "issue_url",
        -    "report"
        -  ],
        -  "type": "object"
        -}
      • changedOutput schema / $defs / Scope / oneOf
        Previous value: -[
        -  {
        -    "const": "metadata",
        -    "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.",
        -    "type": "string"
        -  },
        -  {
        -    "const": "pixels",
        -    "description": "Image planes (`check --planes`, `stats`, `export` of images, `preview`).",
        -    "type": "string"
        -  },
        -  {
        -    "const": "spectra",
        -    "description": "Mass spectra and scan headers (`spectra`, `analyze chromatogram`, mzML export).",
        -    "type": "string"
        -  },
        -  {
        -    "const": "traces",
        -    "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).",
        -    "type": "string"
        -  },
        -  {
        -    "const": "tables",
        -    "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "const": "metadata",
        +    "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.",
        +    "type": "string"
        +  },
        +  {
        +    "const": "pixels",
        +    "description": "Image planes (`planes`, `stats`, `export` of images, `preview`).",
        +    "type": "string"
        +  },
        +  {
        +    "const": "spectra",
        +    "description": "Mass spectra and scan headers (`scans`, `spectrum`, `analyze chromatogram`, mzML export).",
        +    "type": "string"
        +  },
        +  {
        +    "const": "traces",
        +    "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).",
        +    "type": "string"
        +  },
        +  {
        +    "const": "tables",
        +    "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).",
        +    "type": "string"
        +  }
        +]
      • removedOutput schema / $defs / Stage
        Removed value: -{
        -  "description": "One stage of the decode path.",
        -  "properties": {
        -    "detail": {
        -      "description": "What the stage found, in a few words (`12 entries`, `plane 512x512 uint16`).",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "elapsed_ms": {
        -      "description": "Milliseconds the stage took.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    },
        -    "error": {
        -      "anyOf": [
        -        {
        -          "$ref": "#/$defs/StageError"
        -        },
        -        {
        -          "type": "null"
        -        }
        -      ],
        -      "description": "The error, when the stage failed."
        -    },
        -    "stage": {
        -      "description": "`detect`, `open`, `info`, `assurance`, `ls`, `check`, `vendor`, `first_read`.",
        -      "type": "string"
        -    },
        -    "status": {
        -      "description": "`ok`, `error`, `skipped` or `panic` (a bug: the reader crashed in this stage).",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "stage",
        -    "status"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / StageError
        Removed value: -{
        -  "description": "An error as the CLI would report it, text scrubbed.",
        -  "properties": {
        -    "code": {
        -      "description": "Stable code (`corrupt_file`, `unsupported_feature`, ...).",
        -      "type": "string"
        -    },
        -    "exit_code": {
        -      "description": "Process exit code the CLI would return.",
        -      "format": "int32",
        -      "type": "integer"
        -    },
        -    "hint": {
        -      "description": "The hint.",
        -      "type": [
        -        "string",
        -        "null"
        -      ]
        -    },
        -    "message": {
        -      "description": "The message.",
        -      "type": "string"
        -    },
        -    "offset": {
        -      "description": "Byte offset of the problem, when the reader knows it.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": [
        -        "integer",
        -        "null"
        -      ]
        -    }
        -  },
        -  "required": [
        -    "code",
        -    "exit_code",
        -    "message"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / StructureMap
        Removed value: -{
        -  "description": "The container's structure.",
        -  "properties": {
        -    "by_kind": {
        -      "description": "Count and bytes per entry kind.",
        -      "items": {
        -        "$ref": "#/$defs/KindCount"
        -      },
        -      "type": "array"
        -    },
        -    "entries": {
        -      "description": "The first 400 entries in file order.",
        -      "items": true,
        -      "type": "array"
        -    },
        -    "entries_total": {
        -      "description": "Entries `info --view structure` lists.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "entries_total",
        -    "by_kind",
        -    "entries"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / VendorKeys
        Removed value: -{
        -  "description": "Key skeleton of the vendor tree.",
        -  "properties": {
        -    "omitted": {
        -      "description": "Paths not listed (beyond 3000).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "paths": {
        -      "description": "`path`, value `type` (`string`, `number`, `bool`, `null`, `object`, `array`), `count`.",
        -      "items": {
        -        "$ref": "#/$defs/VendorPath"
        -      },
        -      "type": "array"
        -    },
        -    "total_paths": {
        -      "description": "Distinct key paths (array indices folded to `[]`).",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    }
        -  },
        -  "required": [
        -    "total_paths",
        -    "paths"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / $defs / VendorPath
        Removed value: -{
        -  "description": "One vendor key path.",
        -  "properties": {
        -    "count": {
        -      "description": "Occurrences.",
        -      "format": "uint64",
        -      "minimum": 0,
        -      "type": "integer"
        -    },
        -    "path": {
        -      "description": "Dotted key path, arrays as `[]`.",
        -      "type": "string"
        -    },
        -    "type": {
        -      "description": "JSON type of the values (several joined by `|`).",
        -      "type": "string"
        -    }
        -  },
        -  "required": [
        -    "path",
        -    "type",
        -    "count"
        -  ],
        -  "type": "object"
        -}
      • removedOutput schema / anyOf
        Removed value: -[
        -  {
        -    "$ref": "#/$defs/CheckReport",
        -    "description": "The integrity check."
        -  },
        -  {
        -    "$ref": "#/$defs/CompareOutput",
        -    "description": "against: the comparison."
        -  },
        -  {
        -    "$ref": "#/$defs/ReportOutput",
        -    "description": "report: the diagnostic bundle."
        -  }
        -]
      • addedOutput schema / properties
        Added value: +{
        +  "acquisition": {
        +    "anyOf": [
        +      {
        +        "$ref": "#/$defs/Acquisition"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "description": "Present when the file is not finished: still being written (`in_progress`: findings\nabout the unfinished tail are warnings and `ok` covers the complete part) or stopped\nbefore the end (`interrupted`). See `book/src/guides/lab-shares.md`."
        +  },
        +  "assurance": {
        +    "anyOf": [
        +      {
        +        "$ref": "#/$defs/Assurance"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ],
        +    "description": "Whether the file lies inside what its reader has been validated on (the same block as\n`info` → `assurance`). `ok` says the file is intact; `assurance` says whether its values\ncan be trusted. Filled by the `check` command when the header can be read."
        +  },
        +  "checks_performed": {
        +    "description": "What was verified, in plain words, so the caller knows what \"ok\" covers.",
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  "findings": {
        +    "description": "Everything found, in the order checked.",
        +    "items": {
        +      "$ref": "#/$defs/Finding"
        +    },
        +    "type": "array"
        +  },
        +  "format": {
        +    "description": "Format id of the input file.",
        +    "type": "string"
        +  },
        +  "ok": {
        +    "description": "True when no finding has severity `error`.",
        +    "type": "boolean"
        +  },
        +  "path": {
        +    "description": "The input file.",
        +    "type": "string"
        +  }
        +}
      • addedOutput schema / required
        Added value: +[
        +  "path",
        +  "format",
        +  "ok",
        +  "checks_performed",
        +  "findings"
        +]
    • Addedopenreadout_chromatogram
    • Addedopenreadout_compare
    • Addedopenreadout_dose_response
    • Addedopenreadout_ephys_features
    • Changedopenreadout_export8 fields changed
      • removedInput schema / properties / attachment
        Removed value: -{
        -  "description": "Write this embedded attachment instead (a CZI's `Thumbnail`, `Label` or `SlidePreview` image, `TimeStamps`; names from openreadout_info view=structure, kind attachment), or `#<index>`.",
        -  "type": "string"
        -}
      • changedInput schema / properties / format / description
        Previous value: -"`ome-tiff` (default for images; one BigTIFF file), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0, for mass-spectrometry files; the default for them), `asm` (Allotrope Simple Model plate-reader JSON; plate-reader exports only), `rdml` (RDML 1.3; qPCR files: RDML, Applied Biosystems .eds, Rotor-Gene .rex), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces) or `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms)."New value: +"`ome-tiff` (one BigTIFF file; the default for images), `ome-zarr` (OME-NGFF 0.5 / Zarr v3 directory with a pyramid), `mzml` (indexed mzML 1.1.0; the default for mass spectra), `csv` (one table, or one sweep of a trace; the default for tables and traces), `parquet` or `arrow` (Arrow IPC file) for a table, a trace (all sweeps) or mass spectra (`spectra=true`), `nwb` (NWB 2.x; electrophysiology traces), `jcamp` (JCAMP-DX 5.01; NMR FIDs and spectra, other 1-D spectra and chromatograms), `asm` (Allotrope Simple Model plate-reader JSON) or `rdml` (RDML 1.3; qPCR files). Without it, the extension of `output` decides; it must not contradict `output`."
      • addedInput schema / properties / labels
        Added value: +{
        +  "default": false,
        +  "description": "CSV: add a second header line with column labels (FCS `$PnS`).",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / output / description
        Previous value: -"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.asm.json`, `.rdml`, `.parquet`, `.arrow`, `.nwb` or `.jdx`."New value: +"Output path; defaults to the input with `.ome.tiff`, `.ome.zarr`, `.mzML`, `.csv`, `.asm.json`, `.rdml`, `.parquet`, `.arrow`, `.nwb` or `.jdx`. Its extension sets the format when `format` is not given."
      • changedInput schema / properties / rows / description
        Previous value: -"Parquet, Arrow, NWB, JCAMP-DX: rows (samples of each sweep for traces) `A-B`, `A-` or `A`, zero-based and inclusive."New value: +"CSV, Parquet, Arrow, NWB, JCAMP-DX: rows (samples of each sweep for traces) `A-B`, `A-` or `A`, zero-based and inclusive."
      • changedInput schema / properties / sweep / description
        Previous value: -"Parquet, Arrow, NWB, JCAMP-DX: only this sweep (default: every sweep)."New value: +"CSV, Parquet, Arrow, NWB, JCAMP-DX: only this sweep (CSV default 0; the others: every sweep)."
      • changedInput schema / properties / table / description
        Previous value: -"Parquet, Arrow: this table index (FCS data set, plate read, event or peak table)."New value: +"CSV, Parquet, Arrow: this table index (FCS data set, plate read, event or peak table)."
      • changedInput schema / properties / trace / description
        Previous value: -"Parquet, Arrow, NWB, JCAMP-DX: this trace index (NWB default: every trace)."New value: +"CSV, Parquet, Arrow, NWB, JCAMP-DX: this trace index (NWB default: every trace)."
    • Addedopenreadout_extract
    • Removedopenreadout_formats
    • Addedopenreadout_gate
    • Addedopenreadout_growth
    • Addedopenreadout_health
    • Changedopenreadout_info2 fields changed
      • changedOutput schema / $defs / Acquisition2 / description
        Previous value: -"`acquisition` in `info`, `info --view structure`, `check` and `check --planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`."New value: +"`acquisition` in `info`, `info --view structure`, `check` and `planes`: present only for\nfiles that are not finished. See `book/src/guides/lab-shares.md`."
      • changedOutput schema / $defs / Scope / oneOf
        Previous value: -[
        -  {
        -    "const": "metadata",
        -    "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.",
        -    "type": "string"
        -  },
        -  {
        -    "const": "pixels",
        -    "description": "Image planes (`check --planes`, `stats`, `export` of images, `preview`).",
        -    "type": "string"
        -  },
        -  {
        -    "const": "spectra",
        -    "description": "Mass spectra and scan headers (`spectra`, `analyze chromatogram`, mzML export).",
        -    "type": "string"
        -  },
        -  {
        -    "const": "traces",
        -    "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).",
        -    "type": "string"
        -  },
        -  {
        -    "const": "tables",
        -    "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).",
        -    "type": "string"
        -  }
        -]New value: +[
        +  {
        +    "const": "metadata",
        +    "description": "The normalized metadata (`info`, all its views): sizes, channels, instrument, times.",
        +    "type": "string"
        +  },
        +  {
        +    "const": "pixels",
        +    "description": "Image planes (`planes`, `stats`, `export` of images, `preview`).",
        +    "type": "string"
        +  },
        +  {
        +    "const": "spectra",
        +    "description": "Mass spectra and scan headers (`scans`, `spectrum`, `analyze chromatogram`, mzML export).",
        +    "type": "string"
        +  },
        +  {
        +    "const": "traces",
        +    "description": "Sampled signals (`trace`, electrophysiology, chromatograms, NMR and IR/Raman spectra).",
        +    "type": "string"
        +  },
        +  {
        +    "const": "tables",
        +    "description": "Tables (FCS events, plate reads, qPCR results, event and peak tables).",
        +    "type": "string"
        +  }
        +]
    • Addedopenreadout_kinetics
    • Addedopenreadout_nmr_peaks
    • Addedopenreadout_peaks
    • Changedopenreadout_preview10 fields changed
      • changedInput schema / properties / axes / description
        Previous value: -"Image previews: coordinate rulers in full-resolution pixels and a scale bar around the picture (default true); false = the bare plane."New value: +"Image previews: what frames the picture. What frames an image preview. `rulers` = coordinate rulers in full-resolution pixels and a scale bar around the picture (default); `grid` = rulers, plus faint grid lines over the data at the ruler ticks; `none` = the bare downsampled plane."
      • addedInput schema / properties / axes / enum
        Added value: +[
        +  "rulers",
        +  "grid",
        +  "none"
        +]
      • changedInput schema / properties / axes / type
        Previous value: -"boolean"New value: +"string"
      • changedInput schema / properties / format / description
        Previous value: -"`png` (default) or `jpeg`."New value: +"Encoding. Default png (sent as JPEG when a PNG would be too large). Output encoding. `png` = lossless (default); `jpeg` = lossy and smaller."
      • addedInput schema / properties / format / enum
        Added value: +[
        +  "png",
        +  "jpeg"
        +]
      • removedInput schema / properties / grid
        Removed value: -{
        -  "default": false,
        -  "description": "Image previews: faint grid lines at the ruler ticks over the data (default false).",
        -  "type": "boolean"
        -}
      • changedInput schema / properties / lut / description
        Previous value: -"`gray` or `channel-color` (default: gray for one channel, channel colours for composites)."New value: +"Colour lookup. Default: gray for one channel, channel colours for composites. Colour lookup for a single channel. `gray` = black to white; `channel-color` = black to the channel's colour."
      • addedInput schema / properties / lut / enum
        Added value: +[
        +  "gray",
        +  "channel-color"
        +]
      • changedInput schema / properties / mip / description
        Previous value: -"Maximum-intensity projection axis: `z` (or `t`), over the selected range if any."New value: +"Maximum-intensity projection, over the selected range if any. Axis of a maximum-intensity projection. `z` = along z (focal planes); `t` = along t (time points)."
      • addedInput schema / properties / mip / enum
        Added value: +[
        +  "z",
        +  "t"
        +]
    • Addedopenreadout_qpcr
    • Addedopenreadout_report
    • Addedopenreadout_scans
    • Removedopenreadout_spectra
    • Addedopenreadout_spectrum
    • Addedopenreadout_spikes
    • Changedopenreadout_stats2 fields changed
      • addedOutput schema / $defs / StatsOutput / properties / images_skipped
        Added value: +{
        +  "description": "Images left out of a run over every image because the reader refuses their pixel data\n(raw FLIM photon histograms, for one; `info` notes say which). Absent when none were.",
        +  "items": {
        +    "format": "uint32",
        +    "minimum": 0,
        +    "type": "integer"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / $defs / StatsOutput / properties / planes / description
        Previous value: -"Per-plane statistics (omitted with `--no-planes`)."New value: +"Per-plane statistics (with `--per plane`)."
    • Addedopenreadout_summarize
    • Changedopenreadout_table4 fields changed
      • addedInput schema / properties / parameters
        Added value: +{
        +  "default": [],
        +  "description": "FCS only: parameters ($PnN) to transform; default every fluorescence parameter.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • removedInput schema / properties / transform_parameters
        Removed value: -{
        -  "default": [],
        -  "description": "FCS only: parameters ($PnN) to transform; default every fluorescence parameter.",
        -  "items": {
        -    "type": "string"
        -  },
        -  "type": "array"
        -}
      • changedOutput schema / properties / rows / description
        Previous value: -"Row-major values; `rows[r][c]`. Non-finite values serialize as `null`."New value: +"Row-major values; `rows[r][c]`. Non-finite values serialize as `null`. A text column\nholds codes here; `texts` has its text."
      • addedOutput schema / properties / texts
        Added value: +{
        +  "additionalProperties": {
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  "description": "Text columns (`info` → `tables[].columns[].extra.categories`) by column name: the text\nof each returned row, so `texts[name][r]` is what `rows[r][c]` codes. Absent when the\ntable has no text column.",
        +  "type": "object"
        +}
    • Changedopenreadout_watch2 fields changed
      • addedInput schema / properties / stall_after
        Added value: +{
        +  "description": "First call only: seconds without growth before `dataset_stalled` (default 120).",
        +  "type": "number"
        +}
      • removedInput schema / properties / stall_after_s
        Removed value: -{
        -  "description": "First call only: seconds without growth before `dataset_stalled` (default 120).",
        -  "type": "number"
        -}
  3. 15 tool updatesv0.1.0
    • First observedopenreadout_analyze
    • First observedopenreadout_batch
    • First observedopenreadout_check
    • First observedopenreadout_export
    • First observedopenreadout_formats
    • First observedopenreadout_index
    • First observedopenreadout_info
    • First observedopenreadout_link
    • First observedopenreadout_preview
    • First observedopenreadout_search
    • First observedopenreadout_spectra
    • First observedopenreadout_stats
    • First observedopenreadout_table
    • First observedopenreadout_trace
    • First observedopenreadout_watch

TDQS

A3.6/5.0

Scored across 28 tools

Disambiguation4/5

Most tools target a distinct data type or analysis (e.g. chromatogram vs spectrum vs scans vs trace), and descriptions often cross-reference boundaries like 'Draws only; openreadout_export saves'. However, the visualization cluster (plot, preview, export) and data-inspection cluster (info, stats, table) can still be confused by an agent. Overlap exists but is mostly mitigated by detailed descriptions.

Naming Consistency5/5

All 28 tools use the openreadout_ prefix followed by lowercase snake_case, with no case mixing or chaotic patterns. Compound names like ephys_features and nmr_peaks are still predictable. The convention is uniform across the entire set.

Tool Count2/5

28 tools is above the 25-tool threshold for 'too many' and risks overwhelming an agent choosing among them. While most tools are specialized and non-redundant, the surface is heavy for a single MCP server. Some grouping or consolidation would improve usability.

Completeness5/5

The set covers indexing, search, info, preview, plot, export, conversion, integrity checks, batch analysis, summarization, and technique-specific analyses (MS, NMR, qPCR, flow, ephys, plate, imaging). Lifecycle operations for reading, inspecting, analyzing, and exporting lab data are thorough. No obvious dead ends for the apparent scientific data readout domain.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server that extracts clean text, tables, and structured data from documents, images, code, and audio files, supporting 97 formats with OCR, transcription, and code intelligence.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables local, read-only extraction of text and structure from PDF, DOCX, PPTX, SVG, and PNG files, including OCR for images, directory tree and metadata reporting, with strict path isolation and audit logging.
    -
  • F
    license
    B
    quality
    A
    maintenance
    Enables local, offline document extraction and manipulation—PDF first but also HTML, DOCX, XLSX, PPTX, EML, EPUB, Markdown, and plain text—through tools for probing, locating, extracting, converting, assembling, OCR, protecting, and redacting documents, with nothing leaving the machine.
    7
    -
  • A
    license
    A
    quality
    C
    maintenance
    Converts documents among PDF, DOCX, Markdown, plain text, and images while returning fidelity reports that clearly distinguish PASS, FAIL, NOT_CHECKED, and UNSUPPORTED outcomes. Also enables lossless reading, exact search, and structured extraction from long documents without treating unchecked content as passed.
    16
    AGPL 3.0