
Bls Mcp Server
io.github.cyanheads由 GitHub 帳號 cyanheads 發布v0.1.9更新於 Oct 24, 2026
Fetch US Bureau of Labor Statistics data — CPI, unemployment, wages, JOLTS, and more via MCP.
概覽
取得美國勞工統計局資料,例如 CPI、失業率、薪資與 JOLTS,可解析序列 ID 並對大型結果集執行 SQL 查詢。
- 可以做什麼
- 提供 BLS 勞動統計工具:bls_list_surveys 列出調查計畫,bls_search_series 透過離線 LABSTAT 目錄以自然語言解析晦澀的 SeriesID 且不消耗 API 配額,bls_get_series 依年份區間取得 1-50 個序列並可選計算期間變化,bls_get_latest 傳回每個序列的最新觀測值。啟用選用的 DuckDB DataCanvas 後,bls_dataframe_describe 與 bls_dataframe_query 提供結構描述探索與唯讀 SELECT 查詢,明確啟用時 bls_dataframe_drop 可刪除資料框架。
- 適用情境
- 適合助理需要權威美國勞動統計資料用於分析、報告或經濟問題,以及需要自然語言序列探索和對多序列結果執行 SQL 的情境。也適合否則會觸及 BLS API 配額上限的高頻工作負載。
- 執行需求
- 以 stdio 在本機執行,或作為 Streamable HTTP 伺服器執行;也有公開託管端點。需要 Bun v1.4.0+ 或 Node.js v24+,或 Docker。BLS_API_KEY 為選用:沒有金鑰每天 25 次請求,免費金鑰每天 500 次請求並支援計算與年度平均值。選用設定包括 MCP_AUTH_MODE、MCP_HTTP_HOST、MCP_HTTP_PORT、MCP_HTTP_ENDPOINT_PATH 與 MCP_LOG_LEVEL;DataCanvas 需要 CANVAS_PROVIDER_TYPE=duckdb。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Bls Mcp Server,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
@cyanheads/bls-labor-mcp-server
Fetch US Bureau of Labor Statistics data — CPI, unemployment, wages, JOLTS, and more via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://bls-labor.caseyjhand.com/mcp
Overview
US labor statistics from the Bureau of Labor Statistics: jobs, unemployment, wages, and inflation. Find series in plain language instead of decoding SeriesIDs, pull full history or the latest value, and run SQL over large multi-series results.
Tools
Capability reference
bls_list_surveys tool
- Optional
categoryfilters survey programs by subject; returns codes, names, and calculation-support flags (allowsNetChange,allowsPercentChange,hasAnnualAverages). Each row'ssearchCoverage(indexed,composed, ornone) says whetherbls_search_seriesreaches the survey, withseriesIndexedfor indexed ones. - Backed by the BLS surveys API with 30-day process-local caching. Annual-average support is advisory; read
bls_get_series'sannualAverageRowsfor the rows actually returned.
bls_search_series tool
- Search by text or SeriesID, with optional
survey,area, andseasonal_adjustment; blank filters are omitted.areatakes a USPS or 2-digit FIPS state code; a 3-, 4-, 5-, or 7-digit CSA, CPI area, county or CBSA, or state + place code; otherwise a substring of area, title, or SeriesID (all-digit values outside those lengths add a notice).limitdefaults to 10 and requests above 50 clamp to 50 with notice, withoffsetpagination. Exact SeriesIDs rank first, then series matching every query word, with any place the query names in full ahead of the rest; at equal score, current series rank first, then national ones, then the JOLTS aggregate. - Returns decoded SeriesIDs, titles,
frequency, and independently optionalstartYear,endYear, andendPeriodcoverage (for example,1982–2005 Q04). Coverage describes the catalog snapshot, not continuous observations. FollownextOffsetwhiletruncatedis true;capped: truemakestotalCounta 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. Undersurvey: "OE"without those rows, it composes OEWS SeriesIDs from the OE code tables, up to 50 per search; each is markedcomposed: trueand is unconfirmed untilbls_get_seriesreturns data for it. Unindexed surveys remain fetchable by SeriesID.
bls_get_series tool
- Fetch up to 25 SeriesIDs without an API key or 50 with one per call, with a
start_year/end_yearwindow of up to 20 years, optionalcalculations, andannual_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 local-catalog titles when available and optional BLS
measuremetadata, and observations withavailable; preserves the raw-missing-value sentinel, and keeps valid series in mixed batches. Enrichment reports the applied year window, calculations actually returned, annual-summary rows, and any upstream reductions or advisories. - SeriesIDs are trimmed, uppercased, and deduplicated before the cap;
unprocessedSeriesIdslists the exact ordered remainder without automatic extra batches. Omitted year bounds use BLS's three-calendar-year default, subject to coverage. - Large results spill to
dataset.name. WithCANVAS_PROVIDER_TYPE=none, all fetched observations return inline.
bls_get_latest tool
- Fetch the latest observation for up to 50 SeriesIDs (recommended ≤10). IDs are trimmed, uppercased, and deduplicated before the cap;
unprocessedSeriesIdslists the exact ordered remainder. Each processed ID consumes one API query; usebls_get_seriesfor a more efficient multi-series batch. - Returns successful
results[]beside per-seriesfailed[]entries.latestObservation.availabledistinguishes a published value from BLS's missing-value sentinel.
bls_dataframe_describe tool
- Optional
namedescribes one registered dataframe; omit it to list active dataframes for the tenant. Unavailable whenCANVAS_PROVIDER_TYPE=none. - Returns source tool, query params, row count, TTL (
created_at/expires_at, fixed at table creation), andcolumn_schema; BLS columns are nullable. Registered-query types outside the canvas set (DECIMAL,HUGEINT,SMALLINT, lists) report asVARCHAR. Expired entries are removed when their canvas drop succeeds.
bls_dataframe_query tool
- Run one SELECT against registered tables, with JOINs, aggregates, window functions, or CTEs.
row_limitdefaults to 1000; larger values clamp to 10000, andpreviewclamps to the applied row limit with requested/applied notices. Zero preview remains valid; writes, external-file reads, and system catalogs are denied. - Engine-setting functions (
current_setting,current_schema,current_schemas,in_search_path) andquery_tableare denied. Unqualifiedcurrent_schemakeyword or column references are also denied; qualify a real column with its table alias (for example,t.current_schema).query()accepts one plain SQL string literal, checked recursively up to four levels; computed SQL strings are rejected. Reference staged tables directly for analysis. - Returns rows without consuming BLS API quota. Optional
register_asstages the result with a fresh TTL for chained analysis. Unavailable whenCANVAS_PROVIDER_TYPE=none.
bls_dataframe_drop tool
- Required
nameidentifies the dataframe to drop. Available only withBLS_DATAFRAME_DROP_ENABLED=true, and never withCANVAS_PROVIDER_TYPE=none; TTL handles cleanup by default. - Returns
dropped: falsefor a missing table. A failed drop returns retryablecanvas_drop_failedand leaves the dataframe registered.
Features
Built on @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
- DataCanvas spillover (DuckDB, on by default) 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.namehandle plus row count and expiry;bls_search_seriesechoeseffectiveQuery,catalogSize, and whether the FTS candidate pool wascapped - Graceful partial failure —
bls_get_latestreturns per-itemfailed[](seriesId + error) alongside successfulresults[]instead of failing the whole batch;bls_get_serieskeeps valid series when another SeriesID in the same batch is invalid or empty - Discriminated outputs — every observation carries an
availableboolean for BLS's-missing-value sentinel, so callers branch on a typed field instead of parsing raw values - Actionable notices —
enrichment.noticeexplains empty results, canvas spillover, and unavailable data with concrete next steps (e.g. usingbls_search_seriesto 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:
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. The server works without a key at 25 req/day.
Or with npx (no Bun required):
Or with Docker:
For Streamable HTTP, set the transport and start the server:
Prerequisites
- Bun v1.4.0 or higher (or Node.js v24+).
- A free BLS API v2 key — register at bls.gov/developers. Grants 500 queries/day; the server also works without a key at 25 req/day.
Installation
- Clone the repository:
- Navigate into the directory:
- Install dependencies:
- Configure environment:
Configuration
All configuration is validated at startup via Zod schemas in src/config/server-config.ts.
See .env.example for the full list of optional overrides.
Observation mirror (optional)
For high-volume workloads, an opt-in local mirror serves bls_get_series / bls_get_latest from an embedded SQLite store of the LABSTAT files instead of the BLS API, removing the 500/day quota cap; requests fall back to the live API until it is built. Enable it with BLS_OBSERVATIONS_MIRROR_ENABLED=true, then run the one-time bootstrap: node dist/services/bls-observations/subprocess.js --init. Settings, survey coverage, harvest checkpoint and exit codes, fallback and calculation behavior, and upgrade notes are in docs/observation-mirror.md.
Running the server
Local development
-
Build and run:
-
Run checks and tests:
Docker
The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/bls-labor-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
- Handlers throw, framework catches — no
try/catchin tool logic - Use
ctx.logfor request-scoped logging,ctx.statefor tenant-scoped storage bls_search_seriesis the anchor tool — design workflows to call it before the API tools- Wrap BLS API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
License
Apache-2.0 — see LICENSE for details.
來源:README.md,提交 caef232
工具
0版本歷史
1- v0.1.9最新Sep 16, 2026
評分
已滿足適用檢查項的 40%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分
請在儲存庫或註冊中心條目中宣告授權條款。