HexStrike AI Made Security Tooling an API for LLMs. Then the Underground Found It.

A two-process MCP bridge wraps 150 pentesting tools into callable functions. The defaults are careful. The autonomy switch is a single JSON flag.

9 min read • View on GitHub • More from 0x4m4

A wide editorial illustration of a narrow footbridge with no railing spanning a deep chasm. On the left cliff sits a vast open-air warehouse of labeled security tools: a hammer rack, a bin of lockpicks, a shelf of radio scanners, and crates marked HASHCAT and NMAP, with dozens more receding into crosshatched shadow. On the right cliff, a single small terminal sits on a plain desk with a blinking cursor, connected back across the bridge by a thin cable. The image illustrates HexStrike as a bridge that exposes a warehouse of external security binaries to a single LLM terminal, with the missing railing standing in for the absent safety guardrails.
HexStrike is a bridge, not a weapon. It connects a warehouse of external security binaries to a single LLM terminal. The bridge has no railing.

It’s an open-source Model Context Protocol (MCP) agent that enables AI models (GPT, Claude, Copilot, or custom LLMs) to autonomously orchestrate 70+ security tools for penetration testing, vulnerability scanning, recon, bug bounty, and CTF automation.

Muhammad Osama, Creator of HexStrike AI · @0x4m4 on LinkedIn
Key Takeaways

The Forum Post That Started the Conversation

In September 2025, Check Point Research published an executive insight on a tool called HexStrike-AI. The report described chatter in underground forums following Citrix NetScaler vulnerability disclosures, where attackers discussed using the framework to move faster against n-day flaws. BleepingComputer followed with reporting that threat actors had discussed HexStrike against NetScaler targets, and that attackers reportedly achieved unauthenticated remote code execution and deployed webshells.

Both outlets were careful about one thing: neither confirmed HexStrike's involvement in the attacks. Check Point considered attacker use likely. Likely is not proven.

So this is not a story about a tool that hacked Citrix. It is a story about why a tool like this would show up in that conversation at all. The answer lives in the architecture, and the architecture turns out to be more interesting than the rumor.

The most consequential line in the entire repository is not in the code. It is a string inside a sample config file.

That is the tension in one sentence. It sits inside a description field, next to a timeout: 300 and an empty array. The safety posture of an autonomous security agent is documented the way you would document a keyboard shortcut.

What HexStrike Actually Is

HexStrike is not a scanner. It does not find vulnerabilities, exploit them, or reason about a target on its own. It is a bridge.

The Model Context Protocol (MCP) is a standard way for an AI host like Claude Desktop, Cursor, or Roo Code to discover and call external functions. HexStrike implements the server side of that protocol, exposing tools like nmap, sqlmap, nuclei, hashcat, gobuster, ffuf, volatility3, and mitmproxy as callable functions. The LLM picks one, HexStrike runs the underlying binary, and the output comes back as JSON.

The tool count is worth a pause. The README and the MCP client both say 150+. The server's own docstring says 100+. That gap is a small tell about how carefully the claims have been reconciled against the code.

The README also advertises a "Decision Engine" and "12+ Autonomous AI Agents." Those are README claims. The visible source does not show a distinct decision engine, and the agents read as prompt-level abstractions rather than separate services. Attribute them to the marketing, not to the architecture.

Two Processes, One Bridge

Here is the design decision that separates HexStrike from almost every other MCP server.

Most MCP servers are a single file. They speak stdio directly to the host and exit when the session ends. HexStrike splits into two processes. hexstrike_mcp.py is the adapter the AI host launches, and it speaks MCP over stdio. hexstrike_server.py is a Flask backend that listens on 127.0.0.1:8888 and does the actual work.

The adapter does not run tools. It forwards POST /api/tools/<name> requests to the backend over HTTP and returns the answers. The backend spawns the binaries, manages browser sessions through Selenium, and keeps caches alive.

One tool call's full round trip. The backend holds state so the adapter can be restarted freely. Toggle off any station to see what breaks.

Why split? State. A security scan can run for minutes. A browser session needs to survive between prompts. If the adapter held that state, restarting the AI host would kill every in-flight scan and drop every session. By pushing state into a long-lived backend, the adapter becomes disposable. You can restart Cursor, reconnect Claude Desktop, and the backend keeps working.

The cost is real. Two moving parts instead of one. An open local port. A config file that has to point the adapter at the backend. And two separately maintained copies of the same ANSI color palette, one in each file, kept in sync by convention because there is no shared module.

