Pod

Yes, this is on purpose. Pod is built for agents, so the default page is plain HTML.
Human? View the normal website.
Agent? You probably prefer /mcp/eia-mcp-server/issues.md or /mcp/eia-mcp-server/issues.json, or Pod over MCP.

Reported issues for eia-mcp-server

Pod holds 19 of 60 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to eia-mcp-server.

Most discussed

feat(config): eia_dataframe_describe and eia_dataframe_query stay listed when DataCanvas is off, so the default config advertises two unusable tools

Problem

eia_dataframe_drop is gated at registration:

const dropTool = serverConfig.dataframeDropEnabled
  ? dataframeDropTool
  : disabledTool(dataframeDropTool, { reason: '...', hint: 'EIA_DATAFRAME_DROP_ENABLED=true' });

eia_dataframe_describe and eia_dataframe_query are not. They are registered unconditionally and only discover the canvas is absent inside the handler:

const bridge = getCanvasBridge();
if (!bridge) throw ctx.fail('canvas_unavailable', 'DataCanvas 

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/52) · 2026-08-06 · closed · 4 comments

### feat(eia_describe_route): cap high-cardinality facet values in structuredContent — STEO returns all 1,469 seriesId values (~130KB)

`eia_describe_route` returns every value of every facet in `structuredContent` with no cap. For most routes that's fine (~50 states, a handful of sectors), but high-cardinality facets blow up the payload — `eia_describe_route("steo")` returns all **1,469** `seriesId` values, ~130KB of JSON (~35–40K tokens) in a single describe call. `format()` correctly previews 5 and appends "(+N more)", but the truncation lives only in `content[]`; clients that consume `structuredContent` (e.g. Claude Code) re

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/29) · 2026-06-30 · closed · 4 comments

### bug(eia_dataframe_query): row_limit truncation is silent — totalRows reports the capped count and the notice never fires

### Server version

0.3.4

### mcp-ts-core version

^0.11.0

### Runtime

Bun

### Runtime version

Bun 1.3.14 / Node 26.5.0

### Transport

HTTP (transport-agnostic — defect is in the tool handler)

### OS

macOS (server-side logic, platform-independent)

### Description

`eia_dataframe_query` drops the framework's `QueryResult.truncated` signal, so a result cut by `row_limit` comes back indistinguishable from a complete one. The handler only discloses truncation when `result.rowCount > result.

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/40) · 2026-08-06 · closed · 3 comments

### feat(eia_search_routes): index facet values so fuel-type queries resolve — "wind" and "solar photovoltaic generation" return nothing

`eia_search_routes` indexes route names, descriptions, path segments, and STEO series names. It does not index **facet values**, so the vocabulary callers actually search with — fuel types, sectors, states — is invisible to the index. Queries naming a fuel return nothing even when a route exposes that fuel as a facet value.

`electricity/electric-power-operational-data` carries a `fueltypeid` facet with 45 values including `solar photovoltaic`, `solar thermal`, `wind`, `onshore wind turbine`, an

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/36) · 2026-07-31 · closed · 3 comments

### bug(eia_query_route): EIA's incomplete-return advisory still forwards on the canvas-off path, where canvas_preview_note has already accounted for the gap

### Server version

0.3.7

### mcp-ts-core version

0.11.1

### Runtime

Bun

### Runtime version

Bun 1.3.14

### Transport

http

### Description

`isIncompleteReturn` suppresses EIA's per-page advisory once the response itself states where the caller stands, and `gapAccountedFor` is set in two places: the row-less branch, and the canvas branch when the staged table reaches the last row. The third branch — canvas absent, `total > data.length` — writes a `canvas_preview_note` that accounts for 

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/54) · 2026-08-06 · closed · 2 comments

### feat(eia-service): normalize route paths — eia_browse_routes rejects the leading and trailing slashes eia_describe_route and eia_query_route accept

### Problem

The three route-taking tools disagree on whether a path may carry slashes.

`eia_browse_routes` resolves only against the in-process node map, whose keys are bare segments (`electricity/retail-sales`), so any variant misses and comes back `route_not_found`. `eia_describe_route` and `eia_query_route` miss the map too, but then fall through to a direct EIA fetch — and EIA normalizes the path server-side, so they succeed.

| Input | `eia_browse_routes` | `eia_describe_route` | `eia_que

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/53) · 2026-08-06 · closed · 2 comments

### bug(eia_query_route): a rejected sort column or date format is reported as invalid_facet, and the recovery hint sends the caller to the wrong field

### Server version

0.3.7

### mcp-ts-core version

0.11.1

### Runtime

Bun

### Runtime version

Bun 1.3.14

### Transport

http

### Description

`INVALID_PARAM_REASONS` in `eia-service.ts` maps EIA's 400 bodies to a typed reason, and matches two of them:

```ts
const INVALID_PARAM_REASONS = [
  { pattern: /invalid data\b/i,      reason: 'invalid_column',    hint: '... pick a column from data_columns[].id.' },
  { pattern: /invalid frequency\b/i, reason: 'invalid_frequency', hint: '... pick a

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/51) · 2026-08-06 · closed · 2 comments

### feat(eia_query_route): canvas staging pages 25,000 rows on every call with no opt-out — a 3-row preview costs 5-6x the latency

### Problem

`eia_query_route` sets `accumulate: bridge !== undefined`, so whenever DataCanvas is configured the service walks offset pages up to `EIA_CANVAS_MAX_ROWS` (25,000) on **every** call where `total` exceeds the inline preview. There is no input that turns it off. The caller who asks for 3 rows to see what a route looks like pays five extra 5,000-row upstream fetches plus the DuckDB insert before the response returns.

Measured against the live API, same route and same `length: 3`, on t

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/50) · 2026-08-06 · closed · 2 comments

## Most recent

### feat(eia_browse_routes): name the route path parameter consistently across route tools

### Description

`eia_browse_routes` names its route-path input `path`, while `eia_describe_route` and `eia_query_route` name the same concept `route`. One parameter name for one concept would remove a predictable wrong turn in the server's main workflow.

Since tool inputs became strict, the mismatch now fails loudly rather than silently: carrying `path` forward from a browse call into `eia_describe_route` is rejected outright.

### Steps to reproduce

1. `eia_browse_routes({ path: "electricity

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/63) · 2026-08-25 · open · 0 comments

### feat(eia_query_route): a staged dataset reaches structuredContent with no pointer to the dataframe tools

### Server version

0.4.0

### mcp-ts-core version

^0.11.1

### Runtime

Bun

### Transport

Any — the gap is in the tool definition, not the transport.

### Description

`eia_query_route` returns a `df_<id>` handle in `dataset` on a `stage: true` call, but the structured response never names a tool that can reach the staged rows. `eia_dataframe_describe` is named nowhere in the tool at all, and the only mention of `eia_dataframe_query` in the response is a line `format()` writes into `content[

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/62) · 2026-08-13 · open · 0 comments

### bug(formatting): escape HTML and Markdown in table cells

### Server version

0.4.0

### mcp-ts-core version

^0.11.1

### Runtime

Bun

### Transport

HTTP

### Description

The table formatters escape pipe characters but pass HTML and Markdown syntax through unchanged. Upstream strings and SQL result strings can therefore change how `content[]` renders, while `structuredContent` correctly retains the original value.

### Steps to reproduce

With DataCanvas enabled, call:

```sql
SELECT '<b>unsafe</b> | *em* [link](x)' AS text

through `eia_datafr

Read the thread · 2026-08-11 · open · 0 comments

bug(DataCanvas): staging and drop failures return successful calls

Server version

0.4.0

mcp-ts-core version

^0.11.1

Runtime

Bun

Transport

HTTP

Description

Two DataCanvas failure paths return successful tool calls:

  1. CanvasBridge.registerDataframe() catches registration errors and returns undefined. When eia_query_route was called with stage: true, the response contains no dataset and no notice that the requested stage failed.
  2. CanvasBridge.drop() deletes provenance before contacting the canvas. If the canvas call thr

Read the thread · 2026-08-11 · open · 0 comments

bug(eia_describe_route): failed facet fetches look like empty facets

Server version

0.4.0

mcp-ts-core version

^0.11.1

Runtime

Bun

Transport

HTTP

Description

EiaApiService.fetchAndCacheMetadata() catches each failed /facet/{id} request and substitutes { values: [] }. The resulting metadata is cached for the process lifetime with no partial-result field or recovery hint.

This makes a failed facet leg indistinguishable from a facet that genuinely has no values. A later eia_query_route caller can conclude that the route has no fi

Read the thread · 2026-08-11 · open · 0 comments

bug(responses): cap inline query payloads below context-window scale

Server version

0.4.0

mcp-ts-core version

^0.11.1

Runtime

Bun

Transport

HTTP

Description

The two row-returning tools allow inline responses large enough to consume a model's context window. Their input limits match upstream or provider limits rather than an MCP response budget.

Steps to reproduce

  1. Call eia_query_route with { "route": "electricity/retail-sales", "length": 5000 }.
  2. Stage a five-row dataframe, then call eia_dataframe_query with a six-way

Read the thread · 2026-08-11 · open · 0 comments

feat(eia_search_routes): index named SEDS series for filter hints

Server version

0.4.0

mcp-ts-core version

^0.11.1

Runtime

Bun

Transport

HTTP

Description

The State Energy Data System (seds) exposes 968 named seriesId values, but none are searchable. The general facet-indexing path skips every facet above 200 values. STEO already has a dedicated named-series pass; SEDS needs the same treatment so a state-energy workflow can obtain the opaque ID required by eia_query_route.

Workflow gap

A caller looking for state carbon-d

Read the thread · 2026-08-11 · open · 0 comments

bug(eia_search_routes): exact-limit results report false truncation

Server version

0.4.0

mcp-ts-core version

^0.11.1

Runtime

Bun

Transport

HTTP

Description

eia_search_routes reports truncated: true whenever the number of returned matches equals limit. The service has already sliced the search result to limit, so the handler cannot tell whether another match exists.

Steps to reproduce

Call the tool twice with query: "weekly crude oil stocks":

  1. limit: 3
  2. limit: 4

Actual behavior

Both calls return the same

Read the thread · 2026-08-11 · open · 0 comments

bug(inputs): reject blank search terms and empty query collections

Server version

0.4.0

mcp-ts-core version

^0.11.1

Runtime

Bun

Transport

HTTP

Description

Several optional query inputs accept values that contain no usable input, then silently change the request's meaning:

Read the thread · 2026-08-11 · open · 0 comments

bug(eia_query_route): format() stamps one unit on a column whose rows carry different units, so content[] mislabels the values

Server version

0.3.7

mcp-ts-core version

0.11.1

Runtime

Bun

Runtime version

Bun 1.3.14

Transport

http

Description

format() builds its unit annotations from the first preview row only and drops every {col}-units column from the table body:

const unitsMap: Record<string, string> = {};
for (const key of allKeys) {
  if (key.endsWith('-units')) {
    const col = key.slice(0, -6);
    const unit = firstRow[key];            // <- first row only
    if 

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/49) · 2026-08-06 · closed · 2 comments

### bug(eia_describe_route): a facet value whose id is a single space renders as an empty pair in content[], hiding a working filter

### Server version

0.3.6

### mcp-ts-core version

0.11.1

### Runtime

Node

### Runtime version

Node 24

### Transport

http

### Description

Related: #47

EIA sends one facet value in the taxonomy whose `id` is a single space: `electricity/facility-fuel`'s `primeMover` carries `{"id": " "}` alongside its 20 real prime-mover codes. It is a working filter — `facets[primeMover][]=%20` returns 14,955 rows — but `format()` renders it as an empty pair, so the `content[]` line reads `FW=FW,  = , 

[Read the thread](https://github.com/cyanheads/eia-energy-mcp-server/issues/48) · 2026-08-06 · closed · 2 comments

The remaining reports are on [the project's issue tracker](https://github.com/cyanheads/eia-mcp-server/issues).