PortHunter MCP
Supports containerized deployment for analyzing PCAP/PCAPNG network captures in isolated environments
Provides cross-platform network packet analysis capabilities on Linux systems for port scan detection and network security analysis
Operates as a local MCP server for analyzing network capture files stored on the local filesystem with configurable security restrictions
Provides cross-platform network packet analysis capabilities on macOS systems for port scan detection and network security analysis
Includes testing framework integration for validating network analysis functionality and PCAP processing capabilities
Built with Python 3.11+ for network packet analysis, providing tools for PCAP/PCAPNG file processing and port scan detection
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@PortHunter MCPanalyze the suspicious traffic in captures/scan.pcapng"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
PortHunter MCP — Local MCP server for port-scan analysis (PCAP/PCAPNG)
PortHunter es un servidor MCP local (transport STDIO) que:
analiza capturas PCAP/PCAPNG,
detecta técnicas comunes de escaneo (SYN, FIN/NULL/Xmas),
clasifica patrones (horizontal / vertical),
lista sospechosos y obtiene el primer evento relevante,
puede enriquecer IPs públicas (OTX/GreyNoise/ASN/Geo) y correlacionarlas.
Está pensado para ser consumido por cualquier host/chatbot MCP.
Requisitos
Python 3.11+
Windows, Linux o macOS
(Opcional) Docker
Related MCP server: PCAP-Analyzer MCP Server
Instalación
python -m venv .venv
# Windows PowerShell: .\.venv\Scripts\Activate.ps1
# Linux/macOS: source .venv/bin/activate
pip install -U pip
pip install -e .El
-e .instala el paqueteporthunteren editable desde este repo.
Ejecución (STDIO)
Windows PowerShell (recomendado)
$env:PORT_HUNTER_TOKEN = "TEST_TOKEN"
$env:PORT_HUNTER_ALLOWED_DIR = (Get-Location).Path
python -m porthunter.serverWindows CMD
set PORT_HUNTER_TOKEN=TEST_TOKEN
set PORT_HUNTER_ALLOWED_DIR=%CD%
python -m porthunter.serverLinux/macOS
export PORT_HUNTER_TOKEN=TEST_TOKEN
export PORT_HUNTER_ALLOWED_DIR="$PWD"
python -m porthunter.serverEl servidor queda escuchando por STDIO a la espera de llamadas MCP
call_tool.
Variables de entorno (seguridad y límites)
Variable | Default | Descripción |
|
| Token requerido si |
|
| Exige |
|
| Directorio raíz permitido para leer PCAP/PCAPNG. |
|
| Tamaño máximo del archivo a procesar. |
|
| Si |
mcp.json (ejemplo listo para usar)
{
"name": "porthunter",
"version": "0.1.0",
"transport": {
"stdio": { "command": "python", "args": ["-m", "porthunter.server"] }
},
"env": {
"PORT_HUNTER_TOKEN": "TEST_TOKEN",
"PORT_HUNTER_ALLOWED_DIR": ".",
"PORT_HUNTER_REQUIRE_TOKEN": "true",
"PORT_HUNTER_MAX_PCAP_MB": "50"
},
"tools": [
"scan_overview",
"list_suspects",
"first_scan_event",
"enrich_ip",
"correlate"
]
}Tools (API)
Todas las herramientas devuelven UTC ISO-8601 en
generated_at.
1) scan_overview(path, time_window_s=60, top_k=20)
Input
{ "path": "captures/scan-demo.pcapng", "time_window_s": 60, "top_k": 20, "auth_token": "TEST_TOKEN" }Return
{ "ok": true, "overview": { /* ver ejemplo */ }, "generated_at": "..." }2) list_suspects(path, min_ports=10, min_rate_pps=5.0)
Input
{ "path": "captures/scan-demo.pcapng", "min_ports": 10, "min_rate_pps": 5.0, "auth_token": "TEST_TOKEN" }Return
{ "ok": true, "suspects": [ /* items */ ], "generated_at": "..." }3) first_scan_event(path)
Input
{ "path": "captures/scan-demo.pcapng", "auth_token": "TEST_TOKEN" }Return
{ "ok": true, "first_event": { /* o null */ }, "generated_at": "..." }4) enrich_ip(ip)
Input
{ "ip": "8.8.8.8", "auth_token": "TEST_TOKEN" }Return (ok)
{ "ok": true, "enrichment": { "asn": "...", "org": "...", "geo": { "country": "US" }, "threat": { "otx": {...}, "greynoise": {...} } }, "generated_at": "..." }Return (error)
{ "ok": false, "error": "invalid_ip", "generated_at": "..." }5) correlate(ips[])
Input
{ "ips": ["abc", "192.168.0.10", "8.8.8.8"], "auth_token": "TEST_TOKEN" }Return
{
"ok": true,
"results": [
{ "ip": "abc", "ok": false, "error": "invalid_ip" },
{ "ip": "192.168.0.10", "skipped": true, "reason": "private_ip" },
{ "ip": "8.8.8.8", "ok": true, "kind": "public", "enrichment": {/*...*/} }
],
"generated_at": "..."
}Ejemplos de JSON (respuestas reales)
scan_overview (ejemplo)
{
"ok": true,
"overview": {
"file": "captures/scan.pcapng",
"total_pkts": 12345,
"interval_s": 600,
"scanners": [
{
"ip": "1.2.3.4",
"pkts": 500,
"distinct_ports": 120,
"distinct_hosts": 30,
"flag_stats": { "SYN": 480, "FIN": 15, "XMAS": 5 }
}
],
"targets": [
{ "ip": "10.0.0.5", "pkts": 320, "ports_hit": [22, 80, 443] }
],
"port_distribution": [
{ "port": 80, "hits": 450 }, { "port": 22, "hits": 120 }
],
"suspected_patterns": ["syn_scan", "xmas_scan"]
},
"generated_at": "2025-09-20T23:00:02Z"
}list_suspects (ejemplo)
{
"ok": true,
"suspects": [
{
"ip": "5.6.7.8",
"kind": "horizontal",
"distinct_ports": 50,
"rate_pps": 7.2,
"flags_seen": ["SYN"]
},
{
"ip": "9.9.9.9",
"kind": "vertical",
"distinct_ports": 1,
"rate_pps": 12.0,
"flags_seen": ["SYN","FIN"]
}
],
"generated_at": "2025-09-20T23:01:12Z"
}first_scan_event (ejemplo)
{
"ok": true,
"first_event": {
"ts": "2025-09-20T22:59:58Z",
"src": "1.2.3.4",
"dst": "10.0.0.5",
"port": 80,
"flags": "S"
},
"generated_at": "2025-09-20T23:01:45Z"
}enrich_ip (error por IP inválida)
{ "ok": false, "error": "invalid_ip", "generated_at": "2025-09-20T23:02:10Z" }correlate (mixto)
{
"ok": true,
"results": [
{ "ip": "abc", "ok": false, "error": "invalid_ip" },
{ "ip": "192.168.0.10", "skipped": true, "reason": "private_ip" },
{ "ip": "8.8.8.8", "ok": true, "kind": "public" }
],
"generated_at": "2025-09-20T23:02:30Z"
}Errores comunes (contract)
Archivo fuera del directorio permitido:
{ "ok": false, "error": "path_outside_allowed_dir", "generated_at": "..." }Extensión no soportada:
{ "ok": false, "error": "unsupported_file_type", "generated_at": "..." }Excede tamaño máximo:
{ "ok": false, "error": "file_too_large", "generated_at": "..." }Token faltante o incorrecto (si se requiere):
{ "ok": false, "error": "unauthorized", "generated_at": "..." }Uso desde un host MCP (pseudo-cliente)
import asyncio, json
from mcp import StdioServerParameters, types
from mcp.client.stdio import stdio_client
from mcp.client.session import ClientSession
async def main():
params = StdioServerParameters(
command="python",
args=["-m", "porthunter.server"],
env={
"PORT_HUNTER_TOKEN": "TEST_TOKEN",
"PORT_HUNTER_ALLOWED_DIR": ".",
}
)
async with stdio_client(params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
resp = await session.call_tool(
name="scan_overview",
arguments={"path": "captures/scan-demo-20250906-1.pcapng", "auth_token": "TEST_TOKEN"}
)
# structuredContent preferente
sc = getattr(resp, "structuredContent", None)
if isinstance(sc, dict):
print(json.dumps(sc.get("result", sc), indent=2))
else:
text = "".join(b.text for b in resp.content if isinstance(b, types.TextContent))
print(text)
asyncio.run(main())Docker
docker build -t porthunter-mcp .
docker run --rm -it \
-e PORT_HUNTER_TOKEN=TEST_TOKEN \
-e PORT_HUNTER_ALLOWED_DIR=/data \
-v "$PWD:/data" \
porthunter-mcpBenchmark (opcional)
python scripts/benchmark_porthunter.py captures/scan-demo-20250906-1.pcapngSalida sugerida:
tamaño archivo,
paquetes totales,
duración total (s),
pps promedio.
Incluye una tablita de resultados en el README si vas a reportar métricas.
Desarrollo
Código fuente del servidor en
porthunter/Utilidades de PCAP e inteligencia en
porthunter/utils/**Ejecuta linters/tests en tu proyecto principal si los tienes allí.
Si subes pruebas mínimas aquí:
pytest -q
Licencia
MIT (sugerida). Añade un archivo LICENSE si lo deseas.
Créditos y referencias
Técnicas de escaneo: documentación pública (e.g., Nmap)
TL;DR
Arranca con:
$env:PORT_HUNTER_TOKEN = "TEST_TOKEN"
$env:PORT_HUNTER_ALLOWED_DIR = (Get-Location).Path
python -m porthunter.serverLlama scan_overview / list_suspects / first_scan_event / enrich_ip / correlate y consume el JSON como en los ejemplos de arriba.
This server cannot be deployed
Maintenance
Related MCP Connectors
Crypto security, honeypot detection, wallet analysis, and token risk scoring across 31 blockchains.
Honeypot probe data: IP reputation, scanners, CVE probing, TLS and SSH fingerprints.
Enrich, search, assess, and manage threat intelligence through 80+ typed MCP tools.
AI-powered threat intelligence, smart contract auditing, and cybersecurity OSINT.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables LLMs to analyze network packet captures (PCAP files) from local or remote sources through a modular architecture. Supports DNS traffic analysis with structured JSON responses for network security and troubleshooting tasks.9158 PyPI51MIT
- AlicenseNot gradedqualityDmaintenanceEnables natural language analysis of network packet captures, including protocol detection, flow analysis, and security threat identification, integrated with AI assistants.2MIT
- AlicenseNot gradedqualityCmaintenanceBridges AI assistants with network packet analysis, enabling PCAP investigation, protocol discovery, packet filtering, stream analysis, and live capture through natural language.MIT
- FlicenseAqualityFmaintenanceAnalyzes pcap files using tshark to detect network attacks and security threats.42-