# `bls__bls_search_series`

**Search BLS Series**

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.

- Server: [US Bureau of Labor Statistics](https://gateway.mcpharbor.dev/docs/servers/bls) (`dev.mcpharbor.gateway/bls`)
- Price per call: $0.0001 (100 micro-USD); only tools/call is charged
- Endpoint: `https://gateway.mcpharbor.dev/mcp` or `https://gateway.mcpharbor.dev/mcp/bls`
- Upstream tool: exposed by the provider; called through this gateway as `bls__bls_search_series`
- Provider terms: <https://www.bls.gov/developers/termsOfService.htm> (verified 2026-09-19)
- Upstream API documentation: <https://www.bls.gov/developers/>
- Rate limit: 450 requests per 24 hours
- Attribution required: "BLS.gov cannot vouch for the data or analyses derived from these data after the data have been retrieved from BLS.gov", plus cite BLS as source

## Parameters

- `area` (string, optional): State name, MSA name, or FIPS area code to narrow results to a geographic area. Omit for national series.
- `limit` (integer, optional): Maximum number of results to return (1–50, default 10). Default: `10`.
- `query` (string, required): Natural language or keyword query (e.g. "unemployment rate", "CPI food", "nonfarm payrolls"). Also accepts a SeriesID directly for exact lookup.
- `seasonal_adjustment` (boolean, optional): When true, return only seasonally adjusted series. When false, return only not-seasonally-adjusted. Omit to return both.
- `survey` (string, optional): 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.

## Example call

Request headers and body:

```http
POST /mcp HTTP/1.1
Host: gateway.mcpharbor.dev
Authorization: Bearer <your gateway API key>
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: bls__bls_search_series
```

```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/clientCapabilities": {},
      "io.modelcontextprotocol/clientInfo": {
        "name": "example-agent",
        "version": "1.0.0"
      },
      "io.modelcontextprotocol/protocolVersion": "2026-07-28"
    },
    "arguments": {
      "query": "example"
    },
    "name": "bls__bls_search_series"
  }
}
```

A successful response:

```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "result": {
    "_meta": {
      "dev.mcpharbor.gateway/call": {
        "chargedMicroUsd": 100,
        "id": "<the id of this charge>"
      }
    },
    "content": [
      {
        "text": "<whatever the upstream tool returned>",
        "type": "text"
      }
    ],
    "resultType": "complete"
  }
}
```

This call costs $0.0001 (100 micro-USD). Reading this page and listing the tool cost nothing.
The `dev.mcpharbor.gateway/call` record in the result is the receipt for that charge. Each
POST is metered separately, so sending the same call again buys another one: see
[agent.txt](https://gateway.mcpharbor.dev/agent.txt), section 7, before retrying.

## Attribution

This provider requires the attribution below wherever you use results from its tools.
Reproduce it verbatim:

> "BLS.gov cannot vouch for the data or analyses derived from these data after the data have been retrieved from BLS.gov", plus cite BLS as source

## Tool definition

Exactly as `tools/list` returns it (free):

```json
{
  "_meta": {
    "dev.mcpharbor.gateway/pricing": {
      "currency": "USD",
      "pricePerCallMicroUsd": 100
    }
  },
  "annotations": {
    "openWorldHint": true,
    "readOnlyHint": true
  },
  "description": "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.",
  "inputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "properties": {
      "area": {
        "description": "State name, MSA name, or FIPS area code to narrow results to a geographic area. Omit for national series.",
        "type": "string"
      },
      "limit": {
        "default": 10,
        "description": "Maximum number of results to return (1–50, default 10).",
        "maximum": 50,
        "minimum": 1,
        "type": "integer"
      },
      "query": {
        "description": "Natural language or keyword query (e.g. \"unemployment rate\", \"CPI food\", \"nonfarm payrolls\"). Also accepts a SeriesID directly for exact lookup.",
        "minLength": 1,
        "type": "string"
      },
      "seasonal_adjustment": {
        "description": "When true, return only seasonally adjusted series. When false, return only not-seasonally-adjusted. Omit to return both.",
        "type": "boolean"
      },
      "survey": {
        "description": "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.",
        "type": "string"
      }
    },
    "required": [
      "query"
    ],
    "type": "object"
  },
  "name": "bls__bls_search_series",
  "outputSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "additionalProperties": false,
    "anyOf": [
      {
        "not": {
          "required": [
            "error"
          ]
        },
        "required": [
          "series",
          "totalCount",
          "capped",
          "catalogSize",
          "effectiveQuery",
          "limitApplied"
        ]
      },
      {
        "required": [
          "error"
        ]
      }
    ],
    "properties": {
      "areaFilter": {
        "description": "Area filter applied, if any. Absent when no area filter was passed.",
        "type": "string"
      },
      "cap": {
        "description": "The result limit that capped the returned list.",
        "type": "number"
      },
      "capped": {
        "description": "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.",
        "type": "boolean"
      },
      "catalogSize": {
        "description": "Total series in the loaded catalog index. Distinguishes an empty-result search from a failed catalog load.",
        "type": "number"
      },
      "effectiveQuery": {
        "description": "Query string as the server received and searched on. Confirms interpretation for self-correction.",
        "type": "string"
      },
      "error": {
        "additionalProperties": {},
        "description": "Present when the call failed. Absent on success.",
        "properties": {
          "code": {
            "description": "JSON-RPC error code for this failure.",
            "maximum": 9007199254740991,
            "minimum": -9007199254740991,
            "type": "integer"
          },
          "data": {
            "additionalProperties": {},
            "properties": {
              "reason": {
                "description": "Machine-readable failure mode. Declared by this tool: `catalog_unavailable`: The catalog index failed to load at startup. Other values are possible when a failure originates below the handler.",
                "examples": [
                  "catalog_unavailable"
                ],
                "type": "string"
              },
              "recovery": {
                "additionalProperties": {},
                "description": "Actionable next step for the caller.",
                "properties": {
                  "hint": {
                    "type": "string"
                  }
                },
                "required": [
                  "hint"
                ],
                "type": "object"
              },
              "retryable": {
                "description": "Whether retrying may succeed.",
                "type": "boolean"
              }
            },
            "type": "object"
          },
          "message": {
            "description": "Human-readable description of what went wrong.",
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ],
        "type": "object"
      },
      "limitApplied": {
        "description": "Result limit in effect (defaults to 10 when omitted).",
        "type": "number"
      },
      "notice": {
        "description": "Guidance when no results matched — e.g. how to broaden the query or remove filters. Absent when results are returned.",
        "type": "string"
      },
      "seasonalFilter": {
        "description": "Seasonal-adjustment filter applied, if any. Absent when not passed.",
        "type": "boolean"
      },
      "series": {
        "description": "Matching series, ordered by relevance.",
        "items": {
          "additionalProperties": false,
          "description": "A matching BLS series entry.",
          "properties": {
            "area": {
              "description": "Geographic area name, when decoded.",
              "type": "string"
            },
            "item": {
              "description": "Item or subject name, when decoded.",
              "type": "string"
            },
            "seasonal": {
              "description": "Seasonality descriptor matching the data-tool form: \"Seasonally Adjusted\" or \"Not Seasonally Adjusted\".",
              "type": "string"
            },
            "seriesId": {
              "description": "BLS SeriesID — pass to bls_get_series or bls_get_latest to fetch data.",
              "type": "string"
            },
            "survey": {
              "description": "Survey abbreviation (e.g. CU, CE, LN).",
              "type": "string"
            },
            "title": {
              "description": "Plain-language series name.",
              "type": "string"
            }
          },
          "required": [
            "seriesId",
            "title",
            "survey",
            "seasonal"
          ],
          "type": "object"
        },
        "type": "array"
      },
      "shown": {
        "description": "Number of series returned in this response.",
        "type": "number"
      },
      "surveyFilter": {
        "description": "Survey filter applied, if any. Absent when no survey filter was passed.",
        "type": "string"
      },
      "totalCount": {
        "description": "Total candidates scored before the limit was applied. A lower bound when capped is true — the catalog index may contain more matching series.",
        "type": "number"
      },
      "truncated": {
        "description": "True when more candidates matched than the limit returned.",
        "type": "boolean"
      }
    },
    "type": "object"
  },
  "title": "Search BLS Series"
}
```
