otolawn-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@otolawn-mcp water the front lawn for 5 minutes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
otolawn-mcp
A Model Context Protocol (MCP) server for OtO Lawn smart sprinkler devices. Control your OtO zones from any MCP client (Claude, Cursor, etc.):
List devices, zones, and schedules
Start / stop watering on demand, with a water depth or runtime you choose
Enable/disable zones, rename them, change their scheduled water amounts
Browse irrigation event history (what ran, when, how much water, errors)
Enable/disable watering schedules
Read the weather data OtO uses for rain/wind skipping, device diagnostics, battery history and notification messages
The protocol was reverse-engineered from the OtO mobile app (v4.0.8, Android build
com.oto). See docs/API.md for the full API reference. This is an
independent personal-use interoperability project - it is not affiliated with or
endorsed by OtO Inc. Trademarks belong to their owners.
This project talks to YOUR devices with YOUR credentials.How it works
MCP client (Claude, etc.)
| (stdio JSON-RPC)
v
otolawn-mcp server ──► Firebase Auth (email/password sign-in) ─► ID token
| https://oto-cloud-service-ems-prod-*.run.app API
v (Bearer ID-token auth)
OtO sprinkler device(s), polled by OtO's cloudAuthentication uses the same Firebase auth endpoint the app uses, with an embedded app API key (public information, shipped inside the distributed app).
The ID token is cached in memory and refreshed automatically (tokens last ~1 hour).
Manual start/stop are executed via the same schedule-execution endpoints the app uses; the physical device picks up the change within ~1-2 minutes.
Related MCP server: hydrawise-mcp
Install
Requires Python 3.11+.
git clone https://github.com/DmitriyAlergant/otolawn-mcp
cd otolawn-mcp
python -m venv .venv
uv pip install -e . # or: .venv/bin/pip install -e .Configure credentials
export OTO_EMAIL="you@example.com"
export OTO_PASSWORD="your-oto-app-password"These are the same email/password you use in the OtO mobile app.
Tool call contract
All tools return flat JSON blobs:
{"ok": true , "...": "payload"}
{"ok": false, "error": "description on failure"}Water depths are millimetres (wateringQuantity at the API level). Runtimes and
water depth are related by a per-zone calibration curve (timeToWater_form);
water_zone accepts either.
Available tools
Tool | Description |
| Devices with name + winter mode |
| Live hardware status: battery mA/V, charge state, comm info |
| Daily battery level history |
| Device event log (watering starts/stops, errors) |
| Zones with water amount, enabled, days, rain/wind skips |
| Enable / disable a zone |
| Rename a zone |
| Change a zone's scheduled water depth or runtime |
| Start watering now (returns |
| Stop a manual run by |
| Irrigation events (scheduled run instances) with statuses |
| Cancel an event, or un-cancel a rain-skipped one |
| Watering schedules (routines) |
| Weather used by the rain/wind intelligence |
| Account messages |
| Create an unconfigured zone (path calibration still needs the app) |
| Delete a zone |
Example
You: "Water the Front Lawn Far zone about 3 mm, then tell me how much it ran."
Claude: calls list_zones() ─► finds zone "Front Lawn Far"
calls water_zone(device_id, zone_id, water_depth_mm=3)
calls list_events(only_active=true) ...
calls stop_watering(scheduleId) when done (or lets it finish)Registering with Claude Code / other clients
claude mcp add otolawn -- <repo>/venv/bin/otolawn-mcp (with creds in env), or
in mcp.json:
{
"mcpServers": {
"otolawn": {
"command": "/path/to/otolawn-mcp/.venv/bin/otolawn-mcp",
"env": { "OTO_EMAIL": "you@example.com", "OTO_PASSWORD": "..." }
}
}
}Safety notes
water_zonetriggers real watering within a minute or so.A stopped
water_zonerun may still have briefly spawned a run - the device applies commands on its next poll, so stopping immediately after starting is also handled (event ends upUSER_STOPPED).Rain/wind intelligence is not bypassed by manual starts; use large-enough depth if you expect the forecast to interfere.
Deleting zones or devices cannot easily be undone.
Repo contents
src/otolawn_mcp/client.py- OtO cloud API client (auth, zones, events, control)src/otolawn_mcp/server.py- MCP tool surfacedocs/API.md- the full reverse-engineered API reference
Disclaimer
This is an unofficial, independent interoperability implementation, not affiliated with OtO Inc. Endpoints may change without notice. Use at your own risk. Be mindful of local water-use rules and of what you commit to a public repo :).
MIT licensed. See LICENSE.
Available Tools
19 toolsadd_zoneA
Create a new unconfigured zone on a device. The device must calibrate the throw path via the app afterwards (cloud-only path mapping is not possible), but the zone appears immediately and is waterable.
Inputs: name (required), device_id (required), enabled, water_depth_mm.
cancel_eventB
Cancel a scheduled irrigation event (or set cancel=false to un-cancel a rain-skipped event and force it to water anyway).
Inputs: schedule_id (required), cancel.
delete_zoneB
Delete a zone. This cannot be undone from this tool; the app keeps deleted zones recoverable for a short period.
Inputs: zone_id (required), device_id (required).
get_device_battery_historyB
Get the device's battery level history (percent values, one per day).
Inputs: device_id (required).
get_device_logsB
Get the device's recent log entries (watering starts/stops, errors, battery and connectivity events), newest first.
Inputs: device_id (required), limit.
get_device_statusB
Get live hardware status for one device: battery voltage/current, charge state, comms info, and any error data.
Inputs: device_id (required).
get_weatherA
Get the local weather used by the OtO weather engine: current conditions, weekly rain/temperature forecast and historical rain.
Inputs: no named parameters.
get_zoneB
Get full details of one zone: paths, nozzle angles, water amounts, bottle/fertilizer state and scheduling info.
Inputs: zone_id (required), device_id (required).
list_devicesB
List all OtO devices on the account with names and winter-mode state.
Inputs: no named parameters.
list_eventsA
List irrigation events. start/end are dates (YYYY-MM-DD), end included; default window is 7 days back through 14 days ahead. Set only_active=true to fetch just events that are scheduled, pending or currently executing.
Inputs: end, start, zone_id, only_active.
list_messagesC
List recent account messages from OtO (announcements, tips).
Inputs: limit.
list_routinesA
List watering schedules (routine definitions): pattern (daily/even/odd/ interval/daysOfWeek), start time, enabled flag and member zones.
Inputs: no named parameters.
list_zonesA
List watering zones (across all devices or for one device), with each zone's name, enabled state, water amount and schedule days.
Inputs: device_id.
rename_zoneC
Rename a watering zone.
Inputs: name (required), zone_id (required), device_id (required).
set_routine_enabledA
Enable or disable a watering schedule. Fetch-current-then-merge is used so other schedule settings are preserved.
Inputs: enabled (required), routine_id (required).
set_zone_enabledB
Enable or disable a zone. A disabled zone is skipped by schedules; manual watering may still be requested.
Inputs: enabled (required), zone_id (required), device_id (required).
set_zone_wateringB
Set the scheduled water amount for a zone. Pass water_depth_mm (the depth of water the zone should receive per watering day) or minutes. Example: 9.5 mm is a typical summer day for turf grass.
Inputs: zone_id (required), device_id (required), minutes, water_depth_mm.
stop_wateringA
Stop an active manual watering run. Get the scheduleId from water_zone or from the device's event list.
Inputs: schedule_id (required).
water_zoneA
START WATERING a zone now, manually. Give water_depth_mm (water depth in millimetres, e.g. 0.5-10) or minutes (runtime). The device begins its run within a couple of minutes. Returns the event scheduleId needed to stop it. If allow_conflicts is false the request fails when the device is already due to water at this time.
Inputs: zone_id (required), device_id (required), minutes, water_depth_mm, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 19 tools
Most tools target clearly distinct resources and actions (zones vs routines vs events vs devices). A few pairs could be momentarily confused—cancel_event vs stop_watering, and water_zone (manual) vs set_zone_watering (scheduled amount)—but the descriptions explicitly clarify the manual/scheduled distinction.
Every tool follows a consistent snake_case verb_noun pattern (list_zones, get_zone, set_zone_enabled, water_zone, cancel_event, etc.). No mixed conventions or vague verbs appear.
19 tools is on the heavier side but the domain is genuinely broad (zones, routines, events, devices, weather, messages), and each tool maps to a distinct operation. Slightly heavy but not bloated.
Zones have full lifecycle coverage (add/get/list/rename/enable/delete/set-watering) and devices/events are well covered. The main gap is routines: they can only be listed and enabled/disabled, with no create/edit, though zone-level scheduling partially compensates.
Maintenance
Related MCP Connectors
Hosted MCP server for Xweather weather data: conditions, forecasts, alerts, and more.
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
Remote MCP endpoint for U.S. home forecasts, public benchmark data, and permit or zoning readiness.
Host any HTTP API as a standard MCP server; auto-distribute to 12+ mainstream agent platforms.
Related MCP Servers
- FlicenseNot gradedqualityFmaintenanceEnables managing OpenSprinkler irrigation controllers via Claude Desktop, including starting/stopping stations, setting rain delays, and viewing controller status.-
- FlicenseNot gradedqualityDmaintenanceMCP server for Hunter Hydrawise irrigation controllers, exposing the Hydrawise REST API as tools for AI agents to manage watering schedules and controller settings.-
- FlicenseAqualityDmaintenanceQuery and control Orbit B-Hyve irrigation systems from MCP-compatible clients like Claude Code and Cursor.121-
- AlicenseAqualityCmaintenanceMCP server for full control of Rachio sprinkler controllers via the reverse-engineered internal gRPC API, enabling schedule management, manual zone runs, rain delays, and weather data retrieval.248MIT