Files
mcp-tool/update-documentation-complete.js
nasir@endelospay.com 8c74b0e23f first
2025-07-11 20:22:12 +05:00

471 lines
13 KiB
JavaScript

/**
* @fileoverview Update MCP-TOOLS-REFERENCE.md with accurate parameter information
* Update documentation to reflect all changes with exact parameter names, types, and descriptions
* from api-docs.json, ensuring 100% accuracy between documented and actual API specifications.
*/
import fs from "fs";
import path from "path";
/**
* Update documentation with accurate parameter information
*/
function updateDocumentationComplete() {
try {
console.log(
"=== UPDATING MCP-TOOLS-REFERENCE.md WITH ACCURATE PARAMETER INFORMATION ==="
);
console.log("");
// Read the complete API parameters
const apiParametersPath = path.join(
process.cwd(),
"complete-api-parameters.json"
);
const apiParametersContent = fs.readFileSync(apiParametersPath, "utf8");
const apiEndpoints = JSON.parse(apiParametersContent);
// Read the updated endpoints configuration
const endpointsConfigPath = path.join(
process.cwd(),
"src/config/endpoints.js"
);
const endpointsConfigContent = fs.readFileSync(endpointsConfigPath, "utf8");
// Read the current documentation
const docPath = path.join(process.cwd(), "MCP-TOOLS-REFERENCE.md");
const docContent = fs.readFileSync(docPath, "utf8");
console.log(`📊 Processing ${apiEndpoints.length} API endpoints`);
console.log("");
// Extract all tools from the updated configuration
const allTools = extractAllToolsFromConfig(endpointsConfigContent);
console.log(`🔧 Found ${allTools.length} tools in configuration`);
// Group tools by authentication type
const toolsByAuth = groupToolsByAuth(allTools, apiEndpoints);
// Generate complete documentation
const newDocumentation = generateCompleteDocumentation(
toolsByAuth,
apiEndpoints
);
// Create backup
const backupPath = path.join(
process.cwd(),
"MCP-TOOLS-REFERENCE_backup_" + Date.now() + ".md"
);
fs.writeFileSync(backupPath, docContent);
console.log(`📁 Backup created: ${backupPath}`);
// Save updated documentation
fs.writeFileSync(docPath, newDocumentation);
console.log(`💾 Updated documentation saved`);
// Generate statistics
const stats = generateDocumentationStats(toolsByAuth);
console.log("");
console.log("=== DOCUMENTATION UPDATE SUMMARY ===");
Object.keys(stats).forEach((authType) => {
console.log(
`${authType.toUpperCase()}: ${stats[authType]} tools documented`
);
});
console.log(
`Total tools documented: ${Object.values(stats).reduce(
(sum, count) => sum + count,
0
)}`
);
console.log(`Backup created: Yes`);
return {
toolsByAuth,
stats,
backupCreated: true,
};
} catch (error) {
console.error("Error updating documentation:", error);
throw error;
}
}
/**
* Extract all tools from configuration
*/
function extractAllToolsFromConfig(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*["']([^"']+)["']/);
const descMatch = endpointStr.match(/description:\s*["']([^"']+)["']/);
if (pathMatch && methodMatch) {
const tool = {
name: generateToolName(authType, pathMatch[1], methodMatch[1]),
authType: authType,
path: pathMatch[1],
method: methodMatch[1].toUpperCase(),
description: descMatch ? descMatch[1] : "",
parameters: extractParametersFromEndpoint(endpointStr),
};
tools.push(tool);
}
}
}
});
return tools;
}
/**
* Generate tool name from auth type, path, and method
*/
function generateToolName(authType, path, method) {
const action = method.toLowerCase();
const resource = path
.split("/")
.filter((part) => part && !part.startsWith("{"))
.join("_");
return `${authType}_${action}_${resource}`
.replace(/[^a-z0-9_]/g, "_")
.replace(/_+/g, "_");
}
/**
* 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;
}
/**
* Group tools by authentication type
*/
function groupToolsByAuth(allTools, apiEndpoints) {
const grouped = {
public: [],
provider: [],
patient: [],
partner: [],
affiliate: [],
network: [],
};
allTools.forEach((tool) => {
// Find corresponding API endpoint for additional parameter details
const apiEndpoint = apiEndpoints.find(
(ep) => ep.path === tool.path && ep.method === tool.method
);
// Enhance tool with API endpoint data
if (apiEndpoint) {
tool.apiEndpoint = apiEndpoint;
tool.enhancedParameters = mergeParameterData(
tool.parameters,
apiEndpoint
);
}
if (grouped[tool.authType]) {
grouped[tool.authType].push(tool);
}
});
// Sort tools within each group
Object.keys(grouped).forEach((authType) => {
grouped[authType].sort((a, b) => {
if (a.path !== b.path) return a.path.localeCompare(b.path);
return a.method.localeCompare(b.method);
});
});
return grouped;
}
/**
* Merge parameter data from tool config and API endpoint
*/
function mergeParameterData(toolParameters, apiEndpoint) {
const merged = [];
const apiParams = getAllParametersFromEndpoint(apiEndpoint);
// Create a map of API parameters for easy lookup
const apiParamMap = new Map();
apiParams.forEach((param) => {
apiParamMap.set(param.name, param);
});
// Start with tool parameters and enhance with API data
toolParameters.forEach((toolParam) => {
const apiParam = apiParamMap.get(toolParam.name);
merged.push({
name: toolParam.name,
type: apiParam?.type || toolParam.type,
required:
apiParam?.required !== undefined
? apiParam.required
: toolParam.required,
description: apiParam?.description || toolParam.description,
in: apiParam?.in || "body",
});
});
// Add any API parameters not in tool config
apiParams.forEach((apiParam) => {
if (!toolParameters.find((tp) => tp.name === apiParam.name)) {
merged.push({
name: apiParam.name,
type: apiParam.type,
required: apiParam.required,
description: apiParam.description,
in: apiParam.in || "body",
});
}
});
return merged;
}
/**
* Get all parameters from API endpoint
*/
function getAllParametersFromEndpoint(apiEndpoint) {
const allParams = [];
if (apiEndpoint.parameters?.path) {
allParams.push(
...apiEndpoint.parameters.path.map((p) => ({ ...p, in: "path" }))
);
}
if (apiEndpoint.parameters?.query) {
allParams.push(
...apiEndpoint.parameters.query.map((p) => ({ ...p, in: "query" }))
);
}
if (apiEndpoint.parameters?.body) {
allParams.push(
...apiEndpoint.parameters.body.map((p) => ({ ...p, in: "body" }))
);
}
return allParams;
}
/**
* Generate complete documentation
*/
function generateCompleteDocumentation(toolsByAuth, apiEndpoints) {
let doc = generateDocumentationHeader();
// Add each authentication type section
Object.keys(toolsByAuth).forEach((authType) => {
const tools = toolsByAuth[authType];
if (tools.length > 0) {
doc += generateAuthTypeSection(authType, tools);
}
});
doc += generateDocumentationFooter();
return doc;
}
/**
* Generate documentation header
*/
function generateDocumentationHeader() {
return `# Laravel Healthcare MCP Server - Complete Tools Reference
## Overview
This document provides a comprehensive reference for all MCP (Model Context Protocol) tools available in the Laravel Healthcare MCP Server. The server provides **${
new Date().toISOString().split("T")[0]
}** tools organized by authentication type and functionality.
## Authentication Types
- **PUBLIC**: No authentication required (login, registration, public data)
- **PROVIDER**: Provider authentication required (clinical data, EMR operations)
- **PATIENT**: Patient authentication required (patient portal operations)
- **PARTNER**: Partner authentication required (business operations)
- **AFFILIATE**: Affiliate authentication required (affiliate management)
- **NETWORK**: Network authentication required (network operations)
## Tool Naming Convention
All tools follow the pattern: \`{auth_type}_{action}_{resource}\`
- **auth_type**: Authentication type (public, provider, patient, etc.)
- **action**: HTTP method (get, post, put, delete)
- **resource**: API resource or endpoint identifier
---
`;
}
/**
* Generate authentication type section
*/
function generateAuthTypeSection(authType, tools) {
const authTypeTitle = authType.charAt(0).toUpperCase() + authType.slice(1);
const authDescription = getAuthTypeDescription(authType);
let section = `## ${authTypeTitle} Tools (${tools.length} tools)\n\n`;
section += `*${authDescription}*\n\n`;
section += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`;
section += `| --------- | ------ | -------- | ----------- | -------------- |\n`;
tools.forEach((tool) => {
const parameterStr = formatParametersForTable(
tool.enhancedParameters || tool.parameters
);
section += `| \`${tool.name}\` | ${tool.method} | \`${tool.path}\` | ${tool.description} | ${parameterStr} |\n`;
});
section += `\n`;
return section;
}
/**
* Get authentication type description
*/
function getAuthTypeDescription(authType) {
const descriptions = {
public:
"No authentication required. These tools handle login, registration, password management, and public data access.",
provider:
"Provider authentication required (Sanctum token). HIPAA-compliant access to clinical data, EMR operations, and patient management.",
patient:
"Patient authentication required. Patient portal operations and personal health data access.",
partner:
"Partner authentication required. Business partner operations and data access.",
affiliate:
"Affiliate authentication required. Affiliate management and operations.",
network:
"Network authentication required. Network-level operations and management.",
};
return (
descriptions[authType] || "Authentication required for this tool category."
);
}
/**
* Format parameters for table display
*/
function formatParametersForTable(parameters) {
if (!parameters || parameters.length === 0) {
return "No parameters";
}
const paramStrings = parameters.map((param) => {
const requiredText = param.required ? "**Required:**" : "**Optional:**";
const typeText = param.type ? `(${param.type})` : "";
const descText = param.description ? ` - ${param.description}` : "";
return `${requiredText} ${param.name} ${typeText}${descText}`;
});
return paramStrings.join(", ");
}
/**
* Generate documentation statistics
*/
function generateDocumentationStats(toolsByAuth) {
const stats = {};
Object.keys(toolsByAuth).forEach((authType) => {
stats[authType] = toolsByAuth[authType].length;
});
return stats;
}
/**
* Generate documentation footer
*/
function generateDocumentationFooter() {
return `
---
## Usage Notes
1. **Authentication**: Each tool specifies its authentication requirements
2. **Parameters**: All parameters include type information and requirement status
3. **Descriptions**: Tool descriptions are derived from API documentation
4. **Error Handling**: All tools include appropriate error handling for healthcare compliance
## Support
For technical support or questions about specific tools, please refer to the Laravel Healthcare MCP Server documentation or contact the development team.
---
*Last updated: ${new Date().toISOString().split("T")[0]}*
*Total tools documented: Complete API coverage*
`;
}
// Run the documentation update
if (import.meta.url === `file://${process.argv[1]}`) {
updateDocumentationComplete();
}
export { updateDocumentationComplete };