This project is a Model Context Protocol (MCP) server written in Go. It bridges MCP-compatible clients (Cursor, Claude, etc.) to pentest tools on a Kali/Linux host.
- Uses the official Go SDK:
github.com/modelcontextprotocol/go-sdk/mcp(docs). - Provides a growing set of pentest-oriented MCP tools (
nmap,wfuzz,gobuster,nikto,sqlmap, …). - Supports multiple deployment modes:
- Local stdio.
- Remote SSH.
- Remote HTTP bridge + local HTTP proxy (no SSH, public Kali).
- Go 1.21+
- Git (for fetching Go modules)
- Docker (optional, for Kali image)
From your machine:
cd /path/to/pentest-mcps
# Initialize or verify the module (already done, safe to re-run)
go mod init github.com/restuhaqza/pentest-mcps
# Fetch MCP SDK and tidy deps
go get github.com/modelcontextprotocol/go-sdk/mcp@latest
go mod tidy
# Build main server binary
make build # bin/pentest-mcps
# Optional: build client and HTTP components
make build-client # bin/pentest-mcps-client
make build-http-server # bin/pentest-mcps-http
make build-http-proxy # bin/pentest-mcps-http-proxy
# Build for multiple architectures (linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64, windows/arm64)
make build-multi-arch # Builds all binaries for all platforms in bin/<os>-<arch>/ directoriesThe core server (pentest-mcps) speaks MCP over stdio, as expected by MCP clients.
-
Development:
go run . -
Binary:
./bin/pentest-mcps
The Docker image is automatically built and pushed to GitHub Container Registry (GHCR) on every push to main branch or when tags are created.
# Pull the latest image
docker pull ghcr.io/usebadik/pentests-mcp:latest
# Or pull a specific version
docker pull ghcr.io/usebadik/pentests-mcp:v0.1.0
# Run container (stdio-based MCP server)
docker run --rm -it ghcr.io/usebadik/pentests-mcp:latest
# Run HTTP server
docker run --rm -it -p 8080:8080 \
ghcr.io/usebadik/pentests-mcp:latest \
go run ./cmd/http-server --addr :8080 --server-cmd /usr/local/bin/pentest-mcpsNote: You may need to authenticate to GHCR first:
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdinBuild and run a Kali-based image that contains Go and common tools:
# Build Kali-based testing image
docker build -f machines/kali.Dockerfile -t pentest-mcps-kali .
# Run container (stdio-based MCP server; you can also override CMD to run http-server)
docker run --rm -it pentest-mcps-kaliYou can extend this image with additional Kali tools as needed (e.g., metasploit-framework, burpsuite).
To run the HTTP server in Docker by default, use docker-compose.yml:
docker compose up --build kali-httpThis exposes HTTP endpoints:
http://127.0.0.1:8080/call-tool- Call MCP tools via HTTP POSThttp://127.0.0.1:8080/health- Health check endpoint (GET)http://127.0.0.1:8080/tools- List available tools with input schemas (GET)
-
Build:
make build
-
Run:
./bin/pentest-mcps
-
Point your MCP client at
./bin/pentest-mcpsover stdio (see MCP client integration below).
-
On Kali:
make build scp bin/pentest-mcps user@KALI_IP:/opt/pentest-mcps/
-
In your MCP client, use an SSH
commandthat runs/opt/pentest-mcps/pentest-mcps(see JSON examples below).
On Kali (remote / public):
make build build-http-server
./bin/pentest-mcps-http --addr :8080 --server-cmd ./bin/pentest-mcps
# HTTP API now available at:
# - http://KALI_PUBLIC_IP:8080/call-tool (POST - call tools)
# - http://KALI_PUBLIC_IP:8080/health (GET - health check)
# - http://KALI_PUBLIC_IP:8080/tools (GET - list tools with schemas)On your local machine (MCP proxy server):
make build-http-proxy
./bin/pentest-mcps-http-proxy --remote-host http://KALI_PUBLIC_IP:8080Your editor will talk MCP over stdio to pentest-mcps-http-proxy, which forwards each tool call to the HTTP bridge on Kali.
This repo exposes MCP servers over stdio, so you can wire them into any MCP-aware client.
Create or edit .cursor/mcp.json in your repo/home directory. Use one of the following configs depending on how you connect.
Note: For path resolution, use absolute paths or paths relative to where Cursor is launched. If using relative paths like
./bin/pentest-mcps, ensure Cursor's working directory is the project root.
-
Local stdio (binary on your machine):
{ "mcpServers": { "pentest-mcps": { "command": "./bin/pentest-mcps", "args": [], "env": {}, "transport": "stdio" } } }Or use absolute path:
{ "mcpServers": { "pentest-mcps": { "command": "/absolute/path/to/pentest-mcps/bin/pentest-mcps", "args": [], "env": {}, "transport": "stdio" } } } -
Remote SSH (no HTTP, tools on Kali):
{ "mcpServers": { "pentest-mcps": { "command": "ssh", "args": ["user@KALI_IP", "/opt/pentest-mcps/pentest-mcps"], "env": {}, "transport": "stdio" } } } -
Public Kali via HTTP proxy (no SSH):
{ "mcpServers": { "pentest-mcps": { "command": "./bin/pentest-mcps-http-proxy", "args": ["--remote-host", "http://KALI_PUBLIC_IP:8080"], "env": {}, "transport": "stdio" } } }Replace
KALI_PUBLIC_IPwith your actual Kali server IP address or hostname.
Important:
mcpServersmust always point to an MCP server binary (./bin/pentest-mcpsor./bin/pentest-mcps-http-proxy), not the CLI client.
Thepentest-mcps-clientbinary is for manual CLI use (e.g.--remote-host http://IP:8080) and should not be referenced inmcpServers.
Restart Cursor after editing this file so it picks up the configuration.
Most UIs let you add a custom MCP server by specifying:
- Name:
pentest-mcps - Command: one of:
./bin/pentest-mcps(local)ssh user@KALI_IP /opt/pentest-mcps/pentest-mcps(remote SSH)./bin/pentest-mcps-http-proxy --remote-host http://KALI_PUBLIC_IP:8080(HTTP proxy)
- Transport:
stdio
Once configured, you can invoke tools like nmap_host_scan, web_dir_enum, gobuster_enum, nikto_scan, and sqlmap_test directly from the editor’s tooling panel.
The CLI client is useful for quick testing without an editor.
Build:
go build -o bin/pentest-mcps-client ./cmd/clientExamples (local stdio server):
# Health check (default tool is `health`)
./bin/pentest-mcps-client --server-cmd ./bin/pentest-mcps
# nmap host scan against local stdio server
./bin/pentest-mcps-client \
--server-cmd ./bin/pentest-mcps \
--tool nmap_host_scan \
--args '{"host":"scanme.nmap.org","ports":"80,443"}'
# gobuster enum against local stdio server
./bin/pentest-mcps-client \
--server-cmd ./bin/pentest-mcps \
--tool gobuster_enum \
--args '{"url":"https://target/"}'
# sqlmap test against local stdio server
./bin/pentest-mcps-client \
--server-cmd ./bin/pentest-mcps \
--tool sqlmap_test \
--args '{"url":"https://target/vuln.php?id=1"}'Remote HTTP examples (when http-server is running on http://127.0.0.1:8080):
./bin/pentest-mcps-client \
--remote-host http://127.0.0.1:8080 \
--tool health
./bin/pentest-mcps-client \
--remote-host http://127.0.0.1:8080 \
--tool nmap_host_scan \
--args '{"host":"scanme.nmap.org","ports":"80"}'You can add more tools by creating handlers in internal/tools/ and wiring them in main.go.
General pattern:
- Define an input struct with JSON fields for the tool’s parameters.
- Use helpers in
internal/core(sanitization,RunCommand) to invoke the underlying binary. - Define an output struct with
tool, input echo,error, andoutputfields. - Add a schema function in
internal/tools/schema.goto generate JSON Schema for the input. - Register the tool with
mcp.AddTool(server, &mcp.Tool{..., InputSchema: ...}, handlerFn).
Input Schema: All tools now include JSON Schema definitions for their input parameters. This allows MCP clients to:
- Validate input before sending requests
- Display parameter requirements in UI
- Auto-generate forms for tool execution
- Query available tools and their schemas via
/toolsendpoint on HTTP server
Keep outputs plain-text and JSON so they render well in both light and dark themes (avoid color codes unless necessary, or make them optional).
Current structure:
main.go– MCP server bootstrap and tool registration.internal/core/– shared helpers for command execution and sanitization.internal/tools/– implementations for individual tools.cmd/http-server/– HTTP bridge exposing/call-tool(POST),/health(GET), and/tools(GET).cmd/http-proxy/– local MCP server that proxies to the HTTP bridge.cmd/client/– simple MCP client CLI.
The server currently includes:
-
health(tool)- Returns structured JSON health information:
- Overall status, message, and version.
tools_statusmap indicating availability of key tools (nmap,gobuster,nikto,sqlmap).all_essential_tools_availableboolean.
- Returns structured JSON health information:
-
nmap_host_scan(tool)- Runs a basic
nmapscan against a single host. - Params:
host(string, required) – hostname or IP.ports(string, optional) – e.g."80,443"or"1-1024".
- Runs a basic
-
web_dir_enum(tool)- Simple directory enumeration using
wfuzz. - Params:
url(string, required) – base URL, e.g.https://target/. IfFUZZis not present, it will be appended.wordlist(string, optional) – wordlist path; defaults to/usr/share/wordlists/dirb/common.txton Kali.extensions(string, optional) – reserved for future filtering behavior.
- Simple directory enumeration using
-
gobuster_enum(tool)- Directory enumeration using
gobuster dir. - Params:
url(string, required).wordlist(string, optional; defaults to/usr/share/wordlists/dirb/common.txt).
- Directory enumeration using
-
nikto_scan(tool)- Basic web server vulnerability scanning via
nikto. - Params:
url(string, required).
- Basic web server vulnerability scanning via
-
sqlmap_test(tool)- Simple SQL injection testing using
sqlmap. - Params:
url(string, required).data(string, optional) – POST body data for testing.
- Simple SQL injection testing using
Run tests locally:
make test # go test ./...Or inside the Kali image:
make docker-kali-build
docker run --rm -it pentest-mcps-kali go test ./...To see coverage (on your machine or in the container):
go test ./... -cover
go test ./... -coverprofile=coverage.out
go tool cover -func=coverage.outCurrent tests include:
internal/core: sanitization helpers and command runner.internal/tools: validation behavior fornmap_host_scanandweb_dir_enum.cmd/http-proxy: proxy handler forwarding/decoding via a localhttptestserver.
- This repo is intentionally minimal; you should adapt tools and flags to your own environment and threat model.
- Always validate and sanitize inputs before invoking system commands.
- Be careful exposing HTTP endpoints (especially on public IPs). Prefer SSH or well-controlled networks when possible.
- Keep outputs readable in both light and dark themed UIs; avoid hard-coded ANSI colors unless you strip or gate them.***
Thanks to: