Skip to main content
Glama

Openmeteo Dataframe Query

openmeteo_dataframe_query
Read-only

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 the first limit rows (default 25, or the per-call row cap when that is lower), each whole, 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. A page's size rests on limit and the columns selected, so from a member-suffixed ensemble table select the columns the question needs rather than SELECT *. One response carries at most 8,000,000 characters of row data (its rows written as JSON, a character that needs escaping counted at its escaped length), and a page over that fails as result_too_large rather than being cut. An error message relayed from the query engine is cut to 2,000 characters.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "canvas_id": "<canvas_id>",
      "sql": "<sql>"
    },
    "name": "openmeteo_dataframe_query"
  }
}

Input Schema

NameRequiredDescriptionDefault
sqlYesRead-only SELECT statement. Reference table names from openmeteo_dataframe_describe; in the examples below, replace <table_name> with a staged table and <column> with one of its columns. time is ISO 8601 text — YYYY-MM-DDTHH:MM on hourly rows, YYYY-MM-DD on daily rows — as are daily sunrise and sunset, so date functions need a cast: CAST(time AS TIMESTAMP). WHERE time LIKE '%T%' selects the hourly rows of a table that holds both cadences. Monthly means: `SELECT strftime(CAST(time AS TIMESTAMP), '%Y-%m') AS month, AVG(<column>) AS mean FROM <table_name> GROUP BY month ORDER BY month`. An openmeteo_get_ensemble table carries one column per member (precipitation_member01, precipitation_member02, …) beside the unsuffixed control run; count members per row with `SELECT time, list_count(list_filter([*COLUMNS('^precipitation_member\d+$')], lambda x: x > 0.5)) AS members_over, list_count([*COLUMNS('^precipitation_member\d+$')]) AS members_reporting FROM <table_name> ORDER BY time` — the anchored pattern leaves out the control column, and members_reporting is the per-row denominator, since rows past a model's last forecast hour carry no member values. Write lambdas with the lambda x: syntax.
limitNoRows to return: the page size. Default 25; a larger value returns at most 10,000 rows and says so. Rows come back whole, so a page's size rests on limit and on the columns the SQL selects: from a member-suffixed ensemble table, select only the columns the question needs. A page over 8,000,000 characters of row data fails as result_too_large rather than being cut. A LIMIT in the SQL still applies; the page holds the smaller of the two.
canvas_idYesCanvas ID returned by openmeteo_get_forecast, openmeteo_get_historical, openmeteo_get_marine, openmeteo_get_air_quality, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate when truncated: true.

Output Schema

NameRequiredDescriptionDefault
rowsNoLeading result rows, at most limit, each whole: values are never cut. When row_count exceeds rows.length, continue by re-issuing the SQL with OFFSET <rows.length>, added to any OFFSET it already applies, with any LIMIT reduced by the same amount. Page under an ORDER BY: without one, DuckDB guarantees no row order between calls.
errorNoPresent when the call failed. Absent on success.
noticeNoPresent only when limit was above the per-call row cap: names the requested and the applied limit.
canvas_idNoCanvas ID that was queried.
row_countNoExact number of rows in the full result. When count_error is present, the total could not be counted and this is a lower bound: the rows the query confirmed exist.
truncatedNoTrue when the full result holds more rows than this page, so row_count exceeds rows.length; continue as the rows description says. False when rows is the whole result.
count_errorNoPresent only when counting the full result failed after its rows were read — the failure reason (e.g. sql_execution_error, or count_timeout when counting ran past 5 seconds). The rows are still valid; row_count is then a lower bound.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • addedInput schema / properties / limit
      Added value: +{
      +  "default": 25,
      +  "description": "Rows to return: the page size. Default 25; a larger value returns at most 10,000 rows and says so. Rows come back whole, so a page's size rests on limit and on the columns the SQL selects: from a member-suffixed ensemble table, select only the columns the question needs. A page over 8,000,000 characters of row data fails as result_too_large rather than being cut. A LIMIT in the SQL still applies; the page holds the smaller of the two.",
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • changedOutput schema / anyOf
      Previous value: -[
      -  {
      -    "not": {
      -      "required": [
      -        "error"
      -      ]
      -    },
      -    "required": [
      -      "rows",
      -      "row_count",
      -      "canvas_id"
      -    ]
      -  },
      -  {
      -    "required": [
      -      "error"
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "rows",
      +      "row_count",
      +      "truncated",
      +      "canvas_id"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired under its 24 h sliding TTL. `system_catalog_access`: The SQL references a system catalog such as information_schema, sqlite_master, pg_catalog, or a duckdb_*() function. `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. `row_too_large`: The first result row alone cannot fit the 80,000-character inline ceiling, and values are never cut. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired under its 24 h sliding TTL. `system_catalog_access`: The SQL references a system catalog such as information_schema, pg_catalog, a duckdb_*() function, or one of DuckDB's internal metadata views (duckdb_tables, sqlite_master, pg_class, …), or uses a metadata view's name as its own column alias, CTE name, subquery column, or table alias. `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. `result_too_large`: The page holds more than 8,000,000 characters of row data (its rows written as JSON, a character that needs escaping counted at its escaped length), the most one response carries, and rows are never cut. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "canvas_not_enabled",
      -  "canvas_not_found",
      -  "system_catalog_access",
      -  "missing_table",
      -  "row_too_large"
      -]New value: +[
      +  "canvas_not_enabled",
      +  "canvas_not_found",
      +  "system_catalog_access",
      +  "missing_table",
      +  "result_too_large"
      +]
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Present only when limit was above the per-call row cap: names the requested and the applied limit.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / rows / description
      Previous value: -"Leading result rows: at most 100, and fewer when the next row would take the response past its 80,000-character inline ceiling. Values are never cut. When row_count exceeds rows.length, continue by re-issuing the SQL with OFFSET <rows.length>, added to any OFFSET it already applies, with any LIMIT reduced by the same amount. Page under an ORDER BY: without one, DuckDB guarantees no row order between calls."New value: +"Leading result rows, at most limit, each whole: values are never cut. When row_count exceeds rows.length, continue by re-issuing the SQL with OFFSET <rows.length>, added to any OFFSET it already applies, with any LIMIT reduced by the same amount. Page under an ORDER BY: without one, DuckDB guarantees no row order between calls."
    • addedOutput schema / properties / truncated
      Added value: +{
      +  "description": "True when the full result holds more rows than this page, so row_count exceeds rows.length; continue as the rows description says. False when rows is the whole result.",
      +  "type": "boolean"
      +}
  2. Changed1 schema field changed
    • changedInput schema / properties / sql / description
      Previous value: -"Read-only SELECT statement. Reference table names from openmeteo_dataframe_describe. Example: SELECT AVG(temperature_2m) AS avg_temp, strftime(time, '%Y-%m') AS month FROM spilled_abc123 GROUP BY month ORDER BY month"New value: +"Read-only SELECT statement. Reference table names from openmeteo_dataframe_describe; in the examples below, replace <table_name> with a staged table and <column> with one of its columns. time is ISO 8601 text — YYYY-MM-DDTHH:MM on hourly rows, YYYY-MM-DD on daily rows — as are daily sunrise and sunset, so date functions need a cast: CAST(time AS TIMESTAMP). WHERE time LIKE '%T%' selects the hourly rows of a table that holds both cadences. Monthly means: `SELECT strftime(CAST(time AS TIMESTAMP), '%Y-%m') AS month, AVG(<column>) AS mean FROM <table_name> GROUP BY month ORDER BY month`. An openmeteo_get_ensemble table carries one column per member (precipitation_member01, precipitation_member02, …) beside the unsuffixed control run; count members per row with `SELECT time, list_count(list_filter([*COLUMNS('^precipitation_member\\d+$')], lambda x: x > 0.5)) AS members_over, list_count([*COLUMNS('^precipitation_member\\d+$')]) AS members_reporting FROM <table_name> ORDER BY time` — the anchored pattern leaves out the control column, and members_reporting is the per-row denominator, since rows past a model's last forecast hour carry no member values. Write lambdas with the lambda x: syntax."
  3. Changed5 schema fields changed
    • addedOutput schema / properties / count_error
      Added value: +{
      +  "description": "Present only when counting the full result failed after its rows were read — the failure reason (e.g. sql_execution_error, or count_timeout when counting ran past 5 seconds). The rows are still valid; row_count is then a lower bound.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired under its 24 h sliding TTL. `system_catalog_access`: The SQL references a system catalog such as information_schema, sqlite_master, pg_catalog, or a duckdb_*() function. `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired under its 24 h sliding TTL. `system_catalog_access`: The SQL references a system catalog such as information_schema, sqlite_master, pg_catalog, or a duckdb_*() function. `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. `row_too_large`: The first result row alone cannot fit the 80,000-character inline ceiling, and values are never cut. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "canvas_not_enabled",
      -  "canvas_not_found",
      -  "system_catalog_access",
      -  "missing_table"
      -]New value: +[
      +  "canvas_not_enabled",
      +  "canvas_not_found",
      +  "system_catalog_access",
      +  "missing_table",
      +  "row_too_large"
      +]
    • changedOutput schema / properties / row_count / description
      Previous value: -"Total rows in the full result before any cap."New value: +"Exact number of rows in the full result. When count_error is present, the total could not be counted and this is a lower bound: the rows the query confirmed exist."
    • changedOutput schema / properties / rows / description
      Previous value: -"Result rows — a preview capped at 100. When row_count exceeds this, page the rest by re-issuing the SQL with LIMIT / OFFSET."New value: +"Leading result rows: at most 100, and fewer when the next row would take the response past its 80,000-character inline ceiling. Values are never cut. When row_count exceeds rows.length, continue by re-issuing the SQL with OFFSET <rows.length>, added to any OFFSET it already applies, with any LIMIT reduced by the same amount. Page under an ORDER BY: without one, DuckDB guarantees no row order between calls."
  4. Changed1 schema field changed
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired (TTL is 24 h sliding). `system_catalog_access`: The SQL references a system catalog (information_schema, sqlite_master, pg_catalog, or a duckdb_*() function). `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired under its 24 h sliding TTL. `system_catalog_access`: The SQL references a system catalog such as information_schema, sqlite_master, pg_catalog, or a duckdb_*() function. `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. Other values are possible when a failure originates below the handler."
  5. 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: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb `canvas_not_found`: The canvas_id is unknown or has expired (TTL is 24 h sliding) `system_catalog_access`: The SQL references a system catalog (information_schema, sqlite_master, pg_catalog, or a duckdb_*() function) `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb. `canvas_not_found`: The canvas_id is unknown or has expired (TTL is 24 h sliding). `system_catalog_access`: The SQL references a system catalog (information_schema, sqlite_master, pg_catalog, or a duckdb_*() function). `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped. Other values are possible when a failure originates below the handler."
  6. 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": [
      +      "rows",
      +      "row_count",
      +      "canvas_id"
      +    ]
      +  },
      +  {
      +    "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: `canvas_not_enabled`: CANVAS_PROVIDER_TYPE is not set to duckdb `canvas_not_found`: The canvas_id is unknown or has expired (TTL is 24 h sliding) `system_catalog_access`: The SQL references a system catalog (information_schema, sqlite_master, pg_catalog, or a duckdb_*() function) `missing_table`: The SQL references a table that is not staged on this canvas — a mistyped name, or one that expired (24 h sliding TTL) or was dropped Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "canvas_not_enabled",
      +            "canvas_not_found",
      +            "system_catalog_access",
      +            "missing_table"
      +          ],
      +          "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: -[
      -  "rows",
      -  "row_count",
      -  "canvas_id"
      -]
  7. Changed1 schema field changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Canvas ID returned by openmeteo_get_forecast, openmeteo_get_historical, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate when truncated: true."New value: +"Canvas ID returned by openmeteo_get_forecast, openmeteo_get_historical, openmeteo_get_marine, openmeteo_get_air_quality, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate when truncated: true."
  8. Changed1 schema field changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Canvas ID returned by openmeteo_get_historical, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate when truncated: true."New value: +"Canvas ID returned by openmeteo_get_forecast, openmeteo_get_historical, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate when truncated: true."
  9. Changed1 schema field changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Canvas ID returned by openmeteo_get_historical, openmeteo_get_ensemble, or openmeteo_get_climate when truncated: true."New value: +"Canvas ID returned by openmeteo_get_historical, openmeteo_get_ensemble, openmeteo_get_flood, or openmeteo_get_climate when truncated: true."
  10. Changed1 schema field changed
    • changedOutput schema / properties / rows / description
      Previous value: -"Result rows (capped at the canvas row limit, default 10 000)."New value: +"Result rows — a preview capped at 100. When row_count exceeds this, page the rest by re-issuing the SQL with LIMIT / OFFSET."
  11. Changed1 schema field changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Canvas ID returned by openmeteo_get_historical or openmeteo_get_ensemble when truncated: true."New value: +"Canvas ID returned by openmeteo_get_historical, openmeteo_get_ensemble, or openmeteo_get_climate when truncated: true."
  12. Changed1 schema field changed
    • changedInput schema / properties / canvas_id / description
      Previous value: -"Canvas ID returned by openmeteo_get_historical when truncated: true."New value: +"Canvas ID returned by openmeteo_get_historical or openmeteo_get_ensemble when truncated: true."
  13. Added

