bls-labor-mcp-server
Server Details
Fetch US Bureau of Labor Statistics data — CPI, unemployment, wages, JOLTS, and more via MCP.
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
- Repository
- cyanheads/bls-labor-mcp-server
- GitHub Stars
- 1
- Server Listing
- @cyanheads/bls-labor-mcp-server
Available Tools
6 toolsbls_dataframe_describeDescribe BLS DataframesARead-onlyIdempotentInspect
List canvas dataframes materialized by bls_get_series, with provenance (source tool, query parameters), TTL, row count, and column schema. Use before writing SQL to confirm column names. Lazy-sweeps expired tables before responding. Requires CANVAS_PROVIDER_TYPE=duckdb.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional table name (df_XXXXX_XXXXX) to describe a single dataframe. Omit to list all active dataframes. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| dataframes | No | Active dataframes for this tenant, newest first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal readOnlyHint=true and idempotentHint=true. The description adds useful behavioral context beyond annotations: it lazy-sweeps expired tables before responding and requires a specific DuckDB environment variable. This goes beyond the annotation baseline without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four short, information-dense sentences with no fluff. The primary action and return contents are front-loaded, followed by usage context, behavioral notes, and environment prerequisites. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter, a full output schema, strong annotations, and clear sibling context, the description is complete. It covers what the tool lists, why and when to use it, a side-effect behavior, and a required environment setting. Nothing important is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the optional 'name' parameter, its expected format (df_XXXXX_XXXXX), and the omit-to-list-all behavior. The description adds no additional parameter-level meaning beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a specific resource ('canvas dataframes materialized by bls_get_series'), and the exact metadata returned (provenance, TTL, row count, column schema). This clearly distinguishes it from sibling query tools like bls_dataframe_query and from data-fetching tools like bls_get_series.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage context: 'Use before writing SQL to confirm column names.' It also notes an environment requirement (CANVAS_PROVIDER_TYPE=duckdb). It does not explicitly name alternatives or state when not to use the tool, but the intended placement before SQL writing is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bls_dataframe_queryQuery BLS DataframesARead-onlyIdempotentInspect
Run a single-statement SELECT against the canvas dataframes registered by bls_get_series. Read-only: writes, DDL, DROP, COPY, PRAGMA, ATTACH, and external-file table functions are rejected. System catalogs (information_schema, pg_catalog, sqlite_master, duckdb_*) are denied at the bridge layer — use bls_dataframe_describe to list available dataframes. Supports JOINs, aggregates, window functions, and CTEs. Optional register_as persists the result as a new dataframe with a fresh TTL for chained analysis. Canvas SQL operations consume zero BLS API quota. Requires CANVAS_PROVIDER_TYPE=duckdb.
| Name | Required | Description | Default |
|---|---|---|---|
| sql | Yes | Single-statement SELECT against df_<id> tables on the shared canvas. Reference dataframes by the names returned in bls_get_series responses or listed by bls_dataframe_describe. Standard DuckDB SQL — joins, aggregates, window functions, CTEs all supported. Example: SELECT series_id, year, period, value FROM df_AAAAA_BBBBB WHERE year >= '2020' ORDER BY year DESC. | |
| preview | No | Inline row preview count. Defaults to row_limit. Set lower (e.g. 50) when chaining via register_as and only a sample is needed immediately. | |
| row_limit | No | Hard cap on rows materialized in the response (default 1000, max 10000). Full results live on-canvas under register_as when provided. | |
| register_as | No | When set, persist the query result as a new dataframe under this name. Fresh TTL — not inherited from parent tables. Use to chain analyses without re-running source SQL or consuming additional BLS quota. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The preview or row_limit cap that was applied. |
| rows | No | Materialized rows, bounded by preview / row_limit. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of rows returned inline. |
| notice | No | Guidance when results were capped by preview or row_limit — names which parameter was the binding limiter and suggests how to retrieve the rest. Absent when all rows fit in the response. |
| columns | No | Column names in projection order. |
| row_count | No | Rows materialized by the query. Exact when register_as is used; otherwise equals row_limit when truncated is true. |
| truncated | No | True when the returned rows were capped. |
| expires_at | No | ISO 8601 expiry for the newly registered dataframe, when applicable. |
| registered_as | No | Set when register_as was supplied and the result was materialized. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, but the description adds substantial context: the specific rejected operations (writes, DDL, DROP, COPY, PRAGMA, ATTACH, external-file functions), denial of system catalogs at the bridge layer, the requirement for CANVAS_PROVIDER_TYPE=duckdb, support for JOINs/aggregates/window functions/CTEs, and the fresh TTL behavior for register_as. This goes well beyond the annotations and gives an agent a clear model of what the tool can and cannot do.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is multi-sentence but every sentence earns its place: purpose, restrictions, catalog denial, supported features, register_as, quota, and environment. It is front-loaded with the primary purpose and then logically expands. It is slightly dense but well-organized, with no filler. A very minor reduction in length could improve scannability, but it is effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex SQL query tool with four parameters and an output schema, the description is thorough. It covers how to reference dataframes, what SQL features are supported, security restrictions, the environment requirement, and chaining via register_as. The existence of an output schema covers return format. Nothing critical is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so each parameter has a description. The description adds extra value: it clarifies that dataframes are referenced as df_<id> tables derived from bls_get_series responses, and that register_as creates a dataframe with a fresh TTL not inherited from parents. It also mentions chaining and quota-free operation. These additions enhance understanding beyond the schema, though the schema already covers the basics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Run a single-statement SELECT against the canvas dataframes registered by bls_get_series.' It clearly distinguishes itself from sibling tools by focusing on querying existing dataframes, and it explicitly points to bls_dataframe_describe for listing available dataframes. The read-only scope and supported SQL features are unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to use bls_dataframe_describe to list dataframes, providing an alternative for a different purpose. It also states that Canvas SQL operations consume zero BLS API quota, implying a cost advantage over re-fetching via bls_get_series. It mentions the CANVAS_PROVIDER_TYPE=duckdb prerequisite. It does not explicitly say when not to use this tool versus siblings, but the context is clear enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bls_get_latestGet Latest BLS ObservationARead-onlyIdempotentInspect
Return the single most recent observation for one or more BLS series. Use for "what is X right now" questions — the current unemployment rate, the latest CPI reading, etc. Each series consumes one API query against the 500/day limit; for the current value of many series, bls_get_series with a 1-year window is more quota-efficient (one query for up to 50 series). Recommended limit: 10 series; maximum: 50.
| Name | Required | Description | Default |
|---|---|---|---|
| series_ids | Yes | One or more BLS SeriesIDs (1–50). Each consumes one daily API query. Use bls_search_series to resolve concepts to SeriesIDs. Recommended: ≤10 series. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| failed | No | Series that failed to fetch. Inspect seriesId and error for per-item details. Not-found series appear here rather than as a tool-level error. |
| notice | No | Guidance when one or more series failed — e.g. to use bls_search_series to verify SeriesIDs. Absent when all series returned data. |
| results | No | Successfully fetched series with their latest observations. Series that failed appear in failed[] instead. |
| succeeded | No | Number of series with a successfully fetched observation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readOnly, openWorld, and idempotent traits, lowering the burden on the description. The description adds useful behavioral context beyond annotations: each series consumes one API query against the 500/day limit and the tool returns only the single most recent observation. This goes beyond the structured metadata without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences with no filler, front-loading the core function first, then use case, quota behavior, and the alternative path. Every sentence earns its place and directly helps an agent decide whether and how to invoke the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool with an output schema and safety annotations, the description covers everything needed: what it returns, when to use it, quota implications, limits, and when to prefer an alternative. Nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The tool description restates quota and limit information already present in the schema description but does not materially add new parameter-level meaning. The schema fully documents series_ids, min/max, and the per-query cost, so no additional compensation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Return the single most recent observation for one or more BLS series.' It is immediately clear how this differs from sibling tools, especially bls_get_series, which the description explicitly contrasts. No ambiguity remains about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly assigns this tool to 'what is X right now' questions and advises using bls_get_series with a 1-year window when many series are needed for quota efficiency. It also provides recommended and maximum series counts, giving the agent concrete selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bls_get_seriesGet BLS Time-Series DataARead-onlyInspect
Fetch time-series data for 1–50 BLS series by SeriesID in a single API request (one query against the 500/day limit). Supports optional year range (up to 20 years per request) and BLS-computed period-over-period calculations (net change and percent change; a survey returns whichever it supports and silently omits the rest — CPI and PPI return percent change only, the inflation rate). BLS can publish a '-' missing-value sentinel; check observation.available before arithmetic. Set annual_average to add each year's annual-average row, which is that year's mean rather than an additional period. When the total observation count would exceed the inline context budget, results spill to a canvas dataframe and the response includes a dataset.name handle. Call bls_dataframe_describe with that name to inspect the dataframe schema, then use the name in bls_dataframe_query SQL. Use bls_search_series first if you need to resolve a concept to a SeriesID.
| Name | Required | Description | Default |
|---|---|---|---|
| end_year | No | End year for the data range (inclusive). Defaults to the current year when omitted. | |
| series_ids | Yes | One or more BLS SeriesIDs (1–50). The entire batch counts as one API query. Use bls_search_series to resolve concepts to SeriesIDs. | |
| start_year | No | Start year for the data range (inclusive). The BLS API allows up to 20 years per request. Omit for the API default (typically 3–20 years depending on survey). | |
| calculations | No | When true, request BLS-computed period-over-period calculations. The flag is a single boolean (you cannot select an individual calculation type), but the API returns whichever the survey supports and omits the rest — CPI and PPI return percent change only (the inflation rate), and a survey that supports neither simply returns its observations without calculation fields. Requesting calculations never fails, so it is always safe to set; consult bls_list_surveys (allowsNetChange / allowsPercentChange) only to predict which fields will come back. Monthly-cadence series return each supported change type over 1, 3, 6, and 12-month intervals; other cadences return a subset. | |
| annual_average | No | When true, add each year's annual-average row to the observations. An annual average is the mean of that year's real periods, returned as an extra row named "Annual" with period M13 (monthly series), Q05 (quarterly) or S03 (semiannual) — not an additional month or quarter, so it must be excluded from any sum or average over observations. Defaults to false, which returns real periods only; check available before aggregating. Independent of start_year/end_year. Surveys that publish no annual averages return the same rows either way; enrichment.annualAverageRows reports how many rows were actually added. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| notice | No | Guidance for agents — names any SeriesID that returned zero observations, and reports the bls_dataframe_describe then bls_dataframe_query workflow when results spill to canvas. Absent when every requested series returned data and it all fit inline. |
| series | No | Series data, in request order. |
| dataset | No | Canvas dataframe handle — present when the observation volume exceeded the inline budget. Call bls_dataframe_describe with dataset.name to inspect column_schema, then use that table name in bls_dataframe_query SQL across the full data. |
| spilled | No | True when results spilled to canvas due to inline budget overflow. |
| endYearApplied | No | End year in effect, when a range was requested. |
| seriesRequested | No | Number of SeriesIDs requested. Do not compare it against series[] length to find empty series — a SeriesID that returned no data is still listed in series[] with observationCount 0. Check observationCount per entry, or read notice, which names every SeriesID that came back empty. |
| startYearApplied | No | Start year in effect, when a range was requested. |
| annualAverageRows | No | How many observations across all series are annual-average rows (period M13/Q05/S03). Present only when annual_average is true; 0 means none of the requested surveys publish annual averages. |
| totalObservations | No | Total observation rows across all requested series. |
| calculationsApplied | No | Whether BLS net/percent-change calculations were requested. |
| annualAverageApplied | No | Whether annual-average rows were requested. When false, observations hold real periods only; filter on available before aggregation. |
| availableObservations | No | Rows with a published numeric value. |
| unavailableObservations | No | Rows carrying the BLS "-" missing-value sentinel. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint and openWorldHint, but the description adds substantial non-obvious behavior: BLS '-' missing-value sentinels, surveys silently omitting unsupported calculation types, annual-average rows being means rather than periods, and spill-to-dataframe conditions. These disclosures go well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but strongly front-loaded and organized by decision-relevant topics: limits, missing values, calculation semantics, annual averages, spill handling, and searching. A few details duplicate the parameter schema and could be tightened, but the density is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to explain return values, and it covers all essential calling concerns: batch composition, year limits, calculation behavior, missing-value handling, annual-average gotchas, and dataframe spill workflows. Nothing essential for correct selection or invocation appears missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description still adds operational meaning such as the 500/day budget, the 20-year cap, the 'requesting calculations never fails' safety property, and the spill context. Some content repeats the schema, but it is not redundant enough to stay at baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Fetch time-series data for 1–50 BLS series by SeriesID in a single API request.' It clarifies the batch/SeriesID-focused scope and explicitly distinguishes itself from concept-search via bls_search_series and dataframe-handling via bls_dataframe_describe/query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit routing: use bls_search_series first to resolve concepts to SeriesIDs, and use bls_dataframe_describe/query when results spill to a canvas dataframe. It also explains the request-count implication ('one query against the 500/day limit'), helping the agent decide when batching is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bls_list_surveysList BLS SurveysARead-onlyIdempotentInspect
List BLS survey programs with their abbreviation codes, full names, and metadata about calculation support and annual averages. Use to discover which survey covers a topic before calling bls_search_series. Optional category filter narrows results to prices, employment, wages, productivity, injuries, or time_use surveys.
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Optional category filter. One of: prices, employment, wages, productivity, injuries, time_use. Omit to list all surveys. |
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Present when the call failed. Absent on success. |
| total | No | Total surveys returned. |
| surveys | No | BLS survey programs matching the filter, sorted alphabetically by abbreviation. |
| categoryFilter | No | Category filter applied, if any. Absent when all surveys were listed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint, covering safety and repeatability. The description adds value by enumerating what the response includes (abbreviation codes, full names, metadata on calculation support and annual averages) and the effect of the optional filter, which is more than the schema alone. No contradictions found.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with zero filler. The primary action and output are front-loaded, followed by usage guidance and filter behavior. Every sentence earns its place, making it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with one optional parameter and an output schema (mentioned in signals), the description covers the key aspects: what it returns, when to use it, and how to filter. No missing information that an agent would need to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents the optional category parameter, including the enum values and the 'Omit to list all surveys' behavior. The description repeats the enum values and the narrowing effect, but adds no new semantic detail beyond what the schema provides, warranting the baseline score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with 'List BLS survey programs' and immediately specifies the output: 'abbreviation codes, full names, and metadata about calculation support and annual averages.' It also contrasts with a sibling, 'before calling bls_search_series', making the tool's role in the workflow explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool: 'Use to discover which survey covers a topic before calling bls_search_series.' It also describes the optional category filter as a narrowing mechanism, giving the agent clear direction for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bls_search_seriesSearch BLS SeriesARead-onlyInspect
Search the BLS series catalog by natural language query, survey code, geographic area, or keywords to resolve cryptic SeriesIDs. Returns matching series with decoded components (survey, area, item, seasonal flag) and plain-language names. Use this before bls_get_series when you have a concept but not a SeriesID. Operates offline — no API quota consumed. Survey filter accepts two-letter codes (CU, CE, LN, LA, PC, JT, OE, EC, PR). Area filter accepts state names, MSA names, or FIPS area codes.
| Name | Required | Description | Default |
|---|---|---|---|
| area | No | State name, MSA name, or FIPS area code to narrow results to a geographic area. Omit for national series. | |
| limit | No | Maximum number of results to return (1–50, default 10). | |
| query | Yes | Natural language or keyword query (e.g. "unemployment rate", "CPI food", "nonfarm payrolls"). Also accepts a SeriesID directly for exact lookup. | |
| survey | No | Two-letter LABSTAT survey abbreviation to filter results (e.g. CU for CPI, CE for CES, LN for CPS, LA for LAUS, JT for JOLTS, OE for OEWS). Omit to search all loaded surveys. | |
| seasonal_adjustment | No | When true, return only seasonally adjusted series. When false, return only not-seasonally-adjusted. Omit to return both. |
Output Schema
| Name | Required | Description |
|---|---|---|
| cap | No | The result limit that capped the returned list. |
| error | No | Present when the call failed. Absent on success. |
| shown | No | Number of series returned in this response. |
| capped | No | True when the FTS candidate pool reached the internal cap (~1000). totalCount is then a lower bound, not an exact match count. Narrow the query, add survey/area filters, or use a direct SeriesID to get an exact count. |
| notice | No | Guidance when no results matched — e.g. how to broaden the query or remove filters. Absent when results are returned. |
| series | No | Matching series, ordered by relevance. |
| truncated | No | True when more candidates matched than the limit returned. |
| areaFilter | No | Area filter applied, if any. Absent when no area filter was passed. |
| totalCount | No | Total candidates scored before the limit was applied. A lower bound when capped is true — the catalog index may contain more matching series. |
| catalogSize | No | Total series in the loaded catalog index. Distinguishes an empty-result search from a failed catalog load. |
| limitApplied | No | Result limit in effect (defaults to 10 when omitted). |
| surveyFilter | No | Survey filter applied, if any. Absent when no survey filter was passed. |
| effectiveQuery | No | Query string as the server received and searched on. Confirms interpretation for self-correction. |
| seasonalFilter | No | Seasonal-adjustment filter applied, if any. Absent when not passed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description does not need to restate safety. It adds behavioral context beyond annotations: 'Operates offline — no API quota consumed,' and describes the output ('decoded components, plain-language names'). This adds useful context without redundancy, though it does not cover edge cases like no matches or error behavior, which is acceptable given the output schema coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences long, front-loads the core purpose, includes usage guidance and key parameter details, and has no filler. Every sentence contributes actionable information. It is tightly written and well-structured for an agent to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters, 1 required, and an output schema, the description is thorough. It explains what it does, when to use it, parameter specifics (survey codes, area formats), and describes the return content. Since an output schema exists, it doesn't need to detail the return structure. This is complete for an agent to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all 5 parameters with descriptions (100% coverage), so the baseline is 3. The description adds value by expanding on the survey parameter with an explicit list of accepted codes ('CU, CE, LN, LA, PC, JT, OE, EC, PR') that goes beyond the schema's examples, and it clarifies the area filter accepts state, MSA, or FIPS codes. This extra detail helps agents select correct values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states the tool's function: 'Search the BLS series catalog by natural language query, survey code, geographic area, or keywords to resolve cryptic SeriesIDs.' It identifies the specific verb (Search), resource (series catalog), and purpose (resolving SeriesIDs), and clearly distinguishes it from the sibling bls_get_series by stating when to use it instead. This is unambiguous and aimed at an agent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives direct usage guidance: 'Use this before bls_get_series when you have a concept but not a SeriesID.' This explicitly states the condition and names the alternative tool. It also notes that it operates offline and consumes no API quota, which influences tool selection. No exclusions are needed because the positive condition is precise.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user or an account that owns the GitHub organization, then choose Claim with GitHub.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
No comments yet. Be the first to start the discussion!
Related MCP Connectors
Econdata MCP — wraps BLS (Bureau of Labor Statistics) public API v2
BLS MCP — Bureau of Labor Statistics public data API (v2)
Query US Treasury national debt, interest rates, exchange rates, and fiscal datasets via MCP.
Macro data for AI agents: GDP, inflation, unemployment and more (World Bank, US BLS). No keys.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables access to Bureau of Labor Statistics (BLS) economic data including Consumer Price Index, employment statistics, and other labor market indicators. Supports fetching data series, listing available datasets, and retrieving metadata through natural language queries.4MIT
- AlicenseNot gradedqualityCmaintenanceEnables querying and retrieving official U.S. labor market and price data from the Bureau of Labor Statistics, including unemployment, CPI, PPI, and employment figures, via series search, latest observations, and popular series.14MIT
- FlicenseNot gradedqualityDmaintenanceProvides access to U.S. labor market data including employment statistics, Consumer Price Index inflation rates, and wage information. Users can query specific time series data or use shortcuts for common economic indicators like unemployment and industry-specific employment.3
- AlicenseAqualityCmaintenanceProvides curated US economic data from Treasury, FRED, BLS, BEA, and other sources through an MCP interface. Enables querying economic series, fetching data with provenance tracking, and accessing cached artifacts.9MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Each tool serves a distinct purpose: searching, listing, fetching, describing, and querying. No overlap between tools like bls_get_latest and bls_get_series, which have clear scope differences.
All tools follow the bls_verb_noun pattern in snake_case, e.g., bls_search_series, bls_get_latest, bls_dataframe_query. Consistent and predictable.
Six tools cover the essential workflow: discovery (list, search), retrieval (get_latest, get_series), and analysis (describe, query). Neither too few nor too many.
Covers the full read lifecycle from discovery to analysis. Minor gaps like a dedicated metadata tool for specific series, but search_series returns sufficient info. Overall well-scoped.