AI Part 8: Kali 2026.2's Nine New Tools, and the MCP Server With 150 More Behind It
Part 7 was about wiring an LLM into two specific tools, nmap and Metasploit, one at a time. This one’s the wide-angle version: Kali Linux 2026.2 landed with nine new tools in the base repo, and one of them — shell-gpt — is an AI CLI that ships by default now, not bolted on. That felt worth a second post on its own, before I even started looking at what people are building on top of Kali with MCP.
So this is two posts stitched into one. First, all nine of the new 2026.2 tools, run for real wherever the sandbox would let me — these are not Metasploit, nmap, or aircrack-ng, the three everyone already knows. Second, the two AI-platform stories sitting just above the tool layer: HexStrike AI, an MCP server that wraps 150+ security tools behind one interface, and Kali’s own published stack for doing all of this fully offline with a local model.
Same rule as last time: every transcript below is from something that actually ran, in a rootless Ubuntu 22.04 sandbox with outbound network but no GPU, no display, and no sudo. Where that environment said no — and it said no more often this time, since several of these tools assume either a real terminal or a real GPU — I’ve said so plainly instead of writing around it.
The nine, run for real
Kali 2026.2’s new-tools list: arsenal-ng, hydra-gtk, legba, oletools, penelope, shell-gpt, tailscale, tookie-osint, uro. Two are GUI/TUI-only and couldn’t run headless at all; one needs an API key I’m not going to provision; the rest produced real output below.
uro — declutters URLs, but not how you’d guess
uro (Kali 1.0.2) takes a list of URLs meant for crawling/fuzzing and drops the redundant ones. I expected it to dedupe by exact match. It doesn’t — it dedupes by pattern:
$ printf '%s\n' \
"https://example.com/page?id=1" \
"https://example.com/page?id=2" \
"https://example.com/page?id=1&utm_source=x" \
"https://example.com/about" \
"https://example.com/page?id=3" | uro
https://example.com/page?id=1
https://example.com/page?id=1&utm_source=x
https://example.com/about
Three URLs differing only in the value of id collapsed to one representative. The two-parameter variant (id + utm_source) survived as a structurally distinct pattern. That’s the right behavior for feeding a fuzzer — testing id=1, id=2, and id=3 against the same endpoint logic is wasted requests — but it’s not what “declutter” suggests on first read, and it’ll surprise anyone expecting a literal dedupe.
oletools — the macro detector that’s blind to half its own job
oletools (0.60.2) is a suite of fifteen-odd commands for picking apart MS Office/OLE2 files. I pulled a real Excel 4.0 macro test sample — excel4_sample_macro.xls, maintained in the oletools project’s own test-data corpus specifically for exercising this code path — and ran three of the tools against it.
olevba correctly flags it:
$ olevba excel4_sample_macro.xls
olevba 0.60.2 on Python 3.10.12 - http://decalage.info/python/oletools
===============================================================================
FILE: excel4_sample_macro.xls
Type: OLE
-------------------------------------------------------------------------------
VBA MACRO xlm_macro.txt
in file: xlm_macro - OLE stream: 'xlm_macro'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
' Macro,A1,ALERT("This is a sample Excel 4 macro"),""
' Macro,A2,HALT(),""
+----------+--------------------+---------------------------------------------+
|Type |Keyword |Description |
+----------+--------------------+---------------------------------------------+
|AutoExec |Auto_Open |Runs when the Excel Workbook is opened |
|Suspicious|XLM macro |XLM macro found. It may contain malicious |
| | |code |
+----------+--------------------+---------------------------------------------+
So does oleid, which flags it Medium risk under “XLM Macros”. But mraptor — the tool whose entire job is “tell me fast whether this file auto-runs something malicious” — says clean:
$ mraptor excel4_sample_macro.xls
MacroRaptor 0.56.2 - http://decalage.info/python/oletools
Result |Flags|Type|File
----------+-----+----+--------------------------------------------------------
No Macro | |OLE:|excel4_sample_macro.xls
Flags: A=AutoExec, W=Write, X=Execute
Exit code: 0 - No Macro
mraptor’s AutoExec/Write/Execute heuristics are built for the VBA macro language. Excel 4.0 macros (XLM) are a different, older mechanism, and mraptor doesn’t look at them at all — so a file that two other tools in the same suite correctly flag as having an Auto_Open trigger sails through the one tool built specifically to catch that pattern. If mraptor’s exit code is the only thing gating a pipeline, this is a real blind spot, not a hypothetical one.
legba — the bruteforcer that’s natively an MCP server
legba (Rust, Kali ships 1.2.0, current upstream is 1.3.0) is a multiprotocol credential bruteforcer. I stood up a tiny local HTTP Basic Auth target — same pattern as vulnping.py in Part 7, 127.0.0.1 only, a contrived weak password — and pointed legba at it:
$ legba http.basic -T http://127.0.0.1:8090/ -U admin -P /tmp/passwords.txt --timeout 2000
legba v1.3.0
[INFO ] target: http://127.0.0.1:8090/
[INFO ] username -> string 'admin'
[INFO ] password -> wordlist /tmp/passwords.txt
[INFO ] tasks=2 mem=21.5 MiB targets=1 attempts=8 done=0 (0.00%) timeout=2000ms speed=0 reqs/s
[INFO ] [2026-06-30 21:48:47] (http) <http://127.0.0.1:8090/> username=admin password=sw0rdfish99
[INFO ] runtime 1.002897693s
Eight candidate passwords, one real hit, found in just over a second. One real gotcha along the way: I first tried -P @/tmp/passwords.txt with the @ prefix — by analogy with -T’s @filename syntax — and legba silently treated it as a single literal password string, ran exactly one attempt, and reported nothing found. The @ prefix is for glob expressions (@/some/path/*.txt); a plain wordlist just wants the bare path. Easy mistake, no error message to catch it.
The more interesting thing about legba, though, is in its own docs: --mcp <ADDR> starts a native MCP server, SSE or stdio, no wrapper project required. I tried it:
$ legba --mcp 127.0.0.1:3001 --concurrency 16
legba v1.3.0
[INFO ] starting sse mcp server on http://127.0.0.1:3001/sse ...
$ curl -i http://127.0.0.1:3001/sse
HTTP/1.1 200 OK
content-type: text/event-stream
cache-control: no-cache
transfer-encoding: chunked
event: endpoint
data: /message?sessionId=38c38632-058a-45b0-8922-9390f3a6ec92
A real SSE handshake, no third-party project in between. Worth sitting with the contrast: in Part 7, getting nmap and Metasploit in front of an LLM took two separate community wrapper projects (llm-tools-nmap, MetasploitMCP). legba ships that wiring itself, in the same binary, as a documented first-class feature — its own docs literally call it “the only credential bruteforcer with first-class MCP support.” One small, amusing data point on trusting secondary sources over primary ones: Kali’s own tools page for legba links its “Homepage” to github.com/maaaaz/webscreenshot — a completely different tool. The real upstream is github.com/evilsocket/legba. Worth checking the primary source even when the doc is Kali’s own.
tookie-osint — claims 80%, scored 100% on a string I invented thirty seconds earlier
tookie-osint (4.1fix) checks whether a username exists across a list of sites — a Sherlock-alike. Kali’s own tool page claims it’s “successful at this task almost 80% of the time.” I ran it against AzureSparrow8841, a string I made up on the spot specifically so it wouldn’t already be registered anywhere:
$ tookie-osint -u AzureSparrow8841 -t 10 -sk -o txt
[✓] You are running the latest version: v4.1fix
Loaded 262 URLs
[+] Scanning username: AzureSparrow8841
[+] https://www.reddit.com/user/AzureSparrow8841
[+] https://pypi.org/user/AzureSparrow8841
[+] https://trello.com/AzureSparrow8841
[+] https://medium.com/@AzureSparrow8841
[+] https://steamcommunity.com/groups/AzureSparrow8841
...
==============================================
Scan done!
Of 262 target sites, 64 completed a check before I cut the run off, and every single one of the 64 came back positive — true, no exceptions, written straight to the output file. That’s not “found a real account 80% of the time” for a string with zero chance of prior registration; that’s a near-total false-positive rate in this run, on whatever detection heuristic -sk (skip random headers) routes through. Worth independently verifying before trusting a “user not found” or “user found” result from this tool in anger — and worth not taking a tool’s own headline accuracy claim at face value, mine included, until you’ve thrown a deliberately-fresh string at it yourself.
shell-gpt — the AI tool that’s now apt-installable, and the wall it hits immediately
shell-gpt (1.5.1) is the headline new addition: an LLM-backed CLI for generating shell commands, code, and docs, now a stock Kali package rather than a third-party pip install. First run, no config:
$ sgpt --version
Please enter your OpenAI API key: [hangs — no TTY, no key, no way forward]
With a config file present but no key set:
$ sgpt --help
click.exceptions.UsageError: Missing config key: OPENAI_API_KEY
That’s the entire live-test result, and it’s an honest one: shell-gpt needs a real API key (OpenAI-compatible — it’ll also point at a local Ollama endpoint, per its docs) before it does anything at all, interactive or not. There’s no way to demo it further without provisioning a credential I’m not going to put in this sandbox. The fact that it’s apt-installable now, by default, on a security distro, is the actual story — not what it printed when I poked it with no key.
arsenal-ng and penelope — both real, both blocked by the same kind of wall
arsenal-ng (Go, 1.4) is a fuzzy-search command launcher with 200+ cheat-sheets — Kali’s own description: “Just install and start hacking.” It’s a full-screen TUI, and it wants a real terminal device:
$ arsenal-ng -h
Error: TUI error: could not open a new TTY: open /dev/tty: no such device or address
script -qc to fake a pty didn’t get further — confirmed this isn’t a missing-flag problem, it’s a hard requirement on an interactive terminal with no non-interactive escape hatch.
penelope (the Kali shell handler, 0.19.1) hit something similar but with an extra twist. There’s a different, unrelated PyPI package also named penelope (a translation/subtitle CLI, v3.1.3) — installing “penelope” from pip gets you the wrong tool entirely, silently, with no warning that the name collides:
$ pip install penelope && penelope -i 127.0.0.1 -p 4444 -L -C
penelope: error: unrecognized arguments: -L -C
usage: penelope -i INPUT_FILE -j INPUT_FORMAT -f LANGUAGE_FROM -t LANGUAGE_TO ...
Pulling the actual brightio/penelope source and running it directly hit the same TTY wall as arsenal-ng, just earlier — it reads terminal attributes at import time, before any argument parsing happens:
$ python3 penelope.py -h
termios.error: (25, 'Inappropriate ioctl for device')
Two genuinely different tools, two genuinely different failure modes, both boiling down to “this assumes an interactive terminal that a sandboxed shell tool doesn’t have.” Kali’s own published -h output for both (reproduced on their tools pages, not fabricated by me here) confirms what the interfaces look like; I just couldn’t drive them past the door in this environment.
tailscale — the binary’s fine, the daemon needs root
tailscale (1.98.8) is the odd one out — a mesh VPN client, not an offensive tool, presumably included for setting up access to a lab/C2 infra without exposing it publicly. The CLI itself runs cleanly:
$ tailscale --version
1.98.8
tailscale commit: 1241b225bc798707d02db3570992625d3a16594f
go version: go1.26.3 (tailscale/go e877d97384)
$ tailscale status
failed to connect to local tailscaled; it doesn't appear to be running
(sudo systemctl start tailscaled ?)
Exactly the expected failure: tailscaled, the background daemon, needs root to create a TUN interface, and this sandbox has none. Clean binary, honest wall.
hydra-gtk — not even attempted
A GTK GUI front-end for Hydra. No display server in this sandbox, and unlike arsenal-ng there’s no script-trick worth trying against an actual windowed GUI app. Citing Kali’s own description and moving on: this is a real tool, I just have no path to running it headless.
Beyond the apt list: HexStrike AI
That’s the nine. The more interesting story is one layer up — what people are building on top of a Kali-class toolset with MCP, which is the same question Part 7 asked about nmap and Metasploit specifically. HexStrike AI is the largest example I found: a single project that wraps 150+ security tools behind one MCP interface, rather than one wrapper per tool.
The architecture, confirmed by reading the source rather than the README: hexstrike_server.py (17,289 lines) is a Flask REST API exposing 156 routes — /api/tools/nmap, /api/tools/gobuster, /api/command (a generic shell-executor), recon/intel/bug-bounty workflow endpoints, the works. hexstrike_mcp.py (5,470 lines) is a thin FastMCP layer in front of it — I counted 151 @mcp.tool() decorations in the file, which lines up almost exactly with the project’s own “150+ tools” claim. Each MCP tool function is a wrapper that calls the corresponding REST endpoint.
I installed the real dependencies (Flask, psutil, aiohttp, BeautifulSoup, Selenium, mitmproxy — skipped angr/pwntools, which the code only references inside generated exploit-script templates, not at server startup) and ran the actual server.
First, its own health check, which does live binary detection for ~150 tool names:
$ curl http://127.0.0.1:8888/health
{"all_essential_tools_available": false,
"tools_status": {"nmap": false, "gobuster": false, "hydra": false,
"sqlmap": false, "curl": true, "httpx": true,
"objdump": true, "strings": true, "tcpdump": true,
"uro": true, ...},
"category_stats": {"essential": {"available": 0, "total": 8},
"network": {"available": 0, "total": 10},
"web_security": {"available": 1, "total": 19}, ...},
"telemetry": {"success_rate": "6.3%"}}
A 6.3% tool-availability rate is exactly what you’d expect for this on plain Ubuntu instead of Kali — and it’s an honest, live-computed number, not a canned response. uro: true is real too: it’s the one I’d pip-installed earlier in this same sandbox, correctly picked up.
The generic command endpoint works as advertised:
$ curl -X POST http://127.0.0.1:8888/api/command \
-d '{"command":"echo hello from hexstrike && uname -a"}'
{"stdout": "hello from hexstrike\nLinux ... x86_64 GNU/Linux\n",
"return_code": 0, "success": true}
Then the interesting part — what happens when you ask it to run a tool that isn’t there. I called /api/tools/nmap with no nmap on PATH:
$ curl -X POST http://127.0.0.1:8888/api/tools/nmap \
-d '{"target":"127.0.0.1","scan_type":"-sV","ports":"22"}'
{"return_code": 127, "stderr": "/bin/sh: 1: nmap: not found\n",
"success": false,
"alternative_tool_suggested": "rustscan",
"recovery_info": {"recovery_applied": true,
"final_action": "tool_switch_suggested"}}
It noticed the missing binary and suggested a real alternative (rustscan) on its own. So I pulled the same rootless-nmap trick from Part 7 — apt-get download nmap, dpkg-deb -x into a local dir, PATH pointed at it — got a genuine nmap 7.80 on PATH, and tried again. New failure, different shape:
{"return_code": 1,
"stderr": "Unable to find nmap-services! Resorting to /etc/services\n
NSE: failed to initialize the script engine:\n
could not locate nse_main.lua\nQUITTING!\n",
"human_escalation": {"urgency": "medium",
"suggested_actions": ["Review error details and logs"]},
"recovery_info": {"recovery_applied": true,
"final_action": "human_escalation"}}
Different failure (nmap’s data files weren’t part of the unpacked .deb, not unexpected — they’re a separate concern from the binary), and a genuinely different recovery path: instead of suggesting another tool, it decided this error didn’t match a known pattern and escalated with structured context instead of guessing. Two real, different branches of the same “intelligent error handling” feature, triggered by two real, different failures I caused myself rather than scripted. That’s a meaningfully more sophisticated response than a try/except around a subprocess call — whether or not it’s worth the operational risk of giving an LLM agent 150+ tools and a raw command-execution endpoint behind one MCP server is a separate question, and one I’d want a real scope policy answered for before pointing it at anything that isn’t localhost.
The stack Kali itself recommends
Kali’s own blog has been running a parallel series on exactly this question, and the most recent entry — Kali & LLM: Completely local with Ollama & 5ire, March 2026 — is the closest thing to an official answer. The stack: Ollama serving a local model (they tested llama3.1:8b, llama3.2:3b, qwen3:4b, all sized to fit 6GB of VRAM), MCP-Kali-Server — the same Flask-API-plus-MCP-bridge shape as HexStrike, just smaller and Kali-packaged (apt install mcp-kali-server) — and 5ire as the desktop GUI client, since Ollama itself doesn’t speak MCP.
I’m not reproducing that walkthrough here, and I want to be specific about why: it needs an NVIDIA GPU with CUDA drivers and a desktop AppImage GUI, neither of which this sandbox has. Both are hard requirements in Kali’s own writeup, not incidental detail. So this section is citation, not a transcript — I verified MCP-Kali-Server’s architecture by reading its real README (Flask server on 127.0.0.1:5000, a thin client.py that bridges it to Claude Desktop or 5ire, the same “expose Kali tools as one MCP surface” pattern as HexStrike at smaller scale), but I’m not claiming to have run the GPU/GUI half myself. Kali’s own published transcript ends with a real local qwen3:4b model correctly turning “port scan scanme.nmap.org for 80, 443, 21, 22” into an actual nmap invocation, fully offline. I have no reason to doubt it; I just can’t independently confirm it from here.
Kali GPT — not Kali’s, despite the name
One more thing worth a paragraph, mostly so nobody confuses it with the above: Kali GPT is a paid product (€49.90–€79.90 one-time, or a free tier gated behind a ChatGPT Plus subscription via the GPT Store) offering command generation and contextual help across the standard Kali toolset. It is not built or endorsed by Offensive Security — it’s a third-party GPT-based wrapper that happens to be named after the distro. Worth knowing before paying for it expecting an official tool.
What this round cost, and what it adds up to
Two of the nine new tools wouldn’t budge without a real terminal device. One needs a credential I’m not provisioning. One’s accuracy claim didn’t survive thirty seconds of testing against a string I invented myself. The rest ran clean, and two — uro’s dedup-by-pattern and legba’s wordlist-prefix gotcha — behaved subtly differently than their one-line descriptions suggest.
But the throughline across both halves of this post is the same thing Part 7 kept finding: the gap between “wire an LLM into one tool” and “wire an LLM into everything” is closing from both directions at once. Individual tools are shipping native MCP support (legba --mcp, no wrapper project needed). Aggregator projects are wrapping entire toolchains behind one MCP surface (HexStrike’s 151 tools, MCP-Kali-Server’s smaller official equivalent). And the OS distribution itself now ships an AI CLI in the base install and publishes its own blessed end-to-end local stack. None of that was true eighteen months ago. None of it was inevitable, either — mraptor’s blind spot and tookie-osint’s false-positive rate are reminders that “AI-adjacent” and “AI-assisted” tooling still has the exact same correctness problems normal tooling always had, just with one more layer making confident-sounding claims on top of it.