Skip to main content
Glama

Openmeteo Get Historical

openmeteo_get_historical
Read-onlyIdempotent

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 5-day delay, while IFS HRES has none, so for the last few days 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, 5 days delay), era5_land (global 0.1° (~11 km), daily, 5 days delay), era5_ensemble (global 0.5° (~55 km), daily, 5 days 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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modelsNoArchive models to read from: 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, 5 days delay), era5_land (global 0.1° (~11 km), daily, 5 days delay), era5_ensemble (global 0.5° (~55 km), daily, 5 days delay), cerra (Europe only, 5 km, no real-time updates). Omit to use Open-Meteo's Best Match default, which blends IFS HRES, ERA5, and ERA5-Land — pin a model instead when a consistent source matters across the range. With 2+ models each variable column is suffixed with the model name. cerra covers Europe only and is rejected as a coverage gap elsewhere. A name outside this list is sent upstream rather than rejected here.
end_dateYesEnd date (YYYY-MM-DD, inclusive). Must be on or after start_date. For the last few days, either request models: ["ecmwf_ifs"] or use openmeteo_get_forecast with past_days.
latitudeYesLatitude in decimal degrees. Use openmeteo_search_locations to resolve a place name to coordinates.
timezoneNoIANA timezone or "auto". Default "auto".auto
canvas_idNoDataCanvas token for multi-year or multi-variable queries. When a result is too large to return inline — driven by total payload size, so a wide multi-variable pull can spill at any row count — it spills to this canvas: pass the returned token to openmeteo_dataframe_describe to list the staged table and its columns, then to openmeteo_dataframe_query to run SQL against it. Omit to create a fresh canvas.
longitudeYesLongitude in decimal degrees.
start_dateYesStart date (YYYY-MM-DD, e.g., "2024-07-01"). The archive covers from 1940-01-01; how close to today it reaches depends on the model — the ERA5 family runs about 5 days behind, IFS HRES is current.
daily_variablesNoDaily summary variables (e.g., ["temperature_2m_max", "temperature_2m_min", "precipitation_sum", "wind_speed_10m_max"]). Daily names only — an hourly name such as cloud_cover or temperature_2m belongs in hourly_variables and is rejected here; for a daily summary of an hourly variable use its published aggregate (cloud_cover_max, cloud_cover_mean, cloud_cover_min). At least one of hourly_variables or daily_variables required.
wind_speed_unitNoWind speed unit. Default "kmh".kmh
hourly_variablesNoHourly archive variables (e.g., ["temperature_2m", "precipitation", "wind_speed_10m", "relative_humidity_2m", "cloud_cover", "soil_moisture_0_to_7cm"]). Hourly names only — a daily aggregate such as temperature_2m_max or precipitation_sum belongs in daily_variables and is rejected here. At least one of hourly_variables or daily_variables required.
temperature_unitNoTemperature unit. Default "celsius".celsius
precipitation_unitNoPrecipitation unit. Default "mm".mm

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dailyNoPer-day records with "time" (YYYY-MM-DD) + variable keys. Absent when only hourly_variables were requested. When truncated, contains only a preview — query canvas_id for the full dataset when one is present.
errorNoPresent when the call failed. Absent on success.
hourlyNoPer-hour records with "time" (ISO 8601) + variable keys. Absent when only daily_variables were requested. When truncated, contains only a preview — query canvas_id for the full dataset when one is present.
modelsNoArchive models requested — echoes the models parameter. Absent when models was omitted, which means the data came from Open-Meteo Best Match (IFS HRES + ERA5 + ERA5-Land) and the source varies by date.
noticeNoEverything this response needs to say beyond the data, composed into one advisory: columns the archive returned with the unit "undefined" (a name it parsed but does not serve in the requested cadence); recognized variables whose requested window falls outside the data's coverage, with the timestamps that do carry values; and, when the result spilled, either the canvas and table holding the full row set plus the two dataframe tools that read it, or — with DataCanvas disabled — why there is no canvas_id and how to reach the rows the preview omits.
latitudeNoSnapped latitude
timezoneNoResolved IANA timezone
canvas_idNoDataCanvas token for the staged full dataset. Present only when truncated is true AND DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) — absent otherwise, in which case the preview is all this response carries. Pass to openmeteo_dataframe_describe to list the staged table and its columns, then to openmeteo_dataframe_query to run SQL against it.
elevationNoElevation at grid point (meters)
longitudeNoSnapped longitude
truncatedNoTrue when the response was too large to return inline, so hourly and daily carry a bounded preview rather than the full set. With DataCanvas enabled the complete data is staged at canvas_id — every hourly and daily row, including any column the preview omits. With it disabled there is no canvas_id, and the omitted rows are reached only by narrowing the request.
date_rangeNoDate range of returned data
table_nameNoDuckDB table name for the staged data — use as the FROM target in openmeteo_dataframe_query SQL; openmeteo_dataframe_describe lists its columns. Present only alongside canvas_id.
daily_unitsNoVariable → unit string for daily data. Absent when no daily_variables were requested.
hourly_unitsNoVariable → unit string for hourly data (e.g., {"temperature_2m": "°C", "precipitation": "mm"}). Absent when no hourly_variables were requested.
record_countNoTotal number of records (hourly + daily rows) — the full upstream total when truncated is true, not the combined length of the hourly and daily previews.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • addedInput schema / properties / end_date / format
      Added value: +"date"
    • changedInput schema / properties / end_date / pattern
      Previous value: -"^\\d{4}-\\d{2}-\\d{2}$"New value: +"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
    • addedInput schema / properties / start_date / format
      Added value: +"date"
    • changedInput schema / properties / start_date / pattern
      Previous value: -"^\\d{4}-\\d{2}-\\d{2}$"New value: +"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model. `date_order_invalid`: The end_date value is earlier than the start_date value. `no_variables_requested`: Neither hourly_variables nor daily_variables was provided. `invalid_variable`: An unknown variable name or unsupported archive model was requested. `variable_wrong_cadence`: A variable sat in the cadence field Open-Meteo does not document it under — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables — caught before the request is sent. `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone. `request_too_large`: Open-Meteo refused the request as asking for too much data in one call. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model. `date_order_invalid`: The end_date value is earlier than the start_date value. `no_variables_requested`: Neither hourly_variables nor daily_variables named a variable — blank or whitespace-only entries do not count. `invalid_variable`: An unknown variable name or unsupported archive model was requested. `variable_wrong_cadence`: A variable sat in the cadence field Open-Meteo does not document it under — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables — caught before the request is sent. `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone. `request_too_large`: Open-Meteo refused the request as asking for too much data in one call. `rate_limited`: Open-Meteo answered HTTP 429 because a free-tier request limit was reached. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "date_out_of_range",
      -  "date_order_invalid",
      -  "no_variables_requested",
      -  "invalid_variable",
      -  "variable_wrong_cadence",
      -  "invalid_timezone",
      -  "request_too_large"
      -]New value: +[
      +  "date_out_of_range",
      +  "date_order_invalid",
      +  "no_variables_requested",
      +  "invalid_variable",
      +  "variable_wrong_cadence",
      +  "invalid_timezone",
      +  "request_too_large",
      +  "rate_limited"
      +]
  2. Changed1 schema field changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model. `date_order_invalid`: end_date is before start_date. `no_variables_requested`: Neither hourly_variables nor daily_variables was provided. `invalid_variable`: An unknown variable name or unsupported archive model was requested. `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables. `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone. `request_too_large`: Open-Meteo refused the request as asking for too much data in one call. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model. `date_order_invalid`: The end_date value is earlier than the start_date value. `no_variables_requested`: Neither hourly_variables nor daily_variables was provided. `invalid_variable`: An unknown variable name or unsupported archive model was requested. `variable_wrong_cadence`: A variable sat in the cadence field Open-Meteo does not document it under — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables — caught before the request is sent. `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone. `request_too_large`: Open-Meteo refused the request as asking for too much data in one call. Other values are possible when a failure originates below the handler."
  3. Changed2 schema fields changed
    • addedInput schema / properties / canvas_id / pattern
      Added value: +"^[A-Za-z0-9_-]{10}$"
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name or unsupported archive model was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone `request_too_large`: Open-Meteo refused the request as asking for too much data in one call Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model. `date_order_invalid`: end_date is before start_date. `no_variables_requested`: Neither hourly_variables nor daily_variables was provided. `invalid_variable`: An unknown variable name or unsupported archive model was requested. `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables. `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone. `request_too_large`: Open-Meteo refused the request as asking for too much data in one call. Other values are possible when a failure originates below the handler."
  4. Changed6 schema fields changed
    • changedInput schema / properties / end_date / description
      Previous value: -"End date (YYYY-MM-DD, inclusive). Must be on or after start_date. For dates within the last ~5 days, use openmeteo_get_forecast with past_days instead."New value: +"End date (YYYY-MM-DD, inclusive). Must be on or after start_date. For the last few days, either request models: [\"ecmwf_ifs\"] or use openmeteo_get_forecast with past_days."
    • changedInput schema / properties / hourly_variables / description
      Previous value: -"Hourly ERA5 variables (e.g., [\"temperature_2m\", \"precipitation\", \"wind_speed_10m\", \"relative_humidity_2m\", \"cloud_cover\", \"soil_moisture_0_to_7cm\"]). Hourly names only — a daily aggregate such as temperature_2m_max or precipitation_sum belongs in daily_variables and is rejected here. At least one of hourly_variables or daily_variables required."New value: +"Hourly archive variables (e.g., [\"temperature_2m\", \"precipitation\", \"wind_speed_10m\", \"relative_humidity_2m\", \"cloud_cover\", \"soil_moisture_0_to_7cm\"]). Hourly names only — a daily aggregate such as temperature_2m_max or precipitation_sum belongs in daily_variables and is rejected here. At least one of hourly_variables or daily_variables required."
    • addedInput schema / properties / models
      Added value: +{
      +  "description": "Archive models to read from: 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, 5 days delay), era5_land (global 0.1° (~11 km), daily, 5 days delay), era5_ensemble (global 0.5° (~55 km), daily, 5 days delay), cerra (Europe only, 5 km, no real-time updates). Omit to use Open-Meteo's Best Match default, which blends IFS HRES, ERA5, and ERA5-Land — pin a model instead when a consistent source matters across the range. With 2+ models each variable column is suffixed with the model name. cerra covers Europe only and is rejected as a coverage gap elsewhere. A name outside this list is sent upstream rather than rejected here.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 8,
      +  "type": "array"
      +}
    • changedInput schema / properties / start_date / description
      Previous value: -"Start date (YYYY-MM-DD, e.g., \"2024-07-01\"). ERA5 covers from 1940-01-01 to approximately 5 days ago."New value: +"Start date (YYYY-MM-DD, e.g., \"2024-07-01\"). The archive covers from 1940-01-01; how close to today it reaches depends on the model — the ERA5 family runs about 5 days behind, IFS HRES is current."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01 or end_date is within the ERA5 lag window `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone `request_too_large`: Open-Meteo refused the request as asking for too much data in one call Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01, or the requested dates fall outside the coverage of the selected model `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name or unsupported archive model was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone `request_too_large`: Open-Meteo refused the request as asking for too much data in one call Other values are possible when a failure originates below the handler."
    • addedOutput schema / properties / models
      Added value: +{
      +  "description": "Archive models requested — echoes the models parameter. Absent when models was omitted, which means the data came from Open-Meteo Best Match (IFS HRES + ERA5 + ERA5-Land) and the source varies by date.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  5. Changed3 schema fields changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01 or end_date is within the ERA5 lag window `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01 or end_date is within the ERA5 lag window `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone `request_too_large`: Open-Meteo refused the request as asking for too much data in one call Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "date_out_of_range",
      -  "date_order_invalid",
      -  "no_variables_requested",
      -  "invalid_variable",
      -  "variable_wrong_cadence",
      -  "invalid_timezone"
      -]New value: +[
      +  "date_out_of_range",
      +  "date_order_invalid",
      +  "no_variables_requested",
      +  "invalid_variable",
      +  "variable_wrong_cadence",
      +  "invalid_timezone",
      +  "request_too_large"
      +]
    • changedOutput schema / properties / notice / description
      Previous value: -"Everything this response needs to say beyond the data, composed into one advisory: columns the archive returned with the unit \"undefined\" (a name it parsed but does not serve in the requested cadence); recognized variables whose requested window falls outside the data's coverage, with the timestamps that do carry values; and, when the result spilled, the canvas and table holding the full row set plus the two dataframe tools that read it."New value: +"Everything this response needs to say beyond the data, composed into one advisory: columns the archive returned with the unit \"undefined\" (a name it parsed but does not serve in the requested cadence); recognized variables whose requested window falls outside the data's coverage, with the timestamps that do carry values; and, when the result spilled, either the canvas and table holding the full row set plus the two dataframe tools that read it, or — with DataCanvas disabled — why there is no canvas_id and how to reach the rows the preview omits."
  6. Changed4 schema fields changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"DataCanvas token for multi-year or multi-variable queries. When a result is too large to return inline — driven by total payload size, so a wide multi-variable pull can spill at any row count — it spills to this canvas for SQL querying. Omit to create a fresh canvas."New value: +"DataCanvas token for multi-year or multi-variable queries. When a result is too large to return inline — driven by total payload size, so a wide multi-variable pull can spill at any row count — it spills to this canvas: pass the returned token to openmeteo_dataframe_describe to list the staged table and its columns, then to openmeteo_dataframe_query to run SQL against it. Omit to create a fresh canvas."
    • changedOutput schema / properties / canvas_id / description
      Previous value: -"DataCanvas token for the staged full dataset. Present only when truncated is true AND DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) — absent otherwise, in which case the preview is all this response carries. Query with SQL using this token."New value: +"DataCanvas token for the staged full dataset. Present only when truncated is true AND DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) — absent otherwise, in which case the preview is all this response carries. Pass to openmeteo_dataframe_describe to list the staged table and its columns, then to openmeteo_dataframe_query to run SQL against it."
    • changedOutput schema / properties / notice / description
      Previous value: -"Warning that a requested variable came back with no data — names each column whose unit is \"undefined\", which is how the archive reports a name it parsed but does not serve in the requested cadence."New value: +"Everything this response needs to say beyond the data, composed into one advisory: columns the archive returned with the unit \"undefined\" (a name it parsed but does not serve in the requested cadence); recognized variables whose requested window falls outside the data's coverage, with the timestamps that do carry values; and, when the result spilled, the canvas and table holding the full row set plus the two dataframe tools that read it."
    • changedOutput schema / properties / table_name / description
      Previous value: -"DuckDB table name for the staged data — pass to openmeteo_dataframe_query. Present only alongside canvas_id."New value: +"DuckDB table name for the staged data — use as the FROM target in openmeteo_dataframe_query SQL; openmeteo_dataframe_describe lists its columns. Present only alongside canvas_id."
  7. Changed2 schema fields changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01 or end_date is within the ERA5 lag window `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01 or end_date is within the ERA5 lag window `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables `invalid_timezone`: timezone was blank, or upstream did not recognize the requested time zone Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "date_out_of_range",
      -  "date_order_invalid",
      -  "no_variables_requested",
      -  "invalid_variable",
      -  "variable_wrong_cadence"
      -]New value: +[
      +  "date_out_of_range",
      +  "date_order_invalid",
      +  "no_variables_requested",
      +  "invalid_variable",
      +  "variable_wrong_cadence",
      +  "invalid_timezone"
      +]
  8. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "latitude",
      +      "longitude",
      +      "elevation",
      +      "timezone",
      +      "date_range",
      +      "record_count",
      +      "truncated"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "additionalProperties": {},
      +  "description": "Present when the call failed. Absent on success.",
      +  "properties": {
      +    "code": {
      +      "description": "JSON-RPC error code for this failure.",
      +      "maximum": 9007199254740991,
      +      "minimum": -9007199254740991,
      +      "type": "integer"
      +    },
      +    "data": {
      +      "additionalProperties": {},
      +      "properties": {
      +        "reason": {
      +          "description": "Machine-readable failure mode. Declared by this tool: `date_out_of_range`: start_date predates 1940-01-01 or end_date is within the ERA5 lag window `date_order_invalid`: end_date is before start_date `no_variables_requested`: Neither hourly_variables nor daily_variables was provided `invalid_variable`: An unknown variable name was requested `variable_wrong_cadence`: A variable Open-Meteo documents under one cadence was passed in the other cadence field — for example cloud_cover in daily_variables, or temperature_2m_max in hourly_variables Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "date_out_of_range",
      +            "date_order_invalid",
      +            "no_variables_requested",
      +            "invalid_variable",
      +            "variable_wrong_cadence"
      +          ],
      +          "type": "string"
      +        },
      +        "recovery": {
      +          "additionalProperties": {},
      +          "description": "Actionable next step for the caller.",
      +          "properties": {
      +            "hint": {
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "hint"
      +          ],
      +          "type": "object"
      +        },
      +        "retryable": {
      +          "description": "Whether retrying may succeed.",
      +          "type": "boolean"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "message": {
      +      "description": "Human-readable description of what went wrong.",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "code",
      +    "message"
      +  ],
      +  "type": "object"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "latitude",
      -  "longitude",
      -  "elevation",
      -  "timezone",
      -  "date_range",
      -  "record_count",
      -  "truncated"
      -]
  9. Changed3 schema fields changed
    • changedInput schema / properties / daily_variables / description
      Previous value: -"Daily summary variables (e.g., [\"temperature_2m_max\", \"temperature_2m_min\", \"precipitation_sum\", \"wind_speed_10m_max\"]). At least one of hourly_variables or daily_variables required."New value: +"Daily summary variables (e.g., [\"temperature_2m_max\", \"temperature_2m_min\", \"precipitation_sum\", \"wind_speed_10m_max\"]). Daily names only — an hourly name such as cloud_cover or temperature_2m belongs in hourly_variables and is rejected here; for a daily summary of an hourly variable use its published aggregate (cloud_cover_max, cloud_cover_mean, cloud_cover_min). At least one of hourly_variables or daily_variables required."
    • changedInput schema / properties / hourly_variables / description
      Previous value: -"Hourly ERA5 variables (e.g., [\"temperature_2m\", \"precipitation\", \"wind_speed_10m\", \"relative_humidity_2m\", \"cloud_cover\", \"soil_moisture_0_to_7cm\"]). At least one of hourly_variables or daily_variables required."New value: +"Hourly ERA5 variables (e.g., [\"temperature_2m\", \"precipitation\", \"wind_speed_10m\", \"relative_humidity_2m\", \"cloud_cover\", \"soil_moisture_0_to_7cm\"]). Hourly names only — a daily aggregate such as temperature_2m_max or precipitation_sum belongs in daily_variables and is rejected here. At least one of hourly_variables or daily_variables required."
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Warning that a requested variable came back with no data — names each column whose unit is \"undefined\", which is how the archive reports a name it parsed but does not serve in the requested cadence.",
      +  "type": "string"
      +}
  10. Changed7 schema fields changed
    • changedInput schema / properties / latitude / description
      Previous value: -"Latitude in decimal degrees. Use openmeteo_geocode to resolve a place name to coordinates."New value: +"Latitude in decimal degrees. Use openmeteo_search_locations to resolve a place name to coordinates."
    • changedOutput schema / properties / canvas_id / description
      Previous value: -"DataCanvas token — present only when truncated is true (data spilled). Query with SQL using this token."New value: +"DataCanvas token for the staged full dataset. Present only when truncated is true AND DataCanvas is enabled (CANVAS_PROVIDER_TYPE=duckdb) — absent otherwise, in which case the preview is all this response carries. Query with SQL using this token."
    • changedOutput schema / properties / daily / description
      Previous value: -"Per-day records with \"time\" (YYYY-MM-DD) + variable keys. Absent when only hourly_variables were requested. When truncated, contains only a preview; query canvas_id for the full dataset."New value: +"Per-day records with \"time\" (YYYY-MM-DD) + variable keys. Absent when only hourly_variables were requested. When truncated, contains only a preview — query canvas_id for the full dataset when one is present."
    • changedOutput schema / properties / hourly / description
      Previous value: -"Per-hour records with \"time\" (ISO 8601) + variable keys. Absent when only daily_variables were requested. When truncated, contains only a preview; query canvas_id for the full dataset."New value: +"Per-hour records with \"time\" (ISO 8601) + variable keys. Absent when only daily_variables were requested. When truncated, contains only a preview — query canvas_id for the full dataset when one is present."
    • changedOutput schema / properties / record_count / description
      Previous value: -"Total number of records (hourly or daily rows) in this response"New value: +"Total number of records (hourly + daily rows) — the full upstream total when truncated is true, not the combined length of the hourly and daily previews."
    • changedOutput schema / properties / table_name / description
      Previous value: -"DuckDB table name for the staged data — pass to openmeteo_dataframe_query. Present only when truncated is true."New value: +"DuckDB table name for the staged data — pass to openmeteo_dataframe_query. Present only alongside canvas_id."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the response was too large to return inline and data spilled to canvas_id. Query the canvas for the full dataset — it holds every hourly and daily row, including any column the preview omits."New value: +"True when the response was too large to return inline, so hourly and daily carry a bounded preview rather than the full set. With DataCanvas enabled the complete data is staged at canvas_id — every hourly and daily row, including any column the preview omits. With it disabled there is no canvas_id, and the omitted rows are reached only by narrowing the request."
  11. Changed2 schema fields changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"DataCanvas token for multi-year or multi-variable queries. When a query exceeds ~500 records, results spill to this canvas for SQL querying. Omit to create a fresh canvas."New value: +"DataCanvas token for multi-year or multi-variable queries. When a result is too large to return inline — driven by total payload size, so a wide multi-variable pull can spill at any row count — it spills to this canvas for SQL querying. Omit to create a fresh canvas."
    • changedOutput schema / properties / truncated / description
      Previous value: -"True when the response exceeded inline record limit and data spilled to canvas_id. Query the canvas for the full dataset."New value: +"True when the response was too large to return inline and data spilled to canvas_id. Query the canvas for the full dataset — it holds every hourly and daily row, including any column the preview omits."
  12. Changed1 schema field changed
    • addedOutput schema / properties / table_name
      Added value: +{
      +  "description": "DuckDB table name for the staged data — pass to openmeteo_dataframe_query. Present only when truncated is true.",
      +  "type": "string"
      +}
  13. Changed1 schema field changed
    • changedOutput schema / properties / canvas_id / description
      Previous value: -"DataCanvas token — present when record_count exceeded inline limit. Query with SQL using this token."New value: +"DataCanvas token — present only when truncated is true (data spilled). Query with SQL using this token."
  14. First observed

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations only covering readOnly/idempotent, the description supplies the operational traits that matter: per-model update lags (~5 days for ERA5 family, none for IFS HRES), the fact that Best Match silently varies its source by date, large-result spilling to a DataCanvas with truncated: true and a bounded preview when canvas is disabled. This is exactly the context annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded and dense with genuinely useful content, but it is a single unbroken paragraph that reproduces the eight-model list nearly verbatim from the models schema description — a large redundant block. Breaking the model table out or trimming the duplication would tighten it considerably.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter tool with an output schema, the description covers the remaining agent-facing gaps: required variable selection ('at least one of hourly_variables or daily_variables'), date semantics, source-consistency tradeoffs, and the spill/recovery workflow. Nothing needed to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds cross-cutting meaning the schema doesn't: canvas_id behavior (omit to create fresh, pass returned token downstream), the truncated/canvas_id pairing on oversized results, and the 1940-01-01 archive floor. The model enumeration largely restates the schema property description, which caps it at 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+source: 'Historical weather from the Open-Meteo reanalysis archive (1940–present).' It distinguishes itself from siblings by naming openmeteo_get_forecast as the alternative for the most recent days, and the archive scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing rules: omit models for Best Match, pin models when a consistent source matters across a multi-decade series, and for the last few days either request models: ["ecmwf_ifs"] or use openmeteo_get_forecast with past_days. It also names openmeteo_dataframe_describe/query as the follow-ups when results spill.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.