---
summary: "Catalog SQLite index, bls_search_series restored, OES gate"
breaking: false
security: false
---

# 0.4.1 — 2026-06-04

## Changed

- **`BlsCatalogService` moved to on-disk SQLite FTS5 index** ([#33](https://github.com/cyanheads/bls-labor-mcp-server/issues/33)) — the series catalog is parsed once into the framework's `sqliteMirrorStore` and queried on demand. Off-heap storage removes the multi-GB in-memory footprint and the latent stack-overflow on catalog assembly. Search narrows candidates via FTS5 then applies the existing bespoke relevance rescore.
- **`BLS_CATALOG_CACHE_PATH` → `BLS_CATALOG_DB_PATH`** — renamed to reflect the SQLite store. Default `.cache/bls-catalog.db`.
- **User-Agent URL dropped** — `download.bls.gov` (Akamai) returns HTTP 403 for any `User-Agent` containing a URL. The default UA is now `cyanheads-bls-mcp/1.0 (casey@caseyjhand.com)` (name + contact email only; no `https://` link). This was a regression of the #31 UA fix introduced in 0.3.x.

## Fixed

- **`bls_search_series` restored in production** ([#34](https://github.com/cyanheads/bls-labor-mcp-server/issues/34)) — searches returning 0 results regardless of query were caused by the Akamai 403 blocking LABSTAT flat-file downloads during catalog build (see UA change above). Live field-test confirms 187 303 series load and search returns correct results.

## Added

- **`BLS_CATALOG_INCLUDE_OES` gate** ([#33](https://github.com/cyanheads/bls-labor-mcp-server/issues/33)) — the OES/OEWS occupational-wage survey (~6M series / ~1.2 GB) is now excluded unless `BLS_CATALOG_INCLUDE_OES=true`. OES series remain fetchable by ID via `bls_get_series` when off. Prevents a multi-minute first harvest and GBs of on-disk index for a survey most users don't need.
- **Dockerfile `.cache`/`.mirror` directories** — `mkdir -p` + `chown bun:bun` ensures the non-root container user can create the SQLite catalog db and the optional observations mirror store without volume mounts failing.