The adapter also does something right that is easy to miss: it logs to stderr, never stdout. MCP uses stdout for protocol messages. Any stray print() would corrupt the stream. The client routes every log line to stderr, which shows that someone understood the constraint.

{
  "mcpServers": {
    "hexstrike-ai": {
      "command": "python3",
      "args": ["/path/hexstrike_mcp.py", "--server", "http://IPADDRESS:8888"],
      "timeout": 300,
      "alwaysAllow": []
    }
  }
}

Note the IPADDRESS placeholder. The sample ships expecting you to put a real host there. The default binding is localhost, but the template quietly suggests remote deployment is a normal configuration.

The Switch That Decides Everything

A tight close-up editorial illustration of a single brass toggle switch mounted on a plain white panel. A small printed label beside it reads alwaysAllow. The switch is flipped up. Fine crosshatched cables run from the base of the switch toward the edge of the frame and off-page. A human fingertip rests lightly on the switch, not yet pressing. The image makes the single most consequential configuration decision in HexStrike physical and human-scale, isolating the field that controls whether an agent runs autonomously.
The entire autonomy question is one field in a client config. The fingertip is the operator, and the operator usually sets it once.

Now the part that matters.

alwaysAllow is a client-side field in the MCP config. When populated, the host auto-approves tool calls without asking the user. When empty, each call prompts for confirmation. The entire question of whether an agent runs autonomously against a target comes down to what you put in this array.

There is no scope enforcement in the visible code. No target allowlist. No domain restriction. No rate limit on how many tools an agent can chain. The Flask API shows no authentication. The only thing standing between an MCP client and 150 executable security binaries is whether you left alwaysAllow empty.

Contrast that with the care elsewhere in the repo. The server falls back to stdout-only logging if it cannot write its log file, handling read-only working directories. The client retries the /health check three times with a five-second timeout so it fails with a clear message instead of a confusing first-call error. Environment variables drive the host and port. Key order is preserved in JSON responses. Someone thought hard about robustness.

They thought much less about scope. That asymmetry is the story.

One open question the truncated source cannot answer: whether tool arguments from the LLM are passed through shlex.quote or concatenated into shell strings. subprocess is imported, but the invocation pattern is not visible. If arguments are concatenated, an LLM that can be prompt-injected becomes a command-injection vector. That is the question a security reviewer would ask first.

With Hexstrike-AI, that barrier seems to have collapsed.

Amit Weigman, Office of the CTO, Check Point · Check Point Research

How It Compares

The useful column here is not stars. It is what layer each project occupies.

ProjectLayer it occupiesHow a model drives itWhat it does not do
HexStrike AIOrchestration bridgeMCPDoes not scan, exploit, or reason on its own. Ships no tests, no CI, no auth on the API.
PentestGPTReasoning assistantPromptDoes not wrap a broad external tool catalog or expose an MCP server.
StrixApplication security agentPromptFocused on app testing, not a cross-domain tool bridge.
Metasploit FrameworkExploitation frameworkN/ADoes not plan or chain actions from a model.
NucleiTemplate scannerN/ADeterministic checks, no model-driven tool selection.
Burp SuiteWeb testing platformN/ACommercial, closed, not an MCP orchestration layer.
NmapNetwork utilityN/AA single specialist tool, not an orchestrator.

HexStrike is the only row that is a bridge rather than a tool or an assistant. Everything else either performs a fixed job or reasons about one. HexStrike's job is to hand a model a grant to call the others.

What MCP Just Became

MCP turns "an LLM with tools" into "an LLM with a tool grant." That is a meaningful shift. A tool call is a permission, and permissions have blast radius. In most domains, the worst case is a bad answer or a wasted API call. In security, the worst case is a live scan or an exploit run against infrastructure you do not own.

HexStrike is the clearest case study for that shift because it sits at the highest-stakes end of the domain. It is also, to be fair, a well-intentioned red-team automation project. The README frames it as human-in-the-loop. The creator described it as a continuous cycle of prompts, analysis, execution, and feedback. That framing is honest. The defaults just do not enforce it.

A WSJ hedcut-style editorial portrait of Muhammad Osama, creator of HexStrike AI, rendered in black ink on a pure white background. The portrait preserves his actual likeness from his GitHub avatar, using stipple dots for skin texture and fine hatching lines for hair and clothing.

The interesting question is not whether attackers used this specific tool against Citrix. The reporting does not confirm that, and this article will not pretend otherwise. The interesting question is that the category now exists. An MCP server that wraps a hundred offensive binaries is a few hundred lines of glue code, and the safety model is a JSON flag that most operators will set once and forget.

Defaults matter more than intentions. That is the lesson worth carrying out of this repo.