UNPKG

smartlead-mcp-by-leadmagic

Version:

šŸ’œ The Premier Model Context Protocol Server for SmartLead's Cold Email Automation Platform - Complete API coverage with 116+ tools for campaign management, lead tracking, smart delivery, and analytics. Beautiful purple-gradient installer, zero-config set

151 lines • 5.07 kB
#!/usr/bin/env node "use strict"; /** * Script to add proper MCP tool annotations to all SmartLead tools * * This script adds the recommended MCP annotations to improve compliance * with MCP best practices as outlined in the official documentation. */ const fs = require('fs'); const path = require('path'); const { parse } = require('@typescript-eslint/parser'); // MCP Tool Categories and their annotations const toolAnnotations = { // Read-only tools (don't modify state) 'get_': { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, 'list_': { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, 'fetch_': { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true }, // Create operations (non-destructive) 'create_': { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, 'add_': { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, // Update operations (non-destructive) 'update_': { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, 'save_': { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, // Delete operations (destructive) 'delete_': { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true }, 'remove_': { readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: true }, // Default for other operations 'default': { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true } }; // Function to get annotations for a specific tool function getAnnotationsForTool(toolName) { const baseAnnotations = { 'mcp.name': toolName, 'mcp.description': `A tool for ${toolName.replace(/_/g, ' ')}.`, 'mcp.io.input': `Parameters for the ${toolName} tool.`, 'mcp.io.output': `The result of the ${toolName} operation.` }; const dynamicAnnotations = { 'smartlead-mcp.tool.name': toolName, 'smartlead-mcp.tool.category': toolName.split('_')[0], 'smartlead-mcp.tool.version': '1.5.0', 'smartlead-mcp.api.endpoint': `/api/v1/${toolName.replace(/_/g, '/')}`, 'smartlead-mcp.api.method': 'GET', // Default, can be adjusted 'smartlead-mcp.ui.displayName': toolName .replace('smartlead_', '') .replace(/_/g, ' ') .replace(/\b\w/g, (l) => l.toUpperCase()), 'smartlead-mcp.ui.description': `Manage and view ${toolName.replace(/_/g, ' ')}.`, }; return { ...baseAnnotations, ...dynamicAnnotations }; } // Function to add annotations to a file function addAnnotationsToFile(filePath) { if (!fs.existsSync(filePath)) { console.error(`File not found: ${filePath}`); return; } const sourceCode = fs.readFileSync(filePath, 'utf-8'); let modifiedCode = sourceCode; const ast = parse(sourceCode, { ecmaVersion: 2020, sourceType: 'module', ecmaFeatures: { jsx: true, }, range: true, }); for (const node of ast.body) { if (node.type === 'ExportNamedDeclaration' && node.declaration && node.declaration.type === 'FunctionDeclaration') { const func = node.declaration; if (func && func.id && func.range) { // Add the full annotation block const toolName = func.id.name; const annotations = getAnnotationsForTool(toolName); const annotationBlock = Object.entries(annotations) .map(([key, value]) => ` * @${key} ${value}`) .join('\n'); const newFunctionDef = `/**\n${annotationBlock}\n */\n${sourceCode.slice(func.range[0], func.range[1])}`; modifiedCode = modifiedCode.replace(sourceCode.slice(func.range[0], func.range[1]), newFunctionDef); } } } fs.writeFileSync(filePath, modifiedCode, 'utf-8'); } // Main script execution const toolsDir = path.resolve(__dirname, '../src/tools'); if (fs.existsSync(toolsDir)) { const files = fs.readdirSync(toolsDir); files.forEach((file) => { if (file.endsWith('.ts')) { addAnnotationsToFile(path.join(toolsDir, file)); } }); console.log('\nāœ… MCP annotations added successfully!'); console.log('šŸ“‹ Summary:'); console.log(` - Processed ${files.length} tool files`); } else { console.error(`Tools directory not found: ${toolsDir}`); } //# sourceMappingURL=add-mcp-annotations.js.map