Datadis MCP Server
by Jaimegruiz
README.md
# Datadis MCP Server
Servidor MCP de producción que integra la [API de Datadis](https://datadis.es) con agentes IA (Claude, Copilot, Cursor, Open WebUI, etc.) mediante el Model Context Protocol.
## Arquitectura
```
Agente IA (Claude / Copilot / Cursor)
│
│ MCP (stdio o SSE)
▼
Datadis MCP Server (FastMCP 3.x)
├── Auth Layer — ciclo de vida del token, nunca persiste en disco
├── Datadis Client — httpx async, retry exponencial, excepciones tipadas
├── EnergyService — cache-aside por namespace (supplies 24h, consumo 1h…)
├── AnalysisService — análisis semántico, detención de anomalías, informes
├── MCP Tools (13) — wrappers delgados sin lógica de negocio
├── MCP Resources (3) — datos de catálogo en tiempo real
└── MCP Prompts (3) — plantillas de prompts para análisis energético
│
│ HTTPS
▼
Datadis API V2
```
## Estructura del proyecto
```
datadis-mcp/
├── server.py ← punto de entrada FastMCP
├── config.py ← Pydantic Settings (variables de entorno)
├── auth.py ← gestor del ciclo de vida del token
├── datadis_client.py ← cliente HTTP async para todos los endpoints V2
├── exceptions.py ← jerarquía de excepciones tipadas
├── models/ ← modelos de dominio Pydantic v2
├── cache/ ← abstracción de cache TTL por namespace
├── utils/ ← utilidades transversales (seguridad, logging)
├── services/
│ ├── energy_service.py ← wrapper con cache sobre DatadisClient
│ └── analysis_service.py ← análisis semántico de alto nivel
├── tools/ ← 13 tools MCP (sin lógica de negocio)
├── resources/ ← 3 resources MCP (status, distributors, groups)
├── prompts/ ← 3 prompts MCP (analyse_supply, executive_report, compare_years)
├── tests/ ← 150 tests pytest (83.61% cobertura)
├── pyproject.toml
├── requirements.txt
├── Dockerfile
└── .env.example
```
## Quick Start
### Requisitos
- Python 3.12+
- Cuenta en Datadis con credenciales válidas
### Instalación local
```bash
cd datadis-mcp
# Instalar dependencias
pip install -r requirements-dev.txt
# Configurar credenciales
copy .env.example .env # Windows
# cp .env.example .env # Linux/macOS
# Editar .env: rellenar DATADIS_USERNAME y DATADIS_PASSWORD
# Iniciar el servidor (transporte stdio — para Claude Desktop / Cursor)
python server.py
# O con transporte SSE (HTTP — para clientes web)
$env:MCP_TRANSPORT="sse"; python server.py # Windows
MCP_TRANSPORT=sse python server.py # Linux/macOS
```
### Redes corporativas con proxy SSL
Si aparece `CERTIFICATE_VERIFY_FAILED`, añade esto a tu `.env`:
```dotenv
HTTP_SSL_VERIFY=false
```
## Conectar un agente IA
### VS Code (GitHub Copilot Agent)
El fichero [.vscode/mcp.json](.vscode/mcp.json) ya está incluido en el repositorio.
VS Code lo detecta automáticamente — abre el proyecto y el servidor aparecerá en
**Copilot Chat → Agent mode → herramientas disponibles**.
Las credenciales se leen del fichero `.env` del proyecto.
### Claude Desktop
Edita `%APPDATA%\Claude\claude_desktop_config.json` (créalo si no existe):
```json
{
"mcpServers": {
"datadis": {
"command": "python",
"args": ["C:\\ruta\\completa\\a\\datadis-mcp\\server.py"],
"env": {
"DATADIS_USERNAME": "TU_NIF",
"DATADIS_PASSWORD": "TU_PASSWORD",
"HTTP_SSL_VERIFY": "false"
}
}
}
}
```
Reinicia Claude Desktop. Verás el ícono del servidor en la barra de herramientas.
### Cursor
Edita `%USERPROFILE%\.cursor\mcp.json` (créalo si no existe):
```json
{
"mcpServers": {
"datadis": {
"command": "python",
"args": ["C:\\ruta\\completa\\a\\datadis-mcp\\server.py"],
"env": {
"DATADIS_USERNAME": "TU_NIF",
"DATADIS_PASSWORD": "TU_PASSWORD",
"HTTP_SSL_VERIFY": "false"
}
}
}
}
```
Ve a **Cursor Settings → MCP** para verificar que el servidor aparece activo.
### Docker
```bash
# 1. Build
docker build -t datadis-mcp .
# 2. Verificar que la imagen se construyó correctamente
docker images datadis-mcp
docker inspect datadis-mcp --format "Usuario: {{.Config.User}} | Puerto: {{.Config.ExposedPorts}}"
# 3. Arrancar en modo SSE (HTTP, puerto 8000)
docker run -d \
--name datadis \
-p 8000:8000 \
-e DATADIS_USERNAME=TU_NIF \
-e DATADIS_PASSWORD=TU_PASSWORD \
-e HTTP_SSL_VERIFY=false \
-e MCP_TRANSPORT=sse \
datadis-mcp
# 4. Ver logs de arranque
docker logs datadis
# 5. Smoke test — el endpoint SSE debe responder
curl http://localhost:8000/sse # Linux/macOS
Invoke-RestMethod http://localhost:8000/sse # PowerShell
# 6. Verificar healthcheck
docker inspect datadis --format "Health: {{.State.Health.Status}}"
# 7. Parar y eliminar el contenedor
docker stop datadis && docker rm datadis
```
**Variables de entorno disponibles:**
| Variable | Descripción | Requerida |
|----------|-------------|-----------|
| `DATADIS_USERNAME` | NIF de la cuenta Datadis | Sí |
| `DATADIS_PASSWORD` | Contraseña de Datadis | Sí |
| `HTTP_SSL_VERIFY` | `false` en redes con proxy SSL | No |
| `MCP_TRANSPORT` | `sse` (Docker) o `stdio` (local) | No |
| `MCP_HOST` | Host de escucha (defecto `0.0.0.0`) | No |
| `MCP_PORT` | Puerto de escucha (defecto `8000`) | No |
| `LOG_LEVEL` | `DEBUG`\|`INFO`\|`WARNING` (defecto `INFO`) | No |
## Desarrollo
```bash
# Tests con cobertura
pytest
# Linter
ruff check .
# Tipos
mypy .
# Formateo
ruff format .
```
## Tools MCP disponibles
### Técnicas (acceso directo a la API)
| Tool | Descripción |
|------|-------------|
| `get_supplies` | Listado de puntos de suministro (CUPS) |
| `get_contract` | Detalle del contrato de un CUPS |
| `get_consumption` | Curva de carga horaria/cuarto-horaria |
| `get_max_power` | Potencia máxima registrada por periodo |
| `get_reactive_energy` | Energía reactiva por periodo (P1–P6) |
| `get_distributors` | Códigos de distribuidora vinculados a la cuenta |
| `get_groups` | Grupos de suministros definidos |
### Semánticas (análisis de alto nivel)
| Tool | Descripción |
|------|-------------|
| `get_supply_overview` | Resumen consolidado: suministro + contrato (auto-descubre distribuidor) |
| `get_energy_profile` | Perfil estadístico: total, media, máx, mín, desv. estándar |
| `compare_periods` | Comparación entre dos periodos: Δ kWh + % variación + tendencia |
| `detect_anomalies` | Detección de picos anómalos mediante Z-score configurable |
| `get_self_consumption_analysis` | Ratios de autoconsumo/excedentes para instalaciones CAU |
| `executive_energy_report` | Informe ejecutivo anual con recomendaciones autogeneradas |
## Resources MCP
| URI | Contenido |
|-----|----------|
| `datadis://status` | Estado del servidor: autenticación, cache, versión |
| `datadis://distributors` | Catálogo de distribuidoras (cacheado 24h) |
| `datadis://groups` | Grupos de suministro (cacheado 24h) |
## Prompts MCP
| Prompt | Descripción |
|--------|-------------|
| `analyse_supply` | Guía al agente: overview → perfil → potencia máx → informe |
| `executive_energy_report` | Plantilla de informe ejecutivo anual estructurado |
| `compare_years` | Comparación interanual con interpretación de tendencia |
## Seguridad
- Credenciales exclusivamente desde variables de entorno — nunca en código.
- Token bearer en memoria únicamente — nunca en disco ni en logs.
- NIF/NIE enmascarado en todos los logs (`4******0A`).
- TLS obligatorio para todas las comunicaciones con la API.
- Usuario non-root en Docker.
- `HTTP_SSL_VERIFY=false` disponible para proxies corporativos con inspección SSL.
## Licencia
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues