Skip to main content
Glama

nhtsa-vehicle-safety-mcp-server

Nhtsa Search Recalls

nhtsa_search_recalls
Read-only

Search recall campaigns by campaign number, by vehicle, or across every campaign by make, model, model year, and received date. campaignNumber returns that campaign with every vehicle it covers; make, model, and modelYear together return that vehicle's recalls; any other combination of make, model, modelYear, and dateRange is a broad search of NHTSA's recall files, newest first, paged with limit and offset. A broad search matches a campaign when one of its vehicle records carries every vehicle filter given, and the received date it reports can fall one day before the date the other modes report for the same campaign.

Input Schema

NameRequiredDescriptionDefault
makeNoVehicle make (e.g., "Toyota"). With model and modelYear, looks up that vehicle's recalls; otherwise a broad-search filter matching the whole make name, ignoring case.
limitNoCampaigns per page of a broad search. Defaults to 20; at most 50 per page. Not accepted with campaignNumber or a full make + model + modelYear lookup, which return every match.
modelNoVehicle model. With make and modelYear, looks up that vehicle's recalls; otherwise a broad-search filter matching the whole model name, ignoring case.
offsetNoPagination offset into the newest-first results of a broad search. Defaults to 0. Not accepted with campaignNumber or a full make + model + modelYear lookup.
dateRangeNoInclusive received-date bounds in YYYY-MM-DD, in every mode; a bound alone is a broad search. Blank bounds are unset; records without a usable date are excluded only with active bounds.
modelYearNoModel year, a whole number. With make and model, looks up that vehicle's recalls; otherwise a broad-search filter.
campaignNumberNoNHTSA campaign number (e.g., "20V682000"). When provided, returns the campaign detail plus every vehicle it covers. A 6-character number (e.g., "00V419") returns every campaign it covers, each with its own detail and vehicles. Mutually exclusive with make/model/modelYear.

Output Schema

