# Reported issues for bls-labor-mcp-server

Pod holds 19 of 26 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to [bls-labor-mcp-server](/mcp/bls-labor-mcp-server).

## Most discussed

### bug(bls-api-service): mixed all-empty batch reports series_not_found and hides the no-data advisories

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

Related: #22

When every requested series comes back with zero observations, `throwSeriesFailure` selects `series_not_found` as soon as any one advisory carries that reason, and its message lists only the invalid IDs. A batch mixing an invalid SeriesID with a valid series that has no data in the requested window therefore fails…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/59) · 2026-08-02 · closed · 7 comments

### bug(bls-observations): ingester drops the BLS "-" sentinel row, so mirror-served series lose the period and its footnote

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Node.js

### Runtime version

Node 26.5.0

### Transport

HTTP (Streamable HTTP)

### Description

`parseDataFile()` in `src/services/bls-observations/ingester.ts` discards every LABSTAT row whose `value` is the BLS `-` missing-value sentinel, so the period and its footnote never reach the mirror. v0.5.1 taught response normalization to mark those rows `available: false`; a mirror-routed series has nothing to mark. The…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/58) · 2026-08-02 · closed · 4 comments

### bug(bls_search_series): long or repetitive queries block the event loop for seconds

### Server version

0.5.4

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

`BlsCatalogService.search` builds its FTS `OR` match and its rescore loop from every query token, repeats included, and the `query` input has no length bound. Search runs synchronously against SQLite, so a long query holds the event loop for its whole duration and every other request on the process waits.

### Steps to reproduce…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/92) · 2026-09-24 · closed · 2 comments

### bug(bls-api-service): a failed live fallback discards the series the mirror already resolved

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Node.js

### Runtime version

Node 26.x

### Transport

HTTP (Streamable HTTP)

### Description

Related: #73, #81

With the mirror ready and live fallback on, a request mixing mirrored and unmirrored SeriesIDs fails outright when the fallback fails: `fetchSeries` awaits `fetchSeriesLive` before `alignToRequestOrder` runs, so the throw discards the mirrored series. A network failure arrives as a bare `-32603` with no…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/80) · 2026-09-22 · closed · 2 comments

### bug(bls_dataframe_query): registered schemas report every column as VARCHAR

### Server version

0.5.1

### mcp-ts-core version

^0.12.3

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

`bls_dataframe_describe` reports every column of a table registered through `bls_dataframe_query` `register_as` as `VARCHAR`. `CanvasBridge.query()` builds the stored `columnSchema` from the result's column names and hardcodes `type: 'VARCHAR'`, `nullable: true`; the framework's `QueryResult` carries names only. The table itself…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/71) · 2026-08-31 · closed · 2 comments

### bug(bls_dataframe_drop): an invalid dataframe name fails with an internal storage-key message

### Server version

0.5.4

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

`bls_dataframe_describe` and `bls_dataframe_drop` pass `name` straight into a tenant-state key. A name with characters the storage layer rejects fails with the framework's storage-key message, which describes an internal key rather than the table-name rule the caller broke.

### Steps to reproduce

```json…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/99) · 2026-09-24 · closed · 1 comment

### bug(bls-observations): mirror-served series ignore calculations=true while calculationsApplied reports true

### Server version

0.5.4

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

Related: #80

With the observations mirror ready, `bls_get_series` serves mirrored series from the mirror even when `calculations: true`. The `fetchSeries` mirror branch never forwards `options.calculations`, and mirror rows carry no net or percent changes, so a mirror-served series comes back without calculation fields while…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/96) · 2026-09-24 · closed · 1 comment

### bug(bls_search_series): rescore counts query tokens inside other words — unrelated headlines outrank real matches

### Server version

0.5.4

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

The `search()` rescore scores each query token with `titleLower.includes(token)` (likewise area, item, and SeriesID), so a token counts when it appears inside another word. Any positive score then earns a `COMMON_SERIES` headline its +8 boost. For `annual average all items`, the token `all` matches inside "seasonally", which lifts…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/91) · 2026-09-24 · closed · 1 comment

## Most recent

### feat(bls_search_series): return each series' coverage (start year, end year, end period)

### Use case

`bls_search_series` gives no sign that a series has ended, so a caller can pick a discontinued SeriesID and learn it only from what `bls_get_series` returns. On the 2026-09-23 LABSTAT files, 69 of the 500 top-10 rows for a 50-query PPI sample end before 2026, and 34 of the 50 queries return at least one. Coverage is also what separates most rows that no returned field tells apart: it cuts those groups from 294 to 72 in PC, 806 to 476 in WP, and 362 to 27 in LN.

Related: #85…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/90) · 2026-09-24 · open · 0 comments

### bug(bls_search_series): concept aliases match inside words — "shopping" and "happiness" trigger the PPI boost

### Server version

0.5.4

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

`BlsCatalogService.search` matches `CONCEPT_ALIASES` phrases with `query.includes(phrase)`, so a phrase fires inside unrelated words and boosts its surveys. `ppi` matches "happiness" and "shopping", so `happiness` returns the PPI headline `WPUFD49104` and `grocery shopping` ranks PPI rows first. `cpi` has the same exposure, and any…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/89) · 2026-09-24 · closed · 1 comment

### feat(bls-catalog): index current ECEC (CM) and ECI (CI); compensation aliases route to the discontinued EC

### Use case

The offline catalog's only compensation-cost survey is `EC`, the SIC-basis Employment Cost Index, whose 851 series all end in 2005. The current Employer Costs for Employee Compensation (`CM`) and Employment Cost Index (`CI`) are not indexed, yet `CONCEPT_ALIASES` routes "compensation" and "employer cost" to `EC`. A search for current compensation costs ranks a discontinued survey first, and no current ECEC or ECI series can be found by concept.

### Proposed behavior

Append `cm`…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/86) · 2026-09-24 · closed · 1 comment

### feat(bls-catalog): distinguish same-title series that differ only in publication frequency (CU, CW, LN)

### Use case

Surveys that publish one series at several frequencies ship the same upstream `series_title` for every variant, so `bls_search_series` returns rows that differ only in SeriesID. In the 2026-09-23 LABSTAT files, CU has 8,104 series and 4,237 distinct titles, and CW has 7,868 and 4,089. Every duplicate is a monthly/semiannual pair (3,867 CU, 3,779 CW). LN has 68,630 series and 49,151 distinct title + seasonal pairs; `unemployment rate` interleaves `LNS14000000` with its quarterly…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/85) · 2026-09-24 · closed · 1 comment

### bug(bls-api-service): an invalid SeriesID intermittently draws BLS's generic rejection when catalog metadata is requested, losing the valid series

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Node.js

### Runtime version

Node 26.x

### Transport

HTTP (Streamable HTTP)

### Description

Related: #59, #80

Both live calls request catalog metadata (`catalog: true` on the batch POST, `catalog=true` on the latest GET). With it on, BLS answers a request holding a nonexistent SeriesID, malformed or well-formed, sometimes per-series and sometimes with `REQUEST_FAILED`, its generic message, and `Results: null`. That…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/81) · 2026-09-22 · closed · 1 comment

### bug(bls_get_series): start_year alone resolves to a 20-year window that overflows the inline budget with canvas off

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Node.js

### Runtime version

Node 26.x

### Transport

HTTP (Streamable HTTP)

### Description

Related: #76

When `bls_get_series` receives `start_year` alone it resolves `end_year` to the full 20-year window, which for a monthly series is 240 rows — over the inline budget. With DataCanvas disabled (the default) the call fails with `canvas_unavailable`, and the error tells the caller to narrow `start_year`/`end_year`…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/79) · 2026-09-22 · closed · 1 comment

### bug(bls-observations): ingester reads {abbr}.readme, which no survey serves — 8 of 13 surveys never enter the mirror

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Node.js

### Runtime version

Node 26.x

### Transport

HTTP (Streamable HTTP)

### Description

The observations ingester discovers a survey's data files by fetching `{abbr}.readme` from LABSTAT, but no survey serves that file — the index every survey publishes is `{abbr}.txt`. With no index the ingester falls back to `{abbr}.data.1.AllData`, which exists for only 5 of the 13 harvested surveys, so CU, CW, AP, CE, LA, PC,…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/78) · 2026-09-22 · closed · 1 comment

### bug(bls_get_series): start_year or end_year alone is rejected by BLS, contradicting the documented default

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

`bls_get_series` documents `end_year` as "Defaults to the current year when omitted", but the handler forwards whichever bound the caller supplied and BLS requires the pair. A one-sided range is rejected upstream, spends one of the 500 daily queries, and surfaces as `request_rejected`, whose declared recovery hint is about…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/76) · 2026-09-18 · closed · 1 comment

### bug(bls_dataframe_query): Markdown table cells escape pipes but not backslashes

### Server version

0.5.1

### mcp-ts-core version

0.12.3

### Runtime

Bun

### Transport

Any

### Description

The `bls_dataframe_query` table formatter (`bls-dataframe-query.tool.ts`, string and serialized-object cells) escapes `|` as `\|` but leaves existing backslashes untouched. When the table renders, a backslash before ASCII punctuation is consumed as an escape, so the `content[]` text loses characters: `x\|y` renders as `x|y` and `a\*b` as `a*b`. `structuredContent` is unaffected.…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/75) · 2026-09-16 · closed · 1 comment

### bug(bls_dataframe_drop): provider failures erase metadata and report success

### Server version

0.5.1

### mcp-ts-core version

^0.12.3

### Runtime

Bun

### Runtime version

Bun 1.4.0

### Transport

HTTP (Streamable HTTP)

### Description

`CanvasBridge.drop()` deletes a dataframe's metadata first, then swallows any acquire or provider error and returns whether metadata existed. When the provider's drop rejects, `bls_dataframe_drop` reports `dropped: true` while the table survives: queryable, unlisted by `bls_dataframe_describe`, and outside the TTL sweep.…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/74) · 2026-08-31 · closed · 1 comment

### bug(bls-observations): mirror-routed series[] is not in request order and drops unresolved IDs

### Server version

0.5.2

### mcp-ts-core version

0.13.6

### Runtime

Node.js

### Runtime version

Node 26.5.0

### Transport

HTTP (Streamable HTTP)

### Description

Mirror-routed `bls_get_series` responses do not honour the request order its output schema declares, and drop requested SeriesIDs the schema says are always present. Reordering is not confined to the live-fallback path: `queryBySeries` sorts rows `year DESC` and `mirrorRowsToSeriesData` groups them by first appearance, so…

[Read the thread](https://github.com/cyanheads/bls-labor-mcp-server/issues/73) · 2026-08-31 · closed · 1 comment

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