first
This commit is contained in:
296
update-documentation.js
Normal file
296
update-documentation.js
Normal file
@@ -0,0 +1,296 @@
|
||||
/**
|
||||
* @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 };
|
Reference in New Issue
Block a user