Fetch US Bureau of Labor Statistics data — CPI, unemployment, wages, JOLTS, and more via MCP. STDIO or Streamable HTTP.
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
- !Licence file present but not machine-readable
git clone https://github.com/cyanheads/bls-labor-mcp-server{
"mcpServers": {
"bls-labor": {
"command": "node",
"args": ["/path/to/bls-labor-mcp-server/dist/index.js"],
"env": {
"BLS_API_KEY": "<bls_api_key>"
}
}
}
}BLS_API_KEYMCP Servers overview
<div align="center">
<h1>@cyanheads/bls-labor-mcp-server</h1>
<p><b>Fetch US Bureau of Labor Statistics data — CPI, unemployment, wages, JOLTS, and more via MCP. STDIO or Streamable HTTP.</b>
<div>4 Tools by default · 6 with DataCanvas · 7 with opt-in drop</div>
</p>
</div>
<div align="center">
[](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/bls-labor-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/bls-labor-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/)
</div>
<div align="center">
[](https://github.com/cyanheads/bls-labor-mcp-server/releases/latest/download/bls-labor-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=bls-labor-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvYmxzLWxhYm9yLW1jcC1zZXJ2ZXIiXSwiZW52Ijp7IkJMU19BUElfS0VZIjoieW91ci1hcGkta2V5In19) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22bls-labor-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Fbls-labor-mcp-server%22%5D%2C%22env%22%3A%7B%22BLS_API_KEY%22%3A%22your-api-key%22%7D%7D)
[](https://www.npmjs.com/package/@cyanheads/mcp-ts-core)
</div>
<div align="center">
**Public Hosted Server:** [https://bls-labor.caseyjhand.com/mcp](https://bls-labor.caseyjhand.com/mcp)
</div>
---
## Overview
US labor statistics from the Bureau of Labor Statistics public API v2 and LABSTAT flat-file catalog. Resolve opaque SeriesIDs from natural language, fetch historical time-series or the latest observation, and query large multi-series results with SQL through an optional DataCanvas. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
### Tools
| Tool | Description |
|:-----|:------------|
| `bls_list_surveys` | List BLS survey programs (CPI, CPS, CES, JOLTS, PPI, OEWS, …) with codes, descriptions, and calculation-support flags. |
| `bls_search_series` | Search the BLS series catalog by natural language, survey, area, or keywords to resolve cryptic SeriesIDs. |
| `bls_get_series` | Fetch time-series data for 1–50 BLS series by SeriesID, with optional year range and period-over-period calculations. |
| `bls_get_latest` | Return the single most recent observation for one or more BLS series. |
| `bls_dataframe_describe` | List canvas dataframes registered by `bls_get_series` or `bls_dataframe_query` — provenance, TTL, row count, column schema. Available when `CANVAS_PROVIDER_TYPE=duckdb`. |
| `bls_dataframe_query` | Run a SELECT against canvas dataframes registered by `bls_get_series` or an earlier `register_as`. Supports JOINs, aggregates, window functions, CTEs. Available when `CANVAS_PROVIDER_TYPE=duckdb`. |
| `bls_dataframe_drop` | Drop a canvas dataframe by name. Available when `CANVAS_PROVIDER_TYPE=duckdb` and `BLS_DATAFRAME_DROP_ENABLED=true`; TTL handles cleanup by default. |
## Capability reference
### `bls_list_surveys` <sub>tool</sub>
- Optional `category` filters survey programs by subject; returns codes, names, and calculation-support flags (`allowsNetChange`, `allowsPercentChange`, `hasAnnualAverages`).
- Backed by the BLS surveys API with monthly caching. Annual-average support is advisory; read `bls_get_series`'s `annualAverageRows` for the rows actually returned.
---
### `bls_search_series` <sub>tool</sub>
- Search by text or SeriesID, with optional `survey`, `area` (substring of area, title, or SeriesID), and `seasonal_adjustment`; blank filters are omitted. `limit` is 1–50 (default 10), with `offset` pagination; without an area filter, equally matching national series rank first.
- Returns decoded SeriesIDs, titles, and `frequency`. Follow `nextOffset` while `truncated` is true; `capped: true` makes `totalCount` a lower bound, and paging stops at the FTS candidate pool.
- Searches the offline LABSTAT index without using API quota; OE/OEWS is opt-in through `BLS_CATALOG_INCLUDE_OES`. Unindexed surveys remain fetchable by SeriesID.
---
### `bls_get_series` <sub>tool</sub>
- Fetch 1–50 SeriesIDs per call, with a `start_year`/`end_year` window of up to 20 years, optional `calculations`, and `annual_average`. A start alone resolves the end to the current year capped at start + 19; an end alone is rejected. One batch consumes one API query; calculations depend on survey support (CPI/PPI return percent change only).
- Returns observations with `available`, preserves the raw `-` missing-value sentinel, and keeps valid series in mixed batches. Enrichment reports the applied year window, calculations, and annual-average rows.
- Large results spill to `dataset.name` when `CANVAS_PROVIDER_TYPE=duckdb`; otherwise `canvas_unavailable` asks for a narrower window.
---
### `bls_get_latest` <sub>tool</sub>
- Fetch the latest observation for up to 50 SeriesIDs (recommended ≤10). Each ID consumes one API query; use `bls_get_series` for a more efficient multi-series batch.
- Returns successful `results[]` beside per-series `failed[]` entries. `latestObservation.available` distinguishes a published value from BLS's missing-value sentinel.
---
### `bls_dataframe_describe` <sub>tool</sub>
- Optional `name` describes one registered dataframe; omit it to list active dataframes for the tenant. Requires `CANVAS_PROVIDER_TYPE=duckdb`.
- Returns source tool, query params, row count, TTL (`created_at`/`expires_at`), and `column_schema`; BLS columns are nullable. Registered-query types outside the canvas set (`DECIMAL`, `HUGEINT`, `SMALLINT`, lists) report as `VARCHAR`. Expired entries are removed when their canvas drop succeeds.
---
### `bls_dataframe_query` <sub>tool</sub>
- Run one SELECT against registered tables, with JOINs, aggregates, window functions, or CTEs. `row_limit` defaults to 1000 and caps at 10000; writes, external-file reads, and system catalogs are denied.
- Returns rows without consuming BLS API quota. Optional `register_as` stages the result with a fresh TTL for chained analysis; requires `CANVAS_PROVIDER_TYPE=duckdb`.
---
### `bls_dataframe_drop` <sub>tool</sub>
- Required `name` identifies the dataframe to drop. Available only with `CANVAS_PROVIDER_TYPE=duckdb` and `BLS_DATAFRAME_DROP_ENABLED=true`; TTL handles cleanup by default.
- Returns `dropped: false` for a missing table. A failed drop returns retryable `canvas_drop_failed` and leaves the dataframe registered.
## Features
Built on [`@cyanheads/mcp-ts-core`](https://github.com/cyanheads/mcp-ts-core): stdio and Streamable HTTP transports, pluggable auth (`none` / `jwt` / `oauth`), swappable storage (`in-memory`, `filesystem`, `Supabase`, `Cloudflare KV/R2/D1`), structured logging with optional OpenTelemetry tracing.
BLS-specific:
- BLS API v2 client with retry/backoff and daily quota tracking
- Offline series catalog search against LABSTAT flat files, indexed as an on-disk SQLite/FTS5 store — zero API quota for discovery; the OES/OEWS wage survey (~6M series) is opt-in via `BLS_CATALOG_INCLUDE_OES`
- Typed error contracts for BLS-specific failure modes — quota exhaustion, locked database, calculations not supported
- Period-over-period net/percent-change calculations via BLS's own server-side flag, consistent with BLS's published numbers
- Optional DataCanvas spillover (DuckDB) for large multi-series result sets — schema discovery and SQL access without re-querying the API
Agent-friendly output:
- Provenance — canvas-spilled results carry a `dataset.name` handle plus row count and expiry; `bls_search_series` echoes `effectiveQuery`, `catalogSize`, and whether the FTS candidate pool was `capped`
- Graceful partial failure — `bls_get_latest` returns per-item `failed[]` (seriesId + error) alongside successful `results[]` instead of failing the whole batch; `bls_get_series` keeps valid series when another SeriesID in the same batch is invalid or empty
- Discriminated outputs — every observation carries an `available` boolean for BLS's `-` missing-value sentinel, so callers branch on a typed field instead of parsing raw values
- Actionable notices — `enrichment.notice` explains empty results, canvas spillover, and unavailable data with concrete next steps (e.g. using `bls_search_series` to verify a SeriesID)
## Getting started
### Public Hosted Instance
A public instance is available at `https://bls-labor.caseyjhand.com/mcp` — no installation required. Point any MCP client at it via Streamable HTTP:
```json
{
"mcpServers": {
"bls-labor-mcp-server": {
"type": "streamable-http",
"url": "https://bls-labor.caseyjhand.com/mcp"
}
}
}
```
### Self-Hosted / Local
Add the following to your MCP client configuration file. A free BLS API key unlocks 500 queries/day — register at [bls.gov/developers](https://www.bls.gov/developers/home.htm). The server works without a key at 25 req/day.
```json
{
"mcpServerWhat people ask about bls-labor-mcp-server
What is cyanheads/bls-labor-mcp-server?
+
cyanheads/bls-labor-mcp-server is mcp servers for the Claude AI ecosystem. Fetch US Bureau of Labor Statistics data — CPI, unemployment, wages, JOLTS, and more via MCP. STDIO or Streamable HTTP. It has 1 GitHub stars and its last recorded update is dated 2026-10-10.
How do I install bls-labor-mcp-server?
+
You can install bls-labor-mcp-server by cloning the repository (https://github.com/cyanheads/bls-labor-mcp-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is cyanheads/bls-labor-mcp-server safe to use?
+
Our security agent has analyzed cyanheads/bls-labor-mcp-server and assigned a Trust Score of 80/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.
Who maintains cyanheads/bls-labor-mcp-server?
+
cyanheads/bls-labor-mcp-server is maintained by cyanheads. The last recorded GitHub activity is dated 2026-10-10, with 4 open issues.
Are there alternatives to bls-labor-mcp-server?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy bls-labor-mcp-server to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/cyanheads-bls-labor-mcp-server)<a href="https://claudewave.com/repo/cyanheads-bls-labor-mcp-server"><img src="https://claudewave.com/api/badge/cyanheads-bls-labor-mcp-server" alt="Featured on ClaudeWave: cyanheads/bls-labor-mcp-server" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
The fastest path to AI-powered full stack observability, even for lean teams.