Skip to main content
Glama

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
NameRequiredDescriptionDefault
pentest_idYesThe pentest ID (UUID)

Implementation Reference

  • 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,
        };
      }
    },
  • 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)"),
    }),
  • 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,
            };
          }
        },
      );
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/integsec/turbopentest-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server