Skip to main content
Glama
camr8989

mcp-cybersec-server

by camr8989
README.md
# mcp-cybersec-server

**MCP Server de apoyo a operaciones de ciberseguridad** — construido sobre el protocolo *Model Context Protocol* (Anthropic) y la API pública de [CIRCL Vulnerability-Lookup](https://vulnerability.circl.lu/api/).

> Práctica 2 del Módulo 8 (*Diseño y Publicación de Interfaces para Herramientas IA*) del Máster en IA aplicada a la Ciberseguridad.
>

---

## ✨ ¿Qué expone este servidor?

| Tipo | Nombre | Descripción rápida |
|------|--------|--------------------|
| 🛠️ Tool | `search_cve_by_id` | Detalles técnicos completos de un CVE (descripción, CVSS, referencias, productos). |
| 🛠️ Tool | `search_cves_by_keyword` | Búsqueda de CVEs por vendor + product, ordenados por severidad. |
| 🛠️ Tool | `summarize_cve_risk` | Resumen orientado a SOC/Blue Team: urgencia, acción inmediata, indicios de exploit público. |
| 📄 Resource | `file://playbook_high_risk` | Playbook NIST SP 800-61 Rev. 2 para vulnerabilidades de alto/crítico riesgo. |
| 📊 Resource | `file://risk_matrix` | Matriz cuantitativa de riesgo (CVSS + exposición + exploit + criticidad). |
| 💬 Prompt | `analyze_asset_vulnerabilities` | Plantilla orquestadora para análisis integral de vulnerabilidades sobre un activo. |

---

## 🏗️ Arquitectura

```
┌────────────────────────────────────────────────────┐
│   MCP HOST  (MCP Inspector / VS Code Copilot Agent)│
│   Usuario  →  LLM  →  decide qué invocar           │
└──────────────────────┬─────────────────────────────┘
                       │  stdio (JSON-RPC 2.0)
                       ▼
┌────────────────────────────────────────────────────┐
│              MCP SERVER (Python + FastMCP)         │
│   ├─ 3 tools   ├─ 2 resources   └─ 1 prompt        │
│   Capa de negocio: circl_client · cve_parser ·     │
│                    models · logger                 │
└──────────────────────┬─────────────────────────────┘
                       │  HTTPS
                       ▼
┌────────────────────────────────────────────────────┐
│   CIRCL Vulnerability-Lookup API (v5.2.0)          │
└────────────────────────────────────────────────────┘
```

---

## 📂 Estructura del proyecto

```
mcp-cybersec-server/
├── src/
│   ├── server.py                 # Ensamblado FastMCP
│   ├── circl_client.py           # Cliente HTTP + reintentos con backoff
│   ├── cve_parser.py             # Parser CVE Record 5.x (CVSS multinivel)
│   ├── models.py                 # Modelos Pydantic (contratos)
│   ├── logger.py                 # Logger estructurado (stderr)
│   └── tools/
│       ├── search_cve_by_id.py
│       ├── search_cves_by_keyword.py
│       └── summarize_cve_risk.py
├── resources/
│   ├── playbook_high_risk.md
│   └── risk_matrix.json
├── prompts/
│   └── analyze_asset_vulnerabilities.py
├── tests/
│   ├── test_circl_connectivity.py
│   ├── test_tools.py
│   ├── test_resources.py
│   ├── test_prompt.py
│   └── test_error_handling.py
├── .vscode/mcp.json              # Config MCP para VS Code nativo
├── requirements.txt
├── pyproject.toml
└── README.md
```

---

## 🚀 Instalación

### Requisitos previos

- **Python 3.10+** (probado con 3.14.2)
- **Node.js 18+** (solo si vas a usar MCP Inspector)
- **VS Code 1.99+** (si vas a usar VS Code como MCP Host)
- **GitHub Copilot Chat** (extensión oficial, incluye modo Agent con soporte MCP)
- Conexión a Internet para consultar CIRCL

### Instalación paso a paso (Windows / PowerShell)

```powershell
# 1) Clonar y entrar al proyecto
git clone <URL_DEL_REPO> mcp-cybersec-server
cd mcp-cybersec-server

# 2) Crear entorno virtual
python -m venv .venv
.\.venv\Scripts\Activate.ps1

# 3) Instalar dependencias
python -m pip install --upgrade pip setuptools wheel
pip install -r requirements.txt

# 4) Verificar entorno
python -c "from mcp.server.fastmcp import FastMCP; print('SDK MCP listo')"
python tests\test_circl_connectivity.py
```


## ▶️ Lanzar el servidor

El servidor soporta dos modos de arranque, según el Host que lo consuma:

### Modo módulo (VS Code Copilot Agent, Claude Desktop, cualquier Host stdio)

```powershell
python -m src.server
```

### Modo herramienta (MCP Inspector oficial de Anthropic)

```powershell
mcp dev src\server.py
```

Esto lanza el Inspector en `http://localhost:6274` con un token pre-cargado. Al abrirse el navegador, verás el panel de configuración; ajusta:

- **Transport Type:** `STDIO`
- **Command:** `python`
- **Arguments:** `-m src.server`

Pulsa **Connect**.

---

## 🔌 Integración con MCP Hosts

### VS Code + GitHub Copilot Chat (modo Agent) — recomendado para uso interactivo

Con VS Code 1.99+ y la extensión **GitHub Copilot Chat** instalada:

1. Asegúrate de tener sesión iniciada en GitHub Copilot (plan Free es suficiente).
2. Abre `.vscode/mcp.json` — ya viene configurado en el repositorio.
3. Haz clic en el CodeLens **▷ Start** que aparece encima del bloque `"servers"`.
4. Abre el chat con `Ctrl+Alt+I` y usa el modo **Agent**.
5. El Agent detecta automáticamente las tools y las invoca cuando el prompt lo requiera.

```json
{
  "servers": {
    "mcp-cybersec-server": {
      "type": "stdio",
      "command": "${workspaceFolder}/.venv/Scripts/python.exe",
      "args": ["-m", "src.server"],
      "cwd": "${workspaceFolder}",
      "env": { "PYTHONUNBUFFERED": "1" }
    }
  }
}
```

### MCP Inspector oficial — recomendado para validación técnica

Ya explicado arriba con `mcp dev src\server.py`. Muestra el JSON crudo de cada intercambio, lo que resulta especialmente útil para depuración y para la memoria académica.

---

## 🧪 Suite de pruebas

Todos los tests se ejecutan directamente con Python (sin pytest, para minimizar dependencias):

```powershell
# Conectividad con la API CIRCL
python tests\test_circl_connectivity.py

# Funcional de las 3 tools
python tests\test_tools.py

# Validación de los 2 resources
python tests\test_resources.py

# Plantilla del prompt
python tests\test_prompt.py

# Manejo robusto de errores (6 escenarios críticos)
python tests\test_error_handling.py
```

---

## 🧠 Ejemplos de uso desde Copilot Agent

Una vez conectado el servidor, puedes disparar preguntas naturales que activarán las tools automáticamente:

- *"Muéstrame los detalles de CVE-2021-44228 usando el MCP server mcp-cybersec-server."*
- *"¿Qué CVEs recientes afectan a apache/log4j?"*
- *"Actúa como analista SOC. Tengo un servidor Log4j 2.14 expuesto a Internet. Consulta CVE-2021-44228, resume el riesgo, lee la risk_matrix y dame un análisis integral con acciones 24h."*

El prompt registrado `analyze_asset_vulnerabilities` acepta cinco parámetros:

| Parámetro | Tipo | Ejemplo |
|-----------|------|---------|
| `asset_name` | string | `Servidor web de facturación (FRONT-FACT-PROD-01)` |
| `cve_list` | string (separado por comas) | `CVE-2021-44228, CVE-2021-45046` |
| `asset_criticality` | `critico_negocio` \| `alto` \| `medio` \| `bajo` | `critico_negocio` |
| `exposicion` | string | `internet_publico` |
| `notas_contexto` | string libre | *Contexto adicional del analista* |

---

## 🛡️ Manejo de errores

El servidor implementa tres capas de robustez:

1. **Reintentos con backoff exponencial** en el cliente CIRCL (3 intentos, delays 1.5s / 3s / 6s) para códigos 5xx y timeouts.
2. **Excepciones específicas del dominio** (`CVENotFoundError`, `CIRCLAPIError`, `ValueError`).
3. **Envoltorio con logging estructurado** en el servidor — todos los eventos van a `stderr` para no interferir con el transporte `stdio` de MCP.

---

## ⚠️ Particularidades de la API de CIRCL

Durante el desarrollo descubrí varias particularidades del endpoint público de CIRCL que conviene documentar:

- El endpoint de búsqueda válido es `/api/vulnerability/search/{vendor}/{product}` (no acepta *keyword* libre).
- Los nombres de vendor/product en `containers.cna.affected[]` **no coinciden** con el índice de `/browse/`. Ejemplo: en el record aparece "Apache Software Foundation / Apache Log4j2", pero el índice usa `vendor=apache` / `product=log4j`.
- La respuesta de `/search` es un `dict` con `results.cvelistv5` y `results.nvd` como sub-fuentes; cada item viene como tupla `[cve_id, record]`.
- El CVSS puede estar en `containers.cna.metrics` **o** en `containers.adp[*].metrics` (por ejemplo, CVE-2021-44228 solo tiene CVSS publicado por el ADP de CISA).

---