Skip to main content
Glama

eia-energy-mcp-server

Query EIA Route Data

eia_query_route
Read-only

Fetches data from a leaf route with optional facet filters, date range, frequency, and column selection. Use eia_describe_route first to discover valid facet IDs, facet values, column IDs, and frequency codes. Data values are strings in the response (EIA API returns all numeric values as strings, e.g. "9.13"); cast to DOUBLE in SQL when arithmetic is needed. Returns a preview inline and stages nothing by default — one upstream request, whatever total says. Pass stage: true to also page past the preview and stage the accumulated set as a DataCanvas table, then pass the returned dataset name to eia_dataframe_query for SQL. Every dataset a tenant stages lands in the same canvas, so tables from different routes cross-join by name with nothing to thread between calls.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
endNoPeriod end (same format as start).
sortNoResult ordering.
routeYesLeaf route path (e.g. "electricity/retail-sales", "steo"). Discoverable via eia_browse_routes or eia_search_routes. Leading, trailing, and doubled slashes are stripped, so an EIA-doc spelling like "/electricity/retail-sales/" resolves to the same route.
stageNoStage the matching rows as a DataCanvas table for SQL (default false). Off, the call makes one upstream request and returns the preview alone. On, the service pages past the preview up to EIA_CANVAS_MAX_ROWS and registers the accumulated rows, returning the handle in dataset — several extra upstream requests and seconds of latency on a large route, so turn it on when moving to analysis, not while exploring. Requires a canvas (CANVAS_PROVIDER_TYPE=duckdb); without one nothing is staged whatever this is set to.
startNoPeriod start in the route date format (e.g. "2020-01" for monthly, "2020" for annual). Format from eia_describe_route.
lengthNoRows in the inline preview (default 100, max 5000 per EIA limit). With stage: true, staging is not bounded by this — it pages past the preview on its own.
offsetNoRow offset into the matching set (default 0). An offset at or beyond total returns zero rows.
columnsNoData column IDs to return (reduces payload). Defaults to all. IDs discoverable via eia_describe_route.
filtersNoFacet filters keyed by facet ID (e.g. { "stateid": "TX", "sectorid": ["RES", "COM"] }). Use the facets[].id values returned by eia_describe_route as keys here.
frequencyNoAggregation frequency ID (e.g. "monthly", "annual"). Defaults to route default. Valid IDs from eia_describe_route.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataNoPreview rows. All numeric values are strings per the EIA API (e.g. "9.13"). Cast to DOUBLE in SQL for arithmetic: CAST(value AS DOUBLE). Per-column units appear as {col}-units fields inline in each row. Keys are dynamic column IDs from the EIA route.
errorNoPresent when the call failed. Absent on success.
routeNoThe route path queried, in canonical spelling — any leading, trailing, or doubled slashes the input carried are stripped. Reusable verbatim in a follow-up call.
totalNoTotal matching rows in the EIA dataset for this query (may exceed returned rows when pagination or spillover applies).
noticeNoInformational message when the response carries no rows — either zero rows matched the filters (broaden the query) or offset paged past the last row (reduce offset below total).
datasetNodf_<id> table handle for the registered dataset — pass directly to eia_dataframe_query SQL (SELECT ... FROM df_<id>). Present only on a stage: true call against a deployment with a canvas configured; absent otherwise, since nothing was staged. Every dataset a tenant stages shares one canvas, so handles from different routes join directly.
frequencyNoFrequency of the returned data.
appliedEndNoEcho of the end period as applied, when an end was provided.
totalCountNoTotal matching rows in the EIA dataset.
appliedSortNoEcho of the result ordering as applied, when a sort was provided — the ordering that decided which rows a capped stage holds.
date_formatNoPeriod format for the returned data (e.g. "YYYY-MM").
appliedStartNoEcho of the start period as applied, when a start was provided.
appliedLengthNoPreview row count requested for this call.
appliedOffsetNoRow offset applied to the query — the cause when a page comes back empty.
returnedCountNoRows in this response. When returnedCount < totalCount, use offset or canvas for the rest.
appliedColumnsNoEcho of the column projection as applied, when columns were provided.
appliedFiltersNoFacet filters applied to the query, when provided.
effectiveRouteNoThe route path that was queried.
returned_countNoNumber of rows in this response. When returned_count < total, use offset pagination or DataCanvas for the rest.
appliedFrequencyNoEcho of the frequency as applied, when a frequency was provided.
truncation_warningNoUpstream advisories forwarded verbatim from EIA's warnings[], joined with '; ' when more than one applies. These describe the inline page — EIA's "incomplete return" entry fires whenever the requested length is under total, at any size — not a 5,000-row ceiling on this response. Absent when the response already accounts for the gap the advisory names (the staged table reaches the last row, notice explains the empty page, or canvas_preview_note places the inline page against total because nothing was staged).
canvas_preview_noteNoHuman-readable note when total exceeds the inline preview. On a stage: true call it names how many rows actually reached the canvas table, and where in the matching set those rows sit whenever the stage does not start at row 1; when staging also stopped short of total (the EIA_CANVAS_MAX_ROWS cap, or an upstream page that did not return), it says so and gives the offset to resume from. Where staging was not requested it places the inline page against total and names stage: true as the way to get SQL access to the rest; where no canvas is configured at all, staging is unavailable, so it names offset paging and CANVAS_PROVIDER_TYPE=duckdb instead.

TDQS

A4.9/5.0
Behavior5/5

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

The description discloses that data values are strings and need casting in SQL, that one upstream request is made by default, and that stage:true pages past the preview and incurs extra latency. It explains the staging side effect and requirement of a canvas. This goes well beyond the readOnlyHint annotation, providing complete transparency about side effects and performance.

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?

The description is compact yet information-dense. It front-loads the core purpose, then covers prerequisites, data type quirk, default vs. staging behavior, and integration with downstream tools. Every sentence earns its place with no redundancy or fluff.

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 tool with 10 parameters, nested objects, and an output schema, the description covers all necessary context: prerequisites, behavior for preview and staging, latency implications, data type handling, and routing to eia_dataframe_query. The output schema is present, so return-value explanation is not needed. Nothing an agent needs to invoke 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% with detailed parameter descriptions (e.g., route slash stripping, stage behavior, filters keyed by facet ID). The description adds a useful note about data values being strings (relevant to numeric columns) and emphasizes the need to consult eia_describe_route for valid parameter values, but these are not parameter-specific over and above the schema. Since the schema already carries the heavy lifting, a 4 is appropriate for the marginal added context.

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 clearly states the tool fetches data from a leaf route with optional facet filters, date range, frequency, and column selection. It distinguishes itself from siblings by mentioning 'leaf route' and the preview/staging behavior, which is distinct from route discovery (browse/search) and route metadata (describe) tools.

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?

It explicitly instructs to 'Use eia_describe_route first to discover valid facet IDs, facet values, column IDs, and frequency codes.' It also explains when to use stage:true ('turn it on when moving to analysis, not while exploring') and directs the user to pass the staged dataset name to eia_dataframe_query for SQL, providing clear routing among siblings.

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.

TDQS

A4.7/5.0
Disambiguation5/5

Each tool serves a clearly distinct function: taxonomy browsing, fuzzy search, route metadata discovery, data retrieval, dataframe inspection, and SQL querying. There is no overlap between the route-focused and dataframe-focused tools, and even the two describe/query pairs are separated by target (route vs. dataframe).

Naming Consistency4/5

All tools share the eia_ prefix and use descriptive verbs, but there's a minor inconsistency: route tools mix plural (browse_routes, search_routes) and singular (describe_route, query_route) forms, while dataframe tools place 'dataframe' before the verb (eia_dataframe_describe, eia_dataframe_query). This is readable and predictable overall, with only slight deviation from a uniform pattern.

Tool Count5/5

With 6 tools, the server is well-scoped for its purpose. It covers discovery, metadata, data access, and SQL analysis without unnecessary bloat or missing essentials. The number fits comfortably within the ideal range for a domain-specific data server.

Completeness5/5

The tool chain is complete for the domain: browse/search to locate routes, describe to get facet/column metadata, query to fetch data, and optionally stage to query with SQL. Dataframe management includes listing and querying, with automatic expiry, so there are no dead ends in the typical workflow. It's a read-only API, but that's appropriate for the energy data use case.