get-vehicle-recalls
Check vehicle safety recalls by entering a 17-character VIN to identify open recalls.
Instructions
Get vehicle recall information by VIN
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vin | Yes | 17-character Vehicle Identification Number |
Implementation Reference
- src/tools/getVehicleRecalls.ts:7-61 (handler)The `registerGetVehicleRecallsTool` function registers the 'get-vehicle-recalls' MCP tool. It accepts a VIN, calls the CarsXE API endpoint 'v1/recalls', and formats the response using `formatRecallsResponse`. It handles missing API keys and failed API calls with error messages.
export function registerGetVehicleRecallsTool( server: McpServer, getApiKey: () => string | null, ) { server.tool( "get-vehicle-recalls", "Get vehicle recall information by VIN", { vin: z .string() .min(17) .max(17) .describe("17-character Vehicle Identification Number"), }, async ({ vin }) => { const apiKey = getApiKey(); if (!apiKey) { return { content: [ { type: "text", text: "❌ API key not provided. Please ensure X-API-Key header is set.", }, ], }; } const data = await carsxeApiRequest<CarsXERecallsResponse>( "v1/recalls", { vin, }, apiKey, ); if (!data) { return { content: [ { type: "text", text: "❌ Failed to retrieve recall information. Please check the VIN and try again.", }, ], }; } return { content: [ { type: "text", text: formatRecallsResponse(data), }, ], }; }, ); } - src/types/carsxe.ts:198-234 (schema)The `CarsXERecallsResponse` interface defines the full type structure for the recalls API response, including vehicle info, recall count, and an array of recall details (NHTSA ID, component, description, risk, remedy, status, etc.).
export interface CarsXERecallsResponse { success: boolean; input?: { key?: string; vin: string; }; data?: { uuid?: string; vin?: string; manufacturer?: string; model_year?: string; make?: string; model?: string; has_recalls?: boolean; recall_count?: number; recalls?: Array<{ recall_date?: string; expiration_date?: string | null; nhtsa_id?: string; manufacturer_id?: string; recall_campaign_type?: string; recall_name?: string; component?: string; recall_description?: string; risk_description?: string; stop_sale?: boolean | null; dont_drive?: boolean | null; remedy_available?: boolean | null; recall_remedy?: string; parts_available?: boolean | null; labor_hours_min?: string | null; labor_hours_max?: string | null; recall_status?: string; }>; }; timestamp?: string; } - src/MyMCP.ts:9-9 (registration)Import of `registerGetVehicleRecallsTool` in the MyMCP agent class.
import { registerGetVehicleRecallsTool } from "./tools/getVehicleRecalls.js"; - src/MyMCP.ts:39-39 (registration)Registration call for the 'get-vehicle-recalls' tool within the MyMCP agent's `init()` method.
registerGetVehicleRecallsTool(this.server, getApiKey); - src/index.gcp.ts:10-10 (registration)Import of `registerGetVehicleRecallsTool` in the GCP HTTP server entry point.
import { registerGetVehicleRecallsTool } from "./tools/getVehicleRecalls.js"; - src/index.gcp.ts:55-55 (registration)Registration call for the 'get-vehicle-recalls' tool within the `registerAllTools` function in the GCP server entry point.
registerGetVehicleRecallsTool(server, getApiKey); - The `formatRecallsResponse` helper function formats the API response into a human-readable string with vehicle info, recall details (date, NHTSA ID, component, description, risk, remedy, status, etc.), and report timestamp.
export function formatRecallsResponse(data: CarsXERecallsResponse): string { if (!data.success || !data.data) { return "❌ Failed to retrieve recall information. Please check the VIN and try again."; } const v = data.data; const lines = [ "### 🚨 Vehicle Recall Report", `**VIN:** ${v.vin || data.input?.vin || "N/A"}`, `**Make:** ${v.make || "N/A"}`, `**Model:** ${v.model || "N/A"}`, `**Year:** ${v.model_year || "N/A"}`, `**Manufacturer:** ${v.manufacturer || "N/A"}`, "", v.has_recalls ? `**This vehicle has ${v.recall_count || 0} recall(s).**` : "✅ No recalls found for this vehicle.", "", ]; if (v.recalls?.length) { v.recalls.forEach((recall, i) => { lines.push( [ `**Recall ${i + 1}:**`, `- **Date Issued:** ${recall.recall_date || "N/A"}`, recall.expiration_date ? `- **Expiration Date:** ${recall.expiration_date}` : null, recall.nhtsa_id ? `- **NHTSA ID:** ${recall.nhtsa_id}` : null, recall.manufacturer_id ? `- **Manufacturer ID:** ${recall.manufacturer_id}` : null, recall.recall_campaign_type ? `- **Campaign Type:** ${recall.recall_campaign_type}` : null, recall.recall_name ? `- **Recall Name:** ${recall.recall_name}` : null, recall.component ? `- **Component:** ${recall.component}` : null, recall.recall_description ? `- **Description:** ${recall.recall_description}` : null, recall.risk_description ? `- **Risk:** ${recall.risk_description}` : null, recall.stop_sale !== null && recall.stop_sale !== undefined ? `- **Stop Sale:** ${recall.stop_sale ? "Yes" : "No"}` : null, recall.dont_drive !== null && recall.dont_drive !== undefined ? `- **Do Not Drive:** ${recall.dont_drive ? "Yes" : "No"}` : null, recall.remedy_available !== null && recall.remedy_available !== undefined ? `- **Remedy Available:** ${ recall.remedy_available ? "Yes" : "No" }` : null, recall.recall_remedy ? `- **Remedy:** ${recall.recall_remedy}` : null, recall.parts_available !== null && recall.parts_available !== undefined ? `- **Parts Available:** ${recall.parts_available ? "Yes" : "No"}` : null, recall.labor_hours_min ? `- **Labor Hours (Min):** ${recall.labor_hours_min}` : null, recall.labor_hours_max ? `- **Labor Hours (Max):** ${recall.labor_hours_max}` : null, recall.recall_status ? `- **Status:** ${recall.recall_status}` : null, "", ] .filter(Boolean) .join("\n"), ); }); } if (data.timestamp) { lines.push(`**Report Generated:** ${data.timestamp.split("T")[0]}`); } return lines.filter(Boolean).join("\n"); } - src/utils/carsxeApi.ts:10-30 (helper)The generic `carsxeApiRequest` helper function that makes HTTP requests to the CarsXE API base URL, appending query params (key, source, and endpoint-specific params).
export async function carsxeApiRequest<T>( endpoint: string, params: Record<string, string>, apiKey: string ): Promise<T | null> { const CARSXE_API_BASE = "https://api.carsxe.com"; const queryParams = new URLSearchParams({ key: apiKey, source: "mcp", ...params, }); const url = `${CARSXE_API_BASE}/${endpoint}?${queryParams.toString()}`; try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); return (await response.json()) as T; } catch (error) { console.error(`Error making CarsXE request to ${endpoint}:`, error); return null; } }