start_pentest
Launch an AI-powered penetration test against a verified target URL to identify security vulnerabilities and assess application security posture.
Instructions
Launch an AI-powered penetration test against a target URL. The domain must be verified first (see list_domains). Requires an available credit matching the selected tier.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| target_url | Yes | The target URL to scan (must be a verified domain) | |
| repo_url | No | GitHub repository URL for white-box scanning (SAST, secrets, SCA) | |
| tier | No | Scan tier: recon (1 agent, 30min), standard (4 agents, 1hr), deep (10 agents, 2hr), blitz (20 agents, 4hr) | standard |
Implementation Reference
- src/tools/start-pentest.ts:6-86 (registration)The registration and handler for the start_pentest tool. The tool definition, schema, and core logic (invoking client.startPentest) are consolidated in this function.
export function registerStartPentest(server: McpServer, client: TurboPentestClient): void { server.registerTool( "start_pentest", { title: "Start Pentest", description: "Launch an AI-powered penetration test against a target URL. " + "The domain must be verified first (see list_domains). " + "Requires an available credit matching the selected tier.", inputSchema: z.object({ target_url: z.string().url().describe("The target URL to scan (must be a verified domain)"), repo_url: z .string() .url() .optional() .describe("GitHub repository URL for white-box scanning (SAST, secrets, SCA)"), tier: z .enum(["recon", "standard", "deep", "blitz"]) .default("standard") .describe( "Scan tier: recon (1 agent, 30min), standard (4 agents, 1hr), deep (10 agents, 2hr), blitz (20 agents, 4hr)", ), }), }, async ({ target_url, repo_url, tier }) => { try { const result = await client.startPentest({ targetUrl: target_url, repoUrl: repo_url, tier, }); if ("groupId" in result && result.groupId) { const multi = result as MultiDomainResponse; const lines = [ `Pentest group started: ${multi.groupId}`, `Scans launched: ${(multi.scans ?? []).length}`, "", ...(multi.scans ?? []).map((s) => ` - ${s.targetUrl} (ID: ${s.id})`), "", "Use get_pentest with each scan ID to check status.", ]; return { content: [{ type: "text" as const, text: lines.join("\n") }] }; } const scan = result as Scan; const tierInfo: Record<string, { agents: number; duration: string }> = { recon: { agents: 1, duration: "~30 minutes" }, standard: { agents: 4, duration: "~1 hour" }, deep: { agents: 10, duration: "~2 hours" }, blitz: { agents: 20, duration: "~4 hours" }, }; const info = tierInfo[tier] || tierInfo.standard; const lines = [ "Pentest started successfully", "", ` ID: ${scan.id}`, ` Target: ${scan.targetUrl}`, ` Status: ${scan.status}`, ` Tier: ${tier}`, ` Agents: ${info.agents}`, ` Duration: ${info.duration}`, scan.repoUrl ? ` Repo: ${scan.repoUrl}` : null, "", `Use get_pentest("${scan.id}") to check progress.`, ]; return { content: [{ type: "text" as const, text: lines.filter(Boolean).join("\n") }], }; } catch (error) { const message = error instanceof Error ? error.message : String(error); return { content: [{ type: "text" as const, text: `Failed to start pentest: ${message}` }], isError: true, }; } }, ); }