Free VIN decoder MCP server — NHTSA, EPA, safety ratings, recalls, fuel economy, vehicle photos
The server has 9 well-intentioned tools with action verbs (decode_, validate_, lookup_, batch_, list_, save_, remove_, get_, update_) and explicit descriptions. However, there are significant gaps in schema completeness, parameter descriptions, and output documentation. Most tools have basic Zod schemas in the registration code, but critical details are missing: no documented output schemas, minimal parameter constraints (no enums, ranges, or validation rules in descriptions), and no structured error recovery guidance. The tooling is functional but lacks the rigor expected of production-grade agents. Parameter descriptions like 'VIN to look up recalls for' are terse (under 30 chars) and omit constraints. The batch_decode tool caps at 50 VINs but offers no pagination or offset support. The user_token-gated tools (list_saved_vins, save_vin, remove_saved_vin, get_output_preferences, update_output_preferences) expose authentication tokens as parameters, which violates secret-injection best practice. Error messages in the code are generic ('Invalid or expired token', 'NHTSA decode failed', 'Provide a VIN or make + model + year'), they do not guide LLM recovery. The fullReport() helper aggregates multiple external APIs but the response structure is not formally documented as a tool output schema.
Decode multiple VINs at once (up to 50).
Decode a VIN and return a comprehensive vehicle report with specs, recalls, complaints, safety ratings, fuel economy, and photos.
Get the user's VIN report output preferences.
List VINs saved by a user. Requires a user_token from /api/auth/login.
Look up recalls for a vehicle. Provide either a VIN or make/model/year.
Remove a VIN from the user's saved collection.
User tokens exposed as tool parameters (list_saved_vins, save_vin, remove_saved_vin, get_output_preferences, update_output_preferences). Credentials must never appear in tool parameters; agent traces log all parameters, exposing secrets. Use server-side secret injection via environment variables, middleware headers, or OAuth bearer tokens managed by the MCP client.
Output schemas for all tools are undocumented. The fullReport() function returns a complex object with vehicle, engine, transmission, dimensions, plant, safety_equipment, recalls, complaints, safety_ratings, fuel_economy, photos, and raw_nhtsa fields, but the agent has no formal specification of this structure. LLMs cannot plan downstream operations without knowing what fields to expect.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 51 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Save a VIN to a user's collection with an optional label.
Update which sections appear in VIN reports.
Quickly validate a VIN without calling any external APIs.
Parameter descriptions lack constraint details. Example: 'VIN to validate' (19 chars) omits format (17 characters), valid character set, checksum requirement. Description should state: 'VIN must be 17 characters (alphanumeric, excluding I, O, Q); will validate VIN checksum.' Similar terse descriptions for all 9 tools.
batch_decode accepts up to 50 VINs but offers no pagination, offset, or limit parameters for future scaling. If an agent needs to batch-decode 200 VINs, it must manually chunk them in logic outside the tool. Offer limit and offset: batch_decode(vins, limit=50, offset=0) to support progressive fetching.
Error responses are generic and non-actionable. Example: 'Invalid or expired token' (24 chars) does not guide the LLM to try re-authentication, request a new token, or verify JWT format. Errors should state: 'Invalid or expired token. Request a fresh token from /api/auth/login.' Similar issues in 'NHTSA decode failed' and 'Provide a VIN or make + model + year'.
lookup_recalls accepts optional VIN or make/model/year but does not explicitly state mutually exclusive behavior in parameter descriptions. Description says 'Provide either a VIN or make/model/year' but each parameter is marked optional, leaving LLMs to infer the OR constraint. Should state in each param description: 'Required unless vin is provided' and 'Required unless vin is provided'.
update_output_preferences has 9 optional boolean parameters but no guidance on which combinations are valid. Can the agent set show_overview=false while show_engine=true? Are there interdependencies? Lack of validation rules forces LLMs to guess, risking invalid configurations.
Destructive tool (remove_saved_vin) lacks confirmation or dry-run capability. Agents make mistakes, calling remove_saved_vin without a confirmation step risks permanent data loss. Offer a confirm_remove parameter or a separate preview_remove tool.
STDIO transport only. The server uses StdioServerTransport and offers no HTTP/SSE alternative. STDIO is not remotely accessible and cannot be used by hosted MCP clients (e.g., Claude Desktop, hosted Claude). This caps protocol readiness at 50/100.