Content
# 🛡️ Wazuh MCP Server
**Servidor MCP (Model Context Protocol) para Wazuh SIEM/XDR — integración directa con Hermes Agent.**
Servidor MCP de alto rendimiento que expone **101 herramientas** y **11 prompts guiados** para interactuar con la API del Wazuh Manager y el Indexer de OpenSearch. Diseñado para despliegue en producción sobre un VPS Contabo, permitiendo que [Hermes Agent](https://hermes-agent.nousresearch.com) (o Claude Desktop y cualquier cliente MCP) consulte agentes, vulnerabilidades, alertas, reglas, SCA, hardware y salud del cluster, y además realice threat hunting, análisis de incidentes, informes de compliance, enriquecimiento con threat intelligence e integraciones con Jira/TheHive/Slack, directamente desde Wazuh.
- **17 tools núcleo** (`server.py`) — probadas en producción, cliente thread-safe con pool de conexiones, JWT auto-refresh y autenticación por certificados.
- **84 tools extendidas + 11 prompts** (`wazuh_tools/`) — portadas de [adi5353/wazuh-mcp](https://github.com/adi5353/wazuh-mcp) (Apache-2.0) y adaptadas a la infraestructura de este proyecto. Carga tolerante a fallos: si un módulo extendido fallara, las 17 tools núcleo siguen operativas.
---
## 🏗️ Arquitectura
```
┌─────────────────┐ MCP (Streamable HTTP) ┌──────────────────┐
│ Hermes Agent │ ◄──────────────────────────► │ Wazuh MCP Server │
│ (Cliente MCP) │ Puerto 8090 │ (FastMCP) │
└─────────────────┘ └────────┬─────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Wazuh │ │ OpenSearch │ │ Syscollector│
│ Manager │ │ Indexer │ │ (agentes) │
│ API │ │ (alertas, │ │ │
│ :55000 │ │ vulns) │ │ │
└───────────┘ │ :9200 │ └─────────────┘
└─────────────┘
```
### Componentes principales
| Archivo | Descripción |
|---------|-------------|
| `server.py` | **Servidor MCP principal (v2.0)**. Usa FastMCP + httpx con pool de conexiones, timeouts diferenciados, token JWT con refresh automático y cliente thread-safe. |
| `mcp_wazuh.py` | Implementación legacy/alternativa del cliente Wazuh MCP (compatible con mcporter). |
| `direct_api.py` | API HTTP directa sin dependencia MCP — endpoints REST simples para integración con n8n. |
| `http_wrapper.py` | Wrapper HTTP que expone herramientas MCP como endpoints REST (usa mcporter internamente). |
| `Dockerfile` | Imagen Python 3.12-slim con dependencias versionadas (fastmcp, httpx, uvicorn). |
| `docker-compose.yml` | Despliegue production-ready con límites de memoria, healthcheck, montaje de certificados y reinicio automático. |
### Stack tecnológico
- **Python 3.12** + **FastMCP 2.7.0** — servidor MCP con transporte HTTP
- **httpx 0.28.1** — cliente HTTP asíncrono con pool de conexiones
- **uvicorn** — servidor ASGI para el transporte HTTP
- **Docker** — contenedorizado para despliegue consistente
---
## 🔧 Herramientas MCP disponibles
### Agentes
| Herramienta | Descripción |
|-------------|-------------|
| `list_agents` | Lista todos los agentes con estado, versión, SO, IP y grupos |
| `get_agent_info` | Información detallada de un agente específico |
| `get_agents_summary` | Resumen con estadísticas de todos los agentes (activos, desconectados, por SO) |
| `get_agent_groups` | Grupos a los que pertenece un agente |
| `restart_agent` | Reinicia un agente específico |
### Vulnerabilidades (Indexer)
| Herramienta | Descripción |
|-------------|-------------|
| `get_agent_vulnerabilities` | Vulnerabilidades de un agente con filtro por severidad |
| `get_vulnerability_summary` | Resumen de CVEs únicos con desglose por severidad (usa collapse + aggregations) |
### Reglas
| Herramienta | Descripción |
|-------------|-------------|
| `list_rules` | Lista reglas con filtro por estado y grupo |
| `get_rules_groups` | Lista todos los grupos de reglas disponibles |
### Alertas (Indexer)
| Herramienta | Descripción |
|-------------|-------------|
| `search_alerts` | Búsqueda de alertas con query string, filtro por agente |
### Syscollector / SCA
| Herramienta | Descripción |
|-------------|-------------|
| `get_agent_sca` | Resultados del Security Configuration Assessment (SCA) |
| `get_agent_netaddr` | Interfaces de red del agente |
| `get_agent_hardware` | Información de hardware (CPU, RAM, placa base) |
| `get_agent_ports` | Puertos en escucha del agente (desde el Indexer) |
### Infraestructura
| Herramienta | Descripción |
|-------------|-------------|
| `get_manager_stats` | Estadísticas del Wazuh Manager |
| `get_cluster_nodes` | Nodos del cluster Wazuh |
| `get_indexer_health` | Salud del cluster OpenSearch (status, nodos, shards) |
---
## 🚀 Herramientas extendidas (84 tools en 21 dominios)
Portadas de [adi5353/wazuh-mcp](https://github.com/adi5353/wazuh-mcp) y adaptadas al cliente de este proyecto (ver [`wazuh_tools/NOTICE.md`](wazuh_tools/NOTICE.md)):
| Dominio | Tools destacadas |
|---------|------------------|
| **Alertas avanzadas** | `alert_summary`, `alert_timeline`, `search_by_mitre`, `search_by_source_ip`, `search_authentication_failures`, `get_alert_by_id` |
| **Threat Hunting** | `hunt_lateral_movement`, `hunt_persistence_mechanisms`, `hunt_data_exfiltration` |
| **Incidentes** | `incident_timeline`, `blast_radius_analysis`, `create_incident_report`, `tag_alert`, `bulk_suppress_rule` |
| **Vulnerabilidades** | `vulnerability_summary` (flota), `search_cve`, `prioritize_patches`, `get_agent_vulnerabilities_detailed` |
| **FIM** | `get_recent_fim_changes`, `search_fim_alerts`, `fim_summary`, `critical_file_changes` |
| **Compliance** | `compliance_summary` y `generate_compliance_report` (PCI-DSS, HIPAA, GDPR, NIST 800-53, TSC) |
| **SCA** | `get_sca_failed_checks`, `sca_alerts_summary`, `fleet_sca_weakest_agents` |
| **Inventario de flota** | `fleet_find_package`, `fleet_find_process`, `fleet_find_listening_port`, `get_agent_login_history`, `get_agent_packages`, `get_agent_processes` |
| **Reglas y decoders** | `search_rules`, `get_rule_details`, `test_log_against_rules`, `test_rule_coverage`, `list_decoders`, `get_custom_rules` |
| **CDB Lists** | `list_cdb_lists`, `add_to_cdb_list`, `remove_from_cdb_list`, `preview_cdb_list_impact` |
| **Active Response** | `get_active_responses`, `run_active_response`, `correlate_alert_with_response`, `active_response_effectiveness` |
| **MITRE ATT&CK** | `mitre_coverage_analysis`, `get_mitre_gaps` |
| **Threat Intel** | `enrich_ip` (VirusTotal + AbuseIPDB), `enrich_file_hash`, `enrich_ip_geo` (GeoIP gratuito) |
| **Supresión de ruido** | `list_suppressed_rules`, `noise_score_rule`, `expire_suppression` |
| **Reporting** | `generate_weekly_summary`, `generate_shift_handover`, `compare_alert_volume`, `detect_rule_anomalies` |
| **Integraciones** | `create_jira_ticket`, `create_thehive_case`, `update_ticket_status` |
| **Notificaciones** | `send_alert_to_slack`, `send_critical_alert_notify`, `email_compliance_report` |
| **Onboarding** | `generate_enrollment_command`, `list_never_connected_agents`, `agent_onboarding_checklist` |
| **Archive** | `search_archive_logs`, `search_archive_logs_by_agent` (forense) |
| **Cluster** | `get_cluster_health`, `check_event_queue_health` |
| **Agentes/Grupos** | `run_active_response`, `list_groups`, `get_group_agents`, `add_agent_to_group` |
Las integraciones externas (Jira, TheHive, Slack, SMTP, VirusTotal, AbuseIPDB) **degradan con elegancia**: si no configuras sus credenciales, las demás tools funcionan con normalidad.
### 🔐 Operaciones de escritura deshabilitadas por defecto
Las tools extendidas destructivas (`run_active_response`, `add_to_cdb_list`, `tag_alert`, `bulk_suppress_rule`, `add_agent_to_group`, `expire_suppression`, `remove_from_cdb_list`) requieren `WAZUH_ALLOW_WRITES=true`. Además, varias soportan `dry_run=True` (por defecto) para previsualizar el impacto sin aplicar cambios. La tool núcleo `restart_agent` no se ve afectada por este flag (mantiene su comportamiento original).
### 💬 Prompts MCP (workflows guiados)
| Prompt | Uso |
|--------|-----|
| `investigate_brute_force` | Investigación completa de fuerza bruta en 6 pasos |
| `weekly_soc_briefing` | Briefing ejecutivo semanal del SOC |
| `triage_alert` | Triaje estructurado de una alerta (TP/FP + severidad) |
| `cve_emergency_response` | Respuesta de emergencia a un CVE |
| `morning_briefing` | Briefing de inicio de turno |
| `incident_triage_full` | Triaje completo de incidente por agente o IP |
| `threat_hunt_session` | Sesión de threat hunt (lateral + persistencia + exfiltración) |
| `end_of_shift_handover` | Informe de relevo de turno |
| `daily_security_report` | **Reporte diario técnico** — métricas de alertas, amenazas activas, salud de infraestructura, vulnerabilidades y acciones prioritarias (12 tools orquestadas) |
| `weekly_security_report` | **Reporte semanal táctico** — tendencias, threat hunting, MITRE ATT&CK, gestión de vulnerabilidades, compliance y plan de acción (17 tools orquestadas) |
| `monthly_ciso_report` | **Reporte mensual ejecutivo CISO** — scorecard de postura, paisaje de amenazas, riesgos, compliance multi-framework, KPIs y recomendaciones estratégicas (25 tools orquestadas) |
---
## 📋 Variables de entorno
Copia `.env.example` a `.env` y configura los valores:
| Variable | Requerida | Default | Descripción |
|----------|-----------|---------|-------------|
| `WAZUH_URL` | ✅ | `https://localhost:55000` | URL base de la API del Wazuh Manager |
| `WAZUH_USER` | ✅ | — | Usuario con acceso a la API de Wazuh |
| `WAZUH_PASS` | ✅ | — | Contraseña del usuario de la API |
| `INDEXER_URL` | ✅ | `https://localhost:9200` | URL base del Indexer de OpenSearch |
| `INDEXER_USER` | ⚠️ | — | Usuario del Indexer (si no usas certificados) |
| `INDEXER_PASS` | ⚠️ | — | Contraseña del Indexer (si no usas certificados) |
| `INDEXER_CERT` | ⚠️ | — | Ruta al certificado cliente (alternativa a user/pass) |
| `INDEXER_KEY` | ⚠️ | — | Ruta a la clave privada del certificado |
| `INDEXER_CA` | ❌ | — | Ruta al CA bundle (opcional) |
| `VERIFY_SSL` | ❌ | `false` | Verificar certificados SSL (`true`/`false`) |
| `INDEXER_TIMEOUT` | ❌ | `30.0` | Timeout para consultas al Indexer (segundos) |
| `WAZUH_API_TIMEOUT` | ❌ | `15.0` | Timeout para consultas a la API de Wazuh |
| `MAX_CONNECTIONS` | ❌ | `20` | Conexiones máximas en el pool HTTP |
| `MAX_KEEPALIVE` | ❌ | `10` | Conexiones keep-alive máximas |
| `WAZUH_HTTP_PORT` | ❌ | `8090` | Puerto HTTP del servidor MCP |
| `WAZUH_ALLOW_WRITES` | ❌ | `false` | Habilita las tools extendidas de escritura (active response, CDB, tagging) |
| `WAZUH_MAX_RESULTS_GLOBAL` | ❌ | `500` | Límite global de resultados en las tools extendidas |
| `WAZUH_TS_FIELD` | ❌ | `timestamp` | Campo de tiempo de los documentos de alertas (`timestamp` o `@timestamp`) |
| `VIRUSTOTAL_API_KEY` | ❌ | — | Enriquecimiento de IPs/hashes con VirusTotal |
| `ABUSEIPDB_API_KEY` | ❌ | — | Scoring de IPs con AbuseIPDB |
| `JIRA_URL` / `JIRA_USER` / `JIRA_API_TOKEN` / `JIRA_PROJECT_KEY` | ❌ | — | Creación de tickets en Jira |
| `THEHIVE_URL` / `THEHIVE_API_KEY` | ❌ | — | Creación de casos en TheHive |
| `SLACK_WEBHOOK_URL` o `SLACK_BOT_TOKEN` | ❌ | — | Notificaciones a Slack |
| `SMTP_HOST` / `SMTP_USER` / `SMTP_PASS` / `REPORT_EMAIL_TO` | ❌ | — | Envío de informes por email |
> ⚠️ **INDEXER_USER/INDEXER_PASS** o **INDEXER_CERT/INDEXER_KEY** — al menos un par es obligatorio para conectarse al Indexer.
>
> Ver `.env.example` para la lista completa comentada (patrones de índice, canales de Slack, password de enrolamiento, etc.).
---
## 🐳 Despliegue con Docker Compose
### Requisitos previos
1. **Certificados del Wazuh Indexer** en el host:
- `/etc/wazuh-indexer/certs/admin.pem` — certificado de administrador
- `/etc/wazuh-indexer/certs/admin-key.pem` — clave privada
- `/etc/wazuh-indexer/certs/root-ca.pem` — CA raíz
2. **Archivo `.env`** con las credenciales configuradas.
### Despliegue
```bash
# 1. Clonar el repositorio
git clone <repo-url> wazuh-mcp
cd wazuh-mcp
# 2. Crear .env desde el ejemplo
cp .env.example .env
# Editar .env con tus credenciales reales
nano .env
# 3. Construir y levantar
docker compose up -d --build
# 4. Verificar que está corriendo
docker compose ps
docker compose logs -f
```
### Healthcheck
El contenedor incluye un healthcheck funcional que verifica que el endpoint MCP responde correctamente:
```bash
# Verificar estado del healthcheck
docker inspect wazuh-mcp --format='{{.State.Health.Status}}'
# Probar manualmente
curl -X POST http://localhost:8090/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'
```
### Configuración de certificados
Si tu Wazuh Indexer está en el mismo host que el contenedor, los certificados se montan como volúmenes de solo lectura:
```yaml
volumes:
- /etc/wazuh-indexer/certs/admin.pem:/certs/admin.pem:ro
- /etc/wazuh-indexer/certs/admin-key.pem:/certs/admin-key.pem:ro
- /etc/wazuh-indexer/certs/root-ca.pem:/certs/root-ca.pem:ro
```
Luego en tu `.env`:
```env
INDEXER_CERT=/certs/admin.pem
INDEXER_KEY=/certs/admin-key.pem
INDEXER_CA=/certs/root-ca.pem
# INDEXER_USER= ← dejar vacío si usas certificados
# INDEXER_PASS= ← dejar vacío si usas certificados
```
Si el Indexer está en otro servidor, copia los certificados al host Docker y ajusta las rutas de los volúmenes.
---
## 🔌 Conexión con Hermes Agent Gateway
### Configuración del perfil
En tu perfil de Hermes Agent, añade el servidor MCP al archivo de configuración:
```json
{
"mcpServers": {
"wazuh-siem": {
"type": "streamable-http",
"url": "http://<IP_DEL_VPS>:8090/mcp"
}
}
}
```
### Probar la conexión
Una vez configurado, Hermes Agent podrá invocar cualquiera de las herramientas MCP. Ejemplos de prompts:
- *"Muéstrame todos los agentes de Wazuh"*
- *"¿Cuántas vulnerabilidades críticas tiene el agente 001?"*
- *"Busca alertas de rootkit en las últimas 24 horas"*
- *"¿Cuál es el estado de salud del cluster OpenSearch?"*
- *"Dame el resumen de todos los agentes"*
---
## 🛠️ Desarrollo local
```bash
# Instalar dependencias
pip install -r requirements.txt
# Ejecutar en modo HTTP (recomendado)
python server.py http 8090 127.0.0.1
# Ejecutar en modo stdio
python server.py stdio
```
---
## 📁 Estructura del proyecto
```
wazuh-mcp/
├── server.py # Servidor MCP principal (17 tools núcleo + registro de extendidas)
├── wazuh_tools/ # 84 tools extendidas en 21 dominios + 11 prompts MCP
│ ├── __init__.py # Orquestador: register_all() con proxy de prefijos/colisiones
│ ├── compat.py # Clientes async con pool, JWT auto-refresh y certificados
│ ├── helpers.py # trim_alert, trim_vuln, time_window...
│ ├── prompts.py # 11 prompts de workflows guiados
│ ├── alerts.py, fim.py, threat_hunting.py, incidents.py, ... (21 módulos)
│ ├── LICENSE # Apache-2.0 del proyecto original
│ └── NOTICE.md # Atribución y lista de adaptaciones
├── mcp_wazuh.py # Cliente MCP alternativo (compatible mcporter)
├── direct_api.py # API HTTP directa para n8n
├── http_wrapper.py # Wrapper HTTP para herramientas MCP
├── Dockerfile # Imagen Docker
├── docker-compose.yml # Despliegue con Docker Compose
├── requirements.txt # Dependencias pineadas (para instalación sin Docker)
├── .dockerignore # Exclusiones para el build
├── .env.example # Plantilla de variables de entorno
├── .gitignore # Exclusiones de Git
└── README.md # Este archivo
```
---
## 🔒 Seguridad
- **Operaciones de escritura deshabilitadas por defecto** — las tools extendidas destructivas requieren `WAZUH_ALLOW_WRITES=true` explícito, y las más peligrosas exigen además `dry_run=False`.
- **Nunca commitees `.env`** — contiene credenciales reales. Ya está en `.gitignore`.
- Los certificados `.pem` también están excluidos del repositorio.
- El puerto MCP se expone solo en `127.0.0.1` por defecto en docker-compose. Para acceso remoto, usa un reverse proxy con TLS (nginx, Caddy) o ajusta el bind.
- Las credenciales del Indexer pueden usar autenticación por certificados en lugar de user/password.
- El token JWT de Wazuh se refresca automáticamente al expirar o recibir un 401.
---
## 📝 Licencia
MIT — Consulta el archivo `LICENSE` para más detalles.
Los módulos de `wazuh_tools/` derivan de [adi5353/wazuh-mcp](https://github.com/adi5353/wazuh-mcp) (Apache License 2.0). Se conserva la licencia original y la atribución en `wazuh_tools/LICENSE` y `wazuh_tools/NOTICE.md`.
---
## 🤝 Contribuciones
Este proyecto es parte del ecosistema Hermes Agent. Las contribuciones son bienvenidas mediante issues y pull requests en GitHub.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.