Skip to main content
Glama

Keenetic-router-plugin

A plugin (MCP server + skill) that gives an AI agent control over a Keenetic router via RCI — the same API the router's web interface uses. It works directly on the local network, no cloud involved. The MCP server is standalone and works with any MCP client (e.g., Codex), while the skill (domain knowledge about Keenetic for the AI) is only available in the Claude Code plugin ecosystem.

Tested on KeeneticOS 5.0.12. On another model/firmware, specific RCI paths may differ — before getting started, run npm run smoke (read-only, it changes nothing on the router).

What the AI can and cannot do through this plugin

Reading — no confirmation needed, at any time: firmware version, WAN status, list of interfaces, connected devices, Wi-Fi clients, port forwarding, routes, DHCP reservations, VPN interfaces, full configuration export (export_config).

Changes — only if the AI explicitly passes confirm: true: changing the Wi-Fi password, enabling/disabling the access point, adding/removing port forwardings, adding/removing routes, binding/unbinding a network to an already configured VPN tunnel, batch applying routes from a .bat file. Without confirm: true, the call is rejected. You can ask the AI to first run it with dryRun: true — it will show what exactly will be sent to the router, changing nothing.

Dangerous operations — additionally require ALLOW_DESTRUCTIVE=true in the server config: rebooting the router. As long as the flag is not enabled, the router cannot be rebooted through the AI, even with confirm: true.

What the plugin cannot do at all (not implemented): creating VPN tunnels from scratch (WireGuard/OpenVPN/IPsec), factory reset, firmware update.

Every write/destructive call (applied, rejected, or failed with an error) is written to audit.log.

Related MCP server: Keenetic NOC MCP

Installation

Requires Node.js 20+.

  1. Clone the project and install dependencies:

    npm install
    npm run build
  2. Copy .env.example to .env in the same directory and fill it in:

    ROUTER_HOST=192.168.1.1        # LAN-адрес роутера (в свойствах сети — "основной шлюз")
    ROUTER_PORT=80
    ROUTER_LOGIN=имя_пользователя
    ROUTER_PASSWORD=пароль_пользователя
    ALLOW_DESTRUCTIVE=false        # true — разрешить reboot_router

    Instead of .env, the same values can be passed with --env when registering the server — see the below.

  3. Check the connection (read-only, it doesn't change anything on the router):

    npm run smoke

    If a request returned an error, your model/firmware has a different RCI path — fix it in src/capabilities/*.ts before working with the AI.

Connecting to Claude Code

As a plugin (recommended — comes with the skill right away):

claude --plugin-dir "<путь-к-проекту>"

For a permanent connection (not just one session), use /plugin install once you put the project into a Git repository or local marketplace.

Server only, without the skill:

claude mcp add --transport stdio --scope user keenetic -- node "<путь-к-проекту>/dist/index.js"

If you haven't created a .env, add your credentials right here:

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"

Check the connection with claude mcp list, claude mcp get keenetic or /mcp inside a session.

After that, in the conversation you can write, for example: "show the devices connected to the router" or "change the guest Wi-Fi password".

Connecting to Codex

In ~/.codex/config.toml:

[mcp_servers.keenetic]
command = "node"
args = ["<путь-к-проекту>/dist/index.js"]

Security

The guard model (confirm/dryRun/ALLOW_DESTRUCTIVE) protects against accidental and careless action by the AI. It does not protect the router password itself — if .env or the config falls into the wrong hands, someone can directly log into the router with that password, bypassing the server and all these restrictions.

  • export_config is formally read-only, but returns secrets in plain or weakly obfuscated form (password hashes, SSID-PSK, WireGuard parameters) — the same information as behind the "Save" button in the web interface, but now in the conversation with the AI. The tool itself asks the AI to warn you before calling it.

  • Create a separate user for the service in the router web interface (System → Users) rather than using admin, where possible. Caveat: some operations (specifically set_wifi_password/set_wifi_enabled) on Keenetic are available only to admin — if you need these, use admin, but with a fresh unique password.

  • Don't expose RCI/the web admin panel to the Internet — don't enable remote access, KeenDNS with management access, or a public port forward to the web admin panel for this account. By default, Keenetic is already closed from the outside.

  • Restrict access to .env at the OS level (chmod 600 .env on macOS/Linux, or file properties → "Security" on Windows). The file is already in .gitignore.

  • Use a long unique password that doesn't match symlink or any other passwords.

Development

npm run dev     # запуск сервера напрямую через tsx, без сборки
npm test        # unit-тесты (без обращения к реальному роутеру)
npm run smoke   # live read-only проверка на реальном роутере из .env

Versions and releases

The project version (package.json, .claude-plugin/plugin.json) is bumped automatically on push to master — GitHub Actions runs semantic-release, which determines the version level based on commit messages (Angular convention):

  • fix: ... → patch

  • feat: ... → minor

  • feat!: ... / {ANGULAR...} in commit body → major

  • chore:, docs:, refactor:, test: etc. — no release is created

We never bump or edit the version manually — it's fully derived from the commit history.

Available Tools

23 tools
add_domain_routeДобавить доменный маршрут (policy-routing по FQDN)A
Idempotent

Создаёт object-group fqdn со списком доменов и привязывает его через dns-proxy route к указанному интерфейсу. Форма подтверждена вживую (перехват XHR веб-интерфейса на Keenetic Hero 4G+).

Inputs: name (required), target (required), domains (required), description (required), +2 more.

add_port_forwardДобавить проброс портаA
Idempotent

Создаёт правило port forwarding с внешнего порта на внутренний IP:порт.

Inputs: proto (required), internalIp (required), externalPort (required), internalPort (required), +3 more.

add_routeДобавить маршрутC
Idempotent

Добавляет статический маршрут.

Inputs: mask (required), target (required), network (required), dryRun, +2 more.

bind_route_to_vpnПривязать маршрут к VPNA
Idempotent

Направляет трафик указанной сети через уже настроенный на роутере VPN-интерфейс (policy-based routing).

Inputs: mask (required), target (required), network (required), dryRun, +2 more.

check_firmware_updateПроверить обновление прошивкиA
Read-onlyIdempotent

Проверяет через компонентный менеджер роутера, доступна ли новая версия KeeneticOS в настроенном канале обновлений. ТРЕБУЕТ прав основного аккаунта admin — под менее привилегированным аккаунтом роутер отвечает ошибкой "execute denied" (подтверждено вживую на роутере разработки под непривилегированным аккаунтом). Это ограничение самого RCI, а не баг инструмента: если получена такая ошибка, сообщи пользователю, что нужен admin-аккаунт в конфигурации MCP-сервера (ROUTER_LOGIN/ROUTER_PASSWORD), и не пытайся обойти это иначе.

Inputs: no named parameters.

export_configЭкспорт конфигурации (бэкап)A
Read-onlyIdempotent

Возвращает полный running-config роутера текстом (CLI-синтаксис) — та же информация, что и кнопка "Сохранить" у running-config в веб-интерфейсе (Управление → Настройки системы → Системные файлы). ВАЖНО: результат содержит секреты в открытом/слабо обфусцированном виде — хэши паролей пользователей, WPA-PSK Wi-Fi, параметры WireGuard. Перед вызовом предупреди пользователя об этом. После получения результата не пересказывай и не цитируй секретные значения без необходимости; если пользователь просит сохранить бэкап — предложи записать его в файл вне git-репозитория (в нём секреты в открытом виде), а не просто оставить текст в переписке.

Inputs: no named parameters.

get_interfacesСписок интерфейсовA

Все сетевые интерфейсы роутера (WAN, Wi-Fi, VPN, мосты) и их состояние.

Inputs: no named parameters.

get_system_infoСистемная информацияB

Аптайм, загрузка, память и т.п.

Inputs: no named parameters.

get_versionВерсия прошивкиB

Версия KeeneticOS и модель роутера.

Inputs: no named parameters.

get_wan_statusСтатус WANB

Состояние основного интернет-подключения.

Inputs: no named parameters.

list_devicesПодключённые устройстваA

Список устройств из таблицы DHCP/hotspot: MAC, IP, имя, интерфейс.

Inputs: no named parameters.

list_dhcp_reservationsDHCP-резервацииB

Статические привязки IP к MAC.

Inputs: no named parameters.

list_port_forwardsСписок port forwardingC

Текущие правила проброса портов.

Inputs: no named parameters.

list_routesСписок маршрутовB

Таблица статических маршрутов роутера.

Inputs: no named parameters.

list_vpn_interfacesVPN-интерфейсыA

Отфильтрованный список интерфейсов роутера — только VPN-туннели (WireGuard подтверждён вживую; OpenVPN/IKEv2/L2TP/PPTP/VLESS — по типу, не проверено на реальном роутере). Используй для последующей привязки маршрутов (bind_route_to_vpn).

Inputs: no named parameters.

list_wifi_clientsКлиенты Wi-FiB

Устройства, ассоциированные с точками доступа.

Inputs: no named parameters.

reboot_routerПерезагрузить роутерA
Destructive

Немедленная перезагрузка роутера. Требует ALLOW_DESTRUCTIVE=true в конфигурации сервера. RCI-форма запроса НЕ проверена вживую на реальном устройстве в рамках этого проекта — рекомендуется сначала dryRun и явное подтверждение пользователя перед первым использованием.

Inputs: dryRun, confirm.

remove_port_forwardУдалить проброс портаB
Idempotent

Удаляет ранее созданное правило port forwarding.

Inputs: proto (required), externalPort (required), dryRun, confirm.

remove_routeУдалить маршрутB
Idempotent

Удаляет статический маршрут.

Inputs: mask (required), network (required), dryRun, confirm.

run_route_batchПакетно применить маршруты из .bat-файлаA

Читает .bat-файл, разбирает его ограниченной грамматикой (ROUTE ADD/DELETE, VPN BIND/UNBIND) и применяет построчно. Файл не исполняется системным интерпретатором — только заранее известные команды. Любая нераспознанная строка отклоняет весь батч (fail-closed) ещё до применения. dryRun возвращает все RCI payload'ы без отправки на роутер.

Inputs: filePath (required), dryRun, confirm.

set_wifi_enabledВключить/выключить Wi-Fi сетьA
Idempotent

Поднимает или гасит указанную точку доступа (например гостевую сеть).

Inputs: enabled (required), interfaceId (required), dryRun, confirm.

set_wifi_passwordСменить пароль Wi-FiB
Idempotent

Устанавливает новый WPA-PSK пароль на указанной точке доступа.

Inputs: psk (required), interfaceId (required), dryRun, confirm.

unbind_route_from_vpnОтвязать маршрут от VPNB
Idempotent

Убирает привязку сети к VPN-интерфейсу.

Inputs: mask (required), network (required), dryRun, confirm.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 23 tools

    Disambiguation4/5

    Большинство инструментов чётко различаются по ресурсу и действию (get_version, list_routes, set_wifi_password и т.д.). Небольшое пересечение есть между list_devices и list_wifi_clients, а также get_interfaces и list_vpn_interfaces, но описания явно указывают на разные контексты использования, так что путаница маловероятна.

    Naming Consistency5/5

    Все имена следуют единому шаблону 'глагол_существительное' в нижнем регистре с подчёркиваниями: get_version, list_interfaces, set_wifi_enabled, add_port_forward, remove_route, bind_route_to_vpn. Нет разнобоя в стилях или нечитаемых сокращений.

    Tool Count3/5

    23 инструмента попадают в диапазон 16-25, который по калибровке считается тяжёлым. Однако для полноценного управления роутером (сети, VPN, WiFi, проброс портов, маршрутизация) количество оправдано, но всё же превышает идеальный минимум.

    Completeness3/5

    Покрыты основные операции: список/создание/удаление маршрутов и проброса портов, управление WiFi, VPN-привязка, просмотр состояния. Но отсутствуют remove_domain_route (есть только add_domain_route), управление DHCP-резервированиями (только list), а также нет инструментов для обновления прошивки или изменения системных настроек, что создаёт заметные пробелы.

    Maintenance

    ActivityNo data
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      B
      maintenance
      Enables MCP agents to control Keenetic routers via plain language, providing network monitoring, device management, and safe configuration changes with backup and read-only options.
      18
      405 npm
      31
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      Enables AI clients to perform controlled diagnostics and configuration of Keenetic and Netcraze routers over LAN RCI or remote KeenDNS HTTPS, with read-only mode, guarded writes, and centralized secret masking.
      19
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables coding agents to read, query, and safely modify RouterOS 7 devices over the REST API, covering firewall, routing, DHCP, DNS, interfaces, containers, files, and diagnostics, with confirmation gates and a scheduled rollback guard in front of disruptive changes.
      46 PyPI
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables LLM/MCP clients to read and, when explicitly allowed, modify TP-Link Archer AX53 router settings directly over the LAN using the router's own web protocol, without a browser or cloud account. It is read-first, write-gated, and lockout-aware, with tools for clients, DHCP, Wi-Fi, access control, presence history, and other router operations.
      MIT