Skip to main content
Glama
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.