OPenSprinkler MCP Server
MCP server for managing OpenSprinkler controller via Claude Desktop or any MCP-compatible client.
Documentation
OpenSprinkler MCP Server
MCP server for managing OpenSprinkler controller via Claude Desktop or any MCP-compatible client.
Restriction: Only one controller can be managed at a time. This can be changed in the future if needed, but for now it is a limitation of the design.
Available Tools
| Tool | Description |
|---|---|
get_controller_status | Get controller status (device time, enabled state, rain delay) |
get_stations | Get all stations with their current status |
run_station | Start a station for a specified duration |
stop_station | Stop a running station |
stop_all_stations | Stop all running stations immediately |
set_rain_delay | Set rain delay in hours (0 to clear) |
enable_controller | Enable or disable the controller |
reboot_controller | Reboot the OpenSprinkler controller |
view_logs | Get watering history logs for a date range |
get_programs | Get all watering programs |
get_program | Get full details of a single program by ID |
add_program | Add a new watering program |
delete_program | Delete a watering program by ID |
get_options | Get controller options and settings |
Configuration
Environment Variables
| Variable | Description | Default |
|---|---|---|
OPEN_SPRINKLER_HOST | Hostname or IP address of OpenSprinkler | localhost |
OPEN_SPRINKLER_PASSWORD | MD5 hash of the controller password | (empty) |
OPEN_SPRINKLER_PORT | Port number | 80 |
OPEN_SPRINKLER_TLS | Set to true to use HTTPS | false |
PORT | HTTP port for SSE mode | 3000 |
MCP_AUTH_TOKEN | Bearer token required on all HTTP requests (optional) | (unset — no auth) |
Secure Connection (TLS/HTTPS)
If your OpenSprinkler is behind a reverse proxy with HTTPS (e.g. nginx, Traefik), set:
OPEN_SPRINKLER_HOST=opensprinkler.example.com
OPEN_SPRINKLER_PORT=443
OPEN_SPRINKLER_TLS=true
The server will then connect via https://opensprinkler.example.com:443.
Note: OpenSprinkler firmware does not natively support TLS — HTTPS requires a reverse proxy in front of the controller.
Transport Modes
The server supports two transport modes, selected by a command-line argument.
stdio (default)
Used when launched directly by an MCP client (e.g. Claude Desktop). No argument needed:
node dist/index.js
SSE / HTTP (--sse)
Starts an HTTP server that exposes the MCP endpoint over Streamable HTTP (SSE). Use this when you want to run the server as a persistent network service — for example in Docker or Kubernetes — and connect to it from multiple clients or over the network.
node dist/index.js --sse
The server listens on http://0.0.0.0:${PORT}/mcp (default port 3000).
Connect your MCP client to: http://<host>:3000/mcp
Bearer Authentication (HTTP mode only)
Set MCP_AUTH_TOKEN to require a bearer token on every HTTP request. If the variable is not set the server accepts all connections (useful for private networks or local use).
MCP_AUTH_TOKEN=mysecrettoken TRANSPORT=http node dist/index.js
Clients must send the header:
Authorization: Bearer mysecrettoken
Requests without a valid token receive 401 Unauthorized. The stdio transport is unaffected — authentication is not applicable there.
Legacy SSE (backport compatibility)
For testing with tools that implement the older MCP SSE transport (e.g. mcptools, older inspector versions), the server automatically handles legacy clients on the same /mcp endpoint — no extra flag needed.
How the server distinguishes clients:
| Request | Interpreted as |
|---|---|
GET /mcp (no mcp-session-id header) | Legacy SSE — opens an event-stream |
POST /mcp?sessionId=<id> | Legacy SSE — client sending a message |
POST /mcp (with or without mcp-session-id header) | Modern Streamable HTTP |
Connecting a legacy client (example with mcptools):
# Start the server
node dist/index.js --sse
# In another terminal
mcp connect http://localhost:3000/mcp
Note:
SSEServerTransportis deprecated in the MCP SDK and this compatibility layer is intended for testing only. Production clients should use the modern Streamable HTTP transport.
You can enable verbose debug output during testing by setting NODE_ENV=development:
NODE_ENV=development node dist/index.js --sse
This prints every request, response status, and session lifecycle event to stderr.
Docker
See docs/docker/ for the full deployment guide, Docker Compose file, Claude Desktop configuration options, and troubleshooting steps.
Kubernetes
See docs/kubernetes/ for manifests. Adjust the ConfigMap and Secret for your environment, then:
kubectl apply -k docs/kubernetes/
Claude Desktop (Node.js, no 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"
}
}
}
}
Password
The OpenSprinkler firmware stores whatever string was written when the password was last set. The official app MD5-hashes the password before sending it, so the stored value is an MD5 hash — and OPEN_SPRINKLER_PASSWORD must be the MD5 hash of your password, not the plain text.
Generate it with:
echo -n "your_password" | md5
Contributing
Contributions are welcome. Please open an issue or pull request on GitHub.
Acknowledgements
This project is inspired by the work at github.com/Lumeo-sd/opensprinkler-mcp-sdr. All code was automatically re-created from scratch using AI tools due to lack of LICENSE statement in the original repository.
Disclaimer
- I am not affiliated with the manufacturers, sellers or any of the device brands. This plugin is a personal project that I maintain in my free time.
- Refer to the licence for more information.