TDQS

A4.8/5.0
Behavior5/5

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

The readOnlyHint=true annotation is consistent, and the description goes well past it: default 25-row page, per-call cap of 10,000, a hard 8,000,000-character response ceiling that fails as result_too_large instead of truncating, row_count with a count_error lower bound after a 5-second counting limit, and error text cut to 2,000 characters. These are exactly the failure modes an agent must anticipate.

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

Conciseness4/5

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

Front-loaded with purpose and precondition, then paging, then limits — a sensible order with no filler sentences. It loses a point for restating details already carried in the schema's limit and canvas_id descriptions (the 8,000,000-character ceiling and the 'select only needed columns' advice appear twice).

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?

Even though an output schema exists, the description still names the returned payload (whole rows plus row_count) and every documented failure mode, so an agent can call this and interpret results correctly. For a read-only SQL tool over spilled data, nothing material 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% and the schema descriptions are themselves detailed, so the baseline is 3. The description adds some real meaning beyond it — that pages must be advanced with LIMIT/OFFSET, that a SQL LIMIT and the limit parameter combine by taking the smaller page, and that canvas_id/table_name are a paired handoff from a specific truncated call.

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: 'Run a read-only SQL SELECT against tables staged on a DataCanvas,' and enumerates the exact producer tools that create those tables. It also clearly separates itself from openmeteo_dataframe_describe, which is named as the schema-discovery step rather than a query path.

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?

States the precondition precisely: use this only when a getter tool spills (truncated: true), pass that canvas_id, and reference the exact table_name returned alongside it. It also routes the agent to openmeteo_dataframe_describe when table or column names are unknown, so the when-to-use decision is fully determined.

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.