Model or dataset
s0ld13rr/pentestcode avatar
s0ld13rr/pentestcode

PentestCode: an autonomous pentest agent with shared engagement state

PentestCode - Multi-agent AI penetration testing system with persistent engagement state, strategic coordination, and parallel autonomous operations.

704 stars115 forksTypeScriptMIT

At a glance

What is it?
PentestCode is a terminal-based, multi-agent penetration testing system forked from OpenCode. Its distinguishing feature is a persistent engagement state that all thirteen specialist agents read from and write to, plus parser tools that force tool output into that state. It is beta software, and the README says so.
Who is it for?
Adopt PentestCode if you already run nmap, NetExec and BloodHound by hand and want the bookkeeping automated, and if you are comfortable running beta software against targets you are authorised to test. Do not adopt it if you need a stable tool with a long support window, or if your engagement cannot tolerate an LLM provider reading scan output.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem PentestCode targets: bookkeeping, not exploitation

The README frames the gap as memory rather than capability. Its claim is that the difference between PentestCode and "a pentester prompt pasted into a chat window" is a team of agents and a memory they share. That is a narrower and more defensible pitch than general autonomy. The stated failure mode it addresses is human: the agent "sprays every credential against every service on every host, and it doesn't forget to check things." Anyone who has run an internal engagement knows the real cost is not the one clever exploit, it is tracking which credential was tried against which service on which host, and which of those attempts succeeded. The README says everything learned lands in a structured state queryable mid-run with /status, /vulns or /creds. The target user is therefore an operator on a lab or CTF network, or on an authorised internal engagement, who already knows the tools and wants the tracking layer removed. It is not aimed at someone learning what an AS-REP roast is. The README example walks from nmap to domain admin, and that chain assumes the reader recognises ports 88 and 389 as a domain controller without explanation.

Strategist and specialists: how the thirteen agents divide work

The architecture follows what the README calls the strategist-coordinator model, citing HPTSA research and a 4.3x improvement over a single agent. The lead agent is named pentest. It plans, dispatches and tracks state, and it does not run tools itself in the diagram. Below it sit specialists: recon, scanner, enumerator, exploiter, identity for AD and Kerberos, infrastructure for SNMP, IPMI and databases, webapp scoped to OWASP Top 10, post-exploit, exploit-dev, a critic that checks for false positives, and a reporter. Two more agents are hidden: context compression and session management. That is thirteen in total. Each specialist has its own system prompt, tool permissions and domain knowledge, and the lead dispatches them in parallel. The parallel fan-out is visible in the example: ports 88 and 389 are recognised as a domain controller, then three enumerators run at once against SMB, LDAP and HTTP. The critic agent is the most interesting design choice here, because false positives are the standard complaint about automated scanning and the README treats them as a role rather than a filter. Whether a separate agent catches more than a confidence threshold would is not something the README establishes.

The engagement state, and why parser tools are mandatory

The shared state is the actual product. It holds hosts and services with IP, hostname, OS, ports, versions and banners; vulnerabilities with severity, status (suspected, confirmed, exploited), an evidence chain and a confidence score; credentials with username, hash or password, type, domain and what they unlock; access records showing who holds shell, RDP or DB on which host at what privilege level; an entity graph of relationships such as EXPLOITED_VIA, CREDENTIAL_FROM, ADMIN_OF and PIVOT_TO; an AD domain model with controllers, trusts, admins, password policy and GPOs; network segments with VLANs, reachable networks and pivot hosts; and attack paths computed with cost-based Dijkstra plus Yen's K-shortest routes over the relationship graph. The enforcement mechanism is the part worth noting. Parser tools are described as mandatory: after running nmap the agent must pipe output through nmap_parse rather than grep the XML by hand, "so every finding reaches the engagement state." That is a constraint on the agent, not a suggestion, and it is what keeps the graph from drifting away from reality. Eighteen built-in tools exist beyond bash, including nuclei_parse, cme_parse, gobuster_parse, bloodhound_parse and sqlmap_parse, plus xss_detect, jwt_analyze, cred_spray and scope_check. The parser set is the load-bearing wall: any tool whose output has no parser will not populate state automatically. The README excerpt does not list a parser for every tool an operator might reach for.

Persistence across sessions and the findings.md side channel

State survives the session. The README states that you can close the terminal, come back tomorrow, and the agent resumes where it stopped. For multi-day engagements this is the feature that separates PentestCode from a chat transcript, because the relationship graph, the credential list and the attack paths persist as structured data rather than prose. Alongside the state, a human-readable findings.md logs every vulnerability, credential and access gain with timestamps, and the README suggests tail -f to watch the engagement unfold. That file matters more than it first appears. It gives a reviewer something to read without querying the agent, and it gives you a way to check the agent's claims against a flat record. The trade-off is that two representations of the same engagement can diverge if a write path misses one. The README does not describe reconciliation between the structured state and findings.md, so treat the markdown as a log rather than a source of truth.

Install and first run: the commands the README gives

The install path is short. The npm route is npm install -g pentestcode-ai. The curl route is curl -fsSL https://raw.githubusercontent.com/s0ld13rr/pentestcode/main/install.sh | bash. The README states the result is a single self-contained binary with no Bun, Node or runtime to install, for Linux and macOS on x64 and arm64. Version pinning uses an environment variable: PENTESTCODE_VERSION=0.1.7 curl -fsSL ... | bash. Install location is set the same way: PENTESTCODE_INSTALL=/usr/local/bin curl -fsSL ... | bash. Building from source requires bun install, then bun run build --single --skip-embed-web-ui, with the binary at packages/opencode/dist/pentestcode-<os>-<arch>/bin/pentestcode. Note that path still carries the OpenCode package name, consistent with the fork. First run is pentestcode auth login to connect a provider, then pentestcode for an interactive session, or pentestcode --prompt "scan 10.10.10.0/24 and enumerate all services" for one-shot use. Providers are reached through ai-sdk, with Anthropic, OpenAI, Google, Azure, AWS Bedrock and Ollama named among 20-plus options. The README does not document configuration keys beyond these environment variables and the auth login flow.

Where PentestCode is the wrong tool

The README labels the project beta and says to expect rough edges, which is honest and should be taken literally. The larger constraint is architectural. Scan output, credential material and parsed findings pass through an LLM provider. On an engagement where target data cannot leave the operator's control, that rules out the hosted providers entirely and leaves a local option such as Ollama, which the README lists but does not otherwise discuss. Second, the parser dependency cuts both ways. If your toolchain emits a format the parser does not understand, or a version bump changes the output schema, the finding may never reach state, and the agent's picture of the network silently loses a fact. Third, the autonomy described is bounded by the tools present. The README lists 18 built-in pentest tools; anything outside that set falls back to bash, where no parser exists and state does not update automatically. Fourth, the attack-path computation uses Dijkstra and Yen's K-shortest over the relationship graph, which is only as good as the edges the parsers created. A missing BloodHound import produces a graph that looks complete and is not. Finally, the README's own example ends with a domain admin hash, which is a lab outcome. Nothing in the material describes handling of production change control, notification windows or the reporting obligations a client engagement carries.

The alternative: Metasploit with a human at the keyboard

The obvious comparison is Metasploit Framework. The difference is where the decision logic lives. Metasploit gives you modules, a database of hosts and services, and an operator who chooses what to run next; the framework executes and records, but it does not decide. PentestCode moves the decision to the lead agent, which reads the engagement state and dispatches specialists. That is the actual trade. You gain consistency on the tedious parts, particularly credential spraying across every discovered service and host, which the README singles out as something people get lazy about. You lose the ability to reason about a single step before it runs, unless you are watching the session. For a scoped, well-understood engagement where you want control over each action, Metasploit with a human driving is still the more predictable choice. PentestCode is aimed at the case where the enumeration surface is large enough that a human will skip checks. The README's HPTSA citation for the 4.3x figure is a claim about that research, not a benchmark of this project, and the material does not report any measurement of PentestCode itself.

Licence, forks and what maintenance costs you

PentestCode is MIT licensed. It is a hard fork of OpenCode, also MIT, stripped of the code-editing focus and rebuilt for offensive security. The fork relationship has practical consequences. The build output still lives under packages/opencode/dist, and upstream changes to OpenCode will not arrive automatically; someone has to port them or decide not to. Three releases are listed in the material, v0.2.4 through v0.2.6, the latest dated 2026-09-02, which indicates active work at a steady cadence. The README directs bug reports to the issue tracker and says filing them is what improves the project, which is a reasonable signal that maintenance is community-driven rather than backed by a support commitment. Upgrading means re-running the install script or the npm global install, and because engagement state persists across sessions, an upgrade mid-engagement is a real risk if the state schema changes between versions. The material does not describe a migration path. This is a description of the licence terms, not legal advice; if you redistribute PentestCode or bundle it into a service, read the MIT text and your own obligations.

Editorial conclusion

Adopt PentestCode if you already run nmap, NetExec and BloodHound by hand and want the bookkeeping automated, and if you are comfortable running beta software against targets you are authorised to test. Do not adopt it if you need a stable tool with a long support window, or if your engagement cannot tolerate an LLM provider reading scan output. Verify first that your provider is reachable through the ai-sdk path, that the parser tools cover the specific tool versions you use, and that the engagement state file is written somewhere your evidence handling allows.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. s0ld13rr/pentestcode on GitHub
Community notes

Community notes