Install
$ agentstack add mcp-cyanheads-noaa-climate-mcp-server ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
@cyanheads/noaa-climate-mcp-server Search NOAA climate stations and datasets, fetch historical weather observations via MCP. STDIO or Streamable HTTP. 7 Tools • 2 Resources
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/noaa-climate-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/noaa-climate-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
[](https://github.com/cyanheads/noaa-climate-mcp-server/releases/latest/download/noaa-climate-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=noaa-climate-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvbm9hYS1jbGltYXRlLW1jcC1zZXJ2ZXIiXSwiZW52Ijp7Ik5PQUFfQ0RPX1RPS0VOIjoieW91ci10b2tlbi1oZXJlIn19) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22noaa-climate-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Fnoaa-climate-mcp-server%22%5D%2C%22env%22%3A%7B%22NOAACDOTOKEN%22%3A%22your-token-here%22%7D%7D)
[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
Public Hosted Server: https://noaa-climate.caseyjhand.com/mcp
Tools
7 tools for working with the NOAA Climate Data Online (CDO) API v2:
| Tool | Description | |:---|:---| | noaa_climate_list_datasets | List available CDO datasets with IDs, names, and temporal coverage | | noaa_climate_list_data_categories | List data category groups (Temperature, Precipitation, Wind, etc.) | | noaa_climate_list_data_types | List specific measurement labels (TMAX, TMIN, PRCP, SNOW, etc.) by dataset or category | | noaa_climate_find_locations | Search geographic locations by category (states, cities, counties, zip codes, climate regions) | | noaa_climate_find_stations | Search weather stations by location, bounding box, dataset, and data type | | noaa_climate_get_station | Fetch full metadata for a single station by ID | | noaa_climate_fetch_data | Fetch historical observation records for a dataset and date range |
noaa_climate_list_datasets
List all available NOAA CDO datasets — approximately 11 in total.
- Returns dataset IDs, names, data coverage fraction, and temporal range
- No required parameters — returns everything by default
- Optionally filter by data type, location, station, or date range
- Common datasets: GHCND (daily, 1763–present), GSOM (monthly), GSOY (annual), NORMAL_DLY/MLY/ANN/HLY (1981–2010 climate normals)
- Start here to orient before calling
noaa_climate_fetch_data
noaa_climate_list_data_categories
List data category groups that organize related measurement types.
- ~41 categories including Temperature, Precipitation, Wind, Pressure, Sunshine, Sky cover, Weather Type
- Optionally filter by dataset, location, station, or date range
- Use before
noaa_climate_list_data_typesto narrow by measurement domain
noaa_climate_list_data_types
List specific measurement labels for a dataset or category.
- Hundreds of data types across all datasets
- Filter by dataset (e.g.,
GHCND) or category (e.g.,TEMP) to narrow results - Common GHCND types:
TMAX(max temperature),TMIN(min temperature),PRCP(precipitation),SNOW(snowfall),SNWD(snow depth),AWND(average wind speed) - Returns ID, name, coverage fraction, and date range per type
noaa_climate_find_locations
Search geographic locations by category.
- Category types:
ST(US states, ~52),CNTY(counties),CITY(cities),CNTRY(countries),ZIP(zip codes),CLIM_REG(NOAA climate regions),CLIM_DIV(climate divisions), hydrological categories - Use
locationCategoryId=STto list all states in one call; usesortField=namewith pagination to browse cities alphabetically - The CDO API has no name-search parameter — sort by name and page through results to find a specific location
- Returns location IDs (
FIPS:37,CITY:US530031,ZIP:98101) used in station search and data queries
noaa_climate_find_stations
Search weather observation stations.
- Filter by location ID, bounding box (lat/lon), dataset, data type, and date range
- Returns station IDs, names, coordinates, elevation, and data coverage dates
- A station must have data for the dataset and date range you want — pass
datasetIdand date range to ensure compatibility - Common station ID formats:
GHCND:USC00450974,COOP:010008 - Station IDs returned here feed directly into
noaa_climate_fetch_data
noaa_climate_get_station
Fetch full metadata for a single weather station by ID.
- Returns name, coordinates (decimal degrees), elevation, and full data coverage date range
- Use to verify a station before querying data, or to check its temporal coverage
- Mirrors the
noaa://stations/{stationId}resource as a direct lookup
noaa_climate_fetch_data
Fetch historical observation records from a NOAA CDO dataset.
- Requires
datasetId,startDate, andendDate; optionally scoped by station, location, and data type - Date range limits: sub-daily and daily datasets (GHCND, PRECIP15, PRECIPHLY, NORMALDLY, NORMALHLY) — 1 year max per request; monthly and annual datasets (GSOM, GSOY, NORMALMLY, NORMALANN) — 10 years max
- Unit selection: strongly recommended — pass
units=metric(SI) orunits=standard(Fahrenheit/inches). Without it, GHCND values are raw tenths-of-unit integers (TMAX=256 = 25.6°C, PRCP=12 = 1.2mm); GSOM/GSOY are already scaled - Climate normals: for any NORMAL_* dataset, use
startDate=2010-01-01andendDate=2010-12-31— that is the API proxy year regardless of which 30-year period is described - Returns flat tuples of
{ date, datatype, station, value, attributes }with pagination metadata
Resources
| Type | Name | Description | |:---|:---|:---| | Resource | noaa://datasets | All CDO datasets with IDs and temporal coverage — injectable context for orienting an agent before querying data | | Resource | noaa://stations/{stationId} | Station metadata by ID — name, coordinates, elevation, and data coverage date range |
Features
Built on @cyanheads/mcp-ts-core:
- Declarative tool definitions — single file per tool, framework handles registration and validation
- Unified error handling across all tools
- Pluggable auth (
none,jwt,oauth) - Swappable storage backends:
in-memory,filesystem,Supabase,Cloudflare KV/R2/D1 - Structured logging with optional OpenTelemetry tracing
- Runs locally (stdio/HTTP) or on Cloudflare Workers from the same codebase
NOAA CDO-specific:
- Full CDO API v2 coverage — datasets, data categories, data types, locations, stations, and observations
- Client-side date range validation with per-dataset limits enforced before hitting the API
- Unit normalization via the CDO
unitsparameter — avoids raw tenths-of-unit integer confusion - Retry with exponential backoff for transient API failures
Agent-friendly output:
- Paginated results across all list and search tools —
limit,offset, and total count in every response - Station and dataset IDs flow naturally between tools — find a location, find stations in it, fetch data from those stations
- Structured error contracts with
reasoncodes and recovery hints — agents can branch on data, not string parsing - Dataset and station resources for injectable, zero-fetch context
Getting started
Self-Hosted / Local
Add the following to your MCP client configuration file.
{
"mcpServers": {
"noaa-climate-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/noaa-climate-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"NOAA_CDO_TOKEN": "your-token-here"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"noaa-climate-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/noaa-climate-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"NOAA_CDO_TOKEN": "your-token-here"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"noaa-climate-mcp-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "-e", "NOAA_CDO_TOKEN=your-token-here", "ghcr.io/cyanheads/noaa-climate-mcp-server:latest"]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 NOAA_CDO_TOKEN=your-token-here bun run start:http
# Server listens at http://localhost:3010/mcp
Prerequisites
- Bun v1.3.0 or higher (or Node.js ≥24.0.0).
- A free NOAA CDO API token — required for all requests.
Installation
- Clone the repository:
git clone https://github.com/cyanheads/noaa-climate-mcp-server.git
- Navigate into the directory:
cd noaa-climate-mcp-server
- Install dependencies:
bun install
Configuration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default | |:---|:---|:---| | NOAA_CDO_TOKEN | Required. NOAA CDO API token — obtain free at ncdc.noaa.gov/cdo-web/token | — | | MCP_TRANSPORT_TYPE | Transport: stdio or http | stdio | | MCP_HTTP_PORT | HTTP server port | 3010 | | MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path where the MCP server is mounted | /mcp | | MCP_PUBLIC_URL | Public origin override for TLS-terminating reverse-proxy deployments | none | | MCP_AUTH_MODE | Authentication: none, jwt, or oauth | none | | MCP_LOG_LEVEL | Log level (debug, info, warning, error, etc.) | info | | MCP_GC_PRESSURE_INTERVAL_MS | Opt-in Bun-only forced-GC pressure loop (ms). Try 60000 if heap growth is observed under sustained HTTP load. | 0 (disabled) | | STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1 | in-memory | | OTEL_ENABLED | Enable OpenTelemetry | false |
Running the server
Local development
- Build and run the production version:
```sh # One-time build bun run rebuild
# Run the built server bun run start:http # or bun run start:stdio ```
- Run checks and tests:
``sh bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite ``
Project structure
| Directory | Purpose | |:---|:---| | src/mcp-server/tools | Tool definitions (*.tool.ts). Seven tools across datasets, locations, stations, and observations. | | src/mcp-server/resources | Resource definitions. Datasets catalog and station metadata resources. | | src/services/cdo | CDO HTTP client with retry, backoff, and camelCase→lowercase parameter translation. | | src/config | Server-specific environment variable parsing and validation with Zod. | | tests/ | Unit and integration tests, mirroring the src/ structure. |
Development guide
See [CLAUDE.md](./CLAUDE.md) for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor logging,ctx.statefor storage - Register new tools and resources in the
createApp()arrays
Contributing
Issues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
License
This project is licensed under the Apache 2.0 License. See the [LICENSE](./LICENSE) file for details.
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: cyanheads
- Source: cyanheads/noaa-climate-mcp-server
- License: Apache-2.0
- Homepage: https://www.npmjs.com/package/@cyanheads/noaa-cdo-mcp-server
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.