get_pentest
Retrieve comprehensive penetration test details including status, findings summary, executive overview, attack surface map, and STRIDE threat model analysis.
Instructions
Get full details for a pentest including status, progress, findings summary, executive summary, attack surface map, and STRIDE threat model.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| pentest_id | Yes | The pentest ID (UUID) |
Implementation Reference
- src/tools/get-pentest.ts:17-92 (handler)The handler function for the get_pentest tool, which fetches pentest details from the client and formats them into a readable string.
async ({ pentest_id }) => { try { const scan = await client.getPentest(pentest_id); const severityCounts: Record<string, number> = { critical: 0, high: 0, medium: 0, low: 0, info: 0, }; for (const f of scan.findings ?? []) { severityCounts[f.severity] = (severityCounts[f.severity] || 0) + 1; } const toolResults = scan.toolResults ?? []; const toolsDone = toolResults.filter((t) => t.status === "complete").length; const toolsTotal = toolResults.length; const progress = toolsTotal > 0 ? Math.round((toolsDone / toolsTotal) * 100) : 0; const lines: string[] = [ `Pentest: ${scan.id}`, `Target: ${scan.targetUrl}`, `Status: ${scan.status}`, ]; if (scan.status === "scanning") { lines.push(`Progress: ${progress}% (${toolsDone}/${toolsTotal} tools complete)`); } lines.push( `Started: ${scan.startedAt || "pending"}`, scan.completedAt ? `Completed: ${scan.completedAt}` : "", "", `--- Findings (${(scan.findings ?? []).length} total) ---`, ` Critical: ${severityCounts.critical}`, ` High: ${severityCounts.high}`, ` Medium: ${severityCounts.medium}`, ` Low: ${severityCounts.low}`, ` Info: ${severityCounts.info}`, ); if (scan.status === "scanning") { const running = toolResults.filter((t) => t.status === "running").map((t) => t.toolName); const pending = toolResults.filter((t) => t.status === "pending").map((t) => t.toolName); if (running.length) lines.push("", `Running: ${running.join(", ")}`); if (pending.length) lines.push(`Pending: ${pending.join(", ")}`); } if (scan.executiveSummary) { lines.push("", "--- Executive Summary ---", scan.executiveSummary); } if (scan.attackSurface) { lines.push("", "--- Attack Surface ---", JSON.stringify(scan.attackSurface, null, 2)); } if (scan.threatModel) { lines.push("", "--- STRIDE Threat Model ---", JSON.stringify(scan.threatModel, null, 2)); } if (scan.failureReason) { lines.push("", `Failure reason: ${scan.failureReason}`); } return { content: [{ type: "text" as const, text: lines.filter((l) => l !== "").join("\n") }], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: "text" as const, text: `Failed to get pentest: ${message}` }], isError: true, }; } }, - src/tools/get-pentest.ts:13-15 (schema)The input schema defined using Zod, expecting a pentest_id as a UUID.
inputSchema: z.object({ pentest_id: z.string().uuid().describe("The pentest ID (UUID)"), }), - src/tools/get-pentest.ts:5-94 (registration)The registration function that defines the 'get_pentest' tool in the McpServer.
export function registerGetPentest(server: McpServer, client: TurboPentestClient): void { server.registerTool( "get_pentest", { title: "Get Pentest", description: "Get full details for a pentest including status, progress, findings summary, " + "executive summary, attack surface map, and STRIDE threat model.", inputSchema: z.object({ pentest_id: z.string().uuid().describe("The pentest ID (UUID)"), }), }, async ({ pentest_id }) => { try { const scan = await client.getPentest(pentest_id); const severityCounts: Record<string, number> = { critical: 0, high: 0, medium: 0, low: 0, info: 0, }; for (const f of scan.findings ?? []) { severityCounts[f.severity] = (severityCounts[f.severity] || 0) + 1; } const toolResults = scan.toolResults ?? []; const toolsDone = toolResults.filter((t) => t.status === "complete").length; const toolsTotal = toolResults.length; const progress = toolsTotal > 0 ? Math.round((toolsDone / toolsTotal) * 100) : 0; const lines: string[] = [ `Pentest: ${scan.id}`, `Target: ${scan.targetUrl}`, `Status: ${scan.status}`, ]; if (scan.status === "scanning") { lines.push(`Progress: ${progress}% (${toolsDone}/${toolsTotal} tools complete)`); } lines.push( `Started: ${scan.startedAt || "pending"}`, scan.completedAt ? `Completed: ${scan.completedAt}` : "", "", `--- Findings (${(scan.findings ?? []).length} total) ---`, ` Critical: ${severityCounts.critical}`, ` High: ${severityCounts.high}`, ` Medium: ${severityCounts.medium}`, ` Low: ${severityCounts.low}`, ` Info: ${severityCounts.info}`, ); if (scan.status === "scanning") { const running = toolResults.filter((t) => t.status === "running").map((t) => t.toolName); const pending = toolResults.filter((t) => t.status === "pending").map((t) => t.toolName); if (running.length) lines.push("", `Running: ${running.join(", ")}`); if (pending.length) lines.push(`Pending: ${pending.join(", ")}`); } if (scan.executiveSummary) { lines.push("", "--- Executive Summary ---", scan.executiveSummary); } if (scan.attackSurface) { lines.push("", "--- Attack Surface ---", JSON.stringify(scan.attackSurface, null, 2)); } if (scan.threatModel) { lines.push("", "--- STRIDE Threat Model ---", JSON.stringify(scan.threatModel, null, 2)); } if (scan.failureReason) { lines.push("", `Failure reason: ${scan.failureReason}`); } return { content: [{ type: "text" as const, text: lines.filter((l) => l !== "").join("\n") }], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: "text" as const, text: `Failed to get pentest: ${message}` }], isError: true, }; } }, ); }