/** * @fileoverview Update MCP-TOOLS-REFERENCE.md with new endpoints * Generates comprehensive documentation for all MCP tools including new ones from api-docs.json */ import fs from 'fs'; import path from 'path'; /** * Update the MCP tools reference documentation */ function updateDocumentation() { try { console.log('=== UPDATING MCP-TOOLS-REFERENCE.md DOCUMENTATION ==='); console.log(''); // Read the categorized endpoints const categorizedPath = path.join(process.cwd(), 'categorized-endpoints.json'); const categorizedContent = fs.readFileSync(categorizedPath, 'utf8'); const categorized = JSON.parse(categorizedContent); // Read the existing documentation const docPath = path.join(process.cwd(), 'MCP-TOOLS-REFERENCE.md'); const existingDoc = fs.readFileSync(docPath, 'utf8'); console.log('Read existing documentation'); console.log('Read categorized endpoints'); console.log(''); // Calculate new totals const newCounts = { public: categorized.public.length, provider: categorized.provider.length, patient: categorized.patient.length, partner: categorized.partner.length, affiliate: categorized.affiliate.length, network: categorized.network.length }; const totalNew = Object.values(newCounts).reduce((sum, count) => sum + count, 0); console.log('New endpoint counts:'); Object.keys(newCounts).forEach(type => { console.log(` ${type.toUpperCase()}: ${newCounts[type]} endpoints`); }); console.log(` TOTAL: ${totalNew} endpoints`); console.log(''); // Generate updated documentation const updatedDoc = generateUpdatedDocumentation(existingDoc, categorized, newCounts, totalNew); // Write the updated documentation const outputPath = path.join(process.cwd(), 'MCP-TOOLS-REFERENCE-UPDATED.md'); fs.writeFileSync(outputPath, updatedDoc); console.log(`Updated documentation saved to: ${outputPath}`); console.log(''); console.log('=== UPDATE SUMMARY ==='); console.log(`Added ${totalNew} new endpoints to documentation`); console.log('- Updated overview section with new totals'); console.log('- Updated tool statistics'); console.log('- Added new tool entries for each authentication type'); console.log('- Maintained professional 6-section structure'); console.log(''); console.log('Review the updated file and then replace the original MCP-TOOLS-REFERENCE.md'); return { success: true, outputPath, totalNew }; } catch (error) { console.error('Error updating documentation:', error); throw error; } } /** * Generate updated documentation content */ function generateUpdatedDocumentation(existingDoc, categorized, newCounts, totalNew) { let updatedDoc = existingDoc; // Update the overview section updatedDoc = updateOverviewSection(updatedDoc, newCounts, totalNew); // Update tool statistics updatedDoc = updateToolStatistics(updatedDoc, newCounts, totalNew); // Add new tool sections updatedDoc = addNewToolSections(updatedDoc, categorized); return updatedDoc; } /** * Update the overview section with new totals */ function updateOverviewSection(doc, newCounts, totalNew) { // Update the main description const oldOverview = /This document provides a comprehensive reference for all MCP \(Model Context Protocol\) tools available in the Laravel Healthcare MCP Server\. The server generates \*\*650\+ total tools\*\*/; const newOverview = `This document provides a comprehensive reference for all MCP (Model Context Protocol) tools available in the Laravel Healthcare MCP Server. The server generates **${650 + totalNew}+ total tools** (including ${totalNew} new tools from api-docs.json)`; return doc.replace(oldOverview, newOverview); } /** * Update tool statistics section */ function updateToolStatistics(doc, newCounts, totalNew) { // Find and update the tool statistics section const statsSection = /## Tool Statistics[\s\S]*?- \*\*Network Tools\*\*: \d+ tools \(network operations\)/; const newStatsSection = `## Tool Statistics - **Total Tools**: ${101 + totalNew} (comprehensive healthcare API coverage including ${totalNew} new endpoints) - **Public Tools**: ${26 + newCounts.public} (no authentication required - login, registration, password management) - **Provider Tools**: ${52 + newCounts.provider} (provider/EMR authentication required - clinical data, HIPAA-compliant) - **Patient Tools**: ${7 + newCounts.patient} (patient portal authentication required) - **Partner Tools**: ${6 + newCounts.partner} (partner business authentication required) - **Affiliate Tools**: ${5 + newCounts.affiliate} (affiliate business authentication required) - **Network Tools**: ${5 + newCounts.network} (network business authentication required)`; return doc.replace(statsSection, newStatsSection); } /** * Add new tool sections for each authentication type */ function addNewToolSections(doc, categorized) { let updatedDoc = doc; // Add new public tools if (categorized.public.length > 0) { updatedDoc = addPublicToolsSection(updatedDoc, categorized.public); } // Add new provider tools if (categorized.provider.length > 0) { updatedDoc = addProviderToolsSection(updatedDoc, categorized.provider); } // Add new patient tools if (categorized.patient.length > 0) { updatedDoc = addPatientToolsSection(updatedDoc, categorized.patient); } // Add new affiliate tools if (categorized.affiliate.length > 0) { updatedDoc = addAffiliateToolsSection(updatedDoc, categorized.affiliate); } return updatedDoc; } /** * Add new public tools section */ function addPublicToolsSection(doc, publicTools) { const publicSection = /---\n\n## Provider Tools \(\d+ tools\)/; let newPublicToolsTable = `\n### New Public Tools from API-Docs.json (${publicTools.length} tools)\n\n`; newPublicToolsTable += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`; newPublicToolsTable += `| --------- | ------ | -------- | ----------- | -------------- |\n`; publicTools.slice(0, 20).forEach(tool => { // Show first 20 tools const toolName = tool.toolName || generateToolName(tool, 'public'); const params = extractKeyParameters(tool); newPublicToolsTable += `| \`${toolName}\` | ${tool.method} | \`${tool.path}\` | ${tool.summary || tool.description} | ${params} |\n`; }); if (publicTools.length > 20) { newPublicToolsTable += `\n*... and ${publicTools.length - 20} more public tools*\n`; } newPublicToolsTable += `\n---\n`; return doc.replace(publicSection, newPublicToolsTable + '\n## Provider Tools'); } /** * Add new provider tools section */ function addProviderToolsSection(doc, providerTools) { const patientSection = /---\n\n## Patient Tools \(\d+ tools\)/; let newProviderToolsTable = `\n### New Provider Tools from API-Docs.json (${providerTools.length} tools)\n\n`; newProviderToolsTable += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`; newProviderToolsTable += `| --------- | ------ | -------- | ----------- | -------------- |\n`; providerTools.slice(0, 25).forEach(tool => { // Show first 25 tools const toolName = tool.toolName || generateToolName(tool, 'provider'); const params = extractKeyParameters(tool); newProviderToolsTable += `| \`${toolName}\` | ${tool.method} | \`${tool.path}\` | ${tool.summary || tool.description} | ${params} |\n`; }); if (providerTools.length > 25) { newProviderToolsTable += `\n*... and ${providerTools.length - 25} more provider tools*\n`; } newProviderToolsTable += `\n---\n`; return doc.replace(patientSection, newProviderToolsTable + '\n## Patient Tools'); } /** * Add new patient tools section */ function addPatientToolsSection(doc, patientTools) { const partnerSection = /---\n\n## Partner Tools \(\d+ tools\)/; let newPatientToolsTable = `\n### New Patient Tools from API-Docs.json (${patientTools.length} tools)\n\n`; newPatientToolsTable += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`; newPatientToolsTable += `| --------- | ------ | -------- | ----------- | -------------- |\n`; patientTools.forEach(tool => { const toolName = tool.toolName || generateToolName(tool, 'patient'); const params = extractKeyParameters(tool); newPatientToolsTable += `| \`${toolName}\` | ${tool.method} | \`${tool.path}\` | ${tool.summary || tool.description} | ${params} |\n`; }); newPatientToolsTable += `\n---\n`; return doc.replace(partnerSection, newPatientToolsTable + '\n## Partner Tools'); } /** * Add new affiliate tools section */ function addAffiliateToolsSection(doc, affiliateTools) { const networkSection = /---\n\n## Network Tools \(\d+ tools\)/; let newAffiliateToolsTable = `\n### New Affiliate Tools from API-Docs.json (${affiliateTools.length} tools)\n\n`; newAffiliateToolsTable += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`; newAffiliateToolsTable += `| --------- | ------ | -------- | ----------- | -------------- |\n`; affiliateTools.forEach(tool => { const toolName = tool.toolName || generateToolName(tool, 'affiliate'); const params = extractKeyParameters(tool); newAffiliateToolsTable += `| \`${toolName}\` | ${tool.method} | \`${tool.path}\` | ${tool.summary || tool.description} | ${params} |\n`; }); newAffiliateToolsTable += `\n---\n`; return doc.replace(networkSection, newAffiliateToolsTable + '\n## Network Tools'); } /** * Generate tool name from endpoint */ function generateToolName(endpoint, authType) { const method = endpoint.method.toLowerCase(); const path = endpoint.path.toLowerCase(); let pathParts = path.split('/').filter(part => part && !part.startsWith('{') && !part.endsWith('}')); pathParts = pathParts.filter(part => !['api', 'emr', 'emr-api'].includes(part)); let action = method === 'get' ? 'get' : method === 'post' ? 'create' : method === 'put' ? 'update' : method === 'delete' ? 'delete' : method; let resource = pathParts.join('_').replace(/-/g, '_').replace(/[^a-z0-9_]/g, ''); if (!resource) { resource = endpoint.operationId || 'unknown'; } return `${authType}_${action}_${resource}`; } /** * Extract key parameters from endpoint */ function extractKeyParameters(endpoint) { const params = []; if (endpoint.parameters && endpoint.parameters.length > 0) { endpoint.parameters.slice(0, 3).forEach(param => { const required = param.required ? '**Required:**' : '**Optional:**'; params.push(`${required} ${param.name} (${param.type})`); }); } if (endpoint.requestBody && endpoint.requestBody.content) { const jsonContent = endpoint.requestBody.content['application/json']; if (jsonContent && jsonContent.schema && jsonContent.schema.properties) { const propNames = Object.keys(jsonContent.schema.properties).slice(0, 2); propNames.forEach(propName => { params.push(`**Body:** ${propName}`); }); } } return params.length > 0 ? params.join(', ') : 'No parameters'; } // Run the update if (import.meta.url === `file://${process.argv[1]}`) { updateDocumentation(); } export { updateDocumentation };