mech.app
AI Agents

PentestAgent: How Security Testing Agents Orchestrate Recon, Exploitation, and Reporting Without Human Playbooks

Multi-stage security testing workflow orchestration: how an AI agent framework chains reconnaissance tools, vulnerability scanners, and exploit modules.

Source: github.com
PentestAgent: How Security Testing Agents Orchestrate Recon, Exploitation, and Reporting Without Human Playbooks

PentestAgent is an AI agent framework that chains reconnaissance, vulnerability scanning, and exploitation tools into multi-stage penetration testing workflows. It runs in a TUI, calls external security tools through Docker isolation, and supports MCP (Model Context Protocol) for tool discovery. The project hit GitHub trending rank 8 for Python because it demonstrates practical offensive security automation beyond chatbot demos.

Why This Matters Now

Most agent frameworks show toy examples or single-step tool calls. PentestAgent exposes the plumbing for multi-stage workflows where state must persist across recon, scanning, exploitation, and reporting phases. It also shows how to safely execute untrusted binaries (nmap, metasploit, sqlmap) inside containerized boundaries while maintaining LLM context.

The MCP compatibility layer is the interesting part. Instead of hardcoding function schemas, the agent can discover tools at runtime and adapt to different security testing contexts without redeployment.

Architecture

PentestAgent uses LiteLLM as the model abstraction layer, so you can point it at OpenAI, Anthropic, or any relay that speaks the OpenAI API contract. The agent loop runs in Python 3.10+ and orchestrates external tools through subprocess calls or Docker exec.

Execution Modes

ModeIsolationTool AvailabilityUse Case
NativeProcessSystem binaries onlyLocal dev, low-risk targets
Docker baseContainernmap, netcat, curlIsolated recon without heavy tooling
Docker KaliContainermetasploit, sqlmap, hydra, niktoFull pentest suite with exploit modules

The --docker flag switches from native subprocess execution to containerized tool calls. The Kali image ships with metasploit, sqlmap, hydra, and other offensive tools pre-installed.

State Management Across Stages

A typical penetration test follows this flow:

  1. Recon: Port scan, service enumeration, subdomain discovery
  2. Scanning: Vulnerability detection, version fingerprinting
  3. Exploitation: Exploit execution, privilege escalation
  4. Reporting: Evidence collection, finding aggregation

PentestAgent maintains state by passing prior tool outputs into the LLM context window. Each stage appends results to a conversation history that the agent uses to decide the next tool call. This is not a stateful database, it is context accumulation within the LLM’s working memory.

If the context window fills, the agent must summarize or truncate. The framework does not currently implement external memory stores or vector retrieval for long-running engagements.

Tool Calling Surface

PentestAgent exposes security tools as functions the LLM can invoke. In native mode, this is a Python function that wraps subprocess.run(). In Docker mode, it becomes docker exec <container> <command>.

MCP Compatibility

MCP (Model Context Protocol) is a standard for tool discovery and invocation. Instead of hardcoding tool schemas in Python, the agent can query an MCP server for available tools and their signatures.

This changes the deployment model. You can add new security tools by registering them with an MCP server, and the agent will discover them at runtime without code changes. The trade-off is an additional network hop and the need to run an MCP server alongside the agent.

Example Tool Call Flow

# Native mode: direct subprocess
def run_nmap(target: str, flags: str = "-sV") -> str:
    result = subprocess.run(
        ["nmap", flags, target],
        capture_output=True,
        text=True,
        timeout=300
    )
    return result.stdout

# Docker mode: containerized execution
def run_nmap_docker(target: str, flags: str = "-sV") -> str:
    result = subprocess.run(
        ["docker", "exec", "pentestagent", "nmap", flags, target],
        capture_output=True,
        text=True,
        timeout=300
    )
    return result.stdout

The LLM receives the tool schema and decides when to call run_nmap based on the conversation context. If the agent is in recon phase, it might call nmap -sV <target> to enumerate services. If it finds an open HTTP port, it might follow up with nikto -h <target> or sqlmap -u <url>.

Security Boundaries

Running an autonomous agent that executes exploit tools creates obvious risks. PentestAgent mitigates this with:

  • Docker isolation: Tools run in a container with no host network access by default
  • Timeout enforcement: Each tool call has a 300-second timeout to prevent runaway processes
  • No credential storage: API keys live in environment variables, not in agent memory
  • Manual target specification: The -t flag requires explicit target input, no autonomous target discovery

The Docker container does not have network access to the host by default. If you need to test localhost services, you must configure Docker networking explicitly.

