Skip to main content

Standalone Weather MCP server powered by rustwx for model maps, satellite, radar, meteograms, cross sections, and research workflows.

Project description

Hermes Weather Agent

A standalone Weather MCP server and local no-AI UI powered by rustwx and WxStore.

Hermes Weather Agent gives Hermes Agent, Claude, and any MCP-speaking client direct access to rustwx, a pure-Rust weather workspace, and wxstore, the MIT temporal store for 2-D and 3-D weather data. It is meant to be a general weather engine for agents: model maps, satellite imagery, radar products, meteograms, soundings, cross sections, latest-run discovery, local cache management, temporal-store queries, and severe-weather research tools from one server.

The compute and rendering live in rustwx. PNG output goes through the pure-Rust rustwx-render contour engine: no matplotlib for maps, no ANSI rendering, and no Python in the hot path. WRF NetCDF4 reads use netcrust (pure-Rust, feature-gated) so no netcdf.dll runtime is required for the standard agent workflows.

Hermes defaults RustWx renders to the current fast operational plot style by setting RUSTWX_PLOT_STYLE=operational_fast when no explicit style is configured. The Rust CLI also accepts operational-fast; use HERMES_RUSTWX_PLOT_STYLE or RUSTWX_PLOT_STYLE to override it.

Why this matters

  • One MCP server for weather work. Agents can request maps, satellite, radar, meteograms, soundings, cross sections, cache status, and background jobs without a custom web app.
  • A no-AI UI for people. weather-ui opens RustWx Studio: browse models/domains/products, render operational maps, and sample point forecasts from the same released rustwx package APIs.
  • Latest data by default. HRRR requests resolve against advertised forecast-hour availability; longer-range HRRR requests use the newest synoptic cycle with the requested hours.
  • Efficient local data use. rustwx uses .idx byte-range fetches where possible, and Hermes exposes data-pack guidance so users can choose how much disk to reserve.
  • Temporal stores for shared weather data. Hermes can query a running WxStore service, sample WXA grids and WXP pressure-profile stores, search object lanes, and materialize RustWx grids into durable WxStore WXA caches so repeated plotting and point sampling stay fast.
  • Live product discovery. Product support is read from the installed rustwx wheel so the agent can pick slugs the active model actually advertises; optional workspace binaries expose deeper catalog metadata for local development.
  • rustwx 0.5 model compatibility. Hermes now understands the broadened rustwx model set: HRRR/HRRR-AK, GFS/GDAS/GEFS/HGEFS, AIGFS/AIGEFS, ECMWF Open Data, AIFS/Earth2, RAP, NAM, HIRESW/HREF/SREF, RTMA/URMA, NBM, RRFS-A/RRFS-Public/REFS/RRFS-FireWx, and WRF/GDEX-style local workflows.
  • Composite and grid-plot vocabulary. Agents can ask for built-in fill-plus-isopleth recipes, contour labels, ensemble member/stat selectors, and schema-stable grid-overlay requests such as value grids, EBS-style scalar grids, and hodograph glyph grids. Generic custom grid overlays are reserved in the schema and return a clear rustwx error until the generic renderer lands.
  • Fast regular renders by default. Hermes keeps direct and light-derived non-ECAPE products in one shared RustWx pass so ordinary HRRR plot packs avoid repeated decode work, while heavy ECAPE, generic, and windowed requests still use guarded chunking when needed. Set chunk_size for explicit chunk control or chunk_large_requests=false / chunk_size=0 to force one pass.
  • Advanced severe-weather research when needed. ECAPE maps, profile probes, profile sweeps, ratio maps, and severe panels are available as regular tools, not as a separate research-only app.

What an agent can do with this

"Render latest HRRR 2 m temperature and 10 m wind over Los Angeles."
"Show me the latest GOES-West GeoColor image with GLM overlay for southern California."
"Make a point meteogram for Redding for the next 18 hours."
"Render KTLX base reflectivity and dual-pol products."
"Cross-section theta-e from Amarillo to Chicago at f06 using the HRRR VolumeStore."
"What does the latest CONUS QPF look like at f24?"
"Export latest HRRR temperature, wind, and CAPE grids into WxStore."
"Materialize latest HRRR severe grids into WxStore, then render f000-f002 operational maps from the WXA cache."
"Sample the WxStore temporal sounding lane near Norman and include severe diagnostics."

