Skip to main content
Glama

Search U.S. federal product recalls

search_recalls
Read-only

Search the Recall Canary index of U.S. federal product recalls (FDA, FSIS, CPSC, NHTSA) by keyword, agency, severity, category, distribution state, hazard, firm, or date window. Returns up to 50 matching records per page with abbreviated content (title, firm, severity, date, and the canonical URL of each); call get_recall to fetch the full record. With a keyword, the best matches come first unless sort says otherwise. Unknown agency, severity, category, state and date values are rejected with an error message describing the allowed values. An unknown hazard or firm is also an error. Read-only.

Input Schema

NameRequiredDescriptionDefault
qNoFree-text query over one index of canonical recalls and preliminary press releases: titles, firm, product name/brand/description, agency reason text, AI summary, hazard tags, and identifiers (UPC, NDC, lot codes, recall and campaign numbers; codes match as printed or as bare digits, including typed in spaced or dashed groups). Every word must match, in any order; words of 3+ characters also match as prefixes (a 2-letter word matches itself and its plural), a plural also matches its singular, and a double-quoted run is an exact phrase. The one operator is an uppercase OR between two words, binding tighter than the implicit AND (`salmonella OR listeria cheese` = (salmonella OR listeria) AND cheese); NOT and NEAR are ordinary words. If no record matches every word, the results fall back to records matching SOME of them and the response says `relaxed: true` (with a notice): those are not confirmed matches. A `q` with more than 10 distinct words or codes is refused with a tool error, not searched in part. Results are ranked by relevance by default. A `q` with no searchable word (only symbols, punctuation or the operators OR / AND) is refused with a tool error, not browsed: omit `q` to browse by filters. Zero results is never evidence a product is unaffected: agencies print codes inconsistently, so also search the brand or product name and compare codes on the record.
toNoInclusive upper bound, YYYY-MM-DD at 23:59:59 UTC.
dateNoRelative window, resolved against the request clock. Ignored when `from` or `to` is set.
firmNoFirm slug: the firm of one recall, as the `firm.slug` value of a get_recall record, or the last part of a /firm/ page URL (for example "acme-foods"). Matches that firm's recalls and press releases. An unknown or malformed slug is an error, not a dropped filter: no search is returned.
fromNoInclusive lower bound, YYYY-MM-DD at 00:00:00 UTC.
pageNo1-based page number, 50 records per page. Values above 200 clamp to 200; reach deeper archive by narrowing the date window instead. Pass the next page number in this parameter to navigate paginated results.
sortNo`relevance` (the default when `q` is set) puts the best matches first. `recent` orders by listing date descending (the default without `q`). `severity` puts CRITICAL then MODERATE first, date descending within each band.
stateNoTwo-letter USPS code for a U.S. state or DC. Matches records distributed there or flagged nationwide. Territories are not filterable. Note the round trip: this takes a bare code such as "TX", while `distribution.geos` in the response emits ISO 3166-2 ("US-TX").
agencyNoIssuing agencies; matches any. Case-insensitive; values are uppercase.
hazardNoSingle-select hazard tag, lowercase and hyphenated, the same filter as the website hazard pages: matches records whose hazard_tags include it, press releases included. Anything else is an error.
categoryNoSingle-select product category. Case-insensitive; values are uppercase.
severityNoMatches any. The issuing agency's own level (FDA/FSIS class, NHTSA do-not-drive or park-outside warning) on one scale by a fixed rule; null when the agency gave none. A record reporting null can still match MODERATE here. CPSC records are reachable only via UNKNOWN. Preliminary press releases count as UNKNOWN: a filter without UNKNOWN excludes them. Case-insensitive; values are uppercase.

Output Schema

