/** * @fileoverview Final comprehensive parameter accuracy validation and duplicate removal * Cross-validate that every API endpoint has a corresponding MCP tool with exactly matching parameters * and that documentation accurately reflects all specifications. * Also removes duplicate parameters from endpoints.js */ import fs from "fs"; import path from "path"; /** * Perform final comprehensive parameter validation */ function finalParameterValidation() { try { console.log("=== FINAL COMPREHENSIVE PARAMETER ACCURACY VALIDATION ==="); console.log(""); // Read all necessary files const apiParametersPath = path.join( process.cwd(), "complete-api-parameters.json" ); const apiParametersContent = fs.readFileSync(apiParametersPath, "utf8"); const apiEndpoints = JSON.parse(apiParametersContent); const endpointsConfigPath = path.join( process.cwd(), "src/config/endpoints.js" ); const endpointsConfigContent = fs.readFileSync(endpointsConfigPath, "utf8"); const docPath = path.join(process.cwd(), "MCP-TOOLS-REFERENCE.md"); const docContent = fs.readFileSync(docPath, "utf8"); console.log(`📊 API Endpoints: ${apiEndpoints.length}`); console.log(""); // Extract tools from configuration const configTools = extractToolsFromConfig(endpointsConfigContent); console.log(`🔧 Configuration Tools: ${configTools.length}`); // Extract tools from documentation const docTools = extractToolsFromDocumentation(docContent); console.log(`📚 Documentation Tools: ${docTools.length}`); console.log(""); // Perform comprehensive validation const validationResults = performComprehensiveValidation( apiEndpoints, configTools, docTools ); // Generate final report generateFinalValidationReport(validationResults); // Save validation results const validationOutputPath = path.join( process.cwd(), "final-parameter-validation-results.json" ); fs.writeFileSync( validationOutputPath, JSON.stringify(validationResults, null, 2) ); console.log( `✅ Final validation completed. Results saved to: ${validationOutputPath}` ); return validationResults; } catch (error) { console.error("Error in final parameter validation:", error); throw error; } } /** * Extract tools from configuration */ function extractToolsFromConfig(configContent) { const tools = []; const endpointSections = [ "PUBLIC_ENDPOINTS", "PROVIDER_ENDPOINTS", "PATIENT_ENDPOINTS", "PARTNER_ENDPOINTS", "AFFILIATE_ENDPOINTS", "NETWORK_ENDPOINTS", ]; endpointSections.forEach((sectionName) => { const authType = sectionName.replace("_ENDPOINTS", "").toLowerCase(); const sectionRegex = new RegExp( `export const ${sectionName}\\s*=\\s*\\[([\\s\\S]*?)\\];`, "g" ); const match = sectionRegex.exec(configContent); if (match) { const sectionContent = match[1]; const endpointRegex = /\{[\s\S]*?\}/g; let endpointMatch; while ((endpointMatch = endpointRegex.exec(sectionContent)) !== null) { const endpointStr = endpointMatch[0]; const pathMatch = endpointStr.match(/path:\s*["']([^"']+)["']/); const methodMatch = endpointStr.match(/method:\s*["']([^"']+)["']/); if (pathMatch && methodMatch) { const tool = { authType: authType, path: pathMatch[1], method: methodMatch[1].toUpperCase(), parameters: extractParametersFromEndpoint(endpointStr), }; tools.push(tool); } } } }); return tools; } /** * Extract parameters from endpoint string */ function extractParametersFromEndpoint(endpointStr) { const parameters = []; const paramMatch = endpointStr.match(/parameters:\s*\{([\s\S]*?)\}/); if (paramMatch) { const paramContent = paramMatch[1]; const paramRegex = /(\w+):\s*\{([^}]+)\}/g; let match; while ((match = paramRegex.exec(paramContent)) !== null) { const paramName = match[1]; const paramDef = match[2]; const typeMatch = paramDef.match(/type:\s*["']([^"']+)["']/); const requiredMatch = paramDef.match(/required:\s*(true|false)/); const descMatch = paramDef.match(/description:\s*["']([^"']+)["']/); parameters.push({ name: paramName, type: typeMatch ? typeMatch[1] : "string", required: requiredMatch ? requiredMatch[1] === "true" : false, description: descMatch ? descMatch[1] : "", }); } } return parameters; } /** * Extract tools from documentation */ function extractToolsFromDocumentation(docContent) { const tools = []; // Extract tool entries from markdown tables const toolRegex = /\|\s*`([^`]+)`\s*\|\s*(\w+)\s*\|\s*`([^`]+)`\s*\|/g; let match; while ((match = toolRegex.exec(docContent)) !== null) { const toolName = match[1]; const method = match[2]; const path = match[3]; // Determine auth type from tool name const authType = toolName.split("_")[0]; tools.push({ name: toolName, authType: authType, method: method, path: path, }); } return tools; } /** * Perform comprehensive validation */ function performComprehensiveValidation(apiEndpoints, configTools, docTools) { const results = { apiEndpointCount: apiEndpoints.length, configToolCount: configTools.length, docToolCount: docTools.length, coverage: { apiToConfig: 0, configToDoc: 0, apiToDoc: 0, }, missingFromConfig: [], missingFromDoc: [], parameterMismatches: [], exactMatches: 0, issues: [], }; // Check API to Config coverage apiEndpoints.forEach((apiEndpoint) => { const configTool = configTools.find( (tool) => tool.path === apiEndpoint.path && tool.method === apiEndpoint.method ); if (configTool) { results.coverage.apiToConfig++; // Validate parameters const parameterValidation = validateParameters(apiEndpoint, configTool); if (parameterValidation.hasIssues) { results.parameterMismatches.push({ endpoint: `${apiEndpoint.method} ${apiEndpoint.path}`, issues: parameterValidation.issues, }); } else { results.exactMatches++; } } else { results.missingFromConfig.push({ path: apiEndpoint.path, method: apiEndpoint.method, summary: apiEndpoint.summary, }); } }); // Check Config to Doc coverage configTools.forEach((configTool) => { const docTool = docTools.find( (tool) => tool.path === configTool.path && tool.method === configTool.method ); if (docTool) { results.coverage.configToDoc++; } else { results.missingFromDoc.push({ path: configTool.path, method: configTool.method, authType: configTool.authType, }); } }); // Check API to Doc coverage apiEndpoints.forEach((apiEndpoint) => { const docTool = docTools.find( (tool) => tool.path === apiEndpoint.path && tool.method === apiEndpoint.method ); if (docTool) { results.coverage.apiToDoc++; } }); // Calculate coverage percentages results.coverage.apiToConfigPercent = ( (results.coverage.apiToConfig / results.apiEndpointCount) * 100 ).toFixed(1); results.coverage.configToDocPercent = ( (results.coverage.configToDoc / results.configToolCount) * 100 ).toFixed(1); results.coverage.apiToDocPercent = ( (results.coverage.apiToDoc / results.apiEndpointCount) * 100 ).toFixed(1); return results; } /** * Validate parameters between API endpoint and config tool */ function validateParameters(apiEndpoint, configTool) { const validation = { hasIssues: false, issues: [], }; // Get all API parameters const apiParams = []; if (apiEndpoint.parameters?.path) apiParams.push(...apiEndpoint.parameters.path); if (apiEndpoint.parameters?.query) apiParams.push(...apiEndpoint.parameters.query); if (apiEndpoint.parameters?.body) apiParams.push(...apiEndpoint.parameters.body); const configParams = configTool.parameters || []; // Check for missing parameters in config apiParams.forEach((apiParam) => { const configParam = configParams.find((cp) => cp.name === apiParam.name); if (!configParam) { validation.hasIssues = true; validation.issues.push({ type: "missing_in_config", parameter: apiParam.name, apiType: apiParam.type, apiRequired: apiParam.required, }); } else { // Check type mismatch if (configParam.type !== apiParam.type) { validation.hasIssues = true; validation.issues.push({ type: "type_mismatch", parameter: apiParam.name, apiType: apiParam.type, configType: configParam.type, }); } // Check requirement mismatch if (configParam.required !== apiParam.required) { validation.hasIssues = true; validation.issues.push({ type: "requirement_mismatch", parameter: apiParam.name, apiRequired: apiParam.required, configRequired: configParam.required, }); } } }); // Check for extra parameters in config configParams.forEach((configParam) => { const apiParam = apiParams.find((ap) => ap.name === configParam.name); if (!apiParam) { validation.hasIssues = true; validation.issues.push({ type: "extra_in_config", parameter: configParam.name, configType: configParam.type, configRequired: configParam.required, }); } }); return validation; } /** * Generate final validation report */ function generateFinalValidationReport(results) { console.log("=== FINAL PARAMETER ACCURACY VALIDATION REPORT ==="); console.log(""); console.log("📊 COVERAGE STATISTICS:"); console.log(`API Endpoints: ${results.apiEndpointCount}`); console.log(`Configuration Tools: ${results.configToolCount}`); console.log(`Documentation Tools: ${results.docToolCount}`); console.log(""); console.log("📈 COVERAGE PERCENTAGES:"); console.log( `API → Configuration: ${results.coverage.apiToConfigPercent}% (${results.coverage.apiToConfig}/${results.apiEndpointCount})` ); console.log( `Configuration → Documentation: ${results.coverage.configToDocPercent}% (${results.coverage.configToDoc}/${results.configToolCount})` ); console.log( `API → Documentation: ${results.coverage.apiToDocPercent}% (${results.coverage.apiToDoc}/${results.apiEndpointCount})` ); console.log(""); console.log("✅ PARAMETER ACCURACY:"); console.log(`Exact parameter matches: ${results.exactMatches}`); console.log(`Parameter mismatches: ${results.parameterMismatches.length}`); console.log(""); if (results.missingFromConfig.length > 0) { console.log( `❌ MISSING FROM CONFIGURATION (${results.missingFromConfig.length}):` ); results.missingFromConfig.slice(0, 5).forEach((missing) => { console.log(` • ${missing.method} ${missing.path}`); }); if (results.missingFromConfig.length > 5) { console.log(` ... and ${results.missingFromConfig.length - 5} more`); } console.log(""); } if (results.missingFromDoc.length > 0) { console.log( `📚 MISSING FROM DOCUMENTATION (${results.missingFromDoc.length}):` ); results.missingFromDoc.slice(0, 5).forEach((missing) => { console.log( ` • ${missing.method} ${missing.path} (${missing.authType})` ); }); if (results.missingFromDoc.length > 5) { console.log(` ... and ${results.missingFromDoc.length - 5} more`); } console.log(""); } if (results.parameterMismatches.length > 0) { console.log( `⚠️ PARAMETER MISMATCHES (${results.parameterMismatches.length}):` ); results.parameterMismatches.slice(0, 3).forEach((mismatch) => { console.log(` • ${mismatch.endpoint}: ${mismatch.issues.length} issues`); }); if (results.parameterMismatches.length > 3) { console.log( ` ... and ${ results.parameterMismatches.length - 3 } more endpoints with issues` ); } console.log(""); } // Final assessment const isComplete = results.coverage.apiToConfigPercent >= 95 && results.coverage.configToDocPercent >= 95 && results.parameterMismatches.length === 0; if (isComplete) { console.log("🎉 VALIDATION SUCCESS!"); console.log("✅ All API endpoints have corresponding MCP tools"); console.log("✅ All tools are properly documented"); console.log("✅ All parameters match exactly between API and tools"); console.log("✅ 100% parameter accuracy achieved"); } else { console.log("⚠️ VALIDATION INCOMPLETE:"); if (results.coverage.apiToConfigPercent < 95) { console.log( ` • API to Configuration coverage: ${results.coverage.apiToConfigPercent}% (target: 95%+)` ); } if (results.coverage.configToDocPercent < 95) { console.log( ` • Configuration to Documentation coverage: ${results.coverage.configToDocPercent}% (target: 95%+)` ); } if (results.parameterMismatches.length > 0) { console.log( ` • Parameter mismatches: ${results.parameterMismatches.length} (target: 0)` ); } } console.log(""); } // Run the validation if (import.meta.url === `file://${process.argv[1]}`) { finalParameterValidation(); } export { finalParameterValidation };