list_pentests
View and manage penetration tests with status and finding counts to track security assessments in TurboPentest.
Instructions
List all your pentests with status and finding counts. Results are ordered newest first.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return | |
| status | No | Filter by scan status |
Implementation Reference
- src/tools/list-pentests.ts:5-81 (registration)Registration of the 'list_pentests' MCP tool.
export function registerListPentests(server: McpServer, client: TurboPentestClient): void { server.registerTool( "list_pentests", { title: "List Pentests", description: "List all your pentests with status and finding counts. " + "Results are ordered newest first.", inputSchema: z.object({ limit: z .number() .int() .min(1) .max(100) .default(10) .describe("Maximum number of results to return"), status: z .enum(["queued", "scanning", "complete", "failed"]) .optional() .describe("Filter by scan status"), }), }, async ({ limit, status }) => { try { let scans = await client.listPentests(); if (status) { scans = scans.filter((s) => s.status === status); } scans = scans.slice(0, limit); if (scans.length === 0) { return { content: [ { type: "text" as const, text: status ? `No pentests found with status "${status}".` : "No pentests found. Use start_pentest to launch one.", }, ], }; } const lines = [`Pentests (showing ${scans.length})`, ""]; for (const scan of scans) { const severityCounts: Record<string, number> = {}; for (const f of scan.findings ?? []) { severityCounts[f.severity] = (severityCounts[f.severity] || 0) + 1; } const findingSummary = Object.entries(severityCounts) .map(([sev, count]) => `${count} ${sev}`) .join(", "); lines.push( ` ${scan.id}`, ` Target: ${scan.targetUrl}`, ` Status: ${scan.status}`, ` Created: ${scan.createdAt}`, ` Findings: ${findingSummary || "none"}`, "", ); } return { content: [{ type: "text" as const, text: lines.join("\n") }] }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: "text" as const, text: `Failed to list pentests: ${message}` }], isError: true, }; } }, ); } - src/tools/list-pentests.ts:13-25 (schema)Zod schema for 'list_pentests' tool arguments.
inputSchema: z.object({ limit: z .number() .int() .min(1) .max(100) .default(10) .describe("Maximum number of results to return"), status: z .enum(["queued", "scanning", "complete", "failed"]) .optional() .describe("Filter by scan status"), }), - src/tools/list-pentests.ts:27-79 (handler)The handler function that executes the tool logic, including filtering and formatting the pentest scan results.
async ({ limit, status }) => { try { let scans = await client.listPentests(); if (status) { scans = scans.filter((s) => s.status === status); } scans = scans.slice(0, limit); if (scans.length === 0) { return { content: [ { type: "text" as const, text: status ? `No pentests found with status "${status}".` : "No pentests found. Use start_pentest to launch one.", }, ], }; } const lines = [`Pentests (showing ${scans.length})`, ""]; for (const scan of scans) { const severityCounts: Record<string, number> = {}; for (const f of scan.findings ?? []) { severityCounts[f.severity] = (severityCounts[f.severity] || 0) + 1; } const findingSummary = Object.entries(severityCounts) .map(([sev, count]) => `${count} ${sev}`) .join(", "); lines.push( ` ${scan.id}`, ` Target: ${scan.targetUrl}`, ` Status: ${scan.status}`, ` Created: ${scan.createdAt}`, ` Findings: ${findingSummary || "none"}`, "", ); } return { content: [{ type: "text" as const, text: lines.join("\n") }] }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: "text" as const, text: `Failed to list pentests: ${message}` }], isError: true, }; } },