Skip to main content
Glama

ilostat-mcp-server

Query staged ILOSTAT dataframes

ilostat_dataframe_query
Read-onlyIdempotent

Run a single-statement SELECT against the df_ dataframes staged by ilostat_query_indicator and ilostat_compare_geographies or stored by an earlier register_as. Inspect a dataframe with ilostat_dataframe_describe first; its column schema is what the SQL has to match. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and file-reading table functions are rejected, and system catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied. Breakdown versions overlap (AGE_YTHADULT_*, AGE_AGGREGATE_*, AGE_10YRBANDS_*), so filter to one version before summing. Optional register_as stores the result as a new dataframe with a fresh TTL.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sqlYesOne SELECT over df_<id> tables (DuckDB SQL: joins, aggregates, window functions, CTEs), at most 20,000 characters. BIGINT results such as COUNT or SUM of integers serialize as strings; CAST to DOUBLE for inline arithmetic.
previewNoRows returned inline; defaults to row_limit. Set lower when register_as keeps the full result.
row_limitNoHard cap on rows materialized (1–10,000). A query matching more stops at the cap and row_count_capped is true; register_as keeps the full result.
register_asNoStore the result as a new dataframe under this name (df_XXXXX_XXXXX: letters and digits, five in each part; stored uppercased after df_) with a fresh TTL, to chain analyses. A result over 1,000,000 rows is refused, and storing one can evict the oldest dataframes, which evicted names.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
capNoThe row cap that bound: preview when lower than row_limit, else row_limit.
rowsNoResult rows keyed by the names in columns, bounded by preview and row_limit; BIGINT values arrive as strings.
errorNoPresent when the call failed. Absent on success.
shownNoRows returned inline.
noticeNoGuidance when the query returned no rows or a cap withheld some.
columnsNoColumn names in projection order.
evictedNoDataframes dropped, oldest first, to keep this tenant within 1,000,000 staged rows and 100 dataframes; present only when storing the result evicted any.
row_countNoRows the query produced. With register_as this is the exact count of the stored dataframe, which row_limit does not bound; otherwise at most row_limit, and when row_count_capped is true it is the cap, not a total.
truncatedNoTrue when a cap withheld rows from this response.
expires_atNoISO 8601 expiry of the new dataframe.
registered_asNoThe new dataframe name, when register_as stored the result.
row_count_cappedNoTrue when the query matched more rows than row_limit; never true with register_as, which stores every row.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already establish readOnlyHint/openWorldHint/idempotentHint, but the description adds real operational detail beyond them: the exact rejected statement classes (writes, DDL, DROP, COPY, PRAGMA, ATTACH, file-reading table functions), the denied system catalogs, the overlapping breakdown-version trap (AGE_YTHADULT_*/AGE_AGGREGATE_*/AGE_10YRBANDS_*), and that register_as creates a fresh TTL. This is exactly the behavioral context an agent needs to write a valid query.

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

Conciseness5/5

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

Information is front-loaded: purpose first, then prerequisite, then the rejection list, then the semantic pitfall, then the optional output mode. Every sentence carries distinct operational value with no filler.

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?

With an output schema present, the description need not explain return values, and it covers what it must: prerequisites, allowed statement surface, and the analysis trap that would silently corrupt sums. Nothing needed to invoke the tool correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, so each of the four parameters (sql, preview, row_limit, register_as) is already documented in detail, including the BIGINT-as-string caveat and the 1,000,000-row register limit. The description's mention of register_as storing with a fresh TTL largely repeats the schema, so it adds little beyond the baseline.

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?

The description opens with a specific verb and resource: 'Run a single-statement SELECT against the df_<id> dataframes.' It goes further by naming which sibling tools produce those dataframes (ilostat_query_indicator, ilostat_compare_geographies, register_as) and which sibling inspects them (ilostat_dataframe_describe), so the agent can separate this from ilostat_query_indicator without opening any schema.

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

Usage Guidelines4/5

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

It clearly states the precondition — data must already be staged by ilostat_query_indicator or ilostat_compare_geographies — and directs the agent to run ilostat_dataframe_describe first because 'its column schema is what the SQL has to match.' That is strong contextual routing, though it never explicitly says when to prefer querying an indicator directly via ilostat_query_indicator instead.

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.