Labor Market Intelligence

Labor Market Intelligence

Enables Claude users to research U.S. labor-market trends through live BLS and FRED data, covering employment, unemployment, wages, job openings, occupational outlook, and industry comparisons.

Category
访问服务器

README

Labor Market Intelligence — Remote MCP Server

A read-only remote MCP server exposing U.S. Bureau of Labor Statistics (BLS) and FRED (Federal Reserve Bank of St. Louis) data to Claude as a custom connector — for career and labor-market research: employment trends, unemployment, job openings, hires, quits, wages, occupational outlook, and industry comparisons.

Runs on Cloudflare Workers. Cost: $0/month on Cloudflare's free tier.

Built incrementally against a fully verified implementation plan — every BLS and FRED endpoint, series ID, and data-shape quirk referenced in this codebase was confirmed against the live APIs (not assumed from documentation alone) before being implemented.

Status

All 10 implementation checkpoints complete and live-verified against the deployed Cloudflare Worker. 89 unit tests, clean typecheck, all 16 tools confirmed working against real BLS/FRED data.

Connecting to Claude

  1. In Claude, go to Settings → Connectors → Add custom connector.
  2. Remote MCP server URL: https://<your-worker>.<your-subdomain>.workers.dev/mcp/<MCP_PATH_TOKEN> — treat this URL as a credential; the token is the only thing authorizing access.
  3. OAuth Client ID / Secret: leave both blank. This server is authless — the secret path is the credential, and Claude supports authless remote MCP servers natively.
  4. Transport: Streamable HTTP (SSE is the legacy fallback).

Tools (16)

Low-level source tools — thin, faithful passthrough to BLS/FRED

Tool What it does
fred_search_series Full-text search over FRED series
fred_get_series Fetch observations for a known FRED series ID
fred_get_latest Fetch only the most recent FRED observation
bls_get_series Fetch up to 50 BLS series over up to a 20-year span; aspects=true unlocks Employment Projections' projected employment/openings/wage
bls_list_surveys List all 70 BLS survey program abbreviations
bls_popular_series List BLS's "most requested" series (not universal — returns nothing for EP/JOLTS/OR)
search_indicators Search ~13 curated headline indicators (unemployment, JOLTS metrics, payrolls, etc.) for their BLS/FRED IDs
search_occupations Search ~1,113 SOC occupation titles for their BLS Employment Projections series ID

Research tools — composed, higher-level analysis

Tool What it does
analyze_labor_market_trend Change and CAGR for one BLS/FRED series over a date range
compare_labor_market_series Compare 2-10 BLS/FRED series (can mix sources) side by side
analyze_job_market_conditions Snapshot: unemployment, payrolls, openings, hires, quits, layoffs — each with 1mo/12mo change
analyze_industry_employment Long-run BLS Employment Projections outlook for a whole industry
get_occupation_outlook Full BLS Employment Projections outlook for one occupation (employment, openings, median wage)
compare_occupations Compare 2-20 occupations' outlook in a single batched BLS call
analyze_wage_trends Trend/CAGR for an aggregate wage measure (default: average hourly earnings)
ping Connectivity check; uses no BLS/FRED quota

Every tool is annotated readOnlyHint: true and enforced by an automated test (test/unit/server.test.ts) — no tool can mutate state, and none accepts a caller-supplied URL to fetch.

What each source actually provides

Verified against the live APIs, not assumed from documentation:

  • FRED provides broad macro context (GDP, rates, recession indicators), unit transforms, and a real full-text series search. It also republishes many BLS series (UNRATE, PAYEMS, JOLTS metrics) with a clean uniform cadence.
  • BLS is authoritative for anything occupational: Employment Projections (EP, outlook/openings/wage) and OEWS (OE, current wages) exist only on the BLS side — FRED does not carry the National Employment Matrix.
  • OEWS has no history via the API — every series returns exactly one reference year, confirmed by requesting a 10-year range and getting nine "No Data Available" messages plus one datapoint. Occupational wage trends are not retrievable from this API; use get_occupation_outlook for a current-year median wage snapshot instead.
  • Employment Projections is not a time series — one base year + one projection year (currently ~10 years out), updated at most twice a year.
  • Annual openings figures include replacement demand (workers exiting or transferring out), not just net employment growth — a common misreading.
  • No official BLS series-search API exists. search_indicators and search_occupations are backed by a catalog derived from BLS's own flat files and cross-validated during the build (see scripts/build-catalog.ts), not hand-typed or guessed.

Attribution

Every BLS-derived response carries the retrieval timestamp and the exact disclaimer required by BLS's Terms of Service: "BLS.gov cannot vouch for the data or analyses derived from these data after the data have been retrieved from BLS.gov." FRED-derived responses carry their own source attribution.

Anything this server computes (percent change, CAGR, month-over-month deltas) is returned under a separate computedByServer field, explicitly labeled as server-calculated — never presented as an official BLS or FRED statistic. Tool instructions direct Claude to preserve both when answering.