NameRequiredDescriptionDefault
notesYesThe caveat that absence of a match is not a clearance.
filtersYesThe filters as applied, after normalization. An unapplied filter is echoed as null or [].
licenseYesAttribution and terms (DATA-LICENSE).
noticesYesRules that narrowed or widened the results, stated in band. Empty when none apply.
relaxedYes
resultsYes
html_urlYesAbsolute URL of the human-readable page.
canonicalYesAbsolute URL of this representation.
paginationYes
api_versionYes
snapshot_atYesISO-8601 UTC response-generation time, second precision. First key on purpose.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed5 schema fields changed
    • changedInput schema / properties / category / enum
      Previous value: -[
      -  "FOOD",
      -  "DRUG",
      -  "DEVICE",
      -  "COSMETIC",
      -  "CONSUMER_PRODUCT",
      -  "VEHICLE",
      -  "AUTO_EQUIPMENT"
      -]New value: +[
      +  "FOOD",
      +  "DRUG",
      +  "BIOLOGIC",
      +  "DEVICE",
      +  "COSMETIC",
      +  "CONSUMER_PRODUCT",
      +  "VEHICLE",
      +  "AUTO_EQUIPMENT"
      +]
    • changedOutput schema / properties / filters / properties / category / enum
      Previous value: -[
      -  "FOOD",
      -  "DRUG",
      -  "DEVICE",
      -  "COSMETIC",
      -  "CONSUMER_PRODUCT",
      -  "VEHICLE",
      -  "AUTO_EQUIPMENT",
      -  null
      -]New value: +[
      +  "FOOD",
      +  "DRUG",
      +  "BIOLOGIC",
      +  "DEVICE",
      +  "COSMETIC",
      +  "CONSUMER_PRODUCT",
      +  "VEHICLE",
      +  "AUTO_EQUIPMENT",
      +  null
      +]
    • changedOutput schema / properties / results / items / properties / category / description
      Previous value: -"Known values: FOOD, DRUG, DEVICE, COSMETIC, CONSUMER_PRODUCT, VEHICLE, AUTO_EQUIPMENT."New value: +"Known values: FOOD, DRUG, BIOLOGIC, DEVICE, COSMETIC, CONSUMER_PRODUCT, VEHICLE, AUTO_EQUIPMENT."
    • addedOutput schema / properties / results / items / properties / dates
      Added value: +{
      +  "description": "Since api 2.7.0. Present when the recall's start or FDA's posted date is known.",
      +  "properties": {
      +    "began_at": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "fda_posted_at": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "began_at",
      +    "fda_posted_at"
      +  ],
      +  "type": "object"
      +}
    • addedOutput schema / properties / results / items / properties / late
      Added value: +{
      +  "description": "Since api 2.7.0. Present only when the recall is late (see get_recall `late`).",
      +  "properties": {
      +    "began_at": {
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "ended_relation": {
      +      "enum": [
      +        "same_day",
      +        "before",
      +        null
      +      ]
      +    },
      +    "retroactive": {
      +      "description": "The agency's own text says the recall was reported retroactively.",
      +      "type": "boolean"
      +    }
      +  },
      +  "required": [
      +    "began_at",
      +    "ended_relation",
      +    "retroactive"
      +  ],
      +  "type": "object"
      +}
  2. Changed3 schema fields changed
    • changedInput schema / properties / q / description
      Previous value: -"Free-text query over one index of canonical recalls and preliminary press releases: titles, firm, product name/brand/description, agency reason text, AI summary, hazard tags, and identifiers (UPC, NDC, lot codes, recall and campaign numbers; codes match as printed or as bare digits, including typed in spaced or dashed groups). Every word must match, in any order; words also match as prefixes, a plural also matches its singular, and a double-quoted run is an exact phrase. The one operator is an uppercase OR between two words, binding tighter than the implicit AND (`salmonella OR listeria cheese` = (salmonella OR listeria) AND cheese); NOT and NEAR are ordinary words. If no record matches every word, the results fall back to records matching SOME of them and the response says `relaxed: true` (with a notice): those are not confirmed matches. Results are ranked by relevance by default. A `q` with no searchable word (only symbols, punctuation or the operators OR / AND) is refused with a tool error, not browsed: omit `q` to browse by filters. Zero results is never evidence a product is unaffected: agencies print codes inconsistently, so also search the brand or product name and compare codes on the record."New value: +"Free-text query over one index of canonical recalls and preliminary press releases: titles, firm, product name/brand/description, agency reason text, AI summary, hazard tags, and identifiers (UPC, NDC, lot codes, recall and campaign numbers; codes match as printed or as bare digits, including typed in spaced or dashed groups). Every word must match, in any order; words of 3+ characters also match as prefixes (a 2-letter word matches itself and its plural), a plural also matches its singular, and a double-quoted run is an exact phrase. The one operator is an uppercase OR between two words, binding tighter than the implicit AND (`salmonella OR listeria cheese` = (salmonella OR listeria) AND cheese); NOT and NEAR are ordinary words. If no record matches every word, the results fall back to records matching SOME of them and the response says `relaxed: true` (with a notice): those are not confirmed matches. A `q` with more than 10 distinct words or codes is refused with a tool error, not searched in part. Results are ranked by relevance by default. A `q` with no searchable word (only symbols, punctuation or the operators OR / AND) is refused with a tool error, not browsed: omit `q` to browse by filters. Zero results is never evidence a product is unaffected: agencies print codes inconsistently, so also search the brand or product name and compare codes on the record."
    • changedOutput schema / properties / results / items / description
      Previous value: -"One compacted listing row. Null-valued keys are omitted, so only record_type, id, agency, url, product_count and hazard_tags are guaranteed. `title` and `reason` are not in this projection; call get_recall for the full record."New value: +"One compacted listing row. Null-valued keys are omitted, so only record_type, id, agency, url, product_count and hazard_tags are guaranteed, and every row carries `display_title` or `title`. `reason` is not in this projection; call get_recall for the full record."
    • addedOutput schema / properties / results / items / properties / title
      Added value: +{
      +  "description": "Only when `display_title` is absent (a record not yet enriched): the title recallcanary.com shows for it, from the agency record's product names and title; never the agency headline. Not model-written.",
      +  "type": "string"
      +}
  3. First observed

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and openWorldHint=false, and the description usefully corroborates with "Read-only" plus substantive extras: unknown filter values are hard errors rather than silently dropped, page values above 200 clamp, and zero results is explicitly not evidence a product is unaffected. Minor deduction because "Read-only" restates the annotation and the response envelope itself (pagination totals, relaxed notice shape) is left to the output schema.

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?

Front-loaded: capability, coverage, return shape, sibling routing, then failure modes — the agent gets the essentials in the first two sentences. Some sentences are dense run-ons (the error clause enumerating five filter families), but nothing is filler or redundant with the title.

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?

For a 12-parameter, all-optional search tool with an output schema, the description supplies exactly what structured fields cannot: relative ranking of siblings, the relaxed-fallback trust caveat, strict-failure semantics, and pagination ceiling. An agent has everything needed to choose, invoke, and interpret a call.

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 baseline is 3, but the schema descriptions here carry unusual burden and the top-level description reinforces the defaulting rule ("best matches come first unless `sort` says otherwise") and the error-on-unknown-value contract for agency/severity/category/state/hazard/firm. It adds the critical non-obvious semantics that a severity filter without UNKNOWN excludes preliminary press releases, which is a genuine trap for callers.

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?

States a specific verb and resource ("Search the Recall Canary index of U.S. federal product recalls") and enumerates the four agencies covered, which bounds scope precisely. It also names the sibling explicitly: "call get_recall to fetch the full record," so an agent can distinguish the two without opening either schema.

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

Usage Guidelines5/5

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

Goes beyond context to actual routing: browse by filters when no keyword, use get_recall for full records, and the schema's `q` documentation explains that a symbol-only query is refused and that omission of `q` is the way to browse. The relaxed-match caveat ("those are not confirmed matches") tells the agent when results are unreliable and need re-querying.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources