Skip to main content
Glama
cliwant

mcp-sam-gov

bls_timeseries

Read-only

Fetch U.S. BLS time-series data for CPI, PPI, ECI, employment, and more over a specified year range. Returns each series with explicit units and clearly flagged missing values.

Instructions

Fetch one or more BLS time-series over a year range (keyless v1 default; optional free BLS_API_KEY lifts to v2; api.bls.gov POST). At least one of series (curated enum key) or seriesId (raw ^[A-Z0-9]{1,25}$; covers 25-char OEWS IDs) is required; both may be combined. Optional startYear/endYear (defaults to active tier's span cap). Returns { series:[{ seriesId, key, meaning, units, observations:[{year, period, periodName, value:number|null, valueUnavailable:bool, footnotes:[{code,text}], latest:bool}], observationCount, coveredRange:{from,to} }] } + honest _meta. HONESTY: BLS '-' unavailable marker → value:null (NEVER 0); valueUnavailable:true on the observation + footnote reason lifted into _meta.notes so the gap is DISCLOSED, never silent. Each series carries its own units label — an ECI '…A' series is a 12-month PERCENT CHANGE, NOT an index level; CPI/PPI are index levels; CES nonfarm employment is thousands of persons. Do NOT compare values across series without reading each units label. status !== 'REQUEST_SUCCEEDED' THROWS: REQUEST_NOT_PROCESSED (v1 daily limit) → rate_limited retryable; REQUEST_FAILED → upstream_unavailable. Series count refused over active tier cap (v1: 25 series/~10yr; v2: 50 series/~20yr) — overflow is NEVER silently dropped. Span is CLAMPED to tier cap before the fetch and disclosed. totalAvailable is null (batch fetch has no upstream total). A typo'd seriesId returns an empty series with 'Invalid Series' upstream message — NOT a real available series. BLS_API_KEY rides ONLY in the POST body, never URL/label/_meta/log.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
seriesNoOne or more CURATED series enum keys (typo-proof; each carries a meaning + units label): cpi_u_all (CPI-U all items NSA, index), cpi_u_core (CPI-U core NSA, index), ppi_final_demand (PPI final demand NSA, index), eci_total_comp (ECI total comp — ★12-MO % CHANGE, not an index), eci_wages (ECI wages — ★12-MO % CHANGE), unemployment_rate (SA, percent), labor_force_participation (SA, percent), employment_total_nonfarm (SA, thousands of persons), avg_hourly_earnings (SA, dollars/hour). NSA CPI-U is the escalation/EPA-clause reference. At least one of series/seriesId is required; both may be combined.
endYearNoInclusive end year (1900..2027). Default: the current year. Must be ≥ startYear.
seriesIdNoOne or more RAW BLS series IDs (power-user passthrough for the un-curatable space — OEWS area×occupation, local-area unemployment LAUCN…, SA/regional CPI variants). Charclass ^[A-Z0-9]{1,25}$ (uppercase alnum; punctuation/whitespace/lowercase rejected — SSRF + 'verify the ID' honesty). OEWS IDs are 25 chars (e.g. OEUN000000000000015125201). A raw ID has units:null (consult BLS). A nonexistent/typo'd ID returns BLS success + empty data (the ambiguity is disclosed, not asserted as 'no data'). At least one of series/seriesId is required.
startYearNoInclusive start year (1900..2027). Default: endYear − 9 (a ~10-year window). The span is CLAMPED to the active tier's cap (v1 ~10 years/query) BEFORE the request and disclosed in _meta.notes (never a silently truncated range).

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv1.14.0
    • changedInput schema / properties / seriesId / description
      Previous value: -"One or more RAW BLS series IDs (power-user passthrough for the un-curatable space — OEWS area×occupation, local-area unemployment LAUCN…, SA/regional CPI variants). Charclass ^[A-Z0-9]{1,20}$ (uppercase alnum; punctuation/whitespace/lowercase rejected — SSRF + 'verify the ID' honesty). A raw ID has units:null (consult BLS). A nonexistent/typo'd ID returns BLS success + empty data (the ambiguity is disclosed, not asserted as 'no data'). At least one of series/seriesId is required."New value: +"One or more RAW BLS series IDs (power-user passthrough for the un-curatable space — OEWS area×occupation, local-area unemployment LAUCN…, SA/regional CPI variants). Charclass ^[A-Z0-9]{1,25}$ (uppercase alnum; punctuation/whitespace/lowercase rejected — SSRF + 'verify the ID' honesty). OEWS IDs are 25 chars (e.g. OEUN000000000000015125201). A raw ID has units:null (consult BLS). A nonexistent/typo'd ID returns BLS success + empty data (the ambiguity is disclosed, not asserted as 'no data'). At least one of series/seriesId is required."
  2. Addedv1.12.0

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses far beyond annotations (readOnlyHint/openWorldHint): missing-value handling ('BLS '-' → value:null, NEVER 0'), units warnings ('ECI …A is a 12-month PERCENT CHANGE'), error conditions ('status !== REQUEST_SUCCEEDED THROWS'), tier caps ('overflow is NEVER silently dropped'), clamping, totalAvailable null, typo behavior, and API key placement. These are concrete behavioral traits that materially affect invocation and result interpretation. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded with purpose and key constraintsaren't the core. Every unique behavioral detail (honesty, units, errors, clamping, typo handling) earns its place. However, it repeats some schema content verbatim (e.g., 'At least one of series/seriesId is required; both may be combined' and the charclass) which adds length without new value. Still, it is well-structured and not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a complex tool with no output schema, yet the description fully compensates: it specifies the return shape (`series:[{seriesId, key, meaning, units, observations:[...]}]`), error statuses and retryability, tier caps and clamping, missing-value semantics, unit caveats, and even auth key transport. The only thing left to the schema is year-range boundsio, which schema already covers. Nothing an agent needs to call this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and already rich: enum meanings, units, charclass for seriesId, defaults for startYear/endYear, and the requirement that at least one of series/seriesId must be provided. The description largely restates these constraints and adds only marginal parameter-level info such as the v1/v2 cap defaults (which are also covered by schema's 'clamped to tier cap' note). It adds value in the behavioral realm, not parameter semantics, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+object+scope: 'Fetch one or more BLS time-series over a year range.' It further disambiguates from siblings by referencing raw OEWS IDs and mentioning the BLS API, making it distinct from fred_series_observations or bls_qcew. The naming of curated vs raw series also clarifies the tool's two modes of operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use curated `series` keys vs raw `seriesId` passthrough, including examples like 'OEWS area×occupation, local-area unemployment LAUCN…, SA/regional CPI variants.' It also explains v1 vs v2 key usage and span clamping. However, it does not explicitly name sibling alternatives (e.g., bls_qcew or bls_oews_wages) or state when *not* to use this tool in favor of those, stopping short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools