Skip to main content
Glama
VEHICLE_DATA_CONSISTENCY_ANALYSIS.mdβ€’10.3 kB
# Vehicle Data Consistency Analysis & Solutions ## Executive Summary The StockSpark MCP server has inconsistent data formats between different vehicle-related tools, causing confusion for both LLMs and developers. This document analyzes the issue and proposes three solution approaches with clear trade-offs. ## πŸ” The Problem ### Current State The MCP server exposes **two incompatible data models**: 1. **Template/User Model** (returned by `get_vehicle_version_template`): ```javascript { engine: { size: 1598, power: 143, powerHp: 194 }, // Nested seats: 7, // Plural body: "SUV" // String } ``` 2. **API Storage Model** (expected by vehicle APIs): ```javascript { cubicCapacity: 1598, // Flat power: 143, // Flat powerHp: 194, // Flat seat: 7, // Singular body: { name: "SUV", description: "SUV" } // Object } ``` ### Impact Analysis | Tool | Current Behavior | Issues | |------|-----------------|--------| | `get_vehicle` | Returns API format | βœ… Consistent | | `list_vehicles` | Returns API format | βœ… Consistent | | `get_vehicle_version_template` | Returns user format | ❌ Inconsistent with other outputs | | `add_vehicle` | Accepts both formats, converts internally | ⚠️ Hidden complexity | | `update_vehicle` | Has conversion logic for nestedβ†’flat | ⚠️ Scattered logic | ### Root Causes 1. **API Mismatch**: Template compilation API returns different format than storage API 2. **Legacy Support**: Maintaining backward compatibility with multiple formats 3. **Scattered Logic**: Conversion code duplicated across multiple tools ## 🎯 Proposed Solutions ### Solution 1: Documentation-Only Fix (Quick) **Approach**: Update tool schemas to explicitly document expected formats **Implementation**: ```javascript // Update inputSchema for update_vehicle tool { description: "Update vehicle. IMPORTANT: Use flat field structure", properties: { updates: { properties: { // Make it clear these are flat fields cubicCapacity: { description: "Engine size in cc (NOT engine.size)" }, power: { description: "Power in kW (NOT engine.power)" }, powerHp: { description: "Power in HP (NOT engine.powerHp)" }, seat: { description: "Number of seats (NOT seats - singular!)" }, body: { type: "object", description: "Body type object with name and description", properties: { name: { enum: ["SUV", "SEDAN", "ESTATE_CAR", ...] } } } } } } } ``` **Pros**: - βœ… Immediate fix - βœ… No code changes - βœ… Low risk **Cons**: - ❌ LLMs must remember different formats - ❌ Inconsistent user experience - ❌ Doesn't fix underlying problem **Effort**: 1 hour ### Solution 2: Centralized Transformation Layer (Recommended) **Approach**: Create single transformation utility used by all tools **Implementation**: ```javascript // New file: src/utils/vehicle-transformer.js class VehicleTransformer { /** * Convert user-friendly format to API format * Handles both nested and flat inputs gracefully */ static toApiFormat(data) { const result = { ...data }; // Handle engine transformation if (data.engine) { result.cubicCapacity = data.engine.size; result.power = data.engine.power; result.powerHp = data.engine.powerHp; delete result.engine; } // Handle seat/seats if (data.seats !== undefined) { result.seat = data.seats; delete result.seats; } // Handle body string β†’ object if (typeof data.body === 'string') { result.body = this.getBodyObject(data.body); } return result; } /** * Convert API format to user-friendly format * Used for all outputs to ensure consistency */ static toUserFormat(data) { return { ...data, engine: { size: data.cubicCapacity, power: data.power, powerHp: data.powerHp }, seats: data.seat, body: data.body?.name || data.body, // Remove API-specific fields cubicCapacity: undefined, seat: undefined }; } static getBodyObject(bodyString) { const bodyMap = { 'SUV': { name: 'SUV', description: 'SUV' }, 'SEDAN': { name: 'SEDAN', description: 'Berlina' }, 'ESTATE': { name: 'ESTATE_CAR', description: 'Station Wagon' }, // ... etc }; return bodyMap[bodyString.toUpperCase()] || { name: bodyString.toUpperCase(), description: bodyString }; } } ``` **Integration Points**: ```javascript // In vehicle-tools.js update_vehicle: async (args, { vehicleAPI }) => { // Transform once at entry point const apiFormat = VehicleTransformer.toApiFormat(args.updates); await vehicleAPI.updateVehicle(args.vehicleId, apiFormat); } // In get_vehicle handler get_vehicle: async (args, { vehicleAPI }) => { const vehicle = await vehicleAPI.getVehicle(args.vehicleId); // Transform once at exit point return VehicleTransformer.toUserFormat(vehicle); } ``` **Pros**: - βœ… Single source of truth - βœ… Consistent transformation - βœ… Easy to maintain - βœ… Backwards compatible **Cons**: - ⚠️ Requires updating all vehicle tools - ⚠️ Small performance overhead **Effort**: 4-6 hours ### Solution 3: Unified Data Model (Best Long-term) **Approach**: Standardize on ONE format everywhere #### Option 3A: User-Friendly Format Everywhere ```javascript // All tools use this format { engine: { size, power, powerHp }, // Always nested seats: 7, // Always plural body: "SUV" // Always string } ``` **Implementation**: 1. Update all tool outputs to use user format 2. Update all tool inputs to expect user format 3. Transform only at API client boundary 4. Update all documentation #### Option 3B: API Format Everywhere ```javascript // All tools use this format { cubicCapacity: 1598, power: 143, powerHp: 194, seat: 7, body: { name: "SUV", description: "SUV" } } ``` **Implementation**: 1. Update template tool to return API format 2. Remove all transformation logic 3. Update documentation to use API field names **Comparison**: | Aspect | User Format | API Format | |--------|-------------|------------| | **Intuitiveness** | βœ… High (engine.size) | ❌ Low (cubicCapacity) | | **Code Simplicity** | ⚠️ Medium | βœ… High | | **Performance** | ⚠️ Transformation overhead | βœ… No overhead | | **User Experience** | βœ… Better | ❌ Technical | **Recommendation**: Use **User Format** with transformation at API boundary **Pros**: - βœ… Best user experience - βœ… Consistent everywhere - βœ… Future-proof **Cons**: - ❌ Most work required - ❌ Breaking change for existing users **Effort**: 8-12 hours ## πŸ“‹ Implementation Plan ### Phase 1: Immediate (Solution 1) - [ ] Update tool documentation with explicit field formats - [ ] Add examples showing correct field names - [ ] Timeline: 1 hour ### Phase 2: Short-term (Solution 2) - [ ] Create VehicleTransformer utility class - [ ] Update critical tools (add_vehicle, update_vehicle) - [ ] Test transformation logic - [ ] Timeline: 1 week ### Phase 3: Long-term (Solution 3) - [ ] Choose unified format (recommend user-friendly) - [ ] Update all vehicle tools - [ ] Update all documentation - [ ] Add migration guide for existing users - [ ] Timeline: 2-3 weeks ## πŸ”„ Migration Strategy ### For Existing Users 1. **Phase 1**: No changes needed 2. **Phase 2**: Both formats supported (backwards compatible) 3. **Phase 3**: Deprecation notice β†’ Grace period β†’ Migration ### For New Users - Start with documented format from Phase 1 - Automatically benefit from Phase 2/3 improvements ## πŸ“Š Decision Matrix | Criteria | Solution 1 | Solution 2 | Solution 3 | |----------|------------|------------|------------| | **Implementation Effort** | 🟒 Low | 🟑 Medium | πŸ”΄ High | | **User Experience** | πŸ”΄ Poor | 🟑 Good | 🟒 Excellent | | **Maintainability** | πŸ”΄ Poor | 🟒 Good | 🟒 Excellent | | **Risk** | 🟒 Low | 🟑 Medium | πŸ”΄ High | | **Long-term Value** | πŸ”΄ Low | 🟑 Good | 🟒 Excellent | ## 🎯 Recommendation **Immediate**: Implement Solution 1 (documentation fix) TODAY **Next Sprint**: Implement Solution 2 (transformation layer) **Future Roadmap**: Plan Solution 3 (unified model) for major version ## πŸ“ Examples of Current Issues ### Issue 1: Template Output vs Update Input ```javascript // What get_vehicle_version_template returns: { engine: { size: 1598, power: 143, powerHp: 194 } } // What update_vehicle expects (after today's fix): { cubicCapacity: 1598, power: 143, powerHp: 194 } // LLM confusion: Why different formats? ``` ### Issue 2: Inconsistent Field Names ```javascript // Some tools return: { seats: 7 } // Plural, intuitive // Others expect: { seat: 7 } // Singular, API format // Error-prone for users ``` ### Issue 3: Scattered Conversion Logic ```javascript // In update_vehicle: if (updates.engine) { /* convert */ } // In add_vehicle: if (template.engine) { /* convert */ } // In vehicles.js: if (data.seats) { /* convert */ } // Maintenance nightmare ``` ## πŸš€ Next Steps 1. **Review** this document with team 2. **Decide** on approach based on priorities 3. **Create** implementation tickets 4. **Assign** owner for each phase 5. **Track** progress and issues ## πŸ“Œ Related Files - `src/tools/vehicle-tools.js` - Vehicle management tools - `src/tools/reference-tools.js` - Template generation - `src/api/vehicles.js` - API client for vehicles - `src/utils/mappers.js` - Current formatting utilities - `KNOWN_ISSUES.md` - Tracks this as active issue ## πŸ”— References - Original issue: Vehicle update failing with nested engine object - Error: 400 Bad Request on PUT /vehicle/{id} - Date discovered: 2025-08-20 - Temporary fix: Added conversion logic to update_vehicle handler --- **Document maintained by**: AI Assistant **Last updated**: 2025-08-20 **Status**: Awaiting decision on implementation approach

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/loukach/stockspark-mcp-poc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server