rainbird-mcp
by rudy325
README.md
<p align="center">
<img src="assets/logo.svg" width="128" alt="rainbird-mcp logo">
</p>
<h1 align="center">rainbird-mcp</h1>
<p align="center">
An <a href="https://modelcontextprotocol.io">MCP</a> server for <b>Rain Bird</b> irrigation
controllers (ESP-TM2 and compatible) that talk over a local <b>LNK / LNK2 WiFi module</b>.
<br>Local LAN only — no cloud dependency.
</p>
---
## What it does
Exposes your Rain Bird controller to any MCP client (Claude Code, Claude Desktop, etc.)
so you can ask things like *"is the sprinkler running?"*, *"run zone 3 for 10 minutes"*,
or *"set a 2-day rain delay"* in natural language.
It speaks the controller's local encrypted SIP-command protocol via
[`pyrainbird`](https://github.com/allenporter/pyrainbird) — the same protocol the
Rain Bird mobile app uses on your LAN.
## Tools
| Tool | Purpose |
| --- | --- |
| `list_controllers` | configured controllers, hosts, and detected transport URL |
| `get_controller_info` | model, firmware version, serial number |
| `get_status` | one-shot: irrigating?, active zones, remaining runtime, rain sensor, rain delay, clock |
| `get_zone_states` | per-zone on/off map |
| `get_schedule` | programs, run days, start times, per-zone durations |
| `get_rain_delay` | remaining rain delay in days |
| `get_network_info` | LNK WiFi status and parameters |
| `start_zone` | run one zone for N minutes (validated against available zones) |
| `stop_irrigation` | stop everything now |
| `advance_zone` | skip to the next zone in the running program |
| `set_rain_delay` | set/clear rain delay (0–14 days) |
| `run_program` | start stored program 1–4 (A/B/C on the TM2) |
| `sync_clock` | push this machine's local date/time to the controller |
## Requirements
- Python 3.12+
- [`uv`](https://docs.astral.sh/uv/)
- A Rain Bird controller with an LNK/LNK2 WiFi module on the same reachable network
- The controller's **device password** (see below)
## Install
```bash
git clone https://github.com/rudy325/rainbird-mcp.git
cd rainbird-mcp
uv sync
```
## Configure
The password is the controller's **device password** — set/shown in the Rain Bird app
under the controller's settings. It is **not** your WiFi password and **not** your
Rain Bird account login. If you don't know it, remove and re-add the WiFi module in the
app to set a new one (this keeps your zones and schedules).
Single controller:
```bash
export RAINBIRD_HOST=192.168.1.50
export RAINBIRD_PASSWORD=your-device-password
```
Multiple controllers (each tool then takes an optional `controller` argument, required
when more than one is configured):
```bash
export RAINBIRD_CONTROLLERS='{"front":{"host":"192.168.1.50","password":"pw1"},
"back":{"host":"192.168.1.51","password":"pw2"}}'
```
See [`.env.example`](.env.example) for all variables.
## Register with Claude Code
```bash
claude mcp add rainbird \
--env RAINBIRD_HOST=192.168.1.50 \
--env RAINBIRD_PASSWORD=your-device-password \
-- uv --directory /path/to/rainbird-mcp run server.py
```
Or with Claude Desktop, in `claude_desktop_config.json`:
```json
{
"mcpServers": {
"rainbird": {
"command": "uv",
"args": ["--directory", "/path/to/rainbird-mcp", "run", "server.py"],
"env": {
"RAINBIRD_HOST": "192.168.1.50",
"RAINBIRD_PASSWORD": "your-device-password"
}
}
}
}
```
## Use with other clients (OpenAI, local models, etc.)
This is a standard [MCP](https://modelcontextprotocol.io) server — it speaks the open
protocol over stdio and doesn't care which model or client drives it. Anything that
supports MCP works:
- **OpenAI** — the [Agents SDK](https://openai.github.io/openai-agents-python/mcp/) and
Responses API accept MCP servers. Point them at:
`command: "uv"`, `args: ["--directory", "/path/to/rainbird-mcp", "run", "server.py"]`,
with `RAINBIRD_HOST` / `RAINBIRD_PASSWORD` in the environment.
- **Local / open-source models** — via any MCP-capable client (Cline, Continue,
LibreChat, Open WebUI, Goose, Zed, Cursor) running Ollama, Llama, Qwen, etc.
- **Any other MCP client** — same stdio command as the Claude examples above.
The only requirement is a model that's competent at tool/function calling; the large
hosted models and stronger local ones (Llama 3.1+, Qwen 2.5+) handle it well.
## Transport (HTTP vs HTTPS)
Newer LNK modules (certificate CN `fw-cc20.rainbird.com`) serve the SIP endpoint over
**HTTPS on port 443 and refuse port 80**, with a self-signed Rain Bird certificate.
Older modules are plain HTTP on 80. `pyrainbird` hardcodes `http://`, so this server
probes 443 then 80 per host and rewrites the client URL accordingly. Certificate
verification is disabled — the device is LAN-local, addressed by IP, and its certificate
is self-signed by Rain Bird, so verification cannot succeed.
Skip the probe by forcing it: `RAINBIRD_SCHEME=https` (or `http`).
## Notes & gotchas
- **One connection at a time.** The LNK module accepts a single connection; expect slow
or failed calls if the Rain Bird mobile app is open against the same controller.
- **WiFi quality matters.** The module is 2.4 GHz WiFi 4, 1×1. A weak signal shows up as
intermittent timeouts, not clean errors. Check RSSI / TX retries in your AP if calls
are flaky.
- **`run_program`** uses the `ManuallyRunProgramRequest` SIP command; some firmware
revisions NACK it. If it fails, drive zones individually with `start_zone`.
- **The controller clock** drifts and has no NTP. `sync_clock` is worth running
occasionally.
- **Isolated IoT VLANs (UniFi and similar).** If the controller is on an isolated VLAN,
the router's isolation feature typically drops the controller's *replies* to your LAN,
which no user "allow" rule reliably overrides. Disabling isolation on that network (and
optionally re-adding your own outbound-only block rule) is what actually restores access.
## How it fits together
```
MCP client ──stdio──> server.py ──pyrainbird──> HTTP(S) /stick ──> LNK WiFi module ──> controller
```
## Credits
- [`pyrainbird`](https://github.com/allenporter/pyrainbird) — the protocol implementation.
- [Model Context Protocol](https://modelcontextprotocol.io) — the server framework.
## License
[MIT](LICENSE). Not affiliated with or endorsed by Rain Bird Corporation.
"Rain Bird" is a trademark of Rain Bird Corporation.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues