Skip to main content
Glama
README.md
# msf-mcp

A minimal MCP (Model Context Protocol) server that exposes the Metasploit Framework to Claude Code (or any MCP-compatible client) through `msfrpcd`.

> ⚠️ **Use only in environments you are authorized to test** — your own lab, your own infrastructure, or an engagement you have explicit written permission for. This project is a thin wrapper around Metasploit's own documented RPC API; it doesn't add capability beyond what your installed Metasploit already has, but it does let an LLM drive it, so treat it with the same care you'd give any pentest tooling.

## How it works

The project is split into two scripts, on purpose:

| Script | Runs as | Needs sudo? | Purpose |
|---|---|---|---|
| `setup.py` | you, manually | **yes** | Starts `msfrpcd`. If it's already running, stops it and starts a fresh instance; otherwise just starts it. |
| `server.py` | Claude Code | **no** | Connects to the already-running `msfrpcd` over RPC and exposes it as MCP tools. |

```
you  --sudo-->  setup.py  --spawns-->  msfrpcd
                                            ^
                                            | RPC (msgpack)
                                            |
Claude Code  --stdio-->  server.py  -------┘
```

Keeping the privileged piece (`setup.py`) separate from the MCP server (`server.py`) means Claude Code never needs to run with elevated privileges, and the process an LLM is driving has no more access than a normal RPC client would.

## Requirements

- [Metasploit Framework](https://github.com/rapid7/metasploit-framework) installed, with `msfrpcd` on `PATH`
- Python 3.9+
- `pip install -r requirements.txt` (installs `mcp` and `pymetasploit3`)

## Installation

```bash
git clone https://github.com/IMApurbo/msf-mcp.git
cd msf-mcp
pip install -r requirements.txt
```

### Configure

Both `setup.py` and `server.py` have a `CONFIG` block near the top:

```python
RPC_HOST = "127.0.0.1"
RPC_PORT = 55553
RPC_PASSWORD = "change-me-123"
USE_SSL = True
```

**Edit both files and make sure these four values match in each.** There's no shared config file on purpose — it keeps each script standalone and easy to read.

### Start msfrpcd

```bash
sudo python3 setup.py
```

This will:
- start `msfrpcd` if it isn't running, or
- stop and cleanly restart it if it already is

Logs go to `/var/log/msf_setup.log` and to stdout. You can also run explicit actions:

```bash
sudo python3 setup.py status
sudo python3 setup.py start
sudo python3 setup.py stop
sudo python3 setup.py restart
```

### Register the MCP server with Claude Code

```bash
claude mcp add metasploit -- python3 /full/path/to/server.py
```

Using a virtualenv? Just point at that interpreter instead:

```bash
claude mcp add metasploit -- /path/to/venv/bin/python /full/path/to/server.py
```

Check it registered:

```bash
claude mcp list
```

## Verifying it works

Ask Claude Code:

```
Use the metasploit debug_connection_check tool and tell me the result.
```

A healthy response looks like:

```json
{
  "configured_host": "127.0.0.1",
  "configured_port": 55553,
  "tcp_port_reachable": true,
  "rpc_login_ok": true,
  "rpc_error": null,
  "log_file": "/tmp/msf_mcp_server.log"
}
```

- `tcp_port_reachable: false` → `msfrpcd` isn't running — run `sudo python3 setup.py`.
- `tcp_port_reachable: true` but `rpc_login_ok: false` → something's listening on that port, but login failed — usually a `RPC_PASSWORD` mismatch between `setup.py` and `server.py`. Check `rpc_error` for details.

## Available tools

| Tool | Description |
|---|---|
| `debug_connection_check` | Reports whether the server can reach and authenticate to msfrpcd |
| `debug_tail_log` | Returns the last N lines of the server's own log file |
| `list_module_names` | List module names by type (exploit/auxiliary/post/payload/encoder/nop) |
| `search_modules` | Keyword search across Metasploit modules |
| `module_info` | Description, options, and targets for a module |
| `run_module` | Configure and execute an exploit/auxiliary/post module |
| `list_jobs` / `kill_job` | Manage background jobs (handlers, running scans) |
| `list_sessions` | List active shell/meterpreter sessions |
| `session_run_command` | Send a command to a session and read the output |
| `session_kill` | Terminate a session |
| `console_execute` | Run a raw `msfconsole` command (fallback for anything not covered above) |
| `console_list` / `console_destroy` | Manage `msfconsole` instances |

## Debugging

`server.py` logs everything to `/tmp/msf_mcp_server.log` and to stderr — never stdout, since Claude Code uses stdout for the MCP protocol itself. If a tool call fails or behaves unexpectedly:

```bash
tail -f /tmp/msf_mcp_server.log
```

or ask Claude directly to call the `debug_tail_log` tool — no terminal access needed.

`setup.py` logs to `/var/log/msf_setup.log`.

## Project structure

```
msf-mcp/
├── setup.py         # privileged: starts/stops/restarts msfrpcd (run manually with sudo)
├── server.py        # unprivileged: MCP server exposing Metasploit as tools (added to Claude Code)
├── requirements.txt
└── README.md
```

## License

MIT

## Author

**IMApurbo**