An agentic, workflow-driven pentesting CLI. Claude Code-style architecture for authorized offensive security.
Project description
PentestCode
An agentic, workflow-driven pentesting CLI. Claude Code-style architecture — tool modules, permission modes, subagents, dynamic workflows, conversation compaction, and agent teams — rebuilt from scratch for authorized offensive security, on top of a Docker sandbox and a LiteLLM brain that talks to any model.
Authorized testing only. PentestCode is built for security professionals testing systems they own or have explicit written permission to test. Like Metasploit or nuclei, the tool does not police your targets — you are responsible for having authorization for anything you point it at.
Why not just Kali + scripts?
Kali gives you tools; PentestCode gives you an operator. It:
- Remembers the environment. All engagement state lives in plain markdown
(
.pentestcode/), so it never re-runs recon it already did and any session can resume mid-engagement — even after the conversation is compacted. - Fans out work as workflows. Describe a task and it writes an orchestration script that spawns dozens of focused subagents in parallel (recon per host, enum per service, a scanner per target) — then an adversarial verifier re-tests every candidate finding before it's allowed into the report.
- Runs everything in a sandbox. Every command executes inside a Kali Docker container, never on your host.
- Compacts long engagements. Auto-summarizes the conversation as it nears the context window, anchored to the memory files so nothing real is lost.
- Zero setup. No init, no scope ceremony —
pentestcode chat, type a target, go. Just like Claude Code.
The architecture
you ──> CLI (Typer) ──> Agent loop ──> LiteLLM ──> any model (Claude/GPT/local)
│ │
│ ├─> Tools ──> PermissionGate ──> Docker sandbox (Kali)
│ │
│ ├─> MemoryStore (.pentestcode/*.md — env memory)
│ ├─> CompactionManager (auto /compact)
│ ├─> Subagents (isolated contexts)
│ ├─> WorkflowRuntime (agent()/pipeline(), checkpoints)
│ │ └─> Adversarial Verifier
│ └─> TeamManager (shared tasks + mailboxes)
│
└─> ReportGenerator ──> report.md + report.html
Install
Requires Python 3.9+, Docker running, and one model key (ANTHROPIC_API_KEY,
OPENAI_API_KEY, or an Ollama/LM Studio endpoint).
From PyPI (one command):
pip install "pentestcode[tui]" # [tui] = the terminal UI
Straight from GitHub (no clone):
pip install "pentestcode[tui] @ git+https://github.com/Arpitpm23/pentestcode.git"
From a local clone (recommended if you'll edit the code):
git clone https://github.com/Arpitpm23/pentestcode.git
cd pentestcode
pip install -e ".[tui]" # -e = editable, .[tui] = this repo + the TUI
Use either
pip installorpipx install— not both.pipxis just pip in an isolated venv (nice for CLI tools); swappip install→pipx installin any command above if you prefer it.
Then verify:
pentestcode doctor # checks docker + API keys
Quickstart
No init, no scope file required. Just open the chat and go:
pentestcode chat
# (optional, once: build the Kali sandbox image)
pentestcode init
Inside chat — targets come straight from your messages:
> recon scanme.nmap.org # just say what to hit
> ultracode: audit dvwa.local end to end # model writes its own workflow
> /workflow vuln_audit 10.0.0.5 # scan + adversarially verify
> /context # token usage before compaction
> /compact # fold the conversation now
> /report # md + html report
Want to constrain it to a scope? Write .pentestcode/SCOPE.md (or run
pentestcode init --targets a.com,b.com) and commands are checked against it.
No SCOPE.md → runs unrestricted, like any CLI tool.
Dynamic workflows
The centerpiece. Say ultracode: <task> (or /workflow <name>) and the model
writes a Python orchestration script using two primitives:
result = await agent(prompt, schema=None, label=None, tools=None, model=None)
results = await pipeline(items, fn, concurrency=None)
The script runs in a restricted runtime — no filesystem/shell/imports; only
its subagents can act. The plan lives in script variables, not the model's
context; intermediate results never touch the main conversation; every agent is
checkpointed to .pentestcode/workflows/<run_id>/ so an interrupted run resumes
from cache. Scripts you like can be saved to .pentestcode/workflows/ and re-run as
/workflow <name>.
Bundled workflows: recon_sweep, service_enum, vuln_audit,
exploit_verify, full_engagement.
Adversarial verification
Scanners lie. Every candidate finding a workflow produces is handed to a
separate verifier subagent whose job is to refute it — re-test the target,
hunt for false positives. Only confirmed findings are written to
FINDINGS.md and into the report. This is the difference between a 40-item
nuclei dump and a 6-item report you can defend.
Environment memory
.pentestcode/ is the agent's long-term memory, in human-editable markdown:
| File | What it holds |
|---|---|
SCOPE.md |
authorized targets, constraints, authorization |
STATE.md |
hosts, services, credentials, current phase, done-list, open threads |
FINDINGS.md |
verified findings only |
WORKLOG.md |
append-only log of every command + outcome |
Read at session start, injected again after compaction, updated the moment the agent learns anything. Diff it in git, edit it by hand, the agent adapts.
Agent teams
For work that needs parallel collaboration (not just fan-out):
pentestcode teams "full audit of the web tier" --members recon,web,network
A lead session spawns independent teammates — own context, own compaction — coordinating through a shared, file-locked task list and JSON mailboxes, with plan-approval gates before risky stages.
Safety model
PentestCode takes the same posture as Metasploit, nuclei, or sqlmap: the tool doesn't police your targets — you do. It runs unrestricted by default and acts on whatever you give it in chat. Two things are on you:
- Have authorization for every target. This is an authorized-testing tool.
- The Docker sandbox isolates commands from your host — it does not make an unauthorized target authorized.
Optional friction you can turn on:
- Scope enforcement: write
.pentestcode/SCOPE.md(orpentestcode init --targets a.com,b.com) and every command's targets are checked against it; out-of-scope commands are blocked. Delete the file to go back to unrestricted.
Permission modes
Every command runs inside the Docker sandbox — nothing ever executes on your
host (not even ls). The container is the only execution path and can only
reach the engagement workspace volume. So permissions are about friction, not
isolation. Two modes:
| Mode | Behavior |
|---|---|
manual |
Ask before every command (a small approval modal: y allow / a always / n deny). Default — good for unfamiliar targets. |
auto |
Run everything without asking. Safe because the command is confined to the container. |
Switch with /mode manual or /mode auto, cycle with ctrl+m, or start in
auto with pentestcode chat --auto.
Configuration
~/.pentestcode/settings.yaml (user) and .pentestcode/settings.yaml (project).
Every Config field is settable there; env override: PENTESTCODE_MODEL.
model:
provider_model: claude-sonnet-4-6 # any LiteLLM model string
subagent_model: gpt-5-mini # cheaper model for workers
effort: high # low|medium|high|ultracode
workflows:
max_concurrent_agents: 16
size_guideline: medium # unrestricted|small|medium|large
Community plugins
Drop your own workflows in .pentestcode/workflows/<name>.py — same agent() /
pipeline() primitives — and they appear next to the bundled ones. See
docs/plugins.md.
Development
pip install -e ".[dev]"
python tests/test_smoke.py # memory, gate, workflow runtime (mocked), sandbox escape
Contributions welcome — see CONTRIBUTING.md.
License
Apache 2.0 — see LICENSE.
Architecture inspired by Anthropic's Claude Code (dynamic workflows, subagents, compaction). Written from scratch; no Claude Code source is used or distributed.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pentestcode-0.1.2.tar.gz.
File metadata
- Download URL: pentestcode-0.1.2.tar.gz
- Upload date:
- Size: 59.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d5916e5a3794fa13439ba32baa0e4c0d4980d895b30759352d7e3b69263da83
|
|
| MD5 |
88228a96c977ca514cc2e077862b7de6
|
|
| BLAKE2b-256 |
f74d0d8c185a2dacb45d8256cbde92f55225c0a40bd1ac01adbbafefc864a58e
|
File details
Details for the file pentestcode-0.1.2-py3-none-any.whl.
File metadata
- Download URL: pentestcode-0.1.2-py3-none-any.whl
- Upload date:
- Size: 67.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
821d5c722902907376978000cae8f2cc6f5b528c1a0f786f0ecd1a03517e351d
|
|
| MD5 |
29854d3405efd13df7e4591f43456653
|
|
| BLAKE2b-256 |
010159267595c1daedcc91d6d907f77b18dcabaaac98244316d4110a4cd104cb
|