Security model

  • Read-only. No tool mutates state or accepts a caller-supplied URL.
  • Secret-path authentication. The endpoint is /mcp/<256-bit token>. Claude's connector UI accepts a URL but not custom headers, so the credential lives in the path. Comparison is constant-time over SHA-256 digests; every failure (wrong token, missing token, unknown route) returns an identical 404 — no oracle for guessing.
  • Inbound rate limiting. ~60 requests/minute per IP (cf-connecting-ip, set by Cloudflare and unspoofable by the client), checked before auth so a flood can't spend CPU on token comparison. Backed by Workers KV; fails open (allows) if KV isn't bound.
  • Outbound BLS budget guard. A circuit breaker defaulting to 450 of BLS's 500/day registered-key quota — exhausting it fails the call before any network request, protecting the real quota from a runaway loop.
  • Secrets never leave the server. BLS_API_KEY, FRED_API_KEY, and MCP_PATH_TOKEN live only as Workers secrets — never returned in a tool response, never logged. src/lib/logging.ts redacts known secret values and any api_key=/registrationkey= pattern from every log record; this is asserted by unit tests, not just intended.
    • Known limitation: Cloudflare's own platform request logs (and wrangler tail) record the full request URL, including the path token — this is outside application code's control. Don't share raw log output publicly; rotate the token (wrangler secret put MCP_PATH_TOKEN, then re-paste the new URL into Claude) if you ever do.

Caching

Workers KV, two-tier: a "fresh" entry per the TTL table below, plus a 35-day "stale backup" written alongside every success. If a live call fails or the BLS budget is exhausted, the stale backup is served instead of failing outright — flagged explicitly in the response's limitations field so Claude never presents stale data as current without saying so.

Data TTL Why
Employment Projections / OEWS 30 days Updated at most twice a year
BLS surveys / popular-series lists 7 days Near-static
FRED search 24 hours Stable
Monthly series (CES/CPS/JOLTS) 6 hours Monthly releases
fred_get_latest 1 hour Freshness matters most here

Cache keys are derived only from the tool name and its arguments — never from environment or secrets — so no key material can leak into a cache key.

Project structure

src/
  index.ts               Worker entry: routing, auth, rate limiting
  server.ts               MCP server construction + tool registration
  env.ts                  Env typing + secret names
  errors.ts                Typed error hierarchy (network/timeout/429/5xx/BLS-200-with-error-body)
  sources/
    http.ts               Shared fetch: timeout, retry/backoff
    bls.ts                BLS v2 client
    fred.ts               FRED client
  catalog/
    occupations.json      1,113 SOC occupations -> EP series ID (build-generated, validated)
    industries.json        423 EP industries -> series ID (build-generated, validated)
    indicators.ts           ~13 curated headline indicators (individually live-verified)
    search.ts               Shared token-matching + relevance-ranking search
  tools/
    source/                Thin passthrough tools
    research/               Composed analysis tools
  lib/
    cache.ts               Workers KV two-tier cache
    ratelimit.ts             BLS daily budget guard + inbound per-IP limiter
    envelope.ts              Response envelope: citations, timestamps, disclaimers
    stats.ts                 Deterministic trend math
    logging.ts                Structured logs with secret redaction
scripts/
  build-catalog.ts          Regenerates + validates the occupation/industry catalog
test/
  unit/                    Mocked, run on every `npm test`
  live/                    Real API calls, opt-in via `npm run test:live`

Local development

npm install
cp .dev.vars.example .dev.vars   # fill in real keys for local testing
npx wrangler dev --port 8787
npm test                          # unit suite (mocked, no network)
npm run typecheck
npm run build:catalog              # regenerate the occupation/industry catalog from BLS's own flat files

To verify against real BLS/FRED data locally (never commits or logs the keys):

BLS_API_KEY=your_key FRED_API_KEY=your_key npm run test:live

Deployment

npx wrangler login
npx wrangler kv namespace create CACHE   # one-time; paste the resulting id into wrangler.toml
npx wrangler secret put BLS_API_KEY
npx wrangler secret put FRED_API_KEY
npx wrangler secret put MCP_PATH_TOKEN     # generate with: openssl rand -hex 32
npx wrangler deploy
curl https://<your-worker>.<your-subdomain>.workers.dev/health

Secrets and the KV binding persist across wrangler deploy — you only set them once, not on every deploy.

Known limitations

  • Employment Projections and OEWS are single-reference-year snapshots, not time series — every research tool explicitly detects and reports this (trend: null with an explanatory limitation) rather than fabricating a trend from one datapoint.
  • No verified crosswalk exists between BLS Employment Projections' industry codes and BLS's monthly CES industry employment series (different classification schemes) — analyze_industry_employment covers long-run outlook only; pair it with fred_search_series + analyze_labor_market_trend for current monthly industry employment.
  • SOC occupation codes change between Employment Projections vintages — comparing an occupation across catalog rebuilds separated by a vintage change is not reliable.
  • The inbound rate limiter is a best-effort fixed-window counter (a read-then-write race can under-count by a request or two under heavy concurrency) — an accepted tradeoff for a low-volume personal connector, not a precision guarantee.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选