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

501 lines
17 KiB
JavaScript

/**
* @fileoverview Generate complete provider tools documentation
* Creates exact tool names and complete documentation table for all 147 provider endpoints
*/
import fs from 'fs';
import path from 'path';
/**
* Generate complete provider tools documentation
*/
function generateCompleteProviderTools() {
try {
console.log('=== GENERATING COMPLETE PROVIDER TOOLS DOCUMENTATION ===');
console.log('');
// Read the complete provider endpoints
const completeProviderPath = path.join(process.cwd(), 'complete-provider-endpoints.json');
const completeProviderContent = fs.readFileSync(completeProviderPath, 'utf8');
const completeProviderEndpoints = JSON.parse(completeProviderContent);
console.log(`Processing ${completeProviderEndpoints.length} provider endpoints`);
console.log('');
const providerTools = [];
// Process each provider endpoint to create exact tool definitions
completeProviderEndpoints.forEach((endpoint, index) => {
console.log(`Processing ${index + 1}/${completeProviderEndpoints.length}: ${endpoint.method} ${endpoint.path}`);
const tool = {
toolName: generateExactToolName(endpoint),
method: endpoint.method,
path: endpoint.path,
description: endpoint.detailedDescription || endpoint.summary || 'Provider endpoint',
category: endpoint.category,
parameters: formatParametersForDocumentation(endpoint),
operationId: endpoint.operationId,
tags: endpoint.tags || [],
endpoint: endpoint
};
providerTools.push(tool);
});
console.log('');
console.log(`=== TOOL GENERATION COMPLETE ===`);
console.log(`Generated ${providerTools.length} provider tools`);
console.log('');
// Generate the complete documentation table
const documentationTable = generateDocumentationTable(providerTools);
// Save the complete provider tools
const outputPath = path.join(process.cwd(), 'complete-provider-tools.json');
fs.writeFileSync(outputPath, JSON.stringify(providerTools, null, 2));
console.log(`Complete provider tools saved to: ${outputPath}`);
// Save the documentation table
const tableOutputPath = path.join(process.cwd(), 'provider-tools-documentation-table.md');
fs.writeFileSync(tableOutputPath, documentationTable);
console.log(`Documentation table saved to: ${tableOutputPath}`);
// Display summary by category
const categoryCount = {};
providerTools.forEach(tool => {
const category = tool.category || 'unknown';
categoryCount[category] = (categoryCount[category] || 0) + 1;
});
console.log('');
console.log('=== PROVIDER TOOLS BY CATEGORY ===');
Object.keys(categoryCount).sort().forEach(category => {
console.log(`${category}: ${categoryCount[category]} tools`);
});
return { providerTools, documentationTable };
} catch (error) {
console.error('Error generating complete provider tools:', error);
throw error;
}
}
/**
* Generate exact tool name following the established convention
*/
function generateExactToolName(endpoint) {
const method = endpoint.method.toLowerCase();
const path = endpoint.path.toLowerCase();
// Extract meaningful parts from the path
let pathParts = path.split('/').filter(part => part && !part.startsWith('{') && !part.endsWith('}'));
// Remove common prefixes
pathParts = pathParts.filter(part => !['api', 'emr', 'emr-api'].includes(part));
// Determine action based on method and path context
let action = method;
if (method === 'get') {
action = 'get';
} else if (method === 'post') {
if (path.includes('/store') || path.includes('/save') || path.includes('/add') || path.includes('/create')) {
action = 'create';
} else if (path.includes('/search') || path.includes('/find') || path.includes('/list')) {
action = 'search';
} else if (path.includes('/login') || path.includes('/register')) {
action = 'auth';
} else if (path.includes('/sync') || path.includes('/update')) {
action = 'update';
} else {
action = 'create';
}
} else if (method === 'put' || method === 'patch') {
action = 'update';
} else if (method === 'delete') {
action = 'delete';
}
// Create resource name from path parts with better naming
let resource = pathParts.join('_').replace(/-/g, '_');
// Handle special naming cases
if (path.includes('appointment')) {
resource = resource.replace(/appointment/g, 'appointment');
}
if (path.includes('patient')) {
resource = resource.replace(/patient/g, 'patient');
}
if (path.includes('meeting')) {
resource = resource.replace(/meeting/g, 'meeting');
}
if (path.includes('form')) {
resource = resource.replace(/form/g, 'form');
}
if (path.includes('document')) {
resource = resource.replace(/document/g, 'document');
}
if (path.includes('practitioner')) {
resource = resource.replace(/practitioner/g, 'practitioner');
}
if (path.includes('inventory')) {
resource = resource.replace(/inventory/g, 'inventory');
}
if (path.includes('location')) {
resource = resource.replace(/location/g, 'location');
}
if (path.includes('insurance')) {
resource = resource.replace(/insurance/g, 'insurance');
}
if (path.includes('vital')) {
resource = resource.replace(/vital/g, 'vital');
}
if (path.includes('task')) {
resource = resource.replace(/task/g, 'task');
}
if (path.includes('tag')) {
resource = resource.replace(/tag/g, 'tag');
}
if (path.includes('token')) {
resource = resource.replace(/token/g, 'token');
}
if (path.includes('email')) {
resource = resource.replace(/email/g, 'email');
}
if (path.includes('company')) {
resource = resource.replace(/company/g, 'company');
}
if (path.includes('product')) {
resource = resource.replace(/product/g, 'product');
}
if (path.includes('category')) {
resource = resource.replace(/category/g, 'category');
}
if (path.includes('signature')) {
resource = resource.replace(/signature/g, 'signature');
}
if (path.includes('payment')) {
resource = resource.replace(/payment/g, 'payment');
}
if (path.includes('medical')) {
resource = resource.replace(/medical/g, 'medical');
}
if (path.includes('prescription')) {
resource = resource.replace(/prescription/g, 'prescription');
}
if (path.includes('phone')) {
resource = resource.replace(/phone/g, 'phone');
}
if (path.includes('availability')) {
resource = resource.replace(/availability/g, 'availability');
}
if (path.includes('wizard')) {
resource = resource.replace(/wizard/g, 'wizard');
}
if (path.includes('status')) {
resource = resource.replace(/status/g, 'status');
}
if (path.includes('queue')) {
resource = resource.replace(/queue/g, 'queue');
}
if (path.includes('transcribe')) {
resource = resource.replace(/transcribe/g, 'transcribe');
}
if (path.includes('report')) {
resource = resource.replace(/report/g, 'report');
}
if (path.includes('analysis')) {
resource = resource.replace(/analysis/g, 'analysis');
}
if (path.includes('download')) {
resource = resource.replace(/download/g, 'download');
}
if (path.includes('render')) {
resource = resource.replace(/render/g, 'render');
}
if (path.includes('intake')) {
resource = resource.replace(/intake/g, 'intake');
}
if (path.includes('consent')) {
resource = resource.replace(/consent/g, 'consent');
}
if (path.includes('questionnaire')) {
resource = resource.replace(/questionnaire/g, 'questionnaire');
}
if (path.includes('subscription')) {
resource = resource.replace(/subscription/g, 'subscription');
}
if (path.includes('notification')) {
resource = resource.replace(/notification/g, 'notification');
}
if (path.includes('history')) {
resource = resource.replace(/history/g, 'history');
}
if (path.includes('profile')) {
resource = resource.replace(/profile/g, 'profile');
}
if (path.includes('picture')) {
resource = resource.replace(/picture/g, 'picture');
}
if (path.includes('cancel')) {
resource = resource.replace(/cancel/g, 'cancel');
}
if (path.includes('process')) {
resource = resource.replace(/process/g, 'process');
}
if (path.includes('generate')) {
resource = resource.replace(/generate/g, 'generate');
}
if (path.includes('revoke')) {
resource = resource.replace(/revoke/g, 'revoke');
}
if (path.includes('refresh')) {
resource = resource.replace(/refresh/g, 'refresh');
}
if (path.includes('abilities')) {
resource = resource.replace(/abilities/g, 'abilities');
}
if (path.includes('temporary')) {
resource = resource.replace(/temporary/g, 'temporary');
}
if (path.includes('logout')) {
resource = resource.replace(/logout/g, 'logout');
}
if (path.includes('setup')) {
resource = resource.replace(/setup/g, 'setup');
}
if (path.includes('complete')) {
resource = resource.replace(/complete/g, 'complete');
}
if (path.includes('realtime')) {
resource = resource.replace(/realtime/g, 'realtime');
}
if (path.includes('questions')) {
resource = resource.replace(/questions/g, 'questions');
}
if (path.includes('asseblyai')) {
resource = resource.replace(/asseblyai/g, 'assemblyai');
}
if (path.includes('labs')) {
resource = resource.replace(/labs/g, 'labs');
}
if (path.includes('slots')) {
resource = resource.replace(/slots/g, 'slots');
}
if (path.includes('detail')) {
resource = resource.replace(/detail/g, 'detail');
}
if (path.includes('note')) {
resource = resource.replace(/note/g, 'note');
}
if (path.includes('data')) {
resource = resource.replace(/data/g, 'data');
}
if (path.includes('pdf')) {
resource = resource.replace(/pdf/g, 'pdf');
}
if (path.includes('vue')) {
resource = resource.replace(/vue/g, 'vue');
}
if (path.includes('questioner')) {
resource = resource.replace(/questioner/g, 'questioner');
}
if (path.includes('question')) {
resource = resource.replace(/question/g, 'question');
}
if (path.includes('problem')) {
resource = resource.replace(/problem/g, 'problem');
}
if (path.includes('log')) {
resource = resource.replace(/log/g, 'log');
}
if (path.includes('plans')) {
resource = resource.replace(/plans/g, 'plans');
}
if (path.includes('sync')) {
resource = resource.replace(/sync/g, 'sync');
}
if (path.includes('user')) {
resource = resource.replace(/user/g, 'user');
}
if (path.includes('me')) {
resource = resource.replace(/me/g, 'me');
}
if (path.includes('password')) {
resource = resource.replace(/password/g, 'password');
}
if (path.includes('method')) {
resource = resource.replace(/method/g, 'method');
}
if (path.includes('stored')) {
resource = resource.replace(/stored/g, 'stored');
}
if (path.includes('session')) {
resource = resource.replace(/session/g, 'session');
}
if (path.includes('carts')) {
resource = resource.replace(/carts/g, 'carts');
}
if (path.includes('items')) {
resource = resource.replace(/items/g, 'items');
}
if (path.includes('agent')) {
resource = resource.replace(/agent/g, 'agent');
}
if (path.includes('order')) {
resource = resource.replace(/order/g, 'order');
}
if (path.includes('call')) {
resource = resource.replace(/call/g, 'call');
}
if (path.includes('start')) {
resource = resource.replace(/start/g, 'start');
}
if (path.includes('end')) {
resource = resource.replace(/end/g, 'end');
}
if (path.includes('join')) {
resource = resource.replace(/join/g, 'join');
}
if (path.includes('create')) {
resource = resource.replace(/create/g, 'create');
}
if (path.includes('book')) {
resource = resource.replace(/book/g, 'book');
}
if (path.includes('info')) {
resource = resource.replace(/info/g, 'info');
}
if (path.includes('doctors')) {
resource = resource.replace(/doctors/g, 'doctors');
}
if (path.includes('list')) {
resource = resource.replace(/list/g, 'list');
}
if (path.includes('date')) {
resource = resource.replace(/date/g, 'date');
}
if (path.includes('by')) {
resource = resource.replace(/by/g, 'by');
}
if (path.includes('id')) {
resource = resource.replace(/id/g, 'id');
}
if (path.includes('all')) {
resource = resource.replace(/all/g, 'all');
}
if (path.includes('assistant')) {
resource = resource.replace(/assistant/g, 'assistant');
}
if (path.includes('store')) {
resource = resource.replace(/store/g, 'store');
}
if (path.includes('save')) {
resource = resource.replace(/save/g, 'save');
}
if (path.includes('add')) {
resource = resource.replace(/add/g, 'add');
}
if (path.includes('get')) {
resource = resource.replace(/get/g, 'get');
}
if (path.includes('update')) {
resource = resource.replace(/update/g, 'update');
}
if (path.includes('delete')) {
resource = resource.replace(/delete/g, 'delete');
}
if (path.includes('put')) {
resource = resource.replace(/put/g, 'put');
}
if (path.includes('post')) {
resource = resource.replace(/post/g, 'post');
}
// Clean up resource name
resource = resource.replace(/[^a-z0-9_]/g, '');
// Remove duplicate underscores
resource = resource.replace(/_+/g, '_');
// Remove leading/trailing underscores
resource = resource.replace(/^_+|_+$/g, '');
// Ensure we have a resource name
if (!resource) {
if (endpoint.operationId) {
resource = endpoint.operationId.toLowerCase().replace(/[^a-z0-9_]/g, '_');
} else {
resource = 'unknown';
}
}
return `provider_${action}_${resource}`;
}
/**
* Format parameters for documentation
*/
function formatParametersForDocumentation(endpoint) {
const params = [];
// Add path parameters
if (endpoint.completeParameters) {
Object.keys(endpoint.completeParameters).forEach(paramName => {
const param = endpoint.completeParameters[paramName];
const required = param.required ? '**Required:**' : '**Optional:**';
const type = param.type || 'string';
const description = param.description || `${paramName} parameter`;
params.push(`${required} ${paramName} (${type}) - ${description}`);
});
}
// Add request body parameters
if (endpoint.requestBodySchema && endpoint.requestBodySchema.content) {
const jsonContent = endpoint.requestBodySchema.content['application/json'];
if (jsonContent && jsonContent.properties) {
Object.keys(jsonContent.properties).slice(0, 5).forEach(propName => {
const prop = jsonContent.properties[propName];
const required = prop.required ? '**Required:**' : '**Optional:**';
const type = prop.type || 'string';
const description = prop.description || `${propName} property`;
params.push(`${required} ${propName} (${type}) - ${description}`);
});
}
}
return params.length > 0 ? params.join(', ') : 'No parameters';
}
/**
* Generate the complete documentation table
*/
function generateDocumentationTable(providerTools) {
let table = `### Provider Tools (${providerTools.length} tools)\n\n`;
table += `*All provider tools require provider authentication (Sanctum token) for HIPAA-compliant access to clinical data.*\n\n`;
table += `| Tool Name | Method | Endpoint | Description | Key Parameters |\n`;
table += `| --------- | ------ | -------- | ----------- | -------------- |\n`;
providerTools.forEach(tool => {
const toolName = tool.toolName;
const method = tool.method;
const endpoint = tool.path;
const description = (tool.description || '').replace(/\|/g, '\\|').replace(/\n/g, ' ');
const parameters = (tool.parameters || 'No parameters').replace(/\|/g, '\\|').replace(/\n/g, ' ');
table += `| \`${toolName}\` | ${method} | \`${endpoint}\` | ${description} | ${parameters} |\n`;
});
return table;
}
// Run the generation
if (import.meta.url === `file://${process.argv[1]}`) {
generateCompleteProviderTools();
}
export { generateCompleteProviderTools };