State comes from resources that cache and refresh, while anything that changes a device is a tool call — so "what is the living room doing" and "turn the living room off" are structurally different operations, and the second one cannot happen by accident during the first. The scope parameter on the unified tools is the other thing to learn early: `all` is a real option, and it means the whole house.
An async Rust MCP server that connects AI assistants to Loxone Miniservers, with a clean split between tools and resources: 17 tools for actions that change device state, 25+ resources for read-only data with live state and caching. Lighting, blinds, climate, audio, security and workflow tools each accept a scope so a call can target one device, one room, or the whole system.
- Direct device control by UUID, singly or in batch, with actions on, off, toggle, up, down and stop — `control_device`, `control_multiple_devices`
- Lighting scoped to a device, a room or everything, with on, off, dim, bright and toggle and a 0-100 brightness — `control_lights_unified`, plus the legacy `control_room_lights` and `control_all_lights`
- Blinds and rolladen with up, down, stop and an explicit position where 0 is fully up and 100 fully down, plus a capability discovery call — `control_rolladen_unified`, `discover_rolladen_capabilities`, `control_room_rolladen`, `control_all_rolladen`
- Room climate: a target temperature validated to the 5.0-35.0 range, and a heating, cooling, auto or off mode — `set_room_temperature`, `set_room_mode`
- Audio zones with play, stop, pause, volume, mute, next and previous, and a direct volume setter — `control_audio_zone`, `set_audio_volume`
- Alarm arming in home, away or full mode, and disarming — `arm_alarm`, `disarm_alarm`
- Multi-step automations chained from other tools with a timeout and initial variables, plus demo workflows — `create_workflow`, `execute_workflow_demo`
- Read-only state as resources: `loxone://rooms`, `loxone://rooms/{room}/devices`, `loxone://devices/all`, `loxone://devices/category/{category}`, `loxone://sensors/door-window`, `loxone://sensors/temperature`, `loxone://audio/zones`, `loxone://weather/current`, `loxone://energy/consumption`, `loxone://security/status`, `loxone://system/status`
A Loxone Miniserver, Gen 1 or Gen 2, and credentials for it. Rust 1.85+ (2024 edition) to build with `cargo build --release`, or `nix build github:avrabe/mcp-loxone`, or a Docker image you build yourself. Credentials can come three ways: the recommended credential-ID system set up with `loxone-mcp-setup --generate-id`, plain environment variables `LOXONE_HOST`, `LOXONE_USER` and `LOXONE_PASS`, or Infisical with `INFISICAL_PROJECT_ID`, `INFISICAL_CLIENT_ID` and `INFISICAL_CLIENT_SECRET`. Three transports: `stdio` for desktop clients, `http` for n8n and web clients, and `streamable-http`. SSL verification, UUID validation, rate limiting and input sanitisation are on by default, and dev mode is restricted to localhost. Rate limits are role-based: 1000 requests/minute for admin, 100 for operator, 10 for viewer.
Build from source — clone the repository and build it, then point your client at the binary
