Pentest MCP
A Model Context Protocol server that integrates essential penetration testing tools (Nmap, Gobuster, Nikto, John the Ripper) into a unified natural language interface, allowing security professionals to execute and chain multiple tools through conversational commands.
README Documentation
Pentest MCP
Professional penetration-testing MCP server with modern transport/auth support and expanded recon tooling.
What Changed in 0.9.0
- Upgraded MCP SDK to
@modelcontextprotocol/sdk@^1.26.0 - Kept MCP Inspector at the latest release (
@modelcontextprotocol/inspector@^0.20.0) with bundled launcher - Streamable HTTP is now the primary network transport (
MCP_TRANSPORT=http) - SSE is still available only as a deprecated compatibility mode
- Added bearer-token auth with OIDC JWKS and introspection support
- Added first-class tools:
subfinderEnum,httpxProbe,ffufScan,nucleiScan,trafficCapture,hydraBruteforce,privEscAudit,extractionSweep - Added report-admin tools:
listEngagementRecords,getEngagementRecord - Added SoW capture flow for reports using MCP elicitation (
scopeMode=ask) with safe template fallback - Hardened command resolution so web probing uses
httpx-toolkit(preferred) or validated ProjectDiscoveryhttpx, avoiding PythonhttpxCLI collisions - Integrated bundled MCP Inspector launcher (
pentest-mcp inspector) - Runtime baseline is now Node.js 22.7.5+
- Added invocation metadata in new tool outputs when auth/session context is available
Included Tools
nmapScanrunJohnTheRipperrunHashcatgobusterniktosubfinderEnumhttpxProbeffufScannucleiScantrafficCapturehydraBruteforceprivEscAuditextractionSweepgenerateWordlistlistEngagementRecordsgetEngagementRecordcreateClientReportcancelScan
Quick Start
Install
npm install -g pentest-mcp
Run locally (stdio)
pentest-mcp
Launch bundled MCP Inspector (no separate install)
pentest-mcp inspector
You can forward Inspector flags directly:
pentest-mcp inspector --help
Run over network (Streamable HTTP)
MCP_TRANSPORT=http MCP_SERVER_HOST=0.0.0.0 MCP_SERVER_PORT=8000 pentest-mcp
Run legacy SSE mode (deprecated)
MCP_TRANSPORT=sse MCP_SERVER_PORT=8001 pentest-mcp
Transport Notes
stdio: default for local MCP clients.http: modern network transport. Recommended.sse: compatibility only. Deprecated and will be removed in a future major release.
Inspector Integration
pentest-mcp inspectorlaunches the bundled@modelcontextprotocol/inspectorCLI.- It auto-targets this MCP server over stdio by spawning:
node <this-package-entrypoint> stdio
- You do not need to install Inspector separately.
Auth Configuration (Bearer + OIDC)
Set these env vars when using MCP_TRANSPORT=http (or sse if needed):
MCP_AUTH_ENABLED=true
MCP_AUTH_MODE=bearer
MCP_AUTH_SCOPES=read,write
MCP_AUTH_AUDIENCE=
MCP_OIDC_ISSUER=https://issuer.example.com
MCP_OIDC_JWKS_URL=https://issuer.example.com/.well-known/jwks.json
# optional alternative/backup validation mode:
MCP_OIDC_INTROSPECTION_URL=https://issuer.example.com/oauth/introspect
MCP_OAUTH_CLIENT_ID=...
MCP_OAUTH_CLIENT_SECRET=...
Legacy aliases are still accepted temporarily:
MCP_OAUTH_ENABLEDMCP_OAUTH_PROVIDER_URLMCP_OAUTH_SCOPES
Workflow + Reporting
createClientReport now supports SoW handling modes:
scopeMode=ask: prompt user via MCP elicitation (recommended)scopeMode=provided: usescopeOfWorkvalue directlyscopeMode=template: use built-in generic authorized-testing template
If elicitation is declined/unavailable, the report automatically falls back to the template.
How users provide SoW (right now)
There is no separate file-upload API yet. Current options are:
- Ask interactively via MCP user invocation (elicitation)
{
"tool": "createClientReport",
"arguments": {
"title": "Q1 External Pentest",
"assessmentType": "external-network",
"scopeMode": "ask"
}
}
- Paste SoW text directly into
scopeOfWork
{
"tool": "createClientReport",
"arguments": {
"title": "Q1 External Pentest",
"assessmentType": "external-network",
"scopeMode": "provided",
"scopeOfWork": "Authorized targets: ...\nOut-of-scope: ...\nTesting window: ...\nRules of engagement: ..."
}
}
- Use template mode when client details should not be shared
{
"tool": "createClientReport",
"arguments": {
"title": "Q1 External Pentest",
"assessmentType": "external-network",
"scopeMode": "template"
}
}
How this cuts admin time
- Every tool run stores a structured engagement record (
recordId=...) with invocation context. - Use
listEngagementRecordsto pull all work artifacts quickly. - Generate the report from selected
recordIds(or latest records by default) instead of manual copy/paste. - Scope notes are attached automatically from one of:
- user elicitation form (
ask) - pasted SoW text (
provided) - safe default template (
template)
- user elicitation form (
Roadmap
These are planned specifically to reduce pentest admin overhead.
scopeFilePathingestion (load SoW from a local file path on the MCP host)scopeDocumentchunked upload flow (send SoW content directly through MCP for remote clients)- SoW parser that auto-extracts targets, exclusions, test windows, and rules of engagement
- Evidence auto-linking from tool outputs (
recordId) to findings and report sections - Finding dedup/merge across overlapping tools (
nuclei,nikto, etc.) - Auto severity + impact draft text for faster writeups
- One-click report pack generation (executive summary + technical appendix + remediation table)
- Retest diff mode (fixed/reopened/new findings between engagements)
- Ticket export sync (Jira/Linear/GitHub) with status backfill
- Deliverable QA checks (missing evidence, missing scope fields, weak remediation notes)
Adoption note:
- Expect strong usage for
scopeFilePathandscopeDocumentbecause most teams already maintain SoW in docs/PDF and want to avoid repeated paste-and-reformat steps.
Recon + Exploitation Examples
Subdomain enumeration
{
"tool": "subfinderEnum",
"arguments": {
"domain": "example.com",
"recursive": true,
"allSources": true
}
}
Probe live hosts
{
"tool": "httpxProbe",
"arguments": {
"targets": ["example.com", "api.example.com"],
"includeTitle": true,
"includeStatusCode": true
}
}
Fuzz content paths
{
"tool": "ffufScan",
"arguments": {
"targetUrl": "https://example.com/FUZZ",
"wordlist": "/usr/share/seclists/Discovery/Web-Content/common.txt",
"threads": 40
}
}
Template scanning
{
"tool": "nucleiScan",
"arguments": {
"targets": ["https://example.com"],
"severities": ["medium", "high", "critical"]
}
}
Traffic capture (sniffing)
{
"tool": "trafficCapture",
"arguments": {
"networkInterface": "eth0",
"packetCount": 200,
"bpfFilter": "tcp port 80"
}
}
Brute-force checks
{
"tool": "hydraBruteforce",
"arguments": {
"target": "10.10.10.20",
"service": "ssh",
"usernameList": "/usr/share/seclists/Usernames/top-usernames-shortlist.txt",
"passwordList": "/usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt"
}
}
SQLi extraction sweep
{
"tool": "extractionSweep",
"arguments": {
"targetUrl": "https://target.local/item.php?id=1",
"risk": 2,
"level": 3
}
}
Docker
docker-compose --profile http up
docker-compose --profile stdio up
docker-compose --profile sse up
The Docker image installs:
nmap,john,hashcat,gobuster,nikto,ffuf,hydra,sqlmap,tcpdumpsubfinder,httpx+httpx-toolkitalias,nuclei
Required Host Tools (non-Docker runs)
Ensure the binaries are in PATH:
which nmap john hashcat gobuster nikto subfinder httpx-toolkit ffuf nuclei hydra sqlmap tcpdump
If httpx-toolkit is not installed, a validated ProjectDiscovery httpx binary is accepted as fallback.
Security Notice
Authorized use only. Run against systems/networks where you have explicit written permission.