U.S. federal product recalls from FDA, FSIS, CPSC, and NHTSA, in one schema.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Fetch the full Recall Canary record for a single U.S. federal recall, given the agency and slug returned by search_recalls. Includes the hazard description, the affected product list with lot codes and UPCs, the recommended consumer action, distribution, the agency source link, and the firm slug (`firm.slug`, with `firm.page_url` when the firm has a page) for search_recalls' `firm` filter. Also resolves preliminary agency press releases: an orphan, or a linked one that kept its own URL (its recalls in `linked_recalls`). Read-only.
The record slug from its URL, e.g. "acme-foods-peanut-butter". The 26-character ULID id is also accepted and resolves to what its URL shows (for a matched press release, often its recall).
Lowercase agency segment from the record URL. Part of the lookup key, not decoration: a correct slug under the wrong agency is a miss.
Fetch the full Recall Canary record for a single U.S. federal recall, given the agency and slug returned by search_recalls. Includes the hazard description, the affected product list with lot codes and UPCs, the recommended consumer action, distribution, the agency source link, and the firm slug (`firm.slug`, with `firm.page_url` when the firm has a page) for search_recalls' `firm` filter. Also resolves preliminary agency press releases: an orphan, or a linked one that kept its own URL (its recalls in `linked_recalls`). Read-only.
| Argument | Type | Description |
|---|---|---|
| slug* | string | The record slug from its URL, e.g. "acme-foods-peanut-butter". The 26-character ULID id is also accepted and resolves to what its URL shows (for a matched press release, often its recall). |
| agency* | string | Lowercase agency segment from the record URL. Part of the lookup key, not decoration: a correct slug under the wrong agency is a miss. |
{
"type": "object",
"required": [
"agency",
"slug"
],
"properties": {
"slug": {
"type": "string",
"maxLength": 200,
"description": "The record slug from its URL, e.g. \"acme-foods-peanut-butter\". The 26-character ULID id is also accepted and resolves to what its URL shows (for a matched press release, often its recall)."
},
"agency": {
"enum": [
"fda",
"fsis",
"cpsc",
"nhtsa",
"admin"
],
"type": "string",
"description": "Lowercase agency segment from the record URL. Part of the lookup key, not decoration: a correct slug under the wrong agency is a miss."
}
},
"additionalProperties": false
}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.
| Argument | Type | Description |
|---|---|---|
| q | string | 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. |
| to | string | Inclusive upper bound, YYYY-MM-DD at 23:59:59 UTC. |
| date | string | Relative window, resolved against the request clock. Ignored when `from` or `to` is set. |
| firm | string | Firm 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. |
| from | string | Inclusive lower bound, YYYY-MM-DD at 00:00:00 UTC. |
| page | integer | 1-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. |
| sort | string | `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. |
| state | string | Two-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"). |
| agency | array | Issuing agencies; matches any. Case-insensitive; values are uppercase. |
| hazard | string | Single-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. |
| category | string | Single-select product category. Case-insensitive; values are uppercase. |
| severity | array | Matches 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. |
{
"type": "object",
"properties": {
"q": {
"type": "string",
"maxLength": 200,
"description": "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."
},
"to": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Inclusive upper bound, YYYY-MM-DD at 23:59:59 UTC."
},
"date": {
"enum": [
"7d",
"30d",
"90d",
"year"
],
"type": "string",
"description": "Relative window, resolved against the request clock. Ignored when `from` or `to` is set."
},
"firm": {
"type": "string",
"maxLength": 100,
"description": "Firm 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."
},
"from": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Inclusive lower bound, YYYY-MM-DD at 00:00:00 UTC."
},
"page": {
"type": "integer",
"maximum": 200,
"minimum": 1,
"description": "1-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."
},
"sort": {
"enum": [
"recent",
"severity",
"relevance"
],
"type": "string",
"description": "`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."
},
"state": {
"type": "string",
"pattern": "^[A-Za-z]{2}$",
"description": "Two-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\")."
},
"agency": {
"type": "array",
"items": {
"enum": [
"FDA",
"FSIS",
"CPSC",
"NHTSA"
],
"type": "string"
},
"maxItems": 10,
"description": "Issuing agencies; matches any. Case-insensitive; values are uppercase."
},
"hazard": {
"enum": [
"undeclared-allergen",
"undeclared-milk",
"undeclared-egg",
"undeclared-peanut",
"undeclared-tree-nut",
"undeclared-wheat",
"undeclared-soy",
"undeclared-sesame",
"undeclared-fish",
"undeclared-shellfish",
"undeclared-additive",
"salmonella",
"listeria",
"e-coli",
"botulism",
"contamination",
"chemical-contamination",
"foreign-material",
"sterility",
"labeling",
"misbranding",
"potency",
"hidden-drug",
"unapproved-product",
"manufacturing-deviation",
"dissolution",
"impurity",
"specification-failure",
"packaging-defect",
"process-deviation",
"nutrient-deficiency",
"quality-defect",
"software-defect",
"device-defect",
"donor-eligibility",
"import-violation",
"no-inspection",
"fire",
"burn",
"explosion",
"carbon-monoxide",
"electric-shock",
"laceration",
"impalement",
"fall",
"tip-over",
"choking",
"ingestion",
"poisoning",
"lead-or-chemical",
"suffocation",
"strangulation",
"entrapment",
"drowning",
"crush",
"impact",
"crash",
"injury",
"do-not-drive",
"fire-risk-parked",
"vehicle-electrical",
"vehicle-equipment",
"vehicle-mobility-equipment",
"vehicle-structure",
"vehicle-power-train",
"vehicle-backup-camera",
"vehicle-lighting",
"vehicle-seat-belts",
"vehicle-suspension",
"vehicle-visibility",
"vehicle-air-bags",
"vehicle-seats",
"vehicle-brakes",
"vehicle-steering",
"vehicle-fuel-system",
"vehicle-engine",
"vehicle-tires",
"vehicle-wheels",
"vehicle-trailer-hitch",
"vehicle-latches",
"vehicle-child-seat",
"vehicle-driver-assistance"
],
"type": "string",
"description": "Single-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."
},
"category": {
"enum": [
"FOOD",
"DRUG",
"DEVICE",
"COSMETIC",
"CONSUMER_PRODUCT",
"VEHICLE",
"AUTO_EQUIPMENT"
],
"type": "string",
"description": "Single-select product category. Case-insensitive; values are uppercase."
},
"severity": {
"type": "array",
"items": {
"enum": [
"CRITICAL",
"MODERATE",
"LOW",
"UNKNOWN"
],
"type": "string"
},
"maxItems": 10,
"description": "Matches 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."
}
},
"additionalProperties": false
}