What This Does Not Protect Against

  • Lateral movement: If the agent compromises a target, it can pivot to other systems reachable from that target
  • Data exfiltration: The agent can read and transmit any data it discovers during exploitation
  • Destructive actions: Tools like metasploit can modify or delete files on compromised systems
  • API key leakage: If the LLM logs tool calls, API keys in environment variables may appear in logs

This is an offensive security tool. Do not point it at systems you do not own or have explicit permission to test.

Deployment Shape

PentestAgent runs as a local TUI application. You launch it with pentestagent or pentestagent -t <target>. It does not expose an HTTP API or run as a daemon.

Configuration

The .env file controls model selection and API credentials:

# Anthropic
ANTHROPIC_API_KEY=sk-ant-...
PENTESTAGENT_MODEL=claude-sonnet-4-20250514

# OpenAI
OPENAI_API_KEY=sk-...
PENTESTAGENT_MODEL=gpt-5

# Custom relay
OPENAI_API_KEY=relay-token
OPENAI_API_BASE=https://relay.example/v1
PENTESTAGENT_MODEL=openai/custom-model

LiteLLM handles provider routing. If you set ANTHROPIC_API_KEY, it uses Anthropic. If you set OPENAI_API_KEY and OPENAI_API_BASE, it routes through your relay.

Docker Deployment

The pre-built images are available on GitHub Container Registry:

# Base image (nmap, netcat, curl)
docker run -it --rm \
  -e ANTHROPIC_API_KEY=your-key \
  -e PENTESTAGENT_MODEL=claude-sonnet-4-20250514 \
  ghcr.io/gh05tcrew/pentestagent:latest

# Kali image (metasploit, sqlmap, hydra)
docker run -it --rm \
  -e ANTHROPIC_API_KEY=your-key \
  -e PENTESTAGENT_MODEL=claude-sonnet-4-20250514 \
  ghcr.io/gh05tcrew/pentestagent:kali

The Kali image is larger (several GB) because it includes the full Kali Linux toolchain. Use the base image for recon-only workflows.

Observability Gaps

PentestAgent does not ship with structured logging or telemetry. Tool calls and LLM responses appear in the TUI, but there is no persistent audit trail.

For production use, you would need to add:

  • Structured logging: JSON logs with timestamps, tool names, arguments, and results
  • Metrics export: Tool call latency, success/failure rates, token usage
  • State snapshots: Periodic dumps of conversation history for post-mortem analysis
  • Approval gates: Human-in-the-loop confirmation before destructive actions

The current design assumes a human operator is watching the TUI. If you run this headless or in a CI pipeline, you lose visibility into what the agent is doing.

Failure Modes

Context Window Overflow

Long penetration tests generate large tool outputs. If the cumulative context exceeds the model’s window (128k tokens for Claude Sonnet, 200k for GPT-4), the agent must truncate or summarize.

The framework does not currently implement intelligent summarization. It will either fail with a context length error or silently drop early conversation turns.

Tool Execution Timeouts

Each tool call has a 300-second timeout. If nmap takes longer (common for full port scans), the call fails and the agent loses that output.

The agent does not retry or fall back to faster scan modes. It will report the timeout and move on.

Docker Network Isolation

If the target is on the host machine or a private network, the Docker container may not be able to reach it. You must configure Docker networking (host mode or custom bridge) to allow container-to-target connectivity.

This is not documented in the README. You will discover it when your first scan fails with “host unreachable.”

MCP Server Availability

If you enable MCP and the server goes down, the agent loses access to all MCP-registered tools. There is no fallback to native tool execution.

You need monitoring and alerting on the MCP server if you depend on it for tool discovery.

Technical Verdict

Use PentestAgent when:

  • You need to automate repetitive recon and scanning tasks across multiple targets
  • You want to experiment with multi-stage agent workflows in a security context
  • You have explicit permission to test the target systems
  • You can monitor the TUI output in real time

Avoid PentestAgent when:

  • You need compliance-grade audit trails or approval workflows
  • You are testing production systems without a rollback plan
  • You require deterministic, repeatable test sequences
  • You need to preserve state across sessions longer than the LLM context window

This is a research-grade tool for offensive security automation. It shows how to chain tools and maintain state across a multi-stage workflow, but it lacks the observability and safety controls needed for unattended operation. If you are building similar agent systems, study the Docker isolation pattern and the MCP integration. If you are running penetration tests, treat this as a force multiplier for human testers, not a replacement.