NameRequiredDescriptionDefault
errorNoPresent when the call failed. Absent on success.
limitNoBroad search only: pagination limit used for this page
noticeNoGuidance when no recalls match: for a vehicle lookup, how to list the other model names NHTSA may file its recalls under with nhtsa_lookup_vehicles operation="dataset_models"; for a broad search, which filters to relax. Also explains a date range that excluded every recall, a broad-search page past the last match, and a limit lowered to the page maximum.
offsetNoBroad search only: pagination offset used for this page
recallsNoMatching recall campaigns; in a broad search, one page of them
returnedNoBroad search only: campaigns in this page
totalCountNoTotal recalls matching criteria; in a broad search, across every page
effectiveQueryNoThe search key used: campaign number, "make model modelYear" for a vehicle lookup, or the broad-search filters as key=value pairs with make and model uppercased as matched, plus any active date bounds.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed23 schema fields changed
    • changedInput schema / properties / campaignNumber / description
      Previous value: -"NHTSA campaign number (e.g., \"20V682000\"). When provided, returns the campaign detail plus every vehicle it covers. Mutually exclusive with make/model/modelYear."New value: +"NHTSA campaign number (e.g., \"20V682000\"). When provided, returns the campaign detail plus every vehicle it covers. A 6-character number (e.g., \"00V419\") returns every campaign it covers, each with its own detail and vehicles. Mutually exclusive with make/model/modelYear."
    • changedInput schema / properties / dateRange / description
      Previous value: -"Inclusive received-date bounds in YYYY-MM-DD, in either lookup mode. Blank bounds are unset; records without a usable date are excluded only with active bounds."New value: +"Inclusive received-date bounds in YYYY-MM-DD, in every mode; a bound alone is a broad search. Blank bounds are unset; records without a usable date are excluded only with active bounds."
    • addedInput schema / properties / limit
      Added value: +{
      +  "description": "Campaigns per page of a broad search. Defaults to 20; at most 50 per page. Not accepted with campaignNumber or a full make + model + modelYear lookup, which return every match.",
      +  "minimum": 1,
      +  "multipleOf": 1,
      +  "type": "number"
      +}
    • changedInput schema / properties / make / description
      Previous value: -"Vehicle manufacturer. Required with model and modelYear when not using campaignNumber."New value: +"Vehicle make (e.g., \"Toyota\"). With model and modelYear, looks up that vehicle's recalls; otherwise a broad-search filter matching the whole make name, ignoring case."
    • changedInput schema / properties / model / description
      Previous value: -"Vehicle model. Required with make and modelYear."New value: +"Vehicle model. With make and modelYear, looks up that vehicle's recalls; otherwise a broad-search filter matching the whole model name, ignoring case."
    • changedInput schema / properties / modelYear / description
      Previous value: -"Model year, a whole number. Required with make and model."New value: +"Model year, a whole number. With make and model, looks up that vehicle's recalls; otherwise a broad-search filter."
    • addedInput schema / properties / offset
      Added value: +{
      +  "description": "Pagination offset into the newest-first results of a broad search. Defaults to 0. Not accepted with campaignNumber or a full make + model + modelYear lookup.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedOutput schema / properties / effectiveQuery / description
      Previous value: -"The search key used: campaign number, or \"make model modelYear\" for vehicle queries."New value: +"The search key used: campaign number, \"make model modelYear\" for a vehicle lookup, or the broad-search filters as key=value pairs with make and model uppercased as matched, plus any active date bounds."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `mode_conflict`: Both campaignNumber and vehicle params were provided. `missing_required_combo`: Neither campaignNumber nor a complete vehicle triple was supplied. `campaign_not_found`: The campaignNumber did not match any NHTSA recall. `invalid_date`: A dateRange bound is not a calendar-valid YYYY-MM-DD date. `inverted_date_range`: dateRange.after is later than dateRange.before. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `mode_conflict`: campaignNumber was combined with make, model, or modelYear; or limit or offset was sent with campaignNumber or a full make + model + modelYear lookup. `missing_required_combo`: No campaignNumber, make, model, modelYear, or active dateRange bound was supplied. `limit_too_large`: limit exceeds the 50-row page maximum on a server set to reject an over-maximum limit rather than lower it. `campaign_not_found`: The campaignNumber did not match any NHTSA recall. `invalid_date`: A dateRange bound is not a calendar-valid YYYY-MM-DD date. `inverted_date_range`: dateRange.after is later than dateRange.before. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "mode_conflict",
      -  "missing_required_combo",
      -  "campaign_not_found",
      -  "invalid_date",
      -  "inverted_date_range"
      -]New value: +[
      +  "mode_conflict",
      +  "missing_required_combo",
      +  "limit_too_large",
      +  "campaign_not_found",
      +  "invalid_date",
      +  "inverted_date_range"
      +]
    • addedOutput schema / properties / limit
      Added value: +{
      +  "description": "Broad search only: pagination limit used for this page",
      +  "type": "number"
      +}
    • changedOutput schema / properties / notice / description
      Previous value: -"Guidance when no recalls are found — e.g. how to verify make/model/year spelling."New value: +"Guidance when no recalls match: for a vehicle lookup, how to list the other model names NHTSA may file its recalls under with nhtsa_lookup_vehicles operation=\"dataset_models\"; for a broad search, which filters to relax. Also explains a date range that excluded every recall, a broad-search page past the last match, and a limit lowered to the page maximum."
    • addedOutput schema / properties / offset
      Added value: +{
      +  "description": "Broad search only: pagination offset used for this page",
      +  "type": "number"
      +}
    • changedOutput schema / properties / recalls / description
      Previous value: -"Matching recall campaigns"New value: +"Matching recall campaigns; in a broad search, one page of them"
    • changedOutput schema / properties / recalls / items / properties / component / description
      Previous value: -"Affected component (vehicle-scoped queries)"New value: +"Affected component. A broad search joins all of the campaign's components with \" | \"."
    • changedOutput schema / properties / recalls / items / properties / consequence / description
      Previous value: -"Safety consequence"New value: +"Safety consequence. Omitted for older campaigns whose record leaves it blank."
    • changedOutput schema / properties / recalls / items / properties / overTheAirUpdate / description
      Previous value: -"OTA update availability when provided by NHTSA"New value: +"OTA update availability when provided by NHTSA. Never set by a broad search: NHTSA's recall files carry no such flag."
    • changedOutput schema / properties / recalls / items / properties / potentialUnitsAffected / description
      Previous value: -"Units affected (campaign queries)"New value: +"Units affected (campaign queries and broad searches)"
    • changedOutput schema / properties / recalls / items / properties / remedy / description
      Previous value: -"Corrective action"New value: +"Corrective action. Omitted for older campaigns whose record leaves it blank."
    • changedOutput schema / properties / recalls / items / properties / summary / description
      Previous value: -"Recall summary"New value: +"Recall summary. Omitted for older campaigns whose record leaves it blank."
    • changedOutput schema / properties / recalls / items / required
      Previous value: -[
      -  "campaignNumber",
      -  "manufacturer",
      -  "summary",
      -  "consequence",
      -  "remedy",
      -  "reportReceivedDate"
      -]New value: +[
      +  "campaignNumber",
      +  "manufacturer",
      +  "reportReceivedDate"
      +]
    • addedOutput schema / properties / returned
      Added value: +{
      +  "description": "Broad search only: campaigns in this page",
      +  "type": "number"
      +}
    • changedOutput schema / properties / totalCount / description
      Previous value: -"Total recalls matching criteria"New value: +"Total recalls matching criteria; in a broad search, across every page"
  2. Changed5 schema fields changed
    • changedInput schema / properties / dateRange / description
      Previous value: -"Filter recalls by received date. Applied locally since the API lacks native date filtering."New value: +"Inclusive received-date bounds in YYYY-MM-DD, in either lookup mode. Blank bounds are unset; records without a usable date are excluded only with active bounds."
    • changedInput schema / properties / dateRange / properties / after / description
      Previous value: -"Only recalls received after this date (ISO 8601, e.g., \"2025-01-01\")."New value: +"Inclusive lower bound, a calendar date in YYYY-MM-DD. Blank means unset."
    • changedInput schema / properties / dateRange / properties / before / description
      Previous value: -"Only recalls received before this date (ISO 8601, e.g., \"2026-01-01\")."New value: +"Inclusive upper bound, a calendar date in YYYY-MM-DD. Blank means unset."
    • changedOutput schema / properties / error / properties / data / properties / reason / description
      Previous value: -"Machine-readable failure mode. Declared by this tool: `mode_conflict`: Both campaignNumber and vehicle params were provided. `missing_required_combo`: Neither campaignNumber nor a complete vehicle triple was supplied. `campaign_not_found`: The campaignNumber did not match any NHTSA recall. `invalid_date`: A dateRange bound could not be parsed as a date. Other values are possible when a failure originates below the handler."New value: +"Machine-readable failure mode. Declared by this tool: `mode_conflict`: Both campaignNumber and vehicle params were provided. `missing_required_combo`: Neither campaignNumber nor a complete vehicle triple was supplied. `campaign_not_found`: The campaignNumber did not match any NHTSA recall. `invalid_date`: A dateRange bound is not a calendar-valid YYYY-MM-DD date. `inverted_date_range`: dateRange.after is later than dateRange.before. Other values are possible when a failure originates below the handler."
    • changedOutput schema / properties / error / properties / data / properties / reason / examples
      Previous value: -[
      -  "mode_conflict",
      -  "missing_required_combo",
      -  "campaign_not_found",
      -  "invalid_date"
      -]New value: +[
      +  "mode_conflict",
      +  "missing_required_combo",
      +  "campaign_not_found",
      +  "invalid_date",
      +  "inverted_date_range"
      +]
  3. Changed6 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • addedOutput schema / anyOf
      Added value: +[
      +  {
      +    "not": {
      +      "required": [
      +        "error"
      +      ]
      +    },
      +    "required": [
      +      "recalls",
      +      "totalCount",
      +      "effectiveQuery"
      +    ]
      +  },
      +  {
      +    "required": [
      +      "error"
      +    ]
      +  }
      +]
    • addedOutput schema / properties / error
      Added value: +{
      +  "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: `mode_conflict`: Both campaignNumber and vehicle params were provided. `missing_required_combo`: Neither campaignNumber nor a complete vehicle triple was supplied. `campaign_not_found`: The campaignNumber did not match any NHTSA recall. `invalid_date`: A dateRange bound could not be parsed as a date. Other values are possible when a failure originates below the handler.",
      +          "examples": [
      +            "mode_conflict",
      +            "missing_required_combo",
      +            "campaign_not_found",
      +            "invalid_date"
      +          ],
      +          "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"
      +}
    • removedOutput schema / required
      Removed value: -[
      -  "recalls",
      -  "totalCount",
      -  "effectiveQuery"
      -]
  4. Changed9 schema fields changed
    • changedInput schema / properties / campaignNumber / description
      Previous value: -"NHTSA campaign number (e.g., \"20V682000\"). When provided, returns campaign details. Other params ignored."New value: +"NHTSA campaign number (e.g., \"20V682000\"). When provided, returns the campaign detail plus every vehicle it covers. Mutually exclusive with make/model/modelYear."
    • changedInput schema / properties / modelYear / description
      Previous value: -"Model year. Required with make and model."New value: +"Model year, a whole number. Required with make and model."
    • addedInput schema / properties / modelYear / maximum
      Added value: +9007199254740991
    • addedInput schema / properties / modelYear / minimum
      Added value: +-9007199254740991
    • changedInput schema / properties / modelYear / type
      Previous value: -"number"New value: +"integer"
    • addedOutput schema / properties / recalls / items / properties / affectedVehicles
      Added value: +{
      +  "description": "Every distinct make/model the campaign covers (campaign queries). Equipment and tire campaigns name the part here — make is the brand, model is the part — and carry no model year.",
      +  "items": {
      +    "additionalProperties": false,
      +    "description": "One vehicle covered by the campaign",
      +    "properties": {
      +      "make": {
      +        "description": "Vehicle make",
      +        "type": "string"
      +      },
      +      "model": {
      +        "description": "Vehicle model",
      +        "type": "string"
      +      },
      +      "modelYear": {
      +        "description": "Model year",
      +        "type": "number"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / recalls / items / properties / investigationId
      Added value: +{
      +  "description": "ODI investigation that preceded this campaign, when NHTSA links one (campaign queries) — pass it as nhtsaId to nhtsa_search_investigations for the full record.",
      +  "type": "string"
      +}
    • changedOutput schema / properties / recalls / items / properties / reportReceivedDate / description
      Previous value: -"Date received by NHTSA"New value: +"Date received by NHTSA (ISO YYYY-MM-DD)"
    • removedOutput schema / properties / recalls / items / properties / subject
      Removed value: -{
      -  "description": "Recall subject (campaign queries)",
      -  "type": "string"
      -}
  5. Changed3 schema fields changed
    • addedOutput schema / properties / effectiveQuery
      Added value: +{
      +  "description": "The search key used: campaign number, or \"make model modelYear\" for vehicle queries.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / notice
      Added value: +{
      +  "description": "Guidance when no recalls are found — e.g. how to verify make/model/year spelling.",
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "recalls",
      -  "totalCount"
      -]New value: +[
      +  "recalls",
      +  "totalCount",
      +  "effectiveQuery"
      +]
  6. Changed1 schema field changed
    • addedOutput schema / properties / recalls / items / description
      Added value: +"A single recall campaign"
  7. First observed

TDQS

A4.1/5.0
Behavior4/5

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

Annotations only declare readOnlyHint, so the description carries the rest and does add real behavior: broad-search result ordering (newest first), paging via limit/offset, the containment matching rule (a campaign matches when one vehicle record carries every filter), and the subtle one-day received-date discrepancy between modes. It omits default/no-argument behavior and any mention of result size or error conditions.

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?

Three sentences, front-loaded with the modes and ending on the date caveat that only appears here. The final sentence is dense and packs two distinct ideas (matching rule and date offset) into one long clause, which slightly hurts scannability but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With seven optional parameters, a nested dateRange, an output schema, and only a readOnly annotation, the description covers mode routing, paging, matching semantics, and the date quirk well. It leaves unclear what happens when the tool is called with no parameters at all and does not say how large an unfiltered broad search can be.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and each parameter already documents its mode-conditional meaning, so the description largely restates the schema's per-field rules at the composite level. It reinforces which combinations trigger which mode, which is mildly useful, but adds little semantic detail not already in the schema.

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 recall campaigns) and immediately enumerates the three access modes — campaign number, vehicle lookup, and broad filtered search — so the agent knows exactly what domain this covers versus the complaints, investigations, and safety-rating siblings.

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

Usage Guidelines4/5

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

Gives explicit mode-selection rules: campaignNumber for one campaign's detail, make+model+modelYear together for a vehicle's recalls, and any other combination for a broad newest-first search. It does not name sibling tools or say when to prefer nhtsa_search_complaints or nhtsa_search_investigations over this one, so it stops short of full alternative routing.

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.