cpsc-recalls-mcp-server

v0.1.7 pre-1.0

Search and retrieve US consumer product recalls from the CPSC (Consumer Product Safety Commission) via MCP. STDIO or Streamable HTTP.

cpsc-recalls.caseyjhand.com/mcp
claude mcp add --transport http cpsc-recalls-mcp-server https://cpsc-recalls.caseyjhand.com/mcp
codex mcp add cpsc-recalls-mcp-server --url https://cpsc-recalls.caseyjhand.com/mcp
{
  "mcpServers": {
    "cpsc-recalls-mcp-server": {
      "url": "https://cpsc-recalls.caseyjhand.com/mcp"
    }
  }
}
gemini mcp add --transport http cpsc-recalls-mcp-server https://cpsc-recalls.caseyjhand.com/mcp
{
  "mcpServers": {
    "cpsc-recalls-mcp-server": {
      "command": "bunx",
      "args": [
        "mcp-remote",
        "https://cpsc-recalls.caseyjhand.com/mcp"
      ]
    }
  }
}
{
  "mcpServers": {
    "cpsc-recalls-mcp-server": {
      "type": "http",
      "url": "https://cpsc-recalls.caseyjhand.com/mcp"
    }
  }
}
curl -X POST https://cpsc-recalls.caseyjhand.com/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2026-07-28" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}}}'

Tools

3

cpsc_search_recalls

Search consumer product recalls from the CPSC (Consumer Product Safety Commission) database. Covers toys, electronics, furniture, appliances, children's products, tools, and clothing — everything under CPSC jurisdiction. Does NOT cover food/drugs (FDA), motor vehicles/tires (NHTSA), boats (USCG), or pesticides (EPA). All filter fields are optional substring matches that combine with AND. Start with title_search when you have a product in hand — CPSC titles carry the brand, product, and hazard phrasing. For hazard-type filtering ("fire", "choking", "burn"), use hazard_search, which matches hazard text, product names, and remedy instructions in one pass. When manufacturer returns no results, try importer, retailer, or distributor: many recalls list one of those as the primary responsible org. Page past limit with offset — total_found and has_more say where the window sits in the full result set. Use cpsc_get_recall with a recall_number from results to retrieve the full record including complete description, all images, and incident reports.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "cpsc_search_recalls",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "product_name": {
      "description": "Product name to search for, e.g. \"crib\", \"space heater\", \"bicycle\". Substring match — partial names work.",
      "type": "string"
    },
    "manufacturer": {
      "description": "Manufacturer name, e.g. \"Samsung\", \"LEGO\". Substring match against the Manufacturers array. Note: many recalls list the importer or retailer as the primary org rather than the manufacturer — try importer or retailer if this returns no results.",
      "type": "string"
    },
    "retailer": {
      "description": "Retailer name, e.g. \"Walmart\", \"Target\", \"Amazon\". Substring match against the retailer narrative (which includes store name, dates sold, and price).",
      "type": "string"
    },
    "importer": {
      "description": "Importer company name. Use when searching for recalls by the company that brought the product into the US.",
      "type": "string"
    },
    "distributor": {
      "description": "Distributor company name, e.g. \"Walmart\", \"Costco\". Substring match against the Distributors array — a role distinct from retailer and importer, and populated on far fewer records.",
      "type": "string"
    },
    "title_search": {
      "description": "Keyword search within the recall Title, e.g. \"chandelier\", \"space heater\", \"inclined sleeper\". Substring match. CPSC titles name the brand, the product, and the hazard, which makes this the highest-signal single filter for most searches.",
      "type": "string"
    },
    "description_search": {
      "description": "Keyword search within the recall Description field only (does not search Title, Hazards, or remedy text). Use for product details not captured in product_name — model numbers, colors, sale channels. For hazard concepts, prefer hazard_search; for the recall headline, prefer title_search.",
      "type": "string"
    },
    "remedy": {
      "description": "Keyword search within the free-text remedy instructions, e.g. \"repair\", \"refund\", \"firmware update\". Substring match, applied upstream. This searches the remedy narrative, not the structured remedy_options enum — \"repair\" matches records whose remedy_options list only \"Refund\" but whose instructions describe a free repair kit. Combines with the other filters using AND; use hazard_search instead to match remedy text as one of several fields.",
      "type": "string"
    },
    "hazard_search": {
      "description": "Hazard or safety-concept keyword, e.g. \"fire\", \"choking\", \"burn\", \"laceration\". Applied client-side after the upstream fetch. Matches when the term appears in any of: hazard descriptions, product names, or remedy instructions (OR across the three, case-insensitive substring). Use this rather than the upstream Hazard parameter, which CPSC recognizes but never matches.",
      "type": "string"
    },
    "date_start": {
      "description": "Include only recalls on or after this date. ISO 8601 format: \"YYYY-MM-DD\". Must be a real calendar date — \"2026-02-31\" and \"2026-99-99\" are rejected.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "format": "date",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
          "description": "ISO 8601 date: \"YYYY-MM-DD\"."
        }
      ]
    },
    "date_end": {
      "description": "Include only recalls on or before this date. ISO 8601 format: \"YYYY-MM-DD\". Must be a real calendar date, and on or after date_start.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "format": "date",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
          "description": "ISO 8601 date: \"YYYY-MM-DD\"."
        }
      ]
    },
    "updated_start": {
      "description": "Include only recalls last published by CPSC on or after this date. ISO 8601 format: \"YYYY-MM-DD\". A separate axis from date_start: a 2003 recall re-published in 2025 matches updated_start \"2025-01-01\". Use to answer \"what has CPSC updated recently\". Must be a real calendar date.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "format": "date",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
          "description": "ISO 8601 date: \"YYYY-MM-DD\"."
        }
      ]
    },
    "updated_end": {
      "description": "Include only recalls last published by CPSC on or before this date. ISO 8601 format: \"YYYY-MM-DD\". Must be a real calendar date, and on or after updated_start.",
      "anyOf": [
        {
          "type": "string",
          "const": ""
        },
        {
          "type": "string",
          "format": "date",
          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
          "description": "ISO 8601 date: \"YYYY-MM-DD\"."
        }
      ]
    },
    "limit": {
      "default": 20,
      "description": "Maximum number of results to return (applied client-side — the API returns all matches). Defaults to 20.",
      "type": "integer",
      "minimum": 1,
      "maximum": 200
    },
    "offset": {
      "default": 0,
      "description": "Skip this many matching records before returning results. Combine with limit to page through total_found — e.g. limit 20 with offset 0, 20, 40. An offset at or past total_found returns an empty result set rather than an error.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗

cpsc_get_recall

Full detail for a single CPSC recall by recall number. Returns the complete record: hazard description, remedy instructions, all product variants, incident/injury reports, images, and the official CPSC recall page URL. Use after cpsc_search_recalls or cpsc_get_recent to get the full picture on a specific recall. CPSC jurisdiction: consumer products only — food, vehicles, drugs, and pesticides are covered by other agencies.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "cpsc_get_recall",
    "arguments": {
      "recall_number": "<recall_number>"
    }
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "recall_number": {
      "type": "string",
      "pattern": "^\\d{5}([a-d])?$",
      "description": "CPSC recall number. Modern records (2002–present) are 5-digit numeric, e.g. \"25043\". Historical records from 1998–2001 may have a letter suffix a–d, e.g. \"99003a\". Obtain from cpsc_search_recalls results."
    }
  },
  "required": [
    "recall_number"
  ],
  "additionalProperties": false
}
view source ↗

cpsc_get_recent

Fetch the most recent CPSC consumer product recalls, ordered newest-first. Use for "what's been recalled lately?" or a product safety feed. Always applies a date window (default: last 30 days) — without a date filter the API returns all 9,800+ records. Page past limit with offset: narrowing days cannot page, because the window is anchored to today and shrinking it drops the oldest records rather than advancing past the newest. CPSC jurisdiction: consumer products only — food, vehicles, drugs, and pesticides are covered by other agencies.

read
invocation
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "cpsc_get_recent",
    "arguments": {}
  }
}
schema
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "days": {
      "default": 30,
      "description": "Look back this many days from today. Defaults to 30. Use 7 for a weekly digest, 90 for a quarterly review.",
      "type": "integer",
      "minimum": 1,
      "maximum": 365
    },
    "limit": {
      "default": 20,
      "description": "Maximum number of recalls to return. Defaults to 20.",
      "type": "integer",
      "minimum": 1,
      "maximum": 100
    },
    "offset": {
      "default": 0,
      "description": "Skip this many recalls in the window before returning results. Combine with limit to page through total_found — e.g. limit 20 with offset 0, 20, 40. An offset at or past total_found returns an empty result set rather than an error.",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "required": [
    "days",
    "limit",
    "offset"
  ],
  "additionalProperties": false
}
view source ↗