Open Meteo Mcp Server

io.github.cyanheadsPublished by GitHub account cyanheadsv0.5.0Updated Oct 29, 2026

Global weather via Open-Meteo: forecast, historical, marine, air quality, geocoding, elevation.

VerifiedStreamable HTTPWeb executableLocation & LifestyleData & Analytics

Overview

AI-generated overview

Open-Meteo weather server: geocode places, then fetch forecasts, historical archives, marine, air quality, flood, ensemble and climate data, with SQL over…

What you can do
  • Resolve place names to ranked coordinates with timezone and country
  • Fetch current, hourly and daily forecasts up to 16 days ahead plus up to 92 past days, from best match or several models side by side
  • Pull historical reanalysis from 1940, marine wave and sea-surface conditions, modeled CAMS air quality and AQI, GloFAS river discharge, per-member ensemble forecasts and CMIP6 climate projections to 2050
  • Get Copernicus DEM terrain elevation for up to 1,000 coordinate pairs, sampled 100 per call
  • Inspect and query large spilled results with read-only SQL on a DataCanvas, and optionally drop a staged table
When to use it
Useful when an assistant needs weather, climate, ocean, air quality, river or elevation data for a location, including multi-model comparisons, uncertainty ranges and long historical or projected series. It is a good fit for research, planning and reporting tasks that need structured weather numbers rather than a single current reading.
Requirements
Runs as a hosted remote endpoint or locally via npx (Node.js) or Docker; Bun 1.4.0+ or Node.js 24+ for a source build. No API key for non-commercial use; commercial use requires Open-Meteo's paid tier. Network access to the Open-Meteo APIs. All environment variables are optional, including CANVAS_PROVIDER_TYPE, MCP_AUTH_MODE and MCP_TRANSPORT_TYPE.
Before you install
Data is provided by Open-Meteo under CC BY 4.0 and attribution is expected; commercial use needs a paid Open-Meteo tier. Air quality and pollen are modeled grid values, not station measurements, and flood discharge comes from the nearest grid cell, which may not be the intended river. Elevation calls count against per-IP rate limits. The dataframe drop tool is off unless OPENMETEO_DATAFRAME_DROP_ENABLED is true, and it removes staged tables.

Installation

In SourceWeft

  1. Open Open Meteo Mcp Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.cyanheads%2Fopen-meteo-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "open-meteo": {
      "type": "http",
      "url": "https://open-meteo.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/open-meteo-mcp-server

Geocode places, fetch global weather forecasts, historical climate, marine conditions, air quality, and terrain elevation via MCP. STDIO or Streamable HTTP.

12 Tools


Overview

Global weather from Open-Meteo: forecasts, history back to 1940, marine conditions, air quality, probabilistic ensembles, river discharge, and climate projections. Look up any place by name, pull hourly and daily variables, and run SQL over large results. No API key required.

Tools

ToolDescription
openmeteo_search_locationsResolve a place name to ranked coordinates with country, region, timezone, and population
openmeteo_get_forecastCurrent conditions and hourly/daily forecast up to 16 days, with up to 92 past days, from best match or chosen models side by side
openmeteo_get_historicalHourly/daily history from the reanalysis archive, 1940 to present
openmeteo_get_marineWave, swell, and sea-surface conditions: current, up to 8 forecast days, or an archive range, in metric or imperial units
openmeteo_get_air_qualityModeled CAMS pollutants, pollen, and AQI: current, up to 7 forecast days, or an archive range
openmeteo_get_elevationCopernicus DEM terrain elevation: up to 1,000 coordinate pairs, the first 100 sampled per call with the rest reported for resubmission
openmeteo_get_ensemblePer-member ensemble forecast (up to 64 members, up to 35 days) for exceedance and uncertainty
openmeteo_get_floodGloFAS river discharge: a ~6-month forecast or a date range from 1984, from seamless or chosen v4 models
openmeteo_get_climateBias-corrected daily CMIP6 projections, 1950–2050, across up to 7 models
openmeteo_dataframe_describeList the tables and columns staged on a DataCanvas
openmeteo_dataframe_queryRun a read-only SQL SELECT against staged tables
openmeteo_dataframe_dropRemove one staged table or view from a DataCanvas (opt-in)

The server also publishes an agent skill, open-meteo-guide (skill://open-meteo-guide/SKILL.md, source in skills/open-meteo-guide/): which tool answers which question, plus the gates for exceedance odds, frost, comparisons to a normal, climate shifts, surf spots, river cells, and AQI timing.

Capability reference

openmeteo_search_locations tool

  • A bare place name ("Paris", not "Paris, France"), with optional country (ISO 3166-1 alpha-2) and language (default en); count 1–10, default 5
  • Each result carries coordinates, an IANA timezone, country / country_code, admin1 / admin2, population, and feature_code; no match fails as no_results
  • A notice flags a top match with null or sub-100,000 population, which often means a historic exonym ("Bangalore", "Calcutta")
  • A native-script query that misses under en is retried once in the language its script implies; effective_language names it when the retry succeeds (上海 → zh), and results come back localized

openmeteo_get_forecast tool

  • At least one of current_variables, hourly_variables, or daily_variables (up to 50 each); forecast_days 1–16 (default 7), past_days 0–92 (default 0)
  • Per-timestamp hourly / daily records with hourly_units / daily_units; current_variables adds a current object from 15-minute data (interval 900) plus current_units
  • Omitting models reads Open-Meteo best_match; models compares deterministic models (e.g. ncep_gfs_seamless, ecmwf_ifs025, dwd_icon_seamless; older spellings like gfs_seamless still resolve). With 2+ models each hourly and daily column carries a model-name suffix, and models is echoed. current_variables takes at most one model (current_multi_model)
  • A regional model with no data at the point is dropped from a multi-model response: the notice names it, or, when one model is left with unsuffixed columns, says the values cannot be attributed to a model; when every requested model misses, the call fails as coverage_gap
  • Prefer past_days over openmeteo_get_historical for the last week, where the archive's ERA5 components lag

openmeteo_get_historical tool

  • start_date and end_date required (YYYY-MM-DD, from 1940-01-01), plus at least one of hourly_variables / daily_variables, named as on the forecast tool
  • Omitting models reads Best Match (IFS HRES + ERA5 + ERA5-Land, source varies by date); up to 8 models pin a source. The ERA5 family runs about a week behind, ecmwf_ifs has no delay, and cerra covers Europe only
  • Output echoes models and the returned date_range; with 2+ models each column carries a model-name suffix. A model with no data at the point (cerra outside Europe) is dropped from a multi-model response; the notice names it, or, when one model is left with unsuffixed columns (era5,cerra), says the values cannot be attributed to a model

openmeteo_get_marine tool

  • One window per call: forecast_days 1–8 (upstream default 7) with past_days 0–92, or a start_date / end_date archive range back to at least 2022. Mixing them fails as forecast_window_conflict, a lone date as date_range_incomplete
  • At least one of current_variables, hourly_variables, or daily_variables (wave height, period, and direction, swell, sea-surface temperature); sheltered water returns near-zero waves, a point well inland returns nulls (named in the notice), a land point near the coast is answered from a nearby sea cell with real values and no notice (check the response's latitude / longitude is the water you meant), and ocean_current_velocity is null off the open ocean
  • current_variables takes the hourly names and adds a current object from 15-minute data (interval 900) plus current_units, alongside either window; a daily name there fails as variable_wrong_cadence
  • length_unit (metric / imperial) sets every height, sea_level_height_msl included, in m or ft; wind_speed_unit (kmh, mph, ms, kn) sets ocean_current_velocity; temperature_unit (celsius / fahrenheit) sets sea_surface_temperature. Open-Meteo converts the values, and the *_units maps label them (mph reads mp/h)

openmeteo_get_air_quality tool

  • One window per call: forecast_days 1–7 (upstream default 5) with past_days 0–92, or a start_date / end_date archive range from August 2022 (us_aqi starts a day later). Same forecast_window_conflict and date_range_incomplete rejections as the marine tool
  • At least one of current_variables (a current object, interval 3600) or hourly_variables: PM2.5, PM10, NO2, SO2, O3, CO, dust, pollen, European and US AQI. Pollen is modeled for Europe only, in pollen season; elsewhere it comes back null and the notice names it
  • data_source: "CAMS" marks every response as modeled grid data, not station measurements

openmeteo_get_elevation tool

  • Parallel latitudes[] / longitudes[] arrays of up to 1,000 pairs; unequal lengths fail as coordinate_count_mismatch, compared on the full arrays
  • Samples the first 100 pairs (the Elevation API's per-request limit) in one upstream request; unprocessed_count says how many were left and next_offset is where to resume — resubmit latitudes.slice(next_offset) and longitudes.slice(next_offset) until next_offset is null. A call of 100 or fewer returns 0 / null. Each sampled pair counts as one call against Open-Meteo's per-IP limits (600 a minute), so a seventh 100-pair slice inside one minute comes back rate_limited
  • elevations[] in input order, each { latitude, longitude, elevation_m } from the Copernicus DEM (~90 m); elevation_m is null where the DEM has no value (latitude 90), without failing the rest of the call

openmeteo_get_ensemble tool

  • At least one of hourly_variables / daily_variables; forecast_days 1–35 (default 7), past_days 0–92. Most models end within 16 days (ncep_gefs05 runs to about day 34); past that, columns are null and the notice says where data ends
  • models takes one ensemble name (e.g. ecmwf_ifs025_ensemble, 51 members; gem_global_ensemble, 21); omitted or blank selects ecmwf_ifs025_ensemble, echoed in model
  • Each variable returns per-member columns (temperature_2m_member01, …) across up to 64 members; member_count excludes the control run. A regional model queried outside its coverage fails as a non-retryable input error; switch to a global model

openmeteo_get_flood tool

  • daily_variables required (up to 20), all in m³/s: river_discharge plus the statistics river_discharge_mean / _median / _min / _max / _p25 / _p75, which carry ensemble spread on forecast-run days and repeat river_discharge on reanalysis days
  • One mode per call: forecast_days 1–210 (the current GloFAS run reaches about six months; later days are null), or a start_date / end_date range from 1984-01-01. Mixing them fails as forecast_days_conflict, a lone date as date_range_incomplete
  • Omitting models reads seamless_v4: consolidated_v4 reanalysis before 2023-08-05, forecast_v4 runs from then on. models: ["consolidated_v4"] reads the reanalysis through 2025-05-31 (null after, and on forecast_days); forecast_v4 starts 2023-06-01. Output echoes models; with 2+ models each column carries a model-name suffix, and the notice names null spans
  • Discharge comes from the GloFAS 0.05° grid cell nearest the coordinate, not reliably the cell on the river you mean; when the value is far below what the river carries, step the coordinate 0.05° across the channel and compare. Null outside GloFAS coverage

openmeteo_get_climate tool

  • start_date / end_date within 1950-01-01 to 2050-12-31 and daily_variables required (the API is daily-only); up to 7 CMIP6 models, e.g. CMCC_CM2_VHR4, MRI_AGCM3_2_S
  • With 2+ models each variable is suffixed with the model name; a single or omitted model returns plain names. A variable a model doesn't carry comes back null

openmeteo_dataframe_describe tool

  • Takes the canvas_id a spilled weather tool returned; lists each table's name, kind, row_count, and columns (name, type, nullability), plus the canvas expires_at
  • Fails as canvas_not_enabled when canvas is off, or canvas_not_found when the ID is unknown or past its 24-hour sliding TTL

openmeteo_dataframe_query tool

  • canvas_id plus a read-only SELECT against the staged table_name; rows holds up to 100 rows, fewer when wide rows would pass the 80,000-character inline ceiling (values are never cut). row_count is the exact total; page with OFFSET <rows.length> under an ORDER BY
  • If the count fails or runs past 5 seconds, rows still return, row_count is a lower bound, and count_error names the reason (e.g. count_timeout)
  • Fails as canvas_not_enabled, canvas_not_found, missing_table, system_catalog_access (system catalogs are blocked), or row_too_large (the first row alone exceeds the ceiling: select fewer columns, or shorten values with left(), substr(), or list_slice())

openmeteo_dataframe_drop tool

  • Off by default: listed as disabled until OPENMETEO_DATAFRAME_DROP_ENABLED=true
  • canvas_id plus the exact table_name from openmeteo_dataframe_describe; removes that one table or view and returns dropped and the remaining_tables. A name that is not staged returns dropped: false, so a repeated drop is safe
  • Fails as canvas_not_enabled, canvas_not_found, or invalid_table_name (not a plain SQL identifier, or a reserved keyword)

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

Open-Meteo-specific:

  • No API key for non-commercial use; commercial use requires Open-Meteo's paid API tier
  • Columnar API responses reshaped into per-timestamp records with *_units maps, on the same variable names across forecast and archive
  • DataCanvas spillover on the seven weather tools: with CANVAS_PROVIDER_TYPE=duckdb (the default) an over-budget result is staged as a DuckDB table (response carries canvas_id, table_name, truncated: true); with none it returns a bounded preview and truncated: true
  • models on the forecast, historical, ensemble, climate, and flood tools is not an allowlist, so a model Open-Meteo adds later works without a server update

Agent-friendly output:

  • Location-first workflow: openmeteo_search_locations returns the IANA timezone alongside coordinates, ready for any weather tool's timezone input (default auto)
  • Typed rejections: variable_wrong_cadence (names the correct field), request_too_large (names the inputs to narrow), coverage_gap (a coordinate outside the dataset's grid or the model's domain), and rate_limited; only Too many concurrent requests is retried first. An outage that outlasts three attempts fails as upstream_unavailable, or upstream_timeout when the last attempt timed out
  • Request URLs never appear in error data or client-visible logs
  • One notice per response for what the data alone won't show: unserved variable names, nulls outside a dataset's coverage, and where spilled rows went

Getting started

Connect to the hosted instance, no install:

sh
claude mcp add --transport http open-meteo-mcp-server https://open-meteo.caseyjhand.com/mcp

Or run it locally:

sh
claude mcp add open-meteo-mcp-server -- npx -y @cyanheads/open-meteo-mcp-server

For other clients, add this to the MCP config file:

json
{  "mcpServers": {    "open-meteo-mcp-server": {      "command": "npx",      "args": ["-y", "@cyanheads/open-meteo-mcp-server"]    }  }}

No API key is required for non-commercial use; commercial use requires Open-Meteo's paid API tier. For Docker or a source build, see Running the server.

Configuration

Every variable is optional.

VariableDescriptionDefault
OPEN_METEO_API_BASE_URLForecast and elevation API base URL.https://api.open-meteo.com
OPEN_METEO_ARCHIVE_BASE_URLHistorical archive API base URL.https://archive-api.open-meteo.com
OPEN_METEO_MARINE_BASE_URLMarine API base URL.https://marine-api.open-meteo.com
OPEN_METEO_AIR_QUALITY_BASE_URLCAMS air quality API base URL.https://air-quality-api.open-meteo.com
OPEN_METEO_GEOCODING_BASE_URLGeocoding API base URL.https://geocoding-api.open-meteo.com
OPEN_METEO_ENSEMBLE_BASE_URLEnsemble API base URL.https://ensemble-api.open-meteo.com
OPEN_METEO_FLOOD_BASE_URLGloFAS flood API base URL.https://flood-api.open-meteo.com
OPEN_METEO_CLIMATE_BASE_URLCMIP6 climate API base URL.https://climate-api.open-meteo.com
CANVAS_PROVIDER_TYPEduckdb stages over-budget weather results on a DataCanvas and enables the dataframe tools; none returns a bounded preview.duckdb
OPENMETEO_DATAFRAME_DROP_ENABLEDtrue makes openmeteo_dataframe_drop callable; otherwise it is listed as disabled.false
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto.stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, notice, warning, error).info
LOGS_DIRDirectory for log files (Node.js only).<project-root>/logs
STORAGE_PROVIDER_TYPEStorage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1.in-memory
OTEL_ENABLEDEnable OpenTelemetry.false

See .env.example for the full list of optional overrides.

Running the server

Local development

Requires Bun v1.4.0 or higher (or Node.js v24+).

  • Clone and install:

    sh
    git clone https://github.com/cyanheads/open-meteo-mcp-server.gitcd open-meteo-mcp-server && bun install
  • Build and run:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:stdio# orbun run start:http
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, securitybun run test       # Vitest test suitebun run lint:mcp   # Validate MCP definitions against spec

Docker

sh
docker run --rm -p 3010:3010 ghcr.io/cyanheads/open-meteo-mcp-server:latest

The image defaults to HTTP transport, stateless session mode, and logs to /var/log/open-meteo-mcp-server. To run it over stdio from an MCP client, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/open-meteo-mcp-server:latest"]. To build locally, docker build -t open-meteo-mcp-server .; OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point — registers tools, initializes the Open-Meteo service and DataCanvas.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/tools/definitionsTool definitions (*.tool.ts), one file per tool.
src/mcp-server/toolsShared tool helpers — model catalog, cadence validation, columnar reshape, spillover, response notices.
src/services/open-meteoHTTP client for the Open-Meteo APIs — retry, error classification, coverage-gap rejection.
src/services/canvas-accessor.tsDataCanvas accessor shared by the spill-capable tools.
skills/Agent skill published over MCP and in the npm package, Docker image, and .mcpb bundle (open-meteo-guide).
tests/Unit, integration, fuzz, and smoke tests.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Register new tools in the tools[] array in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Attribution

Weather data by Open-Meteo.com, licensed CC BY 4.0.

Contributing

Issues are welcome. Run checks and tests before submitting:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

Source: README.md at commit 77719ce

Tools

11

openmeteo_search_locations

Openmeteo Search Locations

Resolve a place name to ranked coordinate matches with country, region, elevation, timezone, and population. Required prerequisite for name-based queries — all weather tools take latitude/longitude, not place names. Search by a bare place name (city, region, or landmark); never fold a qualifier into it — pass "Baoding", not "Baoding Hebei", and "Paris", not "Paris, France". To disambiguate places that share a name, set the country input (ISO 3166-1 alpha-2, e.g. "US") and/or read the admin1 and country fields on each ranked result — admin1 is a result field for choosing among matches, not a search input. Returns up to 10 matches ranked by population/relevance.

Parametersnamerequiredcountcountrylanguage

openmeteo_get_elevation

Openmeteo Get Elevation

Terrain elevation from the Copernicus Digital Elevation Model (~90m resolution) for one or more coordinate pairs. Accepts up to 1,000 pairs and samples the first 100 in one upstream request; when more were submitted, unprocessed_count says how many remain and next_offset is where to resume — resubmit latitudes.slice(next_offset) and longitudes.slice(next_offset) of the arrays just sent, until next_offset is null. Open-Meteo counts each sampled pair as one call against its per-IP limit of 600 a minute, so a seventh full slice inside one minute comes back rate_limited — space later slices about a minute apart. Useful for geographic context, elevation-adjusted weather interpretation, or route planning. A point the DEM has no value for (latitude 90) returns elevation_m null; the other points in the call are unaffected.

Parameterslatitudesrequiredlongitudesrequired

openmeteo_get_forecast

Openmeteo Get Forecast

Weather forecast for coordinates: hourly and/or daily variables for up to 16 days ahead, with optional past_days (up to 92) for recent history. Use past_days instead of openmeteo_get_historical for dates within the last week, since the archive’s ERA5 components lag by about a week. Returns per-timestamp records — each hourly entry contains a "time" field (ISO 8601) plus one key per requested variable; each daily entry contains a "time" field (YYYY-MM-DD) plus requested variables. Common hourly variables: temperature_2m, precipitation, wind_speed_10m, relative_humidity_2m, cloud_cover, uv_index, apparent_temperature, precipitation_probability, weather_code, surface_pressure, visibility, wind_direction_10m, wind_gusts_10m, dew_point_2m. Common daily variables: temperature_2m_max, temperature_2m_min, precipitation_sum, wind_speed_10m_max, sunrise, sunset, uv_index_max, precipitation_hours, weather_code. Set current_variables for conditions at this instant — Open-Meteo serves those from 15-minute model data, which is more precise than picking the nearest hourly row, and the response carries a current object plus a current_units map. Set models to compare deterministic models side by side (e.g., ["ncep_gfs_seamless", "ecmwf_ifs025", "dwd_icon_seamless"]) — where they disagree, the forecast is uncertain. With 2+ models every hourly and daily key carries the model name as a suffix (temperature_2m_ecmwf_ifs025); with models omitted the data is Open-Meteo’s best_match blend. A wide window — a large past_days plus many hourly variables — produces thousands of records; these spill to a DataCanvas when canvas is enabled, returning canvas_id and table_name with truncated: true — inspect the staged columns with openmeteo_dataframe_describe, then query the full set with openmeteo_dataframe_query. With canvas disabled they return a bounded preview instead. At least one of current_variables, hourly_variables, or daily_variables is required.

Parametersmodelslatituderequiredtimezonecanvas_idlongituderequiredpast_daysforecast_daysdaily_variableswind_speed_unithourly_variablestemperature_unitcurrent_variables+1 more

openmeteo_get_historical

Openmeteo Get Historical

Historical weather from the Open-Meteo reanalysis archive (1940–present). Requires start_date and end_date (ISO 8601 date, e.g., "2024-07-01"). With models omitted the archive answers from Best Match, which blends IFS HRES, ERA5, and ERA5-Land seamlessly — so the source varies by date and no single update lag describes the response. Set models to pin a consistent source for a multi-decade series: the ERA5 family updates daily with about a week of delay, while IFS HRES has none, so for the last week either request models: ["ecmwf_ifs"] or use openmeteo_get_forecast with past_days. Available models: best_match (default, blends IFS HRES + ERA5 + ERA5-Land), ecmwf_ifs (global 9 km, updated every 6 hours, no delay), ecmwf_ifs_analysis_long_window (global 9 km, daily, 2 days delay), era5_seamless (ERA5 and ERA5-Land combined), era5 (global 0.25° (~25 km), daily, about a week delay), era5_land (global 0.1° (~11 km), daily, about a week delay), era5_ensemble (global 0.5° (~55 km), daily, about a week delay), cerra (Europe only, 5 km, no real-time updates). Uses the same variable names as the forecast API for direct comparison. Large date ranges (multi-year hourly) produce thousands of records — these spill to a DataCanvas when canvas is enabled, returning canvas_id and table_name with truncated: true; inspect the staged columns with openmeteo_dataframe_describe, then query the full set with openmeteo_dataframe_query. With canvas disabled they return a bounded preview instead. At least one of hourly_variables or daily_variables is required.

Parametersmodelsend_daterequiredlatituderequiredtimezonecanvas_idlongituderequiredstart_daterequireddaily_variableswind_speed_unithourly_variablestemperature_unitprecipitation_unit

openmeteo_get_marine

Openmeteo Get Marine

Marine wave and ocean conditions for a coastal or ocean coordinate: wave height, wave period, wave direction, wind-wave height, swell height, sea-surface temperature. Forecast horizon up to 8 days, with optional past_days (up to 92) for recent history — or start_date and end_date together for an archive range, which returns real wave values back to at least 2022. One window per call: a date range is mutually exclusive with forecast_days and past_days, and needs both ends — a lone start_date or end_date is rejected. Returns per-timestamp records — each entry contains a "time" field plus one key per requested variable. Best for open-ocean and coastal exposed points — sheltered water such as a sound or bay returns near-zero wave values, and a land point well inland returns null values, which the notice reports. A land point near the coast is answered from a nearby sea cell with real values and no notice, so check the response latitude and longitude is the water you meant. Common hourly variables: wave_height, wave_direction, wave_period, wind_wave_height, wind_wave_direction, wind_wave_period, swell_wave_height, swell_wave_direction, swell_wave_period. Common daily: wave_height_max, wave_direction_dominant, wave_period_max. Note: ocean_current_velocity is null for non-open-ocean coordinates. Set current_variables for conditions at this instant — Open-Meteo serves those from 15-minute model data, and the response carries a current object plus a current_units map, alongside either window. length_unit "imperial" returns heights in ft, wind_speed_unit sets the ocean_current_velocity unit, and temperature_unit the sea_surface_temperature unit — converted upstream, with every unit read from the *_units maps. A wide window — a large past_days or date range plus many variables — produces thousands of records; these spill to a DataCanvas when canvas is enabled, returning canvas_id and table_name with truncated: true — inspect the staged columns with openmeteo_dataframe_describe

Parametersend_datelatituderequiredtimezonecanvas_idlongituderequiredpast_daysstart_datelength_unitforecast_daysdaily_variableswind_speed_unithourly_variables+2 more

openmeteo_get_air_quality

Openmeteo Get Air Quality

Modeled CAMS (Copernicus Atmosphere Monitoring Service) air quality: PM2.5, PM10, nitrogen dioxide, sulphur dioxide, ozone, carbon monoxide, dust, pollen, and European/US AQI indices. This is modeled grid data, not measured station readings — for measured data, use openaq-mcp-server. Forecast horizon up to 7 days, with optional past_days (up to 92) for recent history — or start_date and end_date together for an archive range; the CAMS global archive begins in August 2022, and earlier dates return rows of nulls. One window per call: a date range is mutually exclusive with forecast_days and past_days, and needs both ends — a lone start_date or end_date is rejected. Common variables: pm2_5, pm10, carbon_monoxide, nitrogen_dioxide, sulphur_dioxide, ozone, dust, european_aqi, us_aqi, alder_pollen, birch_pollen, grass_pollen, mugwort_pollen, olive_pollen, ragweed_pollen. Pollen is modeled for Europe only, and only in pollen season — elsewhere the pollen values come back null, and the notice names them. Set current_variables for pollutant and AQI values at this instant — returned as a current object plus a current_units map, and enough on its own without hourly_variables; the block’s interval field is its aggregation interval in seconds (3600 on this endpoint). A wide window — a large past_days or date range plus many variables — produces thousands of records; these spill to a DataCanvas when canvas is enabled, returning canvas_id and table_name with truncated: true — inspect the staged columns with openmeteo_dataframe_describe, then query the full set with openmeteo_dataframe_query. With canvas disabled they return a bounded preview instead.

Parametersend_datelatituderequiredtimezonecanvas_idlongituderequiredpast_daysstart_dateforecast_dayshourly_variablescurrent_variables

openmeteo_get_ensemble

Openmeteo Get Ensemble

Probabilistic ensemble weather forecast — up to 64 ensemble members, up to 35 days ahead with optional past_days (0–92). Most models end within 16 days; a model's columns are null past its horizon, and the response notice names where its data ends. Each member's values appear as separate columns named with a member suffix (e.g. temperature_2m_member01, temperature_2m_member02). Use the spread across members to compute exceedance probabilities, quantify forecast uncertainty, and build decision thresholds. Available models: ecmwf_ifs025_ensemble (51 members, global 0.25°), ecmwf_aifs025_ensemble (51, global 0.25°), ecmwf_ifs_europe_ensemble (51, Europe 9 km), ecmwf_aifs_europe_ensemble (51, Europe 31 km), google_weathernext2_ensemble (64, global 0.25°), ncep_gefs_seamless (31, global blend), ncep_gefs025 (31, global 0.25°), ncep_gefs05 (31, global 50 km, 35 days), ncep_aigefs025 (31, global 0.25°), icon_seamless_eps (20–40, global/Europe blend), icon_global_eps (40, global 26 km), icon_eu_eps (40, Europe 13 km), icon_d2_eps (20, Central Europe 2 km), gem_global_ensemble (21, global 0.25°), bom_access_global_ensemble (18, global 40 km), ukmo_global_ensemble_20km (18, global 20 km), ukmo_uk_ensemble_2km (3, UK 2 km), meteoswiss_icon_ch1_ensemble (11, Central Europe 1 km), meteoswiss_icon_ch2_ensemble (21, Central Europe 2 km). Omit models to use ecmwf_ifs025_ensemble. A regional model returns no data outside the area it covers; that comes back as an input error naming the coverage gap, not a transient failure, so pick a global model or move the coordinate inside the region rather than retrying. A model name this list does not carry is still sent upstream, so a newly added one keeps working. Large multi-member, multi-day pulls produce thousands of records and spill to a DataCanvas when canvas is enabled, returning canvas_id and table_name with truncated: true — inspect the staged columns with openmeteo_dataframe_describe, then query the full set with openmeteo_dataframe_

Parametersmodelslatituderequiredtimezonecanvas_idlongituderequiredpast_daysforecast_daysdaily_variableswind_speed_unithourly_variablestemperature_unitprecipitation_unit

openmeteo_get_flood

Openmeteo Get Flood

GloFAS (Global Flood Awareness System) daily river discharge (m³/s) from the GloFAS 0.05° grid cell nearest the given coordinates — no river ID needed. The response's latitude and longitude name that cell. It is not reliably on the river intended: a point near a confluence, a pair of parallel channels, or a bank can resolve to a cell with little flow. When the value is far below what the named river carries, step the coordinate 0.05° across the channel and compare the values. One mode per call: forecast_days for the outlook, or start_date and end_date together for a date range from 1984-01-01. The two modes are mutually exclusive, and a date range needs both ends — a lone start_date or end_date is rejected. forecast_days accepts up to 210, but the current GloFAS run sets how far the data reaches (about six months ahead); later days come back null and the notice names where the data ends. What a date range holds depends on the model. Omitting models reads seamless_v4: consolidated_v4 reanalysis before 2023-08-05, then forecast-run discharge from 2023-08-05 on, so a range crossing that date changes source mid-series. Set models to pin a source: seamless_v4 (default — consolidated_v4 reanalysis before 2023-08-05, forecast_v4 runs from 2023-08-05 into the live forecast), consolidated_v4 (reanalysis from 1984 through 2025-05-31; null after it and on every forecast_days call), forecast_v4 (forecast runs from 2023-06-01 into the live forecast; null before). consolidated_v4 is the only way to read reanalysis for 2023-08-05 through 2025-05-31. With 2+ models every daily column is suffixed with the model name (river_discharge_consolidated_v4). Available daily variables: "river_discharge" (the daily discharge value; the mean across ensemble members is "river_discharge_mean"), and the ensemble statistics "river_discharge_mean", "river_discharge_median", "river_discharge_min", "river_discharge_max", "river_discharge_p25" (25th percentile), and "river_discharge_p75" (75th percent

Parametersmodelsend_datelatituderequiredtimezonecanvas_idlongituderequiredstart_dateforecast_daysdaily_variables

openmeteo_get_climate

Openmeteo Get Climate

Long-range climate projections from bias-corrected daily CMIP6 models, covering 1950-01-01 to 2050-12-31 at any coordinate. Answers "what will conditions look like through 2050?" — the future-projection counterpart to openmeteo_get_historical (the observed archive, what happened). Daily resolution only. Available models: CMCC_CM2_VHR4, FGOALS_f3_H, HiRAM_SIT_HR, MRI_AGCM3_2_S, EC_Earth3P_HR, MPI_ESM1_2_XR, NICAM16_8S. A model name outside that list is sent upstream rather than rejected here, so a model Open-Meteo adds later still works; if upstream rejects the request, the error names the offending model on its own rather than the whole requested list. With 2+ models each variable appears once per model with the model name as suffix (e.g. temperature_2m_max_CMCC_CM2_VHR4); a single or omitted model returns plain variable names. Not all models carry all variables — missing combinations return null. Multi-decade daily pulls across several models produce thousands of records and spill to a DataCanvas when canvas is enabled, returning canvas_id and table_name with truncated: true — inspect the staged columns with openmeteo_dataframe_describe, then query the full set with openmeteo_dataframe_query. With canvas disabled they return a bounded preview instead.

Parametersmodelsend_daterequiredlatituderequiredtimezonecanvas_idlongituderequiredstart_daterequireddaily_variableswind_speed_unittemperature_unitprecipitation_unit

openmeteo_dataframe_query

Openmeteo Dataframe Query

Run a read-only SQL SELECT against tables staged on a DataCanvas by openmeteo_get_forecast, openmeteo_get_historical, openmeteo_get_marine, openmeteo_get_air_quality, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate. Pass the canvas_id returned when any of those tools spills (truncated: true), and reference the exact table_name those tools return alongside it. Call openmeteo_dataframe_describe to list staged tables and their columns when you need to discover names. Returns up to 100 leading rows — fewer when wide rows would pass the 80,000-character inline ceiling — plus row_count — exact, or a lower bound flagged by count_error when counting fails or runs past 5 seconds; page the rest with LIMIT / OFFSET.

Parameterssqlrequiredcanvas_idrequired

openmeteo_dataframe_describe

Openmeteo Dataframe Describe

List the tables and their columns on a DataCanvas staged by openmeteo_get_forecast, openmeteo_get_historical, openmeteo_get_marine, openmeteo_get_air_quality, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate. Call this first to discover table names before querying with openmeteo_dataframe_query.

Parameterscanvas_idrequired

Version history

6
  1. v0.5.0LatestOct 29, 2026
  2. v0.4.2Oct 24, 2026
  3. v0.4.1Oct 13, 2026
  4. v0.4.0Oct 4, 2026
  5. v0.3.11Sep 22, 2026
  6. v0.3.10Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts