keenetic
# Keenetic-router-plugin
Плагин (MCP-сервер + skill), который даёт ИИ-агенту управлять роутером **Keenetic/Netcraze** через RCI — тот же API, которым пользуется веб-интерфейс роутера. Работает напрямую по локальной сети, без облака. MCP-сервер универсален и не привязан к конкретному ИИ-инструменту — работает с любым MCP-клиентом (Claude Code, Codex и другие), skill (доменные знания о Keenetic/Netcraze для ИИ) — дополнительно доступен в экосистеме плагинов Claude Code.
Протестировано на KeeneticOS 5.0.12. На другой модели/прошивке отдельные RCI-пути могут отличаться — перед началом работы прогоните `npm run smoke` (read-only, ничего не меняет на роутере).
## Что умеет ИИ через этот плагин, а что нет
**Чтение — без подтверждения, в любой момент:**
версия прошивки, статус WAN, список интерфейсов, подключённые устройства, клиенты Wi-Fi, port forwarding, маршруты, DHCP-резервации, VPN-интерфейсы, полный экспорт конфигурации (`export_config`), проверка наличия обновления KeeneticOS (`check_firmware_update` — требует прав `admin`, см. ниже).
**Изменения — только если ИИ явно передал `confirm: true`:**
смена пароля Wi-Fi, включение/выключение точки доступа, добавление/удаление проброса портов, добавление/удаление маршрутов, привязка/отвязка сети к уже настроенному VPN-туннелю, пакетное применение маршрутов из `.bat`-файла. Без `confirm: true` вызов отклоняется. Можно попросить ИИ сначала выполнить с `dryRun: true` — он покажет, что именно будет отправлено на роутер, ничего не применяя.
**Опасные операции — дополнительно требуют `ALLOW_DESTRUCTIVE=true` в конфиге сервера:**
перезагрузка роутера. Пока флаг не включён, роутер нельзя перезагрузить через ИИ, даже с `confirm: true`.
**Чего плагин не умеет в принципе (не реализовано):**
создание VPN-туннелей с нуля (WireGuard/OpenVPN/IPsec), сброс к заводским настройкам, **применение** обновления прошивки (только проверка наличия — см. выше).
Каждый write/destructive-вызов (применённый, отклонённый или упавший с ошибкой) пишется в `audit.log`.
## Установка
Нужен Node.js 20+.
1. Склонируйте проект и установите зависимости:
```bash
npm install
npm run build
```
2. Скопируйте `.env.example` в `.env` в той же папке и заполните:
```
ROUTER_HOST=192.168.1.1 # LAN-адрес роутера (в свойствах сети — "основной шлюз")
ROUTER_PORT=80
ROUTER_LOGIN=имя_пользователя
ROUTER_PASSWORD=пароль_пользователя
ALLOW_DESTRUCTIVE=false # true — разрешить reboot_router
```
Вместо `.env` те же значения можно передать через `--env` при регистрации сервера — см. ниже.
3. Проверьте подключение (read-only, ничего не меняет на роутере):
```bash
npm run smoke
```
Если какой-то запрос вернул ошибку — для вашей модели/прошивки RCI-путь отличается, поправьте его в `src/capabilities/*.ts` до начала работы с ИИ.
## Подключение к Claude Code
**Как плагин (рекомендуется — сразу со skill):**
```bash
claude --plugin-dir "<путь-к-проекту>"
```
Для постоянного подключения (не только на одну сессию) используйте `/plugin install`, когда положите проект в git-репозиторий или локальный marketplace.
**Только сервер, без skill:**
```bash
claude mcp add --transport stdio --scope user keenetic -- node "<путь-к-проекту>/dist/index.js"
```
Если не создавали `.env`, добавьте креды прямо здесь:
```bash
claude mcp add --transport stdio --scope user \
--env ROUTER_HOST=192.168.1.1 --env ROUTER_LOGIN=имя_пользователя --env ROUTER_PASSWORD=его_пароль \
keenetic -- node "<путь-к-проекту>/dist/index.js"
```
Проверить подключение: `claude mcp list`, `claude mcp get keenetic` или `/mcp` внутри сессии.
После этого в диалоге можно писать, например: «покажи подключённые к роутеру устройства» или «поменяй пароль гостевого Wi-Fi».
## Подключение к Codex
В `~/.codex/config.toml`:
```toml
[mcp_servers.keenetic]
command = "node"
args = ["<путь-к-проекту>/dist/index.js"]
```
## Безопасность
Guard-модель (`confirm`/`dryRun`/`ALLOW_DESTRUCTIVE`) защищает от случайных и неаккуратных действий ИИ. Она **не защищает** сам пароль от роутера — если `.env` или конфиг попадёт в чужие руки, с этим паролем можно зайти в роутер напрямую, в обход сервера и всех этих ограничений.
- **`export_config`** формально read-only, но возвращает секреты в открытом/слабо обфусцированном виде (хэши паролей, WPA-PSK, параметры WireGuard) — та же информация, что за кнопкой "Сохранить" в веб-интерфейсе, но теперь в переписке с ИИ. Инструмент сам просит ИИ предупредить вас перед вызовом.
- **Заведите отдельного пользователя** для сервиса в веб-интерфейсе роутера (*Система → Пользователи*), а не используйте `admin`, где это возможно. Оговорка: часть операций (в частности, `set_wifi_password`/`set_wifi_enabled`, `check_firmware_update`) на Keenetic доступна только `admin` — если они нужны, используйте `admin`, но со свежим уникальным паролем.
- **Не открывайте RCI/веб-админку в интернет** — не включайте удалённый доступ, KeenDNS с доступом к управлению или проброс порта на веб-админку для этого аккаунта. По умолчанию Keenetic и так закрыт снаружи.
- **Ограничьте доступ к `.env`** на уровне ОС (`chmod 600 .env` на macOS/Linux, свойства файла → «Безопасность» на Windows). Файл уже в `.gitignore`.
- **Используйте длинный уникальный пароль**, не совпадающий с другими вашими паролями.
## Разработка
```
npm run dev # запуск сервера напрямую через tsx, без сборки
npm test # unit-тесты (без обращения к реальному роутеру)
npm run smoke # live read-only проверка на реальном роутере из .env
```
### Версии и релизы
Версия проекта (`package.json`, `.claude-plugin/plugin.json`) бампается автоматически при push в `master` — GitHub Actions запускает `semantic-release`, который определяет уровень версии по сообщениям коммитов (Angular convention):
- `fix: ...` → patch
- `feat: ...` → minor
- `feat!: ...` / `BREAKING CHANGE: ...` в теле коммита → major
- `chore:`, `docs:`, `refactor:`, `test:` и т.п. — релиз не создаётся
Версию руками не бампаем и не редактируем — она полностью выводится из истории коммитов.
Формат коммитов проверяется локально при `git commit` (husky + commitlint) — коммит с сообщением не по конвенции просто не создастся. Хук ставится сам через `npm install` (`prepare`-скрипт).
TDQS
Scored across 23 tools
Большинство инструментов чётко различаются по ресурсу и действию (get_version, list_routes, set_wifi_password и т.д.). Небольшое пересечение есть между list_devices и list_wifi_clients, а также get_interfaces и list_vpn_interfaces, но описания явно указывают на разные контексты использования, так что путаница маловероятна.
Все имена следуют единому шаблону 'глагол_существительное' в нижнем регистре с подчёркиваниями: get_version, list_interfaces, set_wifi_enabled, add_port_forward, remove_route, bind_route_to_vpn. Нет разнобоя в стилях или нечитаемых сокращений.
23 инструмента попадают в диапазон 16-25, который по калибровке считается тяжёлым. Однако для полноценного управления роутером (сети, VPN, WiFi, проброс портов, маршрутизация) количество оправдано, но всё же превышает идеальный минимум.
Покрыты основные операции: список/создание/удаление маршрутов и проброса портов, управление WiFi, VPN-привязка, просмотр состояния. Но отсутствуют remove_domain_route (есть только add_domain_route), управление DHCP-резервированиями (только list), а также нет инструментов для обновления прошивки или изменения системных настроек, что создаёт заметные пробелы.