get-lien-theft
Check a vehicle's lien and theft status by VIN to assess ownership and risk.
Instructions
Get lien and theft information for a vehicle by VIN
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vin | Yes | 17-character Vehicle Identification Number |
Implementation Reference
- src/tools/getLienTheft.ts:7-60 (handler)The registerGetLienTheftTool function that registers the 'get-lien-theft' tool on the MCP server. It accepts a VIN, calls the CarsXE API /v1/lien-theft endpoint, and returns formatted lien/theft information.
export function registerGetLienTheftTool( server: McpServer, getApiKey: () => string | null, ) { server.tool( "get-lien-theft", "Get lien and theft information for a vehicle by VIN", { vin: z .string() .min(17) .max(17) .describe("17-character Vehicle Identification Number"), }, async ({ vin }) => { const params: Record<string, string> = { 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<CarsXELienTheftResponse>( "/v1/lien-theft", params, apiKey, ); if (!data || !data.success) { return { content: [ { type: "text", text: "❌ Failed to retrieve lien-theft information. Please check the VIN and try again.", }, ], }; } return { content: [ { type: "text", text: formatLienTheftResponse(data), }, ], }; }, ); } - src/types/carsxe.ts:336-361 (schema)The CarsXELienTheftResponse TypeScript interface defining the response shape for lien/theft data including success flag, input VIN, vehicle info, events, trim data, timestamp, and error info.
export interface CarsXELienTheftResponse { success: boolean; input: { vin: string; }; timestamp?: string; year?: number; make?: string; model?: string; type?: string; events?: Array<{ event: string; location?: string; details_list?: string[]; }>; trim_data?: { General?: Record<string, string>; "Passive Safety System"?: Record<string, string>; Mechanical?: Record<string, string>; Exterior?: Record<string, string>; Engine?: Record<string, string>; Interior?: Record<string, string>; [key: string]: Record<string, string> | undefined; }; error?: { code?: string; message?: string }; } - The formatLienTheftResponse function that formats the raw CarsXE lien/theft response into a human-readable string with vehicle info, events, and trim details.
export function formatLienTheftResponse(data: CarsXELienTheftResponse): string { const lines = [ `### 🔒 Lien & Theft Information`, `**VIN:** ${data.input.vin}`, data.success ? "✅ Lien/theft data retrieved." : "❌ No lien/theft data found.", "", ]; // Vehicle Information if (data.year || data.make || data.model) { lines.push("**Vehicle:**"); lines.push( `${data.year || ""} ${data.make || ""} ${data.model || ""}`.trim(), ); if (data.type) { lines.push(`**Type:** ${data.type}`); } lines.push(""); } // Events (Lien & Theft Records) if (data.events && data.events.length > 0) { lines.push("**Events:**"); data.events.forEach((event) => { lines.push(`- **${event.event}**`); if (event.location) { lines.push(` - **Location:** ${event.location}`); } if (event.details_list && event.details_list.length > 0) { event.details_list.forEach((detail) => { lines.push(` - ${detail}`); }); } lines.push(""); }); } else { lines.push("**Events:** No lien or theft events found.", ""); } // Trim Data if (data.trim_data) { lines.push("**Vehicle Details:**"); // General Information if (data.trim_data.General) { lines.push("", "**General:**"); Object.entries(data.trim_data.General).forEach(([key, value]) => { if (value) lines.push(`- **${key}:** ${value}`); }); } // Engine if (data.trim_data.Engine) { lines.push("", "**Engine:**"); Object.entries(data.trim_data.Engine).forEach(([key, value]) => { if (value) lines.push(`- **${key}:** ${value}`); }); } // Mechanical if (data.trim_data.Mechanical) { lines.push("", "**Mechanical:**"); Object.entries(data.trim_data.Mechanical).forEach(([key, value]) => { if (value) lines.push(`- **${key}:** ${value}`); }); } // Exterior if (data.trim_data.Exterior) { lines.push("", "**Exterior:**"); Object.entries(data.trim_data.Exterior).forEach(([key, value]) => { if (value && value !== "Not Applicable") { lines.push(`- **${key}:** ${value}`); } }); } // Safety if (data.trim_data["Passive Safety System"]) { lines.push("", "**Safety:**"); Object.entries(data.trim_data["Passive Safety System"]).forEach( ([key, value]) => { if (value) lines.push(`- **${key}:** ${value}`); }, ); } // Interior if (data.trim_data.Interior) { lines.push("", "**Interior:**"); Object.entries(data.trim_data.Interior).forEach(([key, value]) => { if (value) lines.push(`- **${key}:** ${value}`); }); } } if (data.timestamp) { lines.push( "", `**Timestamp:** ${new Date(data.timestamp).toLocaleString()}`, ); } if (data.error) { lines.push( "", `**Error:** ${data.error.message || "Unknown error"}`, data.error.code ? `**Error Code:** ${data.error.code}` : "", ); } return lines.join("\n"); } - src/utils/carsxeApi.ts:10-30 (helper)The carsxeApiRequest generic utility function that makes the HTTP call to the CarsXE API. Used by the get-lien-theft handler to fetch data from /v1/lien-theft.
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; } } - src/tools/getLienTheft.ts:7-60 (registration)Registration of the 'get-lien-theft' tool via server.tool() on the MCP server. Contains the tool name, description, schema, and handler callback.
export function registerGetLienTheftTool( server: McpServer, getApiKey: () => string | null, ) { server.tool( "get-lien-theft", "Get lien and theft information for a vehicle by VIN", { vin: z .string() .min(17) .max(17) .describe("17-character Vehicle Identification Number"), }, async ({ vin }) => { const params: Record<string, string> = { 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<CarsXELienTheftResponse>( "/v1/lien-theft", params, apiKey, ); if (!data || !data.success) { return { content: [ { type: "text", text: "❌ Failed to retrieve lien-theft information. Please check the VIN and try again.", }, ], }; } return { content: [ { type: "text", text: formatLienTheftResponse(data), }, ], }; }, ); }