Skip to main content
Glama
pikerr

SprutHub MCP Server

by pikerr
README.md
# SprutHub MCP Server

Высокоуровневый Model Context Protocol (MCP) сервер для управления умным домом **SprutHub** с помощью LLM-ассистентов (Antigravity, Claude Desktop, Cursor, Cline и др.).

---

## Ключевые особенности

* ⚡ **Прямой локальный WebSocket:** прямое подключение к хабу в локальной сети (`ws://<IP>/spruthub`), нулевые задержки (< 5 мс), полная автономность без зависимости от внешнего облака.
* 🧠 **Семантический фасад вместо сырого RPC:** сервер берёт на себя нормализацию данных, фильтрацию служебного мусора и разрешение сервисов, предоставляя LLM простые и надежные инструменты для работы за 1 шаг.
* 🛡️ **Автоматическая нормализация типов:** автоматическая упаковка базовых типов (`bool`, `int`, `float`, `str`) в protobuf-подобные структуры SprutHub (`boolValue`, `intValue` и др.).
* 💡 **Умное переключение (`sprut_set_switch`):** вам не нужно знать точный `service_id` или `characteristic_id` реле — сервер автоматически найдёт целевую службу `Switch`/`Lightbulb`/`Outlet`.
* 🔒 **Безопасная аутентификация:** работа по сессионному токену без необходимости хранить постоянный пароль от аккаунта в открытом виде.

---

## Архитектурный подход: Семантический фасад vs Generic RPC-шлюз

При интеграции SprutHub с большими языковыми моделями возможны два подхода:

1. **Сырой generic-прокси (Raw RPC Gateway):** когда все методы контроллера транслируются в MCP «как есть», а LLM сначала ищет метод через `list_methods`, затем запрашивает его схему и пытается вручную собрать сложный JSON-RPC payload.  
   *Недостатки:* на каждое действие уходит 3–4 шага диалога, сотни килобайт сырых схем забивают контекст LLM, а сложная вложенность структур SprutHub приводит к частым галлюцинациям модели.
2. **Семантический фасад (подход данного сервера):** сервер агрегирует рутинную логику внутри себя. Он очищает списки устройств от сервисных метаданных (`AccessoryInformation`, `Identify`, `C_Online`), распаковывает типизированные структуры и предоставляет компактные, понятные функции.  
   *Результат:* модель решает задачу пользователя **за один шаг**, не тратит лишние токены и работает стабильно даже на лёгких и быстрых моделях.

---

## Предоставляемые инструменты (Tools)

| Инструмент | Описание |
|---|---|
| `sprut_get_hub_info` | Информация о контроллере (имя, модель, серийный номер, версия ПО, онлайн-статус). |
| `sprut_list_rooms` | Список комнат с ID, названиями, активными сенсорами и действиями. |
| `sprut_list_devices` | Компактный список устройств и их текущих состояний (с опциональной фильтрацией по `room_id`). |
| `sprut_get_device` | Полная развернутая информация об аксессуаре, его службах и характеристиках. |
| `sprut_set_switch` | Быстрое включение/выключение любого реле, выключателя, розетки или лампы (`on: true/false`). |
| `sprut_set_characteristic` | Универсальная установка любого значения характеристики (яркость, температура, режим). |

---

## Где взять токен (локальный пароль)?

Всё настраивается за 10 секунд прямо из веб-интерфейса SprutHub:

1. **Токен / Локальный пароль (`token`):**
   * В веб-интерфейсе (`http://<IP_ХАБА>`) перейдите в **Настройки** → **Пользователи** → откройте карточку вашего пользователя (Владелец).
   * Скопируйте значение из поля **«Локальный пароль»** (при необходимости можно сгенерировать новый кнопкой *«Сгенерировать новый пароль»*).
2. **Серийный номер (`serial` — опционально):**
   * Указывать **не обязательно**: сервер автоматически определяет подключенный хаб и его серийный номер через API.
   * Если у вас несколько хабов или вы хотите зафиксировать конкретный, серийник можно посмотреть в URL браузера: `http://<IP_ХАБА>/hubs/<СЕРИЙНЫЙ_НОМЕР>/...` либо в **Настройки** → **Основные**.

---

## Конфигурация

Создайте файл `config.json` в корне проекта (на основе `config.example.json`):

```json
{
  "ws_url": "ws://192.168.1.100/spruthub",
  "token": "ВАШ_ЛОКАЛЬНЫЙ_ПАРОЛЬ"
}
```

Также параметры можно передавать через переменные окружения:
* `SPRUTHUB_WS_URL` — WebSocket-адрес хаба (по умолчанию `ws://127.0.0.1/spruthub`)
* `SPRUTHUB_TOKEN` — локальный пароль (токен)
* `SPRUTHUB_SERIAL` — *(опционально)* серийный номер контроллера (если не указан, определяется автоматически)

---

## Подключение к клиентам

### Вариант 1. Запуск через `uvx` (Рекомендуется)

Если установлен менеджер пакетов [uv](https://docs.astral.sh/uv/):

```json
{
  "mcpServers": {
    "spruthub": {
      "command": "uvx",
      "args": ["--from", ".", "spruthub-mcp"],
      "env": {
        "SPRUTHUB_WS_URL": "ws://192.168.1.100/spruthub",
        "SPRUTHUB_TOKEN": "ВАШ_ЛОКАЛЬНЫЙ_ПАРОЛЬ"
      }
    }
  }
}
```

### Вариант 2. Запуск через локальный Python

```json
{
  "mcpServers": {
    "spruthub": {
      "command": "python",
      "args": ["/путь/к/папке/spruthub-mcp/server.py"],
      "env": {
        "SPRUTHUB_WS_URL": "ws://192.168.1.100/spruthub",
        "SPRUTHUB_TOKEN": "ВАШ_ЛОКАЛЬНЫЙ_ПАРОЛЬ"
      }
    }
  }
}
```

---

## Лицензия

[MIT](LICENSE)