Skip to main content
Glama

Nessus MCP Server

scans.ts7.94 kB
/** * Scan-related tools for the Nessus MCP server */ import { z } from 'zod'; import { getScanTemplates, startScan, getScanStatus, getScanResults, listScans } from '../nessus-api.js'; import { validateScanId, validateTarget, validateScanType, handleNessusApiError } from '../utils/error-handling.js'; /** * Tool to list available scan templates */ export const listScanTemplatesToolSchema = { name: 'list_scan_templates', description: 'List available Nessus scan templates', inputSchema: { type: 'object', properties: {} } }; export const listScanTemplatesToolHandler = async () => { try { const templates = await getScanTemplates(); return { content: [ { type: 'text', text: JSON.stringify(templates, null, 2) } ] }; } catch (error) { const mcpError = handleNessusApiError(error); return { content: [ { type: 'text', text: `Error: ${mcpError.message}` } ], isError: true }; } }; /** * Tool to start a new scan */ export const startScanToolSchema = { name: 'start_scan', description: 'Start a new vulnerability scan against a target', inputSchema: { type: 'object', properties: { target: { type: 'string', description: 'Target IP address or hostname to scan' }, scan_type: { type: 'string', description: 'Type of scan to run (basic-network-scan, web-app-scan, compliance-scan)' } }, required: ['target', 'scan_type'] } }; export const startScanToolHandler = async (args: Record<string, unknown>) => { try { // Validate arguments const targetSchema = z.string().min(1); const scanTypeSchema = z.enum(['basic-network-scan', 'web-app-scan', 'compliance-scan']); const target = validateTarget(args.target); const scanType = validateScanType(args.scan_type); // Start the scan const result = await startScan(target, scanType); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } catch (error) { const mcpError = handleNessusApiError(error); return { content: [ { type: 'text', text: `Error: ${mcpError.message}` } ], isError: true }; } }; /** * Tool to get scan status */ export const getScanStatusToolSchema = { name: 'get_scan_status', description: 'Check the status of a running scan', inputSchema: { type: 'object', properties: { scan_id: { type: 'string', description: 'ID of the scan to check' } }, required: ['scan_id'] } }; export const getScanStatusToolHandler = async (args: Record<string, unknown>) => { try { // Validate arguments const scanId = validateScanId(args.scan_id); // Get scan status const status = await getScanStatus(scanId); return { content: [ { type: 'text', text: JSON.stringify(status, null, 2) } ] }; } catch (error) { const mcpError = handleNessusApiError(error); return { content: [ { type: 'text', text: `Error: ${mcpError.message}` } ], isError: true }; } }; /** * Tool to get scan results */ export const getScanResultsToolSchema = { name: 'get_scan_results', description: 'Get the results of a completed scan', inputSchema: { type: 'object', properties: { scan_id: { type: 'string', description: 'ID of the scan to get results for' } }, required: ['scan_id'] } }; export const getScanResultsToolHandler = async (args: Record<string, unknown>) => { try { // Validate arguments const scanId = validateScanId(args.scan_id); // Get scan results const results = await getScanResults(scanId); // Check if there was an error if ('error' in results) { return { content: [ { type: 'text', text: `Error: ${results.error}` } ], isError: true }; } // Format the results const formattedResults = formatScanResults(results); return { content: [ { type: 'text', text: formattedResults } ] }; } catch (error) { const mcpError = handleNessusApiError(error); return { content: [ { type: 'text', text: `Error: ${mcpError.message}` } ], isError: true }; } }; /** * Tool to list all scans */ export const listScansToolSchema = { name: 'list_scans', description: 'List all scans and their status', inputSchema: { type: 'object', properties: {} } }; export const listScansToolHandler = async () => { try { // Get all scans const scans = await listScans(); return { content: [ { type: 'text', text: JSON.stringify(scans, null, 2) } ] }; } catch (error) { const mcpError = handleNessusApiError(error); return { content: [ { type: 'text', text: `Error: ${mcpError.message}` } ], isError: true }; } }; /** * Format scan results for better readability * @param results Scan results to format */ const formatScanResults = (results: any): string => { if (!results || !results.vulnerabilities) { return JSON.stringify(results, null, 2); } // Create a summary section const summary = results.summary || {}; let formattedResults = `# Scan Results for ${results.target || 'Unknown Target'}\n\n`; formattedResults += `Scan ID: ${results.scan_id || 'Unknown'}\n`; formattedResults += `Scan Type: ${results.scan_type || 'Unknown'}\n`; formattedResults += `Start Time: ${results.start_time || 'Unknown'}\n`; formattedResults += `End Time: ${results.end_time || 'Unknown'}\n`; formattedResults += `Status: ${results.status || 'Unknown'}\n\n`; // Add vulnerability summary formattedResults += `## Vulnerability Summary\n\n`; formattedResults += `Total Vulnerabilities: ${summary.total_vulnerabilities || 0}\n`; formattedResults += `Critical: ${summary.critical || 0}\n`; formattedResults += `High: ${summary.high || 0}\n`; formattedResults += `Medium: ${summary.medium || 0}\n`; formattedResults += `Low: ${summary.low || 0}\n`; formattedResults += `Info: ${summary.info || 0}\n\n`; // Add detailed vulnerability information formattedResults += `## Vulnerabilities\n\n`; // Sort vulnerabilities by severity const sortOrder = { 'critical': 0, 'high': 1, 'medium': 2, 'low': 3, 'info': 4 }; const sortedVulns = [...results.vulnerabilities].sort((a, b) => { return (sortOrder[a.severity as keyof typeof sortOrder] || 999) - (sortOrder[b.severity as keyof typeof sortOrder] || 999); }); // Format each vulnerability sortedVulns.forEach((vuln, index) => { formattedResults += `### ${index + 1}. ${vuln.name} (${vuln.id})\n\n`; formattedResults += `Severity: ${vuln.severity.toUpperCase()}\n`; formattedResults += `CVSS Score: ${vuln.cvss_score}\n\n`; formattedResults += `${vuln.description}\n\n`; if (vuln.affected_systems && vuln.affected_systems.length > 0) { formattedResults += `Affected Systems:\n`; vuln.affected_systems.forEach((system: string) => { formattedResults += `- ${system}\n`; }); formattedResults += '\n'; } if (vuln.remediation) { formattedResults += `Remediation: ${vuln.remediation}\n\n`; } if (vuln.references && vuln.references.length > 0) { formattedResults += `References:\n`; vuln.references.forEach((ref: string) => { formattedResults += `- ${ref}\n`; }); formattedResults += '\n'; } }); return formattedResults; };

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Cyreslab-AI/nessus-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server