Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Armur-Ai/Pentest-Swarm-AI/llms.txt

Use this file to discover all available pages before exploring further.

pentestswarm serve starts the Pentest Swarm AI backend — a Fiber HTTP server that exposes a REST API for creating and managing campaigns, querying findings, streaming live events over WebSocket, and listing available models. The server is the backbone of the web dashboard and is also what the pentestswarm campaign subcommands talk to when running in API mode.

Synopsis

pentestswarm serve [flags]

Flags

--port
integer
default:"8080"
The TCP port the server listens on.

Examples

# Start the server on the default port
pentestswarm serve

# Start on a custom port
pentestswarm serve --port 9090
Startup output:
  ██████  ██     ██  █████  ██████  ███    ███
  ██      ██     ██ ██   ██ ██   ██ ████  ████
  ███████ ██  █  ██ ███████ ██████  ██ ████ ██
       ██ ██ ███ ██ ██   ██ ██   ██ ██  ██  ██
  ███████  ███ ███  ██   ██ ██   ██ ██      ██

  API Server:  http://localhost:8080/api/v1
  Health:      http://localhost:8080/api/v1/health
  Provider:    claude

REST API reference

All endpoints are prefixed with /api/v1. CORS is enabled for all origins (*). Authentication is via X-API-Key header (configured in config.yaml).

GET /api/v1/health

Liveness check. Returns immediately with no database dependency. Response:
{ "status": "ok", "service": "pentestswarm" }

POST /api/v1/campaigns

Create a new campaign. Does not start it — call /campaigns/:id/start to begin execution. Request body (CreateCampaignRequest):
FieldTypeRequiredDescription
targetstringDomain, IP, or CIDR to test
scope[]stringIn-scope domains/CIDRs
objectivestringDefaults to "find all vulnerabilities"
modestringmanual | bugbounty | asm | ctf. Defaults to "manual"
dry_runboolSimulate without executing commands
{
  "target": "example.com",
  "scope": ["example.com", "*.example.com"],
  "objective": "find SQL injection vulnerabilities",
  "mode": "bugbounty",
  "dry_run": false
}
Response (201 Created):
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "scan-example.com-20260601-140523",
  "target": "example.com",
  "status": "planned"
}

GET /api/v1/campaigns

List all campaigns. Response:
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "scan-example.com-20260601-140523",
      "target": "example.com",
      "status": "running",
      "objective": "find SQL injection vulnerabilities",
      "created_at": "2026-06-01T14:05:23Z",
      "findings": 7
    }
  ],
  "meta": { "total": 1 }
}

GET /api/v1/campaigns/:id

Get detailed state of a single campaign. Response:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "scan-example.com-20260601-140523",
  "target": "example.com",
  "objective": "find SQL injection vulnerabilities",
  "status": "running",
  "mode": "bugbounty",
  "created_at": "2026-06-01T14:05:23Z",
  "started_at": "2026-06-01T14:05:30Z",
  "findings": 7,
  "events": 124
}

POST /api/v1/campaigns/:id/start

Start executing a planned campaign. Returns 409 Conflict if the campaign is already started. Response (202 Accepted):
{ "status": "starting", "id": "550e8400-e29b-41d4-a716-446655440000" }
The campaign runs in a background goroutine. Use the WebSocket endpoint or GET /events to follow progress.

POST /api/v1/campaigns/:id/stop

Cancel a running campaign. Sends a context cancellation to all running goroutines and sets status to aborted. Response:
{ "status": "stopped", "id": "550e8400-e29b-41d4-a716-446655440000" }

GET /api/v1/campaigns/:id/findings

Get all findings discovered during a campaign. Response:
{
  "data": [
    {
      "title": "SQL Injection in /search?q=",
      "severity": "critical",
      "cvss": 9.8,
      "affected_components": ["/search"],
      "verified": true
    }
  ],
  "meta": { "total": 1 }
}

GET /api/v1/campaigns/:id/events

HTTP polling endpoint for campaign events. Returns the last 50 events. Response:
{
  "data": [
    {
      "event_type": "tool_call",
      "agent_name": "recon",
      "detail": "Running subfinder on example.com",
      "timestamp": "2026-06-01T14:05:35Z"
    }
  ],
  "meta": { "total": 124 }
}

GET /api/v1/campaigns/:id/ws

WebSocket endpoint for real-time event streaming. Connect with any WebSocket client to receive CampaignEvent JSON objects as they are emitted by the swarm. Connecting with websocat:
websocat ws://localhost:8080/api/v1/campaigns/550e8400-e29b-41d4-a716-446655440000/ws
Connecting with JavaScript:
const ws = new WebSocket(
  "ws://localhost:8080/api/v1/campaigns/550e8400.../ws"
);
ws.onmessage = (e) => console.log(JSON.parse(e.data));
Each message is a CampaignEvent JSON object:
{
  "event_type": "finding_discovered",
  "agent_name": "exploit",
  "detail": "SQL injection confirmed in /search?q=",
  "timestamp": "2026-06-01T14:07:22Z",
  "data": { "severity": "critical", "cvss": 9.8 }
}
The server keeps the connection alive. Send any message (e.g. "ping") from the client to keep the connection warm.

GET /api/v1/models

List the models available in the model registry. Response:
{
  "models": [
    { "id": "claude-sonnet-4-6", "provider": "claude" },
    { "id": "claude-opus-4-7", "provider": "claude" },
    { "id": "claude-haiku-4-5-20251001", "provider": "claude" }
  ]
}

GET /api/v1/stats

Aggregate statistics across all campaigns — useful for dashboards. Response:
{
  "campaigns": 12,
  "active_campaigns": 2,
  "total_findings": 87,
  "by_severity": {
    "critical": 3,
    "high": 14,
    "medium": 32,
    "low": 28,
    "info": 10
  },
  "by_agent": {
    "recon": 412,
    "exploit": 231,
    "classifier": 189
  }
}

MCP server (pentestswarm mcp serve)

In addition to the REST API, Pentest Swarm AI exposes a Model Context Protocol (MCP) server over stdio. This lets Claude Desktop, Cursor, and any other MCP-compatible AI client invoke pentestswarm tools natively.
pentestswarm mcp serve
The MCP server is hidden from --help by default (it is an advanced integration path). Configure it in Claude Desktop by adding the following to your claude_desktop_config.json:
{
  "mcpServers": {
    "pentestswarm": {
      "command": "pentestswarm",
      "args": ["mcp", "serve"]
    }
  }
}
After restarting Claude Desktop, the pentestswarm tool set will appear in the tool palette. You can then ask Claude to “scan example.com with pentestswarm” and it will invoke the swarm directly.
The MCP server uses stdio transport. It does not open a TCP port. The API key is resolved from config.yaml or environment variables, identical to the CLI.

scan

Launch campaigns via the CLI (uses the embedded server internally)

campaign

Manage campaigns through the TUI — backed by the same REST API

doctor

Verify the API server is reachable with pentestswarm doctor

init

Configure API keys and generate config.yaml with pentestswarm init

Build docs developers (and LLMs) love