get-market-value
Retrieve the estimated market value of a vehicle using its VIN, optionally adjusting for state, mileage, and condition.
Instructions
Get the estimated market value for a vehicle by VIN
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| vin | Yes | 17-character Vehicle Identification Number | |
| state | No | US state abbreviation (optional) | |
| mileage | No | Current mileage of the vehicle used to adjust the market value (optional) | |
| condition | No | Overall condition of the vehicle: excellent, clean, average, or rough (optional) |
Implementation Reference
- src/tools/getMarketValue.ts:7-76 (registration)Registration function `registerGetMarketValueTool` which registers the 'get-market-value' tool on the MCP server with a Zod schema for vin (required), state, mileage, and condition (optional) and an async handler.
export function registerGetMarketValueTool( server: McpServer, getApiKey: () => string | null, ) { server.tool( "get-market-value", "Get the estimated market value for a vehicle by VIN", { vin: z .string() .min(17) .max(17) .describe("17-character Vehicle Identification Number"), state: z.string().optional().describe("US state abbreviation (optional)"), mileage: z .number() .optional() .describe( "Current mileage of the vehicle used to adjust the market value (optional)", ), condition: z .enum(["excellent", "clean", "average", "rough"]) .optional() .describe( "Overall condition of the vehicle: excellent, clean, average, or rough (optional)", ), }, async ({ vin, state, mileage, condition }) => { const params: Record<string, string> = { vin }; if (state) params.state = state; if (mileage !== undefined) params.mileage = String(mileage); if (condition) params.condition = condition; 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<CarsXEMarketValueResponse>( "v2/marketvalue", params, apiKey, ); if (!data) { return { content: [ { type: "text", text: "❌ Failed to retrieve market value. Please check the VIN and try again.", }, ], }; } return { content: [ { type: "text", text: formatMarketValueResponse(data), }, ], }; }, ); } - src/tools/getMarketValue.ts:34-75 (handler)Async handler that validates API key, calls the CarsXE API endpoint 'v2/marketvalue' with params (vin, state, mileage, condition), checks response, and returns formatted market value text.
async ({ vin, state, mileage, condition }) => { const params: Record<string, string> = { vin }; if (state) params.state = state; if (mileage !== undefined) params.mileage = String(mileage); if (condition) params.condition = condition; 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<CarsXEMarketValueResponse>( "v2/marketvalue", params, apiKey, ); if (!data) { return { content: [ { type: "text", text: "❌ Failed to retrieve market value. Please check the VIN and try again.", }, ], }; } return { content: [ { type: "text", text: formatMarketValueResponse(data), }, ], }; }, ); - src/types/carsxe.ts:125-162 (schema)Type definition `CarsXEMarketValueResponse` with fields for input, make, model, model_year, series, style, retail_*, trade_in_*, and msrp values.
export interface CarsXEMarketValueResponse { uid?: string; input: { vin: string; state?: string; country?: string; }; publish_date?: string; data_freq?: string; state?: string; country?: string; uvc?: string; group_num?: string; model_year?: string; make?: string; model?: string; series?: string; style?: string; mileage_cat?: string; class_code?: string; class_name?: string; description_score?: string; first_values_flag?: boolean; risk_score?: string; whole_xclean?: any; whole_clean?: any; whole_avg?: any; whole_rough?: any; retail_xclean?: any; retail_clean?: any; retail_avg?: any; retail_rough?: any; trade_in_clean?: any; trade_in_avg?: any; trade_in_rough?: any; msrp?: string; retail_equipped?: any; } - Helper function `formatMarketValueResponse` that formats the market value response into a human-readable string with retail/trade-in/msrp details.
export function formatMarketValueResponse( data: CarsXEMarketValueResponse, ): string { // Helper to show value or fallback to JSON string for debugging function showValue(obj: any, key: string): string { if (!obj) return "N/A"; if (obj[key] !== undefined && obj[key] !== null) return obj[key]; // fallback: show first property if exists const firstKey = obj && typeof obj === "object" ? Object.keys(obj)[0] : undefined; if (firstKey && obj[firstKey] !== undefined) return obj[firstKey]; // fallback: show JSON return JSON.stringify(obj); } return [ `💲 Vehicle Market Value`, `VIN: ${data.input?.vin}`, `Make: ${data.make}`, `Model: ${data.model}`, `Year: ${data.model_year}`, `Series: ${data.series}`, `Style: ${data.style}`, `Class: ${data.class_name}`, `State: ${data.state}`, `Country: ${data.country}`, `Publish Date: ${data.publish_date}`, `Data Frequency: ${data.data_freq}`, ``, `Retail (Excellent): ${showValue( data.retail_xclean, "adjusted_whole_xclean", )}`, `Retail (Good): ${showValue(data.retail_clean, "adjusted_whole_clean")}`, `Retail (Average): ${showValue(data.retail_avg, "adjusted_whole_avg")}`, `Retail (Rough): ${showValue(data.retail_rough, "adjusted_whole_rough")}`, ``, `Trade-In (Good): ${showValue( data.trade_in_clean, "adjusted_whole_clean", )}`, `Trade-In (Average): ${showValue(data.trade_in_avg, "adjusted_whole_avg")}`, `Trade-In (Rough): ${showValue( data.trade_in_rough, "adjusted_whole_rough", )}`, ``, `MSRP: ${data.msrp}`, // Debug: print raw objects if values are missing data.retail_xclean && typeof data.retail_xclean === "object" ? `Raw retail_xclean: ${JSON.stringify(data.retail_xclean)}` : undefined, data.retail_clean && typeof data.retail_clean === "object" ? `Raw retail_clean: ${JSON.stringify(data.retail_clean)}` : undefined, data.retail_avg && typeof data.retail_avg === "object" ? `Raw retail_avg: ${JSON.stringify(data.retail_avg)}` : undefined, data.retail_rough && typeof data.retail_rough === "object" ? `Raw retail_rough: ${JSON.stringify(data.retail_rough)}` : undefined, data.trade_in_clean && typeof data.trade_in_clean === "object" ? `Raw trade_in_clean: ${JSON.stringify(data.trade_in_clean)}` : undefined, data.trade_in_avg && typeof data.trade_in_avg === "object" ? `Raw trade_in_avg: ${JSON.stringify(data.trade_in_avg)}` : undefined, data.trade_in_rough && typeof data.trade_in_rough === "object" ? `Raw trade_in_rough: ${JSON.stringify(data.trade_in_rough)}` : undefined, ] .filter(Boolean) .join("\n"); } - src/utils/carsxeApi.ts:10-30 (helper)Generic API request helper `carsxeApiRequest` that builds URL with api key, params, and 'source=mcp', fetches from api.carsxe.com, and returns parsed JSON or null on error.
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; } }