Wraps NOAA's Climate Data Online API v2 to search weather stations and pull historical observations going back to 1763. You get seven tools covering the full discovery flow: list datasets (GHCND daily, GSOM monthly, climate normals), find locations by state or zip, search stations by bounding box or data type, and fetch observation records with automatic date range validation. The fetch tool enforces per-dataset limits (one year for daily, ten for monthly) and handles unit conversion since raw GHCND values come as tenths-of-unit integers. Includes resources for dataset metadata and station lookups. Useful when you need programmatic access to temperature, precipitation, wind, or snow data without writing pagination and validation logic yourself.
Search NOAA climate stations and datasets, fetch historical weather observations via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://noaa-climate.caseyjhand.com/mcp
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_datasetsList all available NOAA CDO datasets — approximately 11 in total.
noaa_climate_fetch_datanoaa_climate_list_data_categoriesList data category groups that organize related measurement types.
noaa_climate_list_data_types to narrow by measurement domainnoaa_climate_list_data_typesList specific measurement labels for a dataset or category.
GHCND) or category (e.g., TEMP) to narrow resultsTMAX (max temperature), TMIN (min temperature), PRCP (precipitation), SNOW (snowfall), SNWD (snow depth), AWND (average wind speed)noaa_climate_find_locationsSearch geographic locations by category.
ST (US states, ~52), CNTY (counties), CITY (cities), CNTRY (countries), ZIP (zip codes), CLIM_REG (NOAA climate regions), CLIM_DIV (climate divisions), hydrological categorieslocationCategoryId=ST to list all states in one call; use sortField=name with pagination to browse cities alphabeticallyFIPS:37, CITY:US530031, ZIP:98101) used in station search and data queriesnoaa_climate_find_stationsSearch weather observation stations.
datasetId and date range to ensure compatibilityGHCND:USC00450974, COOP:010008noaa_climate_fetch_datanoaa_climate_get_stationFetch full metadata for a single weather station by ID.
noaa://stations/{stationId} resource as a direct lookupnoaa_climate_fetch_dataFetch historical observation records from a NOAA CDO dataset.
datasetId, startDate, and endDate; optionally scoped by station, location, and data typeunits=metric (SI) or units=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 scaledstartDate=2010-01-01 and endDate=2010-12-31 — that is the API proxy year regardless of which 30-year period is described{ date, datatype, station, value, attributes } with pagination metadata| 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 |
Built on @cyanheads/mcp-ts-core:
none, jwt, oauth)in-memory, filesystem, Supabase, Cloudflare KV/R2/D1NOAA CDO-specific:
units parameter — avoids raw tenths-of-unit integer confusionAgent-friendly output:
limit, offset, and total count in every responsereason codes and recovery hints — agents can branch on data, not string parsingAdd 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
git clone https://github.com/cyanheads/noaa-climate-mcp-server.git
cd noaa-climate-mcp-server
bun install
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 |
Build and run the production version:
# One-time build
bun run rebuild
# Run the built server
bun run start:http
# or
bun run start:stdio
Run checks and tests:
bun run devcheck # Lints, formats, type-checks, and more
bun run test # Runs the test suite
| 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. |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for logging, ctx.state for storagecreateApp() arraysIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
This project is licensed under the Apache 2.0 License. See the LICENSE file for details.
NOAA_CDO_TOKEN*NOAA CDO API token. Obtain free at https://www.ncdc.noaa.gov/cdo-web/token.
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_PUBLIC_URLPublic origin override for deployments behind a TLS-terminating reverse proxy (e.g. https://mcp.example.com).
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.
com.mcparmory/google-search
io.github.pipeworx-io/brave-search
marcopesani/mcp-server-serper
brave/brave-search-mcp-server
com.mcparmory/google-search-console
acamolese/google-search-console-mcp