"Render MLECAPE and 0-3 km SRH over the southern plains for the latest HRRR."
"Render HRRR DCAPE over Oklahoma City."
"Probe the ECAPE profile at Norman, OK at the latest f01."
"Build a 7-day dataset of MLECAPE / SRH 0-3 / STP renders for southern-plains."
"What's currently in the cache, and what would a 400 GB eviction free?"

Advanced Research Mode

The general weather tools are the main surface area. On top of that, Hermes Weather Agent includes ECAPE and severe-weather research tools for deeper work:

  • full-parcel ECAPE and DCAPE maps at HRRR-grid scale
  • per-profile ECAPE diagnostics from the Rust solver
  • random/target/stress profile sweeps
  • severe-weather panels and ECAPE/CAPE ratio products
  • multi-day render/probe datasets for verification workflows

The ECAPE path is strong for exploratory and product-triage research, not yet calibrated forecast skill. Calibration is downstream of the verification work these tools enable.

Install

pip install -U rustwx hermes-weather-agent
weather-mcp --doctor
weather-ui

That's it for every map-rendering tool — the rustwx PyPI wheel ships the rustwx-agent-v1 Python API used by this plugin (no Rust toolchain, no separate binaries, no netcdf.dll). rustwx>=0.5.10 is recommended for the current public release.

weather-mcp --doctor should report rustwx_module_available: true, agent_api: rustwx-agent-v1, plot_style: operational_fast, and a nonzero domain_count.

weather-ui starts RustWx Studio at http://127.0.0.1:8765/. It uses the installed package APIs directly, so non-agent users can render maps and sample point forecasts without an MCP client.

Optional specialty tools

A small set of tools sit outside the agent-v1 contract today and need rustwx workspace binaries to be built locally:

  • wx_sounding (skew-T renderer)
  • wx_cross_section / wx_volume_cross_section (HRRR pressure VolumeStore renderer; all non-smoke wxsection styles)
  • wx_radar (NEXRAD Level-II renderer)
  • wx_native_dataset_plan / wx_native_dataset_run (Rust-native HRRR/GOES/MRMS/Level-II training-data plans and shards)
  • wx_native_obs_preview (quicklook PNGs from local GOES, MRMS, or Level-II files)
  • wx_goes_native_sequence (native-grid GOES crops, time-window sequences, and GIF loops)
  • wx_ecape_profile (single-point ECAPE probe)
  • wx_ecape_grid (full-grid ECAPE swath research)
  • wx_wxstore_grid_export (RustWx to WxStore dense-grid manifest export)
  • wx_wxstore_grid_import (WxStore CLI import of one or more exported manifests)
  • wx_wxstore_grid_materialize (one-call RustWx export plus WxStore WXA import)
  • wx_wxstore_grid_plot (fast static PNG rendering from cached WXA grids)

If you want those too:

git clone https://github.com/FahrenheitResearch/rustwx
cd rustwx
cargo build -p rustwx-cli --release \
  --bin sounding_plot \
  --bin hrrr_pressure_volume_store \
  --bin volume_store_cross_section_render \
  --bin radar_export \
  --bin native_dataset_plan \
  --bin native_dataset_runner \
  --bin native_obs_preview \
  --bin goes_native_sequence \
  --bin hrrr_ecape_profile_probe \
  --bin hrrr_ecape_grid_research \
  --bin rustwx_grid_export \
  --bin wxstore_wxa_showcase

export HERMES_RUSTWX_BIN_DIR="$(pwd)/target/release"

To import exported grids into WxStore, also build the WxStore CLI and point Hermes at it:

git clone https://github.com/FahrenheitResearch/wxstore
cd wxstore
cargo build --release
export HERMES_WXSTORE_BIN_DIR="$(pwd)/target/release"
export HERMES_WXSTORE_URL="http://127.0.0.1:8897"

These will fold into the agent-v1 contract or service APIs as they stabilize; until then, the corresponding MCP tools degrade with a clear "build the binary" or "service unavailable" error rather than blocking the rest of the plugin.

Configure

# Hermes Agent — ~/.hermes/config.yaml
mcp_servers:
  weather:
    command: weather-mcp
    env:
      HERMES_RUSTWX_BIN_DIR: /path/to/rustwx/target/release
      HERMES_WXSTORE_BIN_DIR: /path/to/wxstore/target/release
      HERMES_WXSTORE_URL: http://127.0.0.1:8897
      HERMES_RUSTWX_PLOT_STYLE: operational_fast
      HERMES_CACHE_DIR: /path/to/weather-cache         # default: ./cache/rustwx
      HERMES_OUT_DIR:   /path/to/weather-outputs       # default: ./outputs
// Claude Desktop / generic MCP — claude_desktop_config.json
{
  "mcpServers": {
    "weather": {
      "command": "weather-mcp",
      "env": { "HERMES_RUSTWX_BIN_DIR": "/path/to/rustwx/target/release" }
    }
  }
}

CLI

weather-mcp --list      # every MCP tool with one-line descriptions
weather-mcp --doctor    # binary discovery + product catalog state
weather-mcp --test      # smoke-test render
weather-ui              # local browser UI for RustWx maps and point forecasts

Tools (49 total)

Discovery

Tool Purpose
wx_models Available models, sources, products, forecast horizons
wx_products Product slugs advertised by the installed rustwx wheel, filterable by kind/model/status/search
wx_recipes Compact recipe summary (live with fallback mirror)
wx_regions rustwx region presets
wx_doctor Local install diagnostics
wx_latest Resolve the latest available run for a model
wx_data_packs HRRR-first local storage tiers: what works without more downloads at 1/5/10/50 GB style budgets

Hermes is HRRR-first for local operational use. Tool defaults use run="latest" and resolve against advertised forecast-hour availability; requests for f019-f048 use the newest HRRR synoptic cycle that actually has those hours. Local data-pack tiers are cache/retention guidance: rustwx uses .idx byte-range fetches wherever the requested fields can be safely subset, while larger tiers simply retain more warmed hours, routes, and artifacts.

Direct & derived rendering

Tool Purpose
wx_fetch Fetch model GRIB2 data via rustwx with idx-byte-range selective download by default
wx_render_recipe Render any combination of direct / derived / windowed / heavy recipes (auto-routes to the right binary)
wx_composite Built-in composite/isopleth recipe helper plus schema-stable custom composite/grid-overlay requests
wx_cape SBCAPE / MLCAPE / MUCAPE shortcut
wx_ecape First-class ECAPE map (sbecape / mlecape / muecape)
wx_srh 0-1 km or 0-3 km SRH
wx_shear 0-1 km or 0-6 km bulk shear
wx_stp Fixed-layer Significant Tornado Parameter
wx_windowed Time-window products: full HRRR QPF/UH/surface-extrema family, plus cross-model qpf_total for validated v0.5 indexed-GRIB models
wx_severe_panel Multi-product severe + ECAPE plate from one shared heavy thermo load

ECAPE specialists

Tool Purpose
wx_ecape_profile Per-profile ECAPE diagnostics at a (lat, lon) — sub-millisecond Rust solver
wx_ecape_grid Full-grid ECAPE research over a swath (background)
wx_ecape_ratio_map MLECAPE filled + ECAPE/CAPE ratio contours w/ magnitude mask

Vertical / observations

Tool Purpose
wx_cross_section Compatibility alias for HRRR pressure VolumeStore cross sections
wx_volume_cross_section HRRR pressure VolumeStore cross sections; builds a short-lived 1-3 hour local store and renders PNG/WebP for all non-smoke wxsection styles
wx_satellite Latest GOES satellite imagery via rustwx.render_goes_satellite_json; supports GeoColor, GLM overlay, RGB composites, and ABI Bands 1-16
wx_meteogram Point forecast time series via rustwx.sample_point_timeseries_json, or a warmed store when store_id is supplied
wx_meteogram_warm_store Warm a point-timeseries grid store for repeated meteogram sampling
wx_radar Native rustwx NEXRAD Level-II rendering via radar_export: base, dual-pol, SRV, VIL, echo tops, and feature JSON
wx_sounding Skew-T at (lat, lon) rendered by rustwx's native sounding_plot binary; supports sample_method="box-mean" with box_radius_km
wx_native_obs_preview Quicklook PNG from a local GOES, MRMS, or Level-II file before it becomes a training shard; Level-II velocity supports rustwx dealiasing
wx_goes_native_sequence Fast GOES ABI image/loop generator for arbitrary lat/lon boxes, full disk, CONUS, or mesoscale sectors; can return PNG frames and an animated GIF

WxStore temporal stores

Tool Purpose
wx_wxstore_status Check WxStore service health and local binary discovery
wx_wxstore_catalog Query WxStore status, model/product/variable catalogs, latest runs, observation sources, satellite/radar layers, and vertical-render status
wx_wxstore_forecast Sample WxStore WXA spatial lanes as Open-Meteo-style point forecasts
wx_wxstore_sample Sample one WxStore grid variable at a lat/lon or named location
wx_wxstore_temporal_sounding Query WxStore WXP temporal pressure-profile lanes, optionally with diagnostics
wx_wxstore_objects Search WxStore observation, model, static-plot, evidence, satellite, radar, and source objects
wx_wxstore_mesoanalysis Query WxStore mesoanalysis innovation status, targeted station/source checks, and watchlists
wx_wxstore_grid_export Export RustWx direct, derived, or windowed grids into WxStore-importable WXA manifests
wx_wxstore_grid_import Import one or more exported manifests into a WxStore spatial root and optionally publish latest
wx_wxstore_grid_materialize Export RustWx grids and import them into a durable WXA spatial cache in one call
wx_wxstore_grid_plot Render operational-fast static PNGs directly from cached WXA grids

Research mode

Tool Purpose
wx_research_profile_sweep Multi-point ECAPE sweep across (point × date × cycle × fhour). Modes: targets / random / stress. Aggregated CSV with timing breakdown
wx_build_dataset Multi-day batch renders or profile probes (background)
wx_native_dataset_plan Write a selectable HRRR/GOES/MRMS/Level-II training-data plan
wx_native_dataset_run Fetch/materialize a native training-data plan into shards

Cache & jobs

Tool Purpose
wx_cache_status Disk usage + top consumers + per-subdir totals
wx_cache_evict LRU eviction to bring cache below target_gb (dry-run by default)
wx_job_status / wx_job_list / wx_job_cancel Background-job control

Showcase gallery

The repo ships a one-shot script that exercises every tool against a single canonical run, captures per-call timing, and emits a self-contained HTML gallery:

python examples/showcase_full.py        # ~3 min with warm cache, ~5 min cold
python examples/showcase_html.py        # builds outputs/showcase/index.html

The showcase includes HRRR VolumeStore cross sections, the GOES18 product set, direct point meteograms, warmed point-timeseries store sampling, and native rustwx radar export. Open outputs/showcase/index.html after running.

Top wall-time consumers from the canonical run:

42.7 s  HRRR derived  — 44 recipes / one shared decode    72 PNGs
41.3 s  HRRR severe panel (heavy_panel_hour)              24 PNGs
35.1 s  ECAPE/CAPE ratio display (background)              6 PNGs
 8.0 s  mini research dataset (1 cycle × 2 recipes)
 7.9 s  HRRR windowed — 8 QPF/UH products                  6 PNGs
 6.6 s  HRRR direct — 52 recipes / one shared decode      72 PNGs
 6.6 s  ECAPE grid research (background)
 5.9 s  stress profile sweep (10 curated points)
 5.1 s  GFS derived (sbcape/mucape/lapse)                  6 PNGs
 4.7 s ×5  cross sections (4 routes + 1 city pair)

The HRRR direct + derived passes each render dozens of products from one shared thermodynamic decode — that's where the per-product cost approaches zero. A focused HRRR CONUS benchmark with the default smart chunk policy produced 81 regular non-ECAPE PNGs (52 direct + 29 light-derived) in 27.27 s warm-cache for one hour, and 162 PNGs in 56.27 s warm-cache for two hours.

Programmatic use (without an LLM)

Every tool is also a plain Python function:

from hermes_weather.rustwx import discover
from hermes_weather.tools import (
    render, ecape, volume_cross_section,
    satellite, meteogram, radar, catalog, wxstore,
)

env = discover()

# Single first-class ECAPE map
out = render.ecape(env, parcel="ml", region="southern-plains",
                   run_str="latest", forecast_hour=0)
print(out["pngs"])

# Per-profile ECAPE in <1ms (Rust kernel)
prof = ecape.profile(env, location="Norman, OK",
                     run_str="latest", forecast_hour=1,
                     include_input_column=True)
print(prof["diagnostics"]["parcels"][1]["ratio_ecape_to_undiluted_cape"])

# HRRR VolumeStore cross sections: temporary 1-hour SoCal cube,
# all non-smoke wxsection styles, PNG + WebP outputs.
fast_xs = volume_cross_section.volume_cross_section(
    env, products=["all"], route="socal-coast-desert",
    run_str="latest", forecast_hour=0,
)

# GOES satellite set, short point meteogram, and native radar export.
sat = satellite.satellite(env, products=satellite.DEFAULT_PRODUCTS)
met = meteogram.meteogram(env, location=(34.0522, -118.2437),
                          forecast_hour_start=0, forecast_hour_end=3)
rad = radar.radar(env, site="KTLX", products="all")

# Discover what every recipe is and where it works
products = catalog.products(env, kind="derived", search="ecape")
for p in products["products"]:
    supported_models = [s["model"] for s in p["support"] if s["status"] == "supported"]
    print(f"{p['slug']:35s} {p['maturity']:14s} {supported_models}")

# Query WxStore if a service is running
store = wxstore.catalog(env, endpoint="latest", model="hrrr", domain="conus")
print(store)

# Cache-first WXA workflow: pay the GRIB -> grid cost once, then plot quickly.
mat = wxstore.grid_materialize(
    env,
    products=["vpd_2m", "dewpoint_depression_2m", "heat_index_2m", "stp_fixed"],
    forecast_hours="0-2",
    region="conus",
    jobs=4,
)
plots = wxstore.grid_plot(env, products=["stp_fixed"], forecast_hours="0-2")
print(mat["spatial_root"], plots["png_count"])

Speed reality check (ECAPE-RS validation paper, April 2026)

Operation Python (ecape-parcel + MetPy) Rust (rustwx-calc) Speedup
ECAPE per HRRR profile (one parcel/config) 2.8–6.1 s 0.45–0.65 ms 5,600–13,000×
ECAPE full-grid (272,955 HRRR cells / forecast hour) impractical 17.6–18.4 s —

Per-profile ECAPE is essentially free; full-grid is the heavy one. Heavy tools (wx_ecape_grid, wx_ecape_ratio_map for CONUS, wx_research_profile_sweep over many cycles) run as background jobs. Profile-sweep results separate raw_fetch_s / profile_extract_s / parcel_solver_s / render_s so you can attribute time honestly.

License

MIT.

Acknowledgements

Built on top of rustwx (Rust meteorology workspace, Fahrenheit Research), wxstore (MIT temporal stores for weather data), and the public ecape-parcel reference implementation. Validation methodology described in Validation and Acceleration of an ecape-parcel-Compatible Solver for HRRR-Scale Entraining-CAPE Diagnostics, ECAPE-RS Project, April 2026.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hermes_weather_agent-0.5.10.tar.gz (91.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hermes_weather_agent-0.5.10-py3-none-any.whl (96.7 kB view details)

Uploaded Python 3

File details

Details for the file hermes_weather_agent-0.5.10.tar.gz.

File metadata

  • Download URL: hermes_weather_agent-0.5.10.tar.gz
  • Upload date:
  • Size: 91.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for hermes_weather_agent-0.5.10.tar.gz
Algorithm Hash digest
SHA256 ac91335e02012dfd786b0d3e5ef2fdc8dd6494f103d04b104703239d6644e207
MD5 66aaf3eff02f3ffaf3a575f854328904
BLAKE2b-256 9f7d75255f3395631dd63174e18376bc7411d6919e4be0d04278dd5c1cdbfb20

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_weather_agent-0.5.10.tar.gz:

Publisher: pypi-publish.yml on FahrenheitResearch/hermes-weather-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hermes_weather_agent-0.5.10-py3-none-any.whl.

File metadata

File hashes

Hashes for hermes_weather_agent-0.5.10-py3-none-any.whl
Algorithm Hash digest
SHA256 a4396915dcd7622d9ab4fc5d38ceb593a844549d1ab131ef55ace23ffe60bd8f
MD5 255092994f15dd86cb69085209d10c86
BLAKE2b-256 f1ecfbadef0ae70f4c40dbf311f58a5a1c4e9babcc5ad26b85ee7cd4e87bc0c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for hermes_weather_agent-0.5.10-py3-none-any.whl:

Publisher: pypi-publish.yml on FahrenheitResearch/hermes-weather-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page