ensmcp
Servidor MCP con las medidas de seguridad del ENS (Anexo II del RD 311/2022): consulta el Anexo II, genera la Declaración de Aplicabilidad y el alcance de auditoría de un sistema, y funciona sin conexión
Qué es
ensmcp es un servidor MCP (Model Context Protocol) que pone las medidas de seguridad del ENS Navegable (Anexo II del RD 311/2022) al alcance de Claude Desktop, Claude Code y cualquier otro cliente MCP.
Los datos viajan incluidos en el paquete como un snapshot, así que el servidor responde al instante y funciona sin conexión. Al arrancar, comprueba en segundo plano el sitio oficial y, si el contenido ha cambiado, actualiza los datos automáticamente; si no hay red o no hay navegador disponible, sigue funcionando con el snapshot sin más.
Además del Anexo II, incorpora el cuestionario de verificación de la guía CCN-STIC 808 (edición para el RD 311/2022): las preguntas de auditoría por medida, las comprobaciones sobre el articulado del RD y las evidencias documentales que puede pedir el auditor.
Características principales
| Característica | Descripción |
|---|---|
| Servidor MCP sobre stdio | Integrable en Claude Desktop, Claude Code y otros clientes MCP |
| Funciona sin conexión | El corpus completo viaja como snapshot en el paquete |
| Se mantiene al día | Una comprobación en segundo plano detecta cambios en el sitio oficial y actualiza los datos |
| Nunca bloquea | Sin red o sin navegador, se sigue respondiendo desde el snapshot |
| Declaración de Aplicabilidad | La DdA completa de un sistema, valorando cada dimensión por separado, en una llamada |
| Auditoría CCN-STIC 808 | Temario de auditoría, requisitos esenciales, artículos del RD y evidencias documentales |
Tools disponibles
Consulta del Anexo II
| Tool | Args | Descripción |
|---|---|---|
list_categories |
— | Las categorías del Anexo II con su grupo (org, op, mp). |
list_measures |
category_code?, dimension?, level? |
Medidas filtradas por categoría, dimensión de seguridad o nivel. |
get_measure |
code |
Una medida por código exacto (p. ej. "org.1"), con su texto del RD, refuerzos y niveles. |
search_measures |
query |
Búsqueda por texto en código, título, descripción y redacción del RD (ignora mayúsculas y tildes). |
Declaración de Aplicabilidad y auditoría
| Tool | Args | Descripción |
|---|---|---|
declaracion_aplicabilidad |
confidencialidad?, integridad?, disponibilidad?, autenticidad?, trazabilidad? |
La DdA de un sistema en una llamada: se valora cada dimensión (basico/medio/alto, u omitida) y devuelve las medidas exigibles con sus refuerzos. |
alcance_auditoria |
mismas que la DdA | El temario de auditoría del sistema: las medidas aplicables con sus preguntas de verificación acumuladas y el nivel de madurez mínimo exigible. |
requisitos_auditoria |
code?, level? |
El cuestionario CCN-STIC 808 en bruto, por medida o por tramo, marcando los requisitos esenciales. |
requisitos_articulos |
— | Las comprobaciones de auditoría sobre el articulado del RD (DdA formal, categorización, INES...). |
evidencias_auditoria |
code? |
La documentación que puede pedir el auditor, por medida. |
Estado y actualización
| Tool | Args | Descripción |
|---|---|---|
refresh_live_page |
— | Comprueba ahora el sitio oficial y actualiza los datos si han cambiado. |
snapshot_status |
— | Origen y frescura de los datos que se están sirviendo. |
Qué devuelve una medida
Cada medida trae dos textos, y hacen falta los dos: norm_text es la redacción del RD 311/2022 (lo que la medida exige) y description es el cuestionario de la CCN-STIC 808 (lo que el auditor pregunta). Los refuerzos vienen emparejados con el nivel que los exige y con su redacción en el RD:
{
"code": "mp.s.4",
"title": "Protección frente a denegación de servicio",
"description": "Categoría Media 1.1 ¿Se ha planificado y dotado al sistema de capacidad suficiente ...?",
"norm_text": "Se establecerán medidas preventivas frente a ataques de denegación de servicio ...",
"category_code": "mp.s",
"dimensions": ["disponibilidad"],
"levels": ["medio", "alto"],
"reinforcements": [
{ "code": "R1", "level": "alto", "alternative": false, "text": "R1-Detección y reacción. ..." }
],
"raw_levels": { "basico": "n.a.", "medio": "aplica", "alto": "+ R1" }
}
alternative distingue los refuerzos obligatorios (+ R1 + R2) de los alternativos (+ [R1 o R2], donde basta uno cualquiera): confundirlos cambia lo que hay que implantar.
Declaración de Aplicabilidad
El ENS no aplica un nivel al sistema entero: aplica uno por dimensión. Se valora cada una y la tool devuelve lo que ese sistema debe cumplir:
{
"categoria_sistema": "alto",
"measures": [
{ "code": "op.acc.5", "title": "Mecanismo de autenticación (usuarios externos)",
"required_level": "alto",
"required_reinforcements": [
{ "code": "R2", "alternative": true, "text": "R2-..." },
{ "code": "R5", "alternative": false, "text": "R5-..." }
] }
]
}
La regla sale del RD 311/2022: la categoría del sistema es el mayor de los niveles valorados (Anexo I, ap. 4), las medidas marcadas «Categoría» se exigen según la categoría del sistema, las que protegen dimensiones según el nivel de esas dimensiones, y una dimensión sin valorar deja fuera las medidas que solo la protegen.
Alcance de auditoría
Si la DdA contesta «¿qué tengo que implantar?», alcance_auditoria contesta «¿qué me va a preguntar el auditor?». Devuelve, por cada medida aplicable, los requisitos de verificación acumulados hasta su nivel exigible y el nivel de madurez mínimo que exige la guía:
| Categoría | Nivel mínimo de madurez |
|---|---|
| BÁSICA | L2 — Reproducible, pero intuitivo |
| MEDIA | L3 — Proceso definido |
| ALTA | L4 — Gestionado y medible |
El matiz importa: los tramos que el ENS Navegable etiqueta «Categoría Básica / Media / Alta» son acumulativos según la CCN-STIC 808 §5 — «Categoría Básica» significa exigible a todas las categorías, no solo para sistemas básicos. Un sistema de categoría media responde las preguntas de básica y las de media. Para un sistema C=alto, I=medio, D=bajo, A=medio, T=medio, el temario real son 382 preguntas (136 esenciales, cuyo incumplimiento bloquea la certificación), no las 73 de su tramo.
requisitos_articulos y evidencias_auditoria cubren la otra mitad de la auditoría: las comprobaciones sobre el articulado del RD (si la DdA existe y está suscrita, si el sistema está categorizado formalmente, si se reporta a INES...) y las 365 evidencias documentales que la guía propone. Estos datos salen de la CCN-STIC 808; el ENS Navegable no los publica.
De dónde salen los datos
src/ensmcp/data/anexo_ii.json— el corpus del ENS Navegable (medidas, textos del RD, cuestionario, aplicabilidad por niveles), capturado del sitio oficial. Cada consulta es un lookup en memoria.src/ensmcp/data/guia_808.json— el dato extraído de la guía CCN-STIC 808 con su atribución (la guía en sí no se redistribuye).snapshot_statusindica de qué edición procede.
Para regenerar el snapshot:
python scripts/build_snapshot.py
Para que el servidor no abra Chrome nunca por su cuenta: ENSMCP_LIVE_CHECK=0.
Requisitos
- Python 3.14+
Solo para actualizar el snapshot (refresh_live_page, la comprobación de arranque, scripts/build_snapshot.py) hacen falta además:
- Google Chrome instalado
- Un display (o
xvfben servidores sin él)
Instalación
git clone https://github.com/seifreed/ensmcp.git
cd ensmcp
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r pylock.toml # versiones exactas, verificadas por hash
pip install -e . --no-deps # el propio paquete, sin re-resolver
patchright install chromium
En Linux recién instalado puede hacer falta además:
patchright install-deps chromium
pyproject.toml es el único sitio donde se declaran las dependencias; pylock.toml es un artefacto generado a partir de él (PEP 751) que fija todas las dependencias —runtime y desarrollo juntas— a versión exacta y hash, con marcadores para Windows, Linux y macOS en x64 y ARM. Para actualizar dependencias, edita los rangos en pyproject.toml y regenera:
uv pip compile pyproject.toml --all-extras --universal --python-version 3.14 \
--format pylock.toml -o pylock.toml
Inicio rápido
python -m ensmcp
Configúralo en un cliente MCP (p. ej. Claude Desktop / Claude Code) apuntando al intérprete del entorno virtual:
{
"mcpServers": {
"ensmcp": {
"command": "/ruta/a/ensmcp/venv/bin/python",
"args": ["-m", "ensmcp"]
}
}
}
No hace falta configurar nada más: las consultas se responden desde el snapshot del paquete.
Para inspeccionarlo manualmente:
npx @modelcontextprotocol/inspector venv/bin/python -m ensmcp
Contribuir
Las contribuciones son bienvenidas.
- Haz un fork del repositorio
- Crea tu rama de funcionalidad (
git checkout -b feature/nueva-funcionalidad) - Haz commit de tus cambios (
git commit -m 'Añade nueva funcionalidad') - Sube la rama (
git push origin feature/nueva-funcionalidad) - Abre un Pull Request
Asegúrate de que todas las gates de calidad y seguridad pasen sin errores ni warnings antes de enviar el PR.
Apoya el proyecto
Si este proyecto te es útil, puedes apoyar su desarrollo:
Autor
- Marc Rivero López | @seifreed
- Repositorio: github.com/seifreed/ensmcp
Las medidas del ENS, accesibles por MCP
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ensmcp-0.1.0.tar.gz.
File metadata
- Download URL: ensmcp-0.1.0.tar.gz
- Upload date:
- Size: 455.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06f3fcf6891203c84edfbf963aeedaca3605a60ed098814beb48f862adf59e70
|
|
| MD5 |
f504397612b97e26d6496ff58e086756
|
|
| BLAKE2b-256 |
df5d56fa801f6ca86f8b582c30ae7497ffc247026422d5eea3f442d2e160f22c
|
Provenance
The following attestation bundles were made for ensmcp-0.1.0.tar.gz:
Publisher:
release.yml on seifreed/ensmcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ensmcp-0.1.0.tar.gz -
Subject digest:
06f3fcf6891203c84edfbf963aeedaca3605a60ed098814beb48f862adf59e70 - Sigstore transparency entry: 2469346329
- Sigstore integration time:
-
Permalink:
seifreed/ensmcp@c43c07d5d00bfdbbdf77190db9a3c704e90ef203 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/seifreed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c43c07d5d00bfdbbdf77190db9a3c704e90ef203 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ensmcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ensmcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 139.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1d34d7b8c4ab0230a9dccb989f2489154b14798fbb6ae831438d245cb5e9b37
|
|
| MD5 |
e1f2e8c456079bdc8dc8e72961c7d035
|
|
| BLAKE2b-256 |
05e8d46b10df6c7fbe80950a61daaaccbf2110ca4e8ae9525e8371d012ce1f89
|
Provenance
The following attestation bundles were made for ensmcp-0.1.0-py3-none-any.whl:
Publisher:
release.yml on seifreed/ensmcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ensmcp-0.1.0-py3-none-any.whl -
Subject digest:
f1d34d7b8c4ab0230a9dccb989f2489154b14798fbb6ae831438d245cb5e9b37 - Sigstore transparency entry: 2469346343
- Sigstore integration time:
-
Permalink:
seifreed/ensmcp@c43c07d5d00bfdbbdf77190db9a3c704e90ef203 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/seifreed
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c43c07d5d00bfdbbdf77190db9a3c704e90ef203 -
Trigger Event:
push
-
Statement type: