MCPKaliServer
README.md
# MCPKaliServer
An **MCP (Model Context Protocol) server that connects LLMs to a Kali Linux host
over SSH** for authorized cloud, API and web-application penetration testing.
It exposes your Kali toolbox to any MCP client (Claude Desktop, Claude Code, or
your own agent) as a set of well-defined tools organised into the classic pentest
phases — **Reconnaissance → Service Enumeration → Exploitation** — plus health
monitoring, a generic command executor, and an engagement-scope guardrail.
> ⚠️ **Authorized use only.** This drives offensive security tooling against
> whatever you point it at. Only use it against systems you have explicit,
> written permission to test, and configure the `scope` allow-list to your rules
> of engagement.
---
## Features
- **Secure SSH access** to the Kali host with **public-key or OpenSSH-certificate
authentication**, strict `known_hosts` verification, pooled connection with
automatic reconnect. (Password auth is available as a discouraged fallback.)
- **Optional mutual TLS (mTLS)** on the networked `streamable-http` transport, so
the LLM↔server channel is mutually authenticated.
- **Health tool + heartbeat** — a background heartbeat probes the SSH connection
**every 2 minutes**; `health_check`, `server_status` and `list_available_tools`
report liveness and installed tooling.
- **Phase group functions** — `recon_sweep`, `enumerate_services`,
`exploit_target` orchestrate the common steps of each phase in one call.
- **One function per tool** — `recon_*`, `enum_*`, `exploit_*` map 1:1 to the
underlying Kali tools (nmap, subfinder, httpx, nuclei, ffuf, sqlmap, hydra,
ScoutSuite, Pacu, …).
- **Generic executor** — `execute_command` / `execute_script` for anything not
covered by a dedicated tool.
- **Scope guardrail** — every target-taking tool refuses out-of-scope hosts when
a `scope` allow-list is set; exploitation tools are gated by `allow_exploitation`.
- **A Claude skill** (`skills/cloud-api-pentest-methodology`) that teaches the
methodology (inspired by Bishop Fox, NetSPI, Rhino Security Labs, with
HackerOne as the exploitation reference) and maps every phase to a tool.
---
## Architecture
```
┌──────────────┐ MCP (stdio or HTTPS+mTLS) ┌────────────────────┐ SSH (key/cert) ┌────────────┐
│ LLM client │ ─────────────────────────────▶│ MCP Kali Server │ ──────────────────▶│ Kali host │
│ (Claude etc.)│ ◀─────────────────────────────│ (this project) │◀───────────────────│ toolbox │
└──────────────┘ tool calls / results └────────────────────┘ stdout/stderr └────────────┘
• heartbeat every 2m
• scope + exploitation guard
```
The MCP server runs on your **control host** (laptop/jump box). It holds the SSH
credentials and connects to the Kali host; tools execute remotely over SSH. The
LLM never gets shell access directly — it can only call the defined tools.
---
## Requirements
- **Control host:** Python 3.10+, network access to the Kali host over SSH.
- **Kali host:** the pentest tooling the tools invoke (install with
`scripts/install_kali_tools.sh`), and SSH access.
---
## Install
```bash
git clone https://github.com/ElusiveHacker/MCPKaliServer.git
cd MCPKaliServer
./install.sh # creates .venv, installs the package, copies config.example.yaml -> config.yaml
```
Then install the tooling the server drives on the **Kali host**. Two ways:
- **From the LLM, over SSH (recommended):** once the server is connected, call the
`install_kali_tools` tool (it runs the installer remotely with sudo). Then call
`list_available_tools` to confirm.
- **Manually on the box:**
```bash
scp scripts/install_kali_tools.sh kali@<kali-host>:
ssh kali@<kali-host> 'sudo bash install_kali_tools.sh'
```
Verify tooling any time from the client by calling the `list_available_tools` tool.
---
## Configure
Copy and edit `config.yaml` (created by `install.sh`), or supply everything via
environment variables (`.env.example`). **Env vars override the YAML file** and
are the recommended way to pass secrets.
Minimum viable config:
```yaml
transport: stdio
ssh:
host: 10.0.0.10
port: 22
username: kali
private_key: ~/.ssh/id_ed25519
known_hosts: ~/.ssh/known_hosts
scope:
- "*.example.com" # your in-scope targets
allow_exploitation: true
```
Key settings:
| Setting | Meaning |
|---|---|
| `transport` | `stdio` (local, default) or `streamable-http` (networked, supports mTLS) |
| `heartbeat_interval` | Seconds between heartbeats (default 120 = 2 min) |
| `command_timeout` | Per-command timeout (seconds) |
| `max_output_bytes` | stdout/stderr truncation cap returned to the LLM |
| `allow_exploitation` | Gate for all `exploit_*` tools |
| `scope` | Allow-list of hosts / `*.wildcard` domains / CIDRs; empty = no enforcement |
| `ssh.*` | Connection + auth to the Kali host |
| `http.*` | TLS/mTLS options for `streamable-http` |
### SSH authentication
**Key + OpenSSH certificate (recommended).** Generate a CA, client key and signed
user certificate:
```bash
scripts/gen_ssh_cert.sh kali ./ssh-certs # principal = remote user
```
Trust the CA on the Kali host (the script prints the exact commands):
```bash
sudo cp ssh-certs/ssh_ca.pub /etc/ssh/mcp_user_ca.pub
echo 'TrustedUserCAKeys /etc/ssh/mcp_user_ca.pub' | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart ssh
```
Point the config at the key + certificate:
```yaml
ssh:
private_key: ./ssh-certs/id_ed25519
certificate: ./ssh-certs/id_ed25519-cert.pub
```
**Plain key.** Omit `certificate` and use any key the Kali host authorizes
(`ssh-copy-id`). **Host verification:** keep `strict_host_key_checking: true` and
make sure the Kali host key is in your `known_hosts` (`ssh-keyscan -H <host> >>
~/.ssh/known_hosts`).
### mTLS (for the networked transport)
Generate a CA + server/client certificates:
```bash
scripts/gen_mtls_certs.sh <server-hostname-or-ip> ./certs
```
Enable it:
```yaml
transport: streamable-http
http:
host: 0.0.0.0
port: 8000
tls_cert: certs/server.crt
tls_key: certs/server.key
tls_client_ca: certs/ca.crt # requiring a client cert = mTLS
```
The client must present `certs/client.crt` + `certs/client.key`. Test with:
```bash
curl --cacert certs/ca.crt --cert certs/client.crt --key certs/client.key https://<host>:8000/mcp
```
---
## Run
```bash
source .venv/bin/activate
mcp-kali-server --config config.yaml # uses transport from config
mcp-kali-server --config config.yaml -t streamable-http
mcp-kali-server -v # debug logging (to stderr)
```
Logs go to **stderr** (stdout is reserved for the stdio MCP protocol).
---
## Connecting a client
### Claude Desktop / Claude Code (stdio)
Add to your MCP client config (e.g. Claude Desktop `claude_desktop_config.json`,
or `claude mcp add`):
```json
{
"mcpServers": {
"kali": {
"command": "/path/to/MCPKaliServer/.venv/bin/mcp-kali-server",
"args": ["--config", "/path/to/MCPKaliServer/config.yaml"],
"env": {
"MCP_KALI_SSH_PASSPHRASE": "<key passphrase if any>"
}
}
}
}
```
Claude Code CLI equivalent:
```bash
claude mcp add kali -- /path/to/.venv/bin/mcp-kali-server --config /path/to/config.yaml
```
### Networked (streamable-http + mTLS)
Run the server with the `streamable-http` transport and point an
mTLS-capable MCP client at `https://<host>:8000/mcp` with the client
certificate/key.
---
## Using the skill
The repo ships a Claude skill at
[`skills/cloud-api-pentest-methodology`](skills/cloud-api-pentest-methodology/SKILL.md).
It documents the phase-by-phase methodology and tells the model which MCP tool to
use for each step, so you can drive an engagement in natural language.
**Claude Code / claude.ai:** copy the skill folder into your skills directory:
```bash
mkdir -p ~/.claude/skills
cp -r skills/cloud-api-pentest-methodology ~/.claude/skills/
```
(or a project-local `.claude/skills/`). The skill activates when you ask about
planning or running a cloud/API/web pentest. With the `kali` MCP server connected,
the model reads the methodology from the skill and executes it through the tools.
**Example prompts once both are loaded:**
- "Run a recon sweep of `app.example.com` and summarise the live services."
- "Enumerate services on the hosts you found; focus on the web app at
`https://app.example.com`."
- "We found a `?id=` parameter — validate SQL injection safely and show only the
DB banner and current user."
- "Audit the AWS account configuration with ScoutSuite and list the highest-risk
findings."
The model will call `health_check` / `list_available_tools`, then the appropriate
`recon_* / enum_* / exploit_*` tools, respecting the scope guardrail.
---
## Tool reference
**Health & control**
`health_check` · `server_status` · `list_available_tools`
**Setup / provisioning**
`install_kali_tools` — installs/refreshes the required tooling on the Kali host
over SSH (apt packages, Go/ProjectDiscovery tools, ScoutSuite/Pacu, cloud_enum,
awscli). Components: `all` or a subset of `apt,go,cloud,cloudenum,aws`. Needs
sudo on the Kali host (pass `sudo_password`, or configure passwordless sudo).
Long-running — verify afterwards with `list_available_tools`.
**Generic**
`execute_command` · `execute_script`
**Reconnaissance** (group: `recon_sweep`)
`recon_nmap_discovery` · `recon_dns_records` · `recon_dns_enum` ·
`recon_subdomains` · `recon_whois` · `recon_http_probe` · `recon_web_crawl` ·
`recon_wayback_urls` · `recon_osint` · `recon_cloud_assets` · `recon_ssl_info`
**Service enumeration** (group: `enumerate_services`)
`enum_nmap_services` · `enum_web_tech` · `enum_web_nikto` · `enum_dir_bruteforce`
· `enum_vhosts` · `enum_parameters` · `enum_nuclei` · `enum_api_routes` ·
`enum_smb` · `enum_cms_wordpress` · `enum_cloud_config` · `enum_ssl_ciphers`
**Exploitation** (group: `exploit_target`, gated by `allow_exploitation`)
`exploit_sqlmap` · `exploit_nuclei` · `exploit_bruteforce` ·
`exploit_command_injection` · `exploit_metasploit` · `exploit_aws_pacu` ·
`exploit_aws_cli`
Each tool returns `{ command, exit_status, success, timed_out, stdout, stderr,
truncated }`. Group functions return a `steps` map of per-step results.
---
## Security notes
- **Scope & consent** — set `scope`; the server refuses out-of-scope targets. This
is a guardrail, not a substitute for a signed authorization.
- **Least privilege** — give the Kali SSH user only what the engagement needs;
prefer certificates with a bounded validity (`gen_ssh_cert.sh` sets ~1 year).
- **Secrets** — never commit `config.yaml`, keys or certs; `.gitignore` already
excludes them. Pass secrets via environment variables where possible.
- **Exploitation off-switch** — set `allow_exploitation: false` for recon/enum
engagements to disable every `exploit_*` tool.
- **Generic executor** — `execute_command`/`execute_script` are intentionally
unrestricted (operator escape hatch) and are **not** scope-checked. Treat access
to this MCP server as equivalent to shell access on the Kali host.
---
## Development
```bash
source .venv/bin/activate
pip install -e ".[dev]"
pytest -q # smoke tests (no Kali host required)
```
Project layout:
```
mcp_kali_server/
__main__.py CLI entry point + transport/TLS selection
config.py layered config (defaults < YAML < env)
ssh_client.py asyncssh transport (key/cert auth, reconnect)
guard.py engagement-scope enforcement
health.py health state + 2-minute heartbeat loop
installer.py builds the remote Kali tooling-install script
server.py FastMCP assembly, lifespan, health tools
runtime.py shared singletons
tools/
setup.py install_kali_tools
generic.py execute_command / execute_script
recon.py reconnaissance tools + recon_sweep
enumeration.py enumeration tools + enumerate_services
exploitation.py exploitation tools + exploit_target
skills/cloud-api-pentest-methodology/ the methodology skill
scripts/ install_kali_tools.sh, gen_ssh_cert.sh, gen_mtls_certs.sh
```
## License
MIT — see `pyproject.toml`. Use responsibly and legally.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues