Skip to main content
Glama
cliwant

mcp-sam-gov

bls_oews_wages

Read-only

Retrieve BLS OEWS occupational wage and employment benchmarks for specific occupations, areas, and measures. Builds validated series IDs and batches them into one request, no API key needed.

Instructions

BLS OEWS occupational wage/employment benchmarking by area × occupation × datatype (keyless; api.bls.gov). Builds validated 25-char series IDs from structured inputs and batches them into one POST — NO year input (OEWS serves only the latest annual release). Inputs: occupation (curated enum, e.g. 'software_developer') or soc (raw 6-digit SOC, ^[0-9]{6}$ NO hyphen — at least ONE required); area (default 'national', 2-letter USPS state, or 5-digit CBSA metro code); datatype (default 'annual_mean'; annual_mean/annual_median/hourly_mean/hourly_median/employment). Returns { results:[{ area:{type,code,label}, occupation:{soc,key,label}, measure:{key,code,units}, value:number|null, valueUnavailable:bool, referenceYear, referencePeriod, footnotes, seriesId }] } + honest _meta. ★H1: OEWS is an ANNUAL point-in-time snapshot (reference May ); BLS API serves ONLY the most recent release, may lag ~1 year. NOT monthly/current-quarter. ★H2: a built-ID with no published value (occupation not surveyed or suppressed in that area) → value:null (NOT a tool error). ★H3: measure.units is set from datatype — annual_mean/annual_median=dollars/year; hourly_mean/hourly_median=dollars/hour; employment=count. NEVER mislabeled. ★H4: the API returns real numerics (no '#' top-code). area×occupation×datatype is capped at the tier's series cap (v1 25 / v2 50) and refused over-cap with the count named — never silently truncated; REQUEST_NOT_PROCESSED → rate_limited THROWS. Active tier (v1 keyless ~25/day or v2 BLS_API_KEY ~500/day) and series-cap limits disclosed.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
socNoOne or more RAW 6-digit SOC codes (the long-tail passthrough) — HYPHENLESS (use 151252, not 15-1252; the hyphen is rejected). A raw soc that matches a curated occupation is auto-labeled; otherwise key/label are null. At least one of occupation/soc is required.
areaNoOne or more geographies (default ["national"]). Each element is "national", a 2-letter USPS state code (e.g. CA, TX, DC — the curated state enum), OR a 5-digit CBSA metropolitan code (^\d{5}$, e.g. 19100 for Dallas-Fort Worth). Resolved internally to the OEWS areatype + zero-padded area code; an unknown token is rejected (invalid_input, never a malformed series ID on the wire).
datatypeNoOne or more measures (default ["annual_mean"]): annual_mean (dollars/year), annual_median (dollars/year), hourly_mean (dollars/hour), hourly_median (dollars/hour), employment (count jobs). Each row carries measure.units from this map (H3 — never mislabel).
occupationNoOne or more CURATED occupation enum keys (typo-proof; each carries an SOC + official label): all_occupations, software_developer (15-1252), computer_systems_analyst, info_security_analyst, management_analyst, project_mgmt_specialist, logistician, accountant_auditor, general_ops_manager, civil_engineer, electrical_engineer, mechanical_engineer, industrial_engineer, lawyer, technical_writer, admin_assistant. The ~830-SOC long tail is reachable via `soc`. At least one of occupation/soc is required.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Addedv1.12.0

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the annotations readOnlyHint=true and openWorldHint=true, the description discloses a wealth of extra behavior: value:null instead of an error for suppressed/unsurveyed values (H2), measure.units is deterministic per datatype (H3), the API returns real numerics with no top-code (H4), rate limits and series caps with throwing behavior, and the promise of an 'honest _meta'. These are substantive behavioral details not derivable from annotations alone.

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 long but front-loaded: the core purpose and key constraints appear before the detailed return shape and H1-H4 highlights. Every sentence carries essential caveats for a complex API. Some redundancy exists (e.g., 'NO year input' appears twice), but the structure (inputs → returns → highlighted notes) makes it navigable. It earns its length for the tool's complexity.

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?

With no output schema, the description fully specifies the return object: the result fields (area, occupation, measure, value, valueUnavailable, referenceYear, referencePeriod, footnotes, seriesId) and the '_meta' object. It also details error modes (rate_limited throws, invalid_input for unknown tokens), series caps, and the annual point-in-time nature. An agent has all necessary information to invoke the tool correctly without guessing.

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

Parameters4/5

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

Schema coverage is 100%, so the schema already describes all parameters. The description adds meaningful extra semantics: the mutual exclusivity of occupation/soc (at least one required), the 'NO hyphen' SOC constraint, the area resolution to areatype + zero-padded code with unknown tokens rejected, and the units mapping per datatype. While some details duplicate the schema, these additions clarify interpretation and edge cases enough to merit above-baseline scoring.

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 identification: 'BLS OEWS occupational wage/employment benchmarking by area × occupation × datatype'. It clearly states what data the tool returns (wages/employment from the BLS OEWS API) and differentiates it from similar siblings like bls_timeseries by emphasizing 'NO year input (OEWS serves only the latest annual release)' and 'NOT monthly/current-quarter'.

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 gives explicit when-not-to-use guidance: 'NOT monthly/current-quarter' and 'NO year input', which steers agents away from using it for time-series or historical queries. It also explains when to use occupation (curated, typo-proof) versus soc (raw long-tail passthrough) and provides defaults and required constraints. However, it never names alternative sibling tools directly, so the exclusion is clear but not fully explicit.

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