297 lines
12 KiB
JavaScript
297 lines
12 KiB
JavaScript
/**
|
|
* @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 };
|