AI skills
Overview
⚠️ These skills are an early experiment in tool composition for weather/climate data pipelines. Interfaces, dataset schema, and skill boundaries may change without notice. Fetchers hit real APIs and require credentials; middle- pipeline skills have only been smoke-tested on small synthetic data. Do not use in any automated workflow you rely on, and do not assume outputs are scientifically validated. Expect breakage. Small tools an AI agent can run to fetch weather data and transform it. Each skill is a command-line script. They share one Zarr file format so outputs of one skill can feed into the next — see STANDARD_DATASET.md. Built as Agent Skills by Rhiza Research. Prefer dynamical-fetch when the dynamical.org catalog has the dataset (GFS, GEFS, ECMWF IFS-ENS, AIFS, Google WeatherNext 2, ICON-EU, analyses, IMERG, CHIRPS). Use a credentialed or source-specific fetcher only when it does not. Capabilities the agent uses alongside pipelines; none of them produces a dataset output.
README
Weather Skills
⚠️ Under active development — not production ready.
These skills are an early experiment in tool composition for weather/climate data pipelines. Interfaces, dataset schema, and skill boundaries may change without notice. Fetchers hit real APIs and require credentials; middle- pipeline skills have only been smoke-tested on small synthetic data. Do not use in any automated workflow you rely on, and do not assume outputs are scientifically validated. Expect breakage.
Small tools an AI agent can run to fetch weather data and transform it. Each
skill is a command-line script. They share one Zarr file format so outputs of
one skill can feed into the next — see
STANDARD_DATASET.md.
Built as Agent Skills by Rhiza Research.
Skills
Fetchers (ingress — source-specific)
Prefer dynamical-fetch when the dynamical.org catalog has the dataset
(GFS, GEFS, ECMWF IFS-ENS, AIFS, Google WeatherNext 2, ICON-EU, analyses,
IMERG, CHIRPS). Use a
credentialed or source-specific fetcher only when it does not.
| Skill | What it does |
|---|---|
dynamical-fetch |
Preferred when the catalog has it. dynamical.org open catalog (GFS, GEFS, ECMWF IFS-ENS 15-day and 46-day, AIFS, Google WeatherNext 2, ICON-EU, MRMS, analyses, IMERG, CHIRPS) via --dataset, credential-free → Zarr. Forecasts: one init (--date) or a range of inits (repeatable --start-time/--end-time). Default IMERG source: nasa-imerg-analysis-late / nasa-imerg-analysis-early. CHIRPS products: ucsb-chc-chirps-analysis-final / ucsb-chc-chirps-analysis-preliminary. |
ecmwf-fetch |
ECDS fallback for ECMWF S2S / ER (pre-2026, ocean, unmapped fields). Prefer dynamical-fetch --dataset ecmwf-ifs-ens-forecast-46-day-daily-1-5-degree for 2026+ catalog fields. |
chirps-fetch |
Default CHIRPS source: dynamical.org final + prelim fallback → precip Zarr |
imerg-fetch |
Earthdata daily IMERG Final (GPM_3IMERGDF) → Zarr. All IMERG Late/Early comes from dynamical-fetch. |
clim-fetch |
Climatology (mean + std) for a --dataset (imerg_final, era5, chirps, ecmwf_ifs, oisst, …), at a selected --prediction-timedelta lead and --window (days; correctly rolled up, centered, with circular padding if not pre-mirrored), expanded to a --start-time/--end-time window → Zarr. OISST SST is --dataset oisst --variable sst. |
tahmo-fetch |
TAHMO station observations (daily-aggregated) → Zarr |
3dpaws-fetch |
3D-PAWS station observations from a CHORDS portal (default: FEWS NET Kenya; daily precip, temperature, humidity, pressure, wind) → station Zarr. Requires credentials. |
cumulus-fetch |
Cumulus AI operational ensemble precip (Aurora S2S run) — 30 members, 46 daily leads, 0.25° or 1° global (--dataset precip, precip_1deg, precip_era5), one init or a range of inits → Zarr. Requires credentials. |
neuralgcm-fetch |
NeuralGCM S2S ensemble (IMERG precip tp, ERA5 surface t2m/d2m) — up to 50 members, 6-hour leads to 60 days, ~2.8°, one init or a range of inits → Zarr. Requires credentials. |
weathernext-fetch |
Google WeatherNext 2 ensemble (2025 on; 64 members, 6-hour leads to 15 days, 0.25°, 13 pressure levels) or WeatherNext 3 (2026 on; 64-member ensemble, requester pays, or free ensemble mean/percentiles; hourly leads to 15 days, 0.1°) → Zarr. One init or a range of inits. Pass -v and --member or --statistic (full cubes are ~1 TB). Requires credentials. |
windborne-fetch |
WindBorne data, one --product per call: WeatherMesh-6 ensemble grids (live or archived runs from mid-2026; 128 members as mean, std or all; 3-hour leads to 15 days, 0.25°), point forecasts with spread, percentiles and rain-exceedance probabilities, vertical soundings, plain-language site summaries, ERA5 1991–2020 hourly normals at points, the recent ECMWF IFS analysis, or US state heating/cooling degree days → Zarr. Requires credentials. |
pbc-fetch |
PBC / StillLearning AI Weather Quest precip quintile probabilities (era5-p_pr_19 week 3, era5-p_pr_26 week 4), 1.5° global, one init or a range of inits → Zarr. Requires credentials. |
ecmwf-hres-fetch |
Deterministic ECMWF HRES forecast — 0.25°, out to 15 days, surface and pressure-level fields → Zarr. No credentials; needs the eccodes system library. |
arco-era5-fetch |
ERA5 hourly reanalysis (ARCO-ERA5) → Zarr. No credentials. |
cmip6-fetch |
One CMIP6 model run (historical 1850–2014 or ssp* to 2100) → Zarr. No credentials. |
rfe-fetch |
NOAA CPC African Rainfall Estimate (RFE2) — daily, 0.1° over Africa, from 2001 → Zarr. No credentials. |
gsmap-fetch |
JAXA GSMaP v6 gauge-corrected hourly 0.1° precip (from April 2025, 60°N–60°S) → Zarr. No credentials. |
oisst-fetch |
NOAA OISST v2.1 daily 0.25° sea-surface temperature (1981-09 on) → Zarr. No credentials. |
smap-fetch |
NASA SMAP Enhanced L3 (SPL3SMP_E) daily 9 km surface soil moisture → Zarr. Requires credentials. |
ghcn-daily-fetch |
NOAA GHCN-Daily station observations (daily precip and max/min/mean temperature, ~130,000 stations) → station Zarr. No credentials. |
openaq-fetch |
OpenAQ air-quality station observations (daily mean PM2.5, PM10, NO2, O3, SO2, CO) → station Zarr. Requires credentials. |
cams-fetch |
CAMS global air-quality fields (PM2.5, PM10, near-surface NO2/O3/SO2/CO, AOD, total columns) — 5-day forecast at 0.4° (2015 on) or EAC4 reanalysis at 0.75° (2003 on) → Zarr. Requires credentials. |
meteosat-fetch |
Meteosat FCI or SEVIRI satellite imagery (0° or Indian Ocean) at chosen times — visible reflectance and infrared brightness temperature on a regular lat/lon grid at native sampling → Zarr. Up to 12 scans per call by default, since each is a ~200 MB whole-disk download. Requires credentials. |
Generic middle (operate on any standard dataset)
| Skill | What it does |
|---|---|
clip-region |
Clip a gridded or station Zarr to a --bbox N/W/S/E, a named --region, or a --geojson polygon (use resolve-region for a country’s bbox) |
aggregate-temporal |
Resample rates along time/step (mean/min/max) into fixed (--period) or rolling (--window duration) windows; duration-weights CF bounds; stamps data_interval = the output spacing (the period, or the input spacing for --window), plus aggregation_period + aggregation_coverage + cell_methods |
convert-to-totals |
Terminal: rate × stamped aggregation_period → amount (100% coverage default; refuses overlapping Δt < period — select first) |
deaccumulate |
Convert a leftover cumulative-since-init forecast variable into per-step diffs along the step axis (fetchers already write rates) |
step-to-time |
Realize a forecast’s step lead-time axis as wall-clock valid times (time = init + step) so it can be compared against time-based observations — one init, or many inits at one selected lead |
select |
Pick entries along one dim by position or coordinate value; a single pick collapses the dim (e.g. one forecast week from each model before concat) |
convert-calendar |
Convert the time axis to another CF calendar (standard, noleap, 360_day, …) so two datasets share one calendar before comparing |
unit-convert |
Convert a variable to target --to-units (e.g. precip flux kg m-2 s-1 → depth rate mm/day via ÷ liquid-water density) |
downscale |
Spatial downscaling onto a finer grid (by factor, finer resolution, or a reference grid) via --algorithm (linear-interpolation or q-q empirical quantile mapping) |
coarsen |
Coarsen or align a grid onto a target (resolution, offset) or another Zarr’s grid, by linear interpolation or an area-weighted (conservative) mean — adds no information |
edit-coords |
Rename data variables, coordinates, or dims (--rename OLD=NEW) and re-index a dim by another 1-D coordinate (--swap-dims OLD=NEW); refuses edits that lose an ontology dim |
drop |
Drop named data variables or non-index coordinates (--name) — e.g. stray valid_time / spatial_ref before concat |
concat |
Join Zarr stores along a named dim (incl. new dims with coord values) |
merge |
Combine the variables of several Zarrs into one dataset on their shared coordinates |
label-group |
Add label coords: the country / admin-1 / admin-2 / subregion / continent or GeoJSON polygon each cell or station lies in (--level, --geojson), and time labels (--time month, year, dayofyear, or month groups MAM,OND) — data unchanged |
summarize-dim |
Summarize named dims with a statistic (mean/std/min/max/sum/median/quantile) — e.g. ensemble spread as the std across number, a 10–90% band with --method quantile -q 0.1 -q 0.9, or a time-mean baseline. --by LABEL gives one value per label (per county, per season), e.g. after label-group |
point-value |
Sample a gridded dataset at point locations (station Zarr, --point LAT,LON[,ID], or CSV) into a station_id point_obs dataset — nearest, bilinear, or N×N cell-mean — for grid-vs-station difference / verify |
local-extrema |
Find the local highs or lows of a gridded field (pressure centres, rainfall maxima) into a station_id point_obs dataset of locations and central values — for H / L map labels or listing centres |
csv-io |
Export a Zarr as it is to a CSV or Excel table (units in the headers), or read a CSV or Excel sheet — station records, a gridded table, or one gauge (--point) — into a Zarr. Day-first dates need --date-format; missing codes need --na-value. |
netcdf-io |
Export a Zarr to a NetCDF .nc file (attrs and history kept), or read one or more .nc files into a Zarr. Variables without units need --units VAR=UNITS. |
difference |
Subtract one dataset from another (A − B) with inner-join alignment and broadcasting — anomalies vs a baseline, scenario-minus-historical change maps |
standardize-anomaly |
Standardized anomaly aka z-score: (field − clim_avg) / clim_std against a climatology (e.g. clim-fetch) — dimensionless output, errors on units mismatch. For a plain physical-unit anomaly, use difference instead. |
zonal-moisture-transport |
Eastward moisture flux q·u, default column-integrated to IVT (viwve, kg m-1 s-1). Compose after dynamical-fetch (46-day pressure_level group) with q and u |
wind-speed-direction |
Wind speed (hypot(u, v)) and the directions the wind blows from and to (degrees clockwise from north) from a --u / --v component pair; calm cells (speed ≤ --calm-speed) get NaN direction |
verify |
Forecast vs obs verification: `–metric hits |
indicator |
Daily or weekly boolean indicator from one --rule (aliases icpac-onset / chc-onset, or clauses like precip sum 8d >= 25); optional --probability, --detect first / any, --cumulative |
Agent capabilities
Capabilities the agent uses alongside pipelines; none of them produces a dataset output.
| Skill | What it does |
|---|---|
resolve-region |
Resolve a country, multi-country region, ocean box, state/province/county, or landmark to a --bbox N/W/S/E (and optional boundary polygon GeoJSON). |
resolve-time |
Resolve relative calendar dates (“the last two weeks”, latest, now-3d) to absolute --start-time/--end-time or --date. Latest published day is the fetcher’s --probe-latest, not this skill. |
inspect-zarr |
Print dims, coordinate values, and a bounded data-variable summary of a Zarr (stdout; no write). Data arrays can be huge — this skill never dumps them in full. |
provenance |
Inspect weather_skills_history on a Zarr, figure (PNG/JPEG/GIF/HTML/PDF/SVG), GeoJSON, or CSV/Excel table (DAG lineage, JSON, or a commit-pinned reproduction script). |
submit-feedback |
Build a length-checked prefilled GitHub new-issue URL the user clicks to file feedback under their own account. Holds no token, makes no network call, creates no issue itself. |
Install
These skills live at . There are three ways to use them.
As a Claude Code plugin
Install the plugin once — add the marketplace, then install the plugin:
claude plugin marketplace add rhiza-research/weather-skills
claude plugin install rhiza-forecasting@weather-skills
Then run the bundled forecaster agent. The --allowedTools flag pre-approves
the plugin’s skills for the session so a multi-step pipeline runs end to end
without a prompt at each step:
claude --agent rhiza-forecasting:forecaster --allowedTools "Skill(rhiza-forecasting:*)"
Fetchers still need their credentials in the environment; see each skill’s
compatibility: frontmatter for what it reads (for example an
EXAMPLE_API_KEY).
To make the approval permanent instead of passing the flag every time, add the
same rule to permissions.allow in a settings file (.claude/settings.json for
one project, ~/.claude/settings.json for every project):
{
"permissions": {
"allow": [
"Skill(rhiza-forecasting:*)"
]
}
}
With that rule in place, plain claude --agent rhiza-forecasting:forecaster
works without the flag. This lets the plugin’s skills run unprompted —
including reaching the network and writing output files — so add an ask or
deny rule instead if you want to be prompted for some or all of them.
As a CLI tool
For ad-hoc command-line use (no agent involved), install the skills as a
single weather-skills binary:
# One-shot, no install — list available skills
uvx --from git+https://github.com/rhiza-research/weather-skills weather-skills
# Run one
uvx --from git+https://github.com/rhiza-research/weather-skills weather-skills [args]
Or install once and invoke directly:
uv tool install git+https://github.com/rhiza-research/weather-skills
weather-skills # list
weather-skills [args] # run one
Each skill’s PEP 723 inline dependency block is resolved by uv run
on each invocation, so the runner itself contributes no Python deps to the
script’s runtime environment.
As agent skills
For use by an LLM agent (Claude Code, etc.), install the SKILL.md files
into your project with skillkit — no
local install needed, npx runs the latest skillkit on demand (add @latest
to always pull the newest):
# List what skillkit discovers in the repo
npx skillkit install rhiza-research/weather-skills --list
# Install all skills to the current project
npx skillkit install rhiza-research/weather-skills --all --yes
# Install globally so any project can use them
npx skillkit install rhiza-research/weather-skills --all --yes --global
# Target a specific agent (otherwise skillkit installs for every agent it detects)
npx skillkit install rhiza-research/weather-skills --all --yes --agent claude-code
# Install just a subset
npx skillkit install rhiza-research/weather-skills --skill=ecmwf-fetch
npx skillkit install rhiza-research/weather-skills --skills=clip-region,difference
# Overwrite an existing install
npx skillkit install rhiza-research/weather-skills --all --yes --force
Pin in a manifest for team / reproducible use:
npx skillkit manifest init
npx skillkit manifest add rhiza-research/weather-skills
npx skillkit manifest install
See npx skillkit install --help for more flags.
Composition pattern
Middle-pipeline skills are designed to chain. Example — a weekly forecast and
the matching observations for one country, using the weather-skills CLI from
the Install section above:
# Kenya bbox (N/W/S/E) from resolve-region
weather-skills resolve-region KEN
# ECMWF 46-day ensemble forecast, weekly totals
weather-skills dynamical-fetch \
--dataset ecmwf-ifs-ens-forecast-46-day-daily-1-5-degree \
--date 2026-09-14 --bbox 5.5/33.9/-4.7/41.9 -v tp \
--output /tmp/ecmwf.zarr
weather-skills aggregate-temporal \
--input /tmp/ecmwf.zarr --period weekly --output /tmp/ecmwf_weekly.zarr
weather-skills convert-to-totals \
--input /tmp/ecmwf_weekly.zarr --output /tmp/ecmwf_weekly_totals.zarr
# CHIRPS observations for the same weeks
weather-skills chirps-fetch \
--start-time 2026-09-14 --end-time 2026-09-20 --bbox 5.5/33.9/-4.7/41.9 \
--output /tmp/chirps.zarr
weather-skills aggregate-temporal \
--input /tmp/chirps.zarr --period weekly --output /tmp/chirps_weekly.zarr
weather-skills convert-to-totals \
--input /tmp/chirps_weekly.zarr --output /tmp/chirps_weekly_totals.zarr
In practice a user just states the goal in natural language and the agent picks and composes skills from this set.
Standard dataset contract
Skills share a simple Zarr contract: fixed dimension names (latitude,
longitude, time, step, number, station_id, …) and short types (spatial, observations, forecast,
vertical_forecast, point_obs, …).
See
STANDARD_DATASET.md.
Fetchers write that shape; other skills only depend on dims, coords, data
variables, and weather_skills_* attrs — not on per-variable encoding.
CLI flag conventions
Each skill declares its CLI through the @weather_skill decorator from
weather_skills_core, so common parameters (--input / -o, --bbox,
--start-time / --end-time, etc.) mean the same thing wherever they appear.
See
CONVENTIONS.md
for the full mapping of concept → canonical flag.
Credentials
Fetchers read credentials from environment variables (or .netrc where
supported by the underlying client). Nothing is hardcoded. See each skill’s
compatibility: frontmatter for the specific vars required.
Contributing
See CONTRIBUTING.md for the publishing model (main is the
consumer-facing branch — every merge is a release), the PR workflow, and the
version-bump conventions (per-skill metadata.version in SKILL.md, driven by release: major
/ release: minor PR labels, with patch as the default).
License
MIT. See LICENSE.
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add rhiza-research/weather-skills