# dynamical.org Weather & Climate Catalog

> Search dynamical.org's open STAC catalog of weather & climate datasets (GFS, ECMWF, HRRR).

- name: io.github.dynamical-org/mcp
- version: 0.1.1
- connection class: R0 (autonomous)
- trust: 72/100 flags: no-repository
- quality: 82/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.dynamical-org%2Fmcp
- tools: https://api.protogrid.dev/v1/servers/io.github.dynamical-org%2Fmcp/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "dynamical-org": {
      "type": "http",
      "url": "https://mcp.dynamical.org/mcp"
    }
  }
}
```


## Trust

- hygiene: 80
- liveness: 98
- freshness: 65
- provenance: 45
- drivers: +website +reachable +uptime-95% ~updated-106d-ago -no-repository
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 82/100 (good)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 79 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 1 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 4 of 4 tools declare readOnlyHint or destructiveHint
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: get_access_pattern (destructiveHint, idempotentHint); get_dataset_info (destructiveHint, idempotentHint); list_recent_runs (destructiveHint, idempotentHint); …
- pass `tools.token_cost`: about 1,159 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 4, about 1,159 tokens to load them all
- tool set hash: 56fae2f2e2fc32c0887abc87bb852b22
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.dynamical-org/mcp.svg)](https://protogrid.dev/servers/io.github.dynamical-org/mcp)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://mcp.dynamical.org/mcp (streamable-http, auth none, reachable true, uptime30d 0.9478261)

## Packages

_none_

## Tools (4)

- `get_access_pattern`: Get the storage URI and working code for opening a dynamical.org
dataset's data.

dynamical.org publishes a Python package, `dynamical-catalog`, that
reads the STAC catalog itself to resolve and open a dataset -- it's the
recommended access pattern because it can't go stale even if the
underlying storage format or location changes. This tool also returns
the dataset's low-level storage details (from the STAC asset, fetched
live) and a lower-level xarray/fsspec snippet for callers who need
direct access instead of the wrapper package.

Args:
    collection_id: A STAC collection id, e.g. "noaa-gfs-forecast". Use
        search_catalog to discover ids.

Returns:
    A dict with the recommended `dynamical_catalog.open(...)` snippet,
    a `worked_example` pulled from the collection's own STAC metadata
    when one is published, the raw asset URI/type/storage options, and
    a generated low-level open snippet (icechunk/zarr/geoparquet,
    chosen from the asset's declared type). Raises ValueError (listing
    valid ids) if collection_id is unknown.

- `get_dataset_info`: Get documentation, spatial/time resolution, domain, and update cadence
for one dynamical.org dataset.

dynamical.org/catalog is itself rendered from this same STAC catalog, so
this tool fetches the collection document live (short TTL cache) rather
than relying on anything baked into this server -- it's always as fresh
as the STAC catalog itself.

Args:
    collection_id: A STAC collection id, e.g. "noaa-gfs-forecast",
        "noaa-hrrr-analysis", or "ecmwf-aifs-ens-forecast". Use
        search_catalog to discover ids.

Returns:
    A dict with title/model name, prose descriptions, spatial and time
    domain/resolution, forecast range (for forecast datasets), license
    and attribution, the dataset's variables, and links to its docs
    page and example notebooks. Raises ValueError (listing valid ids)
    if collection_id is unknown.

- `list_recent_runs`: Check run freshness and arrival status for a dynamical.org forecast
dataset, from the same public feed status.dynamical.org's dashboard polls.

Only forecast collections are pipeline-monitored today (analysis
collections like noaa-gfs-analysis or noaa-mrms-conus-analysis-hourly
aren't yet tracked by this feed).

Args:
    collection_id: A STAC collection id, e.g. "noaa-gfs-forecast".
    limit: Maximum number of recent runs to return, most recent first
        (default 10).

Returns:
    A dict with the overall pipeline `sla_status`, this product's
    cadence and next expected init/completion time, typical latency
    stats, and up to `limit` recent runs (`init_time`, `status`,
    `completion_pct`, `on_timedness`, arrival/latency timestamps). If
    collection_id isn't pipeline-monitored, returns `monitored`: False
    plus the list of collection ids that are.

- `search_catalog`: Search dynamical.org's STAC catalog of cloud-optimized weather and
climate datasets.

Matches against each dataset's model name, description, spatial/time
domain and resolution, forecast range, and variable names -- so a query
can be a model ("GFS"), a variable ("precipitation", "temperature_2m"),
a region ("continental US", "global"), or a resolution ("3km", "0.25
degree"). Results are ranked by number of matching terms.

Args:
    query: Free-text search terms, e.g. "hourly precipitation CONUS"
        or "ECMWF ensemble forecast".
    limit: Maximum number of results to return (default 5).

Returns:
    {"query": ..., "results": [{"collection_id", "title", "model_name",
    "description_summary", "spatial_domain", "spatial_resolution",
    "matched_variables", "score"}, ...]}, most relevant first. Pass a
    result's collection_id to get_dataset_info, get_access_pattern, or
    list_recent_runs.

