create_vulnerabilities
Add security vulnerabilities to penetration testing reports with CVSS scoring and structured HTML formatting for clear documentation.
Instructions
Create one or more vulnerabilities for a specific report. Use minimal HTML formatting: only tags for paragraphs and for simple bullet lists. NO nesting, NO numbered lists, NO code blocks, NO headers.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bearerToken | No | Bearer token for authentication (optional if REPORTS_JWT_TOKEN env var is set) | |
| reportId | Yes | The ID of the report to add vulnerabilities to (24-character MongoDB ObjectId) | |
| vulnerabilities | Yes | Array of vulnerability objects to create. Format content with minimal HTML: <p> for text, <ul><li> for lists only. |
Implementation Reference
- server.js:655-776 (handler)The main handler function that executes the tool logic: validates reportId and vulnerabilities array, auto-formats HTML fields using formatAsHTML helper, makes POST request to API to create vulnerabilities for the report, returns formatted success/error response.async function createVulnerabilities(providedToken, reportId, vulnerabilities) { try { const bearerToken = getBearerToken(providedToken); // Validate reportId format (should be MongoDB ObjectId) if (!reportId || !reportId.match(/^[0-9a-fA-F]{24}$/)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid reportId format. Must be a valid MongoDB ObjectId (24 characters)' ); } // Ensure vulnerabilities is an array if (!Array.isArray(vulnerabilities)) { vulnerabilities = [vulnerabilities]; } // Validate and format each vulnerability object for (const vuln of vulnerabilities) { if (!vuln.title || typeof vuln.title !== 'string') { throw new McpError( ErrorCode.InvalidParams, 'Each vulnerability must have a title (string)' ); } if (!vuln.description || typeof vuln.description !== 'string') { throw new McpError( ErrorCode.InvalidParams, 'Each vulnerability must have a description (HTML string)' ); } // Auto-format content fields as HTML vuln.description = formatAsHTML(vuln.description); if (vuln.details) vuln.details = formatAsHTML(vuln.details); if (vuln.impact) vuln.impact = formatAsHTML(vuln.impact, 'list'); if (vuln.remediation) vuln.remediation = formatAsHTML(vuln.remediation, 'list'); // Validate CVSS fields if provided if (vuln.cvssScore !== undefined) { if (typeof vuln.cvssScore !== 'number' || vuln.cvssScore < 0 || vuln.cvssScore > 10) { throw new McpError( ErrorCode.InvalidParams, 'CVSS Score must be a number between 0.0 and 10.0' ); } } if (vuln.severity !== undefined) { const validSeverities = ['Informational', 'Low', 'Medium', 'High', 'Critical']; if (!validSeverities.includes(vuln.severity)) { throw new McpError( ErrorCode.InvalidParams, `Severity must be one of: ${validSeverities.join(', ')}` ); } } if (vuln.cvss !== undefined) { if (typeof vuln.cvss !== 'string' || !vuln.cvss.startsWith('CVSS:3.1/')) { throw new McpError( ErrorCode.InvalidParams, 'CVSS vector must be a valid CVSS 3.1 string starting with "CVSS:3.1/"' ); } } } const response = await axios.post(`${VULNERABILITY_ENDPOINT}/${reportId}`, vulnerabilities, { headers: { 'Authorization': `Bearer ${bearerToken}`, 'Content-Type': 'application/json', }, timeout: 15000, }); return { content: [ { type: 'text', text: JSON.stringify({ success: true, status: response.status, data: response.data, timestamp: new Date().toISOString(), message: `Successfully created ${vulnerabilities.length} vulnerability(ies) for report ${reportId}`, }, null, 2), }, ], }; } catch (error) { if (error instanceof McpError) { throw error; } if (error.response) { return { content: [ { type: 'text', text: JSON.stringify({ success: false, status: error.response.status, error: error.response.data || error.message, timestamp: new Date().toISOString(), }, null, 2), }, ], }; } else if (error.request) { throw new McpError( ErrorCode.InternalError, `Network error: Unable to reach the API at ${VULNERABILITY_ENDPOINT}/${reportId}` ); } else { throw new McpError( ErrorCode.InternalError, `Request setup error: ${error.message}` ); } } }
- server.js:1012-1070 (schema)JSON Schema defining the input parameters for the create_vulnerabilities tool, including bearerToken (optional), required reportId, and vulnerabilities array with required title and description, optional fields like details, impact, etc., with types and constraints.inputSchema: { type: 'object', properties: { bearerToken: { type: 'string', description: 'Bearer token for authentication (optional if REPORTS_JWT_TOKEN env var is set)', }, reportId: { type: 'string', description: 'The ID of the report to add vulnerabilities to (24-character MongoDB ObjectId)', }, vulnerabilities: { type: 'array', items: { type: 'object', properties: { title: { type: 'string', description: 'The title of the vulnerability', }, description: { type: 'string', description: 'Simple HTML description using only <p> tags. Keep it concise and minimal.', }, details: { type: 'string', description: 'Simple HTML details using only <p> and <ul><li> tags. No nesting or complex formatting.', }, impact: { type: 'string', description: 'Simple HTML impact using only <p> and <ul><li> tags. List impacts as simple bullet points.', }, remediation: { type: 'string', description: 'Simple HTML remediation using only <p> and <ul><li> tags. List fixes as simple bullet points.', }, cvss: { type: 'string', description: 'CVSS 3.1 vector string (e.g., "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N")', }, cvssScore: { type: 'number', minimum: 0, maximum: 10, description: 'CVSS 3.1 score (0.0 to 10.0)', }, severity: { type: 'string', enum: ['Informational', 'Low', 'Medium', 'High', 'Critical'], description: 'Vulnerability severity level based on CVSS score', }, }, required: ['title', 'description'], }, description: 'Array of vulnerability objects to create. Format content with minimal HTML: <p> for text, <ul><li> for lists only.', }, }, required: ['reportId', 'vulnerabilities'], },
- server.js:1009-1071 (registration)Tool metadata registration in the ListToolsRequestHandler response: includes name, description, and inputSchema.{ name: 'create_vulnerabilities', description: 'Create one or more vulnerabilities for a specific report. Use minimal HTML formatting: only <p> tags for paragraphs and <ul><li> for simple bullet lists. NO nesting, NO numbered lists, NO code blocks, NO headers.', inputSchema: { type: 'object', properties: { bearerToken: { type: 'string', description: 'Bearer token for authentication (optional if REPORTS_JWT_TOKEN env var is set)', }, reportId: { type: 'string', description: 'The ID of the report to add vulnerabilities to (24-character MongoDB ObjectId)', }, vulnerabilities: { type: 'array', items: { type: 'object', properties: { title: { type: 'string', description: 'The title of the vulnerability', }, description: { type: 'string', description: 'Simple HTML description using only <p> tags. Keep it concise and minimal.', }, details: { type: 'string', description: 'Simple HTML details using only <p> and <ul><li> tags. No nesting or complex formatting.', }, impact: { type: 'string', description: 'Simple HTML impact using only <p> and <ul><li> tags. List impacts as simple bullet points.', }, remediation: { type: 'string', description: 'Simple HTML remediation using only <p> and <ul><li> tags. List fixes as simple bullet points.', }, cvss: { type: 'string', description: 'CVSS 3.1 vector string (e.g., "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N")', }, cvssScore: { type: 'number', minimum: 0, maximum: 10, description: 'CVSS 3.1 score (0.0 to 10.0)', }, severity: { type: 'string', enum: ['Informational', 'Low', 'Medium', 'High', 'Critical'], description: 'Vulnerability severity level based on CVSS score', }, }, required: ['title', 'description'], }, description: 'Array of vulnerability objects to create. Format content with minimal HTML: <p> for text, <ul><li> for lists only.', }, }, required: ['reportId', 'vulnerabilities'], }, },
- server.js:1201-1215 (registration)Handler registration in the CallToolRequestHandler switch statement: validates args and calls the createVulnerabilities function.case 'create_vulnerabilities': if (!args.reportId) { throw new McpError( ErrorCode.InvalidParams, 'Report ID is required' ); } if (!args.vulnerabilities || !Array.isArray(args.vulnerabilities) || args.vulnerabilities.length === 0) { throw new McpError( ErrorCode.InvalidParams, 'At least one vulnerability is required' ); } return await createVulnerabilities(args.bearerToken, args.reportId, args.vulnerabilities);
- server.js:398-419 (helper)Supporting utility function to automatically format plain text content into minimal HTML (paragraphs or bullet lists), used in createVulnerabilities for description, details, impact, and remediation fields.function formatAsHTML(content, fieldType = 'paragraph') { if (!content || typeof content !== 'string') { return content; } // If already contains HTML tags, return as-is if (content.includes('<') && content.includes('>')) { return content; } // For simple text, wrap in appropriate HTML tags if (fieldType === 'list') { // Split by newlines or common list separators and create bullet list const items = content.split(/\n|;|,|\|/).map(item => item.trim()).filter(item => item); if (items.length > 1) { return '<ul>' + items.map(item => `<li>${item}</li>`).join('') + '</ul>'; } } // Default: wrap in paragraph tags return `<p>${content}</p>`; }