OPenSprinkler MCP Server
Servidor MCP para gestionar el controlador OpenSprinkler a través de Claude Desktop o cualquier cliente compatible con MCP.
Documentación
Servidor MCP de OpenSprinkler
Servidor MCP para gestionar el controlador OpenSprinkler mediante Claude Desktop o cualquier cliente compatible con MCP.
Restricción: Solo se puede gestionar un controlador a la vez. Esto se puede cambiar en el futuro si es necesario, pero por ahora es una limitación del diseño.
Herramientas Disponibles
| Herramienta | Descripción |
|---|---|
get_controller_status | Obtener el estado del controlador (hora del dispositivo, estado de habilitación, retraso por lluvia) |
get_stations | Obtener todas las estaciones con su estado actual |
run_station | Iniciar una estación durante una duración especificada |
stop_station | Detener una estación en funcionamiento |
stop_all_stations | Detener todas las estaciones en funcionamiento inmediatamente |
set_rain_delay | Establecer retraso por lluvia en horas (0 para limpiar) |
enable_controller | Habilitar o deshabilitar el controlador |
reboot_controller | Reiniciar el controlador OpenSprinkler |
view_logs | Obtener registros del historial de riego para un rango de fechas |
get_programs | Obtener todos los programas de riego |
get_program | Obtener detalles completos de un solo programa por ID |
add_program | Agregar un nuevo programa de riego |
delete_program | Eliminar un programa de riego por ID |
get_options | Obtener opciones y configuraciones del controlador |
Configuración
Variables de Entorno
| Variable | Descripción | Predeterminado |
|---|---|---|
OPEN_SPRINKLER_HOST | Nombre de host o dirección IP de OpenSprinkler | localhost |
OPEN_SPRINKLER_PASSWORD | Hash MD5 de la contraseña del controlador | (vacío) |
OPEN_SPRINKLER_PORT | Número de puerto | 80 |
OPEN_SPRINKLER_TLS | Establecer en true para usar HTTPS | false |
OPEN_SPRINKLER_TIMEOUT_MS | Abortar una solicitud del controlador después de esta cantidad de milisegundos | 10000 |
PORT | Puerto HTTP para modo SSE | 3000 |
HOST | Interfaz a la que vincularse en modo SSE. Use 127.0.0.1 para aceptar solo conexiones locales | 0.0.0.0 |
MCP_AUTH_TOKEN | Token de portador requerido en todas las solicitudes HTTP (opcional) | (sin establecer — sin autenticación) |
MCP_ALLOWED_HOSTS | Lista de permitidos del encabezado Host separada por comas. Cuando se establece, otros hosts reciben 403 — esto es lo que bloquea los ataques de re-vinculación de DNS | (sin establecer — no validado) |
MCP_ALLOWED_ORIGINS | Lista de permitidos Origin separada por comas para clientes de navegador. Las solicitudes sin Origin no se ven afectadas | (sin establecer — no validado) |
Conexión Segura (TLS/HTTPS)
Si su OpenSprinkler está detrás de un proxy inverso con HTTPS (por ejemplo, nginx, Traefik), establezca:
OPEN_SPRINKLER_HOST=opensprinkler.example.com
OPEN_SPRINKLER_PORT=443
OPEN_SPRINKLER_TLS=true
El servidor se conectará entonces mediante https://opensprinkler.example.com:443.
Nota: El firmware de OpenSprinkler no admite TLS de forma nativa — HTTPS requiere un proxy inverso delante del controlador.
Modos de Transporte
El servidor admite dos modos de transporte, seleccionados mediante un argumento de línea de comandos.
stdio (predeterminado)
Se usa cuando lo lanza directamente un cliente MCP (por ejemplo, Claude Desktop). No se necesita argumento:
node dist/index.js
SSE / HTTP (--sse)
Inicia un servidor HTTP que expone el endpoint MCP a través de HTTP Transmisible (SSE). Use esto cuando quiera ejecutar el servidor como un servicio de red persistente — por ejemplo en Docker o Kubernetes — y conectarse a él desde múltiples clientes o a través de la red.
node dist/index.js --sse
El servidor escucha en http://${HOST}:${PORT}/mcp (predeterminado 0.0.0.0:3000).
Conecte su cliente MCP a: http://<host>:3000/mcp
Autenticación de Portador (solo modo HTTP)
Establezca MCP_AUTH_TOKEN para requerir un token de portador en cada solicitud HTTP. Si la variable no está establecida, el servidor acepta todas las conexiones (útil para redes privadas o uso local).
MCP_AUTH_TOKEN=mysecrettoken TRANSPORT=http node dist/index.js
Los clientes deben enviar el encabezado:
Authorization: Bearer mysecrettoken
Las solicitudes sin un token válido reciben 401 Unauthorized. Los tokens se comparan en tiempo constante. El transporte stdio no se ve afectado — la autenticación no es aplicable allí.
Endurecimiento de Red (solo modo HTTP)
Estas herramientas pueden iniciar y detener el riego, deshabilitar el controlador, reiniciarlo y eliminar programas, por lo que cualquiera que pueda alcanzar el puerto HTTP puede hacer todo eso. En modo HTTP, el servidor se vincula a 0.0.0.0 de forma predeterminada e imprime una advertencia al inicio cuando no se establece ningún token.
Para cualquier cosa más allá de una red privada de confianza:
MCP_AUTH_TOKEN=mysecrettoken \
HOST=127.0.0.1 \
MCP_ALLOWED_HOSTS=localhost:3000,127.0.0.1:3000 \
node dist/index.js --sse
MCP_AUTH_TOKENes el control principal — sin él, el endpoint está abierto.MCP_ALLOWED_HOSTSdefiende contra la re-vinculación de DNS: una página web maliciosa puede hacer que un navegador en su red alcance127.0.0.1:3000, pero la solicitud aún lleva el nombre de host del atacante en el encabezadoHost, que la lista de permitidos rechaza.HOST=127.0.0.1mantiene el listener fuera de la red por completo. Déjelo en el valor predeterminado0.0.0.0dentro de Docker/Kubernetes, donde el contenedor necesita aceptar conexiones desde fuera de su espacio de nombres de red.
SSE heredado (compatibilidad con versiones anteriores)
Para pruebas con herramientas que implementan el transporte SSE MCP más antiguo (por ejemplo, mcptools, versiones anteriores del inspector), el servidor maneja automáticamente clientes heredados en el mismo endpoint /mcp — no se necesita ninguna bandera adicional.
Cómo distingue el servidor a los clientes:
| Solicitud | Interpretada como |
|---|---|
GET /mcp (sin encabezado mcp-session-id) | SSE heredado — abre un flujo de eventos |
POST /mcp?sessionId=<id> | SSE heredado — cliente enviando un mensaje |
POST /mcp (con o sin encabezado mcp-session-id) | HTTP Transmisible moderno |
Conexión de un cliente heredado (ejemplo con mcptools):
# Start the server
node dist/index.js --sse
# In another terminal
mcp connect http://localhost:3000/mcp
Nota:
SSEServerTransportestá obsoleto en el SDK de MCP y esta capa de compatibilidad está destinada solo para pruebas. Los clientes de producción deben usar el transporte HTTP Transmisible moderno.
Puede habilitar la salida de depuración detallada durante las pruebas estableciendo NODE_ENV=development:
NODE_ENV=development node dist/index.js --sse
Esto imprime cada solicitud, estado de respuesta y evento del ciclo de vida de la sesión en stderr.
Docker
Consulte docs/docker/ para la guía de implementación completa, el archivo Docker Compose, las opciones de configuración de Claude Desktop y los pasos de solución de problemas.
Kubernetes
Consulte docs/kubernetes/ para los manifiestos. Ajuste el ConfigMap y Secret para su entorno, luego:
kubectl apply -k docs/kubernetes/
Claude Desktop (Node.js, sin Docker)
{
"mcpServers": {
"opensprinkler": {
"command": "node",
"args": ["/path/to/opensprinkler-mcp/dist/index.js"],
"env": {
"OPEN_SPRINKLER_HOST": "192.168.1.100",
"OPEN_SPRINKLER_PASSWORD": "your_password"
}
}
}
}
Contraseña
El firmware de OpenSprinkler almacena cualquier cadena que se haya escrito cuando se estableció la contraseña por última vez. La aplicación oficial aplica hash MD5 a la contraseña antes de enviarla, por lo que el valor almacenado es un hash MD5 — y OPEN_SPRINKLER_PASSWORD debe ser el hash MD5 de su contraseña, no el texto plano.
Genérelo con:
echo -n "your_password" | md5
Contribuciones
Las contribuciones son bienvenidas. Por favor, abra un problema o solicitud de extracción en GitHub.
Agradecimientos
Este proyecto está inspirado en el trabajo en github.com/Lumeo-sd/opensprinkler-mcp-sdr. Todo el código fue recreado automáticamente desde cero utilizando herramientas de IA debido a la falta de declaración de LICENCIA en el repositorio original.
Aviso Legal
- No estoy afiliado con los fabricantes, vendedores ni ninguna de las marcas de dispositivos. Este plugin es un proyecto personal que mantengo en mi tiempo libre.
- Consulte la licencia para obtener más información.