UNPKG

vulnzap-mcp

Version:

Multi-ecosystem vulnerability scanning service with MCP interface for LLMs

199 lines (169 loc) 5.44 kB
#!/usr/bin/env node /** * VulnZap MCP - CLI interface * * This script provides a command-line interface for starting the VulnZap MCP server. * It allows easy connection to LLM clients like Cursor, Claude Code, and Windsurf. */ import { spawn } from 'child_process'; import path from 'path'; import fs from 'fs'; import { fileURLToPath } from 'url'; // Get the current directory const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const packagePath = path.resolve(__dirname, '..'); // Parse command-line arguments const args = process.argv.slice(2); const flags = {}; for (let i = 0; i < args.length; i++) { if (args[i].startsWith('--')) { const flag = args[i].slice(2); const nextArg = args[i + 1]; if (nextArg && !nextArg.startsWith('--')) { flags[flag] = nextArg; i++; } else { flags[flag] = true; } } } // Display help if requested if (flags.help || flags.h) { console.log(` VulnZap MCP - Vulnerability scanning server for LLM integration USAGE: vulnzap [options] OPTIONS: --help, -h Show this help message --port PORT Set the server port (default: 3000) --nvd-key KEY Set the NVD API key --github-token TOKEN Set the GitHub API token --data-path PATH Set the path to the advisories file --premium-key KEY Set the premium API key --verbose Enable verbose logging --version, -v Show version information EXAMPLES: vulnzap # Start the server with default settings vulnzap --nvd-key YOUR_KEY # Start with NVD integration vulnzap --github-token YOUR_TOKEN # Start with GitHub integration vulnzap --nvd-key KEY --github-token KEY # Start with both NVD and GitHub `); process.exit(0); } // Display version if requested if (flags.version || flags.v) { const packageJsonPath = path.join(packagePath, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); console.log(`VulnZap MCP v${packageJson.version}`); process.exit(0); } // Set environment variables based on provided flags const env = { ...process.env }; if (flags.port) { env.PORT = flags.port; } if (flags['nvd-key']) { env.NVD_API_KEY = flags['nvd-key']; env.USE_NVD = 'true'; console.log('NVD integration enabled'); } if (flags['github-token']) { env.GITHUB_TOKEN = flags['github-token']; console.log('GitHub Advisory Database integration enabled'); } if (flags['data-path']) { env.DATA_PATH = flags['data-path']; } if (flags['premium-key']) { env.PREMIUM_API_KEY = flags['premium-key']; } // Create a temporary patched index file const tempPath = path.join(packagePath, '_temp_index.js'); const originalIndexPath = path.join(packagePath, 'index.js'); try { // Read the original index.js let indexContent = fs.readFileSync(originalIndexPath, 'utf8'); // Replace the problematic import lines indexContent = indexContent.replace( "import { Server as McpServer } from '@modelcontextprotocol/sdk/dist/server/index.js';", "import { Server as McpServer } from '@modelcontextprotocol/sdk/dist/server/index.js'.replace('/dist/dist/', '/dist/');" ); indexContent = indexContent.replace( "import { StdioServerTransport } from '@modelcontextprotocol/sdk/dist/server/stdio.js';", "import { StdioServerTransport } from '@modelcontextprotocol/sdk/dist/server/stdio.js'.replace('/dist/dist/', '/dist/');" ); // Add a try-catch block around the main function indexContent = indexContent.replace( "async function main() {", `async function main() { try {` ); indexContent = indexContent.replace( "main().catch(error => {", ` } catch (error) { console.error('Error in MCP server:', error); process.exit(1); } } main().catch(error => {` ); // Write the patched file fs.writeFileSync(tempPath, indexContent); // Start the server console.log('Starting VulnZap MCP server...'); // Use Node.js with the --no-warnings flag and experimental modules const serverProcess = spawn('node', [ '--no-warnings', '--experimental-modules', '--experimental-import-meta-resolve', tempPath ], { env, stdio: 'inherit' }); // Handle server lifecycle serverProcess.on('error', (error) => { console.error(`Failed to start server: ${error.message}`); // Clean up temp file try { fs.unlinkSync(tempPath); } catch (e) { // Ignore cleanup errors } process.exit(1); }); process.on('SIGINT', () => { console.log('\nShutting down VulnZap MCP server...'); serverProcess.kill('SIGINT'); // Clean up temp file try { fs.unlinkSync(tempPath); } catch (e) { // Ignore cleanup errors } }); process.on('SIGTERM', () => { console.log('\nShutting down VulnZap MCP server...'); serverProcess.kill('SIGTERM'); // Clean up temp file try { fs.unlinkSync(tempPath); } catch (e) { // Ignore cleanup errors } }); serverProcess.on('exit', (code) => { console.log(`VulnZap MCP server exited with code ${code}`); // Clean up temp file try { fs.unlinkSync(tempPath); } catch (e) { // Ignore cleanup errors } process.exit(code); }); } catch (error) { console.error('Error starting VulnZap MCP server:', error); process.exit(1); }