createClientReport
Generate detailed penetration testing reports for clients by compiling scan results, executive summaries, and actionable recommendations with the Pentest MCP server.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| assessmentType | Yes | Type of assessment | |
| client | Yes | Client name for the report | |
| recommendations | No | List of recommendations | |
| scanIds | Yes | IDs of scans to include | |
| summary | No | Executive summary | |
| title | Yes | Title of the assessment report |
Implementation Reference
- src/index.ts:1075-1087 (handler)The core handler implementation for the 'createClientReport' MCP tool. It processes input parameters, retrieves associated scan data, analyzes findings by severity, constructs a ClientReport object, stores it in an in-memory map, and returns the report ID with access URI.server.tool("createClientReport", createClientReportToolSchema.shape, async (args /*: z.infer<typeof createClientReportToolSchema> */ /*, extra */) => { const { client, title, assessmentType, scanIds, summary, recommendations } = args; const reportId = `report-${Date.now()}`; const scans = scanIds.map(getScanDataById).filter(Boolean); const findings = analyzeFindings(scans); const report: ClientReport = { reportId, title, client, createdAt: Date.now(), assessmentType, findings, scans, summary: summary || "", recommendations: recommendations || [] }; clientReports.set(reportId, report); return { content: [ { type: "text", text: `Client report created: ${reportId}` }, { type: "text", text: `URI: mcp://pentest/clientReport/${reportId}` } ] }; });
- src/index.ts:1066-1073 (schema)Zod validation schema defining the input parameters and descriptions for the createClientReport tool.client: z.string().describe("Client name for the report"), title: z.string().describe("Title of the assessment report"), assessmentType: z.string().describe("Type of assessment"), scanIds: z.array(z.string()).describe("IDs of scans to include"), summary: z.string().optional().describe("Executive summary"), recommendations: z.array(z.string()).optional().describe("List of recommendations") }).describe( "Create a summarized client report from completed scans. Include scanIds returned from tools like `nmapScan`."
- src/index.ts:629-639 (schema)TypeScript interface defining the structure of a ClientReport, used by the tool handler for report data.interface ClientReport { reportId: string; title: string; createdAt: number; client: string; assessmentType: string; findings: { critical: Finding[], high: Finding[], medium: Finding[], low: Finding[], info: Finding[] }; scans: any[]; summary: string; recommendations: string[]; }
- src/index.ts:124-172 (helper)Helper function that categorizes open ports from scan data into severity levels (critical, high, medium, low, info) based on common vulnerable ports.function analyzeFindings(scans: any[]): { critical: Finding[]; high: Finding[]; medium: Finding[]; low: Finding[]; info: Finding[]; } { const findings: { critical: Finding[]; high: Finding[]; medium: Finding[]; low: Finding[]; info: Finding[]; } = { critical: [], high: [], medium: [], low: [], info: [] }; for (const scan of scans) { if (!scan || !scan.results) continue; for (const ip in scan.results) { const host = scan.results[ip] as Host; if (!host.ports) continue; for (const port of host.ports) { if (port.state === 'open') { const finding: Finding = { host: ip, port: port.portId, service: port.service?.name || 'unknown', description: `Open port ${port.portId} (${port.service?.name || 'unknown'})`, details: port }; if (['3389', '5432', '1433', '21', '23'].includes(port.portId)) { findings.critical.push(finding); } else if (['22', '445', '139'].includes(port.portId)) { findings.high.push(finding); } else if (['80', '443', '8080'].includes(port.portId)) { findings.medium.push(finding); } else { findings.low.push(finding); } } } } } return findings; }
- src/index.ts:96-112 (helper)Helper function to retrieve scan data by scanId from active scans (placeholder for log retrieval). Used by the handler to fetch scans for the report.function getScanDataById(scanId: string): any { // First check active scans const activeScan = activeScans.get(scanId); if (activeScan) { return { scanId, target: activeScan.progress.target, options: [], // Would need to store this in the activeScan object timestamp: activeScan.progress.startTime, results: {} // Would need to store partial results }; } // Otherwise, would need to retrieve from log file // This is a placeholder - real implementation would parse logs return null; }