Skip to main content
Glama

mcp-unifi

CI Release License: MIT Python MCP Coverage

Un servidor MCP para la gestión de gateways UniFi autohospedados. Quince herramientas que cubren dispositivos, redes/VLANs, SSIDs WiFi (CRUD completo), reglas de firewall (CRUD completo), perfiles de puertos de switch, clientes conectados, además de una herramienta create_iot_network de un solo paso que aprovisiona una subred IoT aislada (VLAN, SSID y bloqueo de firewall) en una sola llamada con reversión automática en caso de fallo parcial.

Construido sobre FastMCP con transporte HTTP Streamable. Se comunica con un UCG-Fiber, UDM Pro o cualquier otro gateway UniFi OS a través de la clave API local. No requiere Site Manager ni cuenta en la nube.

Cada herramienta devuelve JSON. Los errores se devuelven como un objeto estructurado {"error": "...", "stub_mode": bool} para que el bucle MCP nunca se bloquee ante un problema del gateway.

Por qué

La mayoría de la automatización de UniFi hoy en día implica hacer clic en la interfaz de usuario del controlador, escribir scripts frágiles de un solo uso o importar un SDK comunitario pesado. mcp-unifi ofrece a cualquier cliente compatible con MCP (Claude Code, Claude Desktop, agentes personalizados) una superficie pequeña, enfocada y bien tipada para las operaciones que realmente realizas cada semana: crear una VLAN IoT, añadir una regla de firewall, auditar tus SSIDs, listar dispositivos adoptados.

La herramienta compuesta create_iot_network convierte un flujo de trabajo de 15 pasos en la interfaz de usuario en una sola llamada de herramienta.

Inicio rápido

Extrae la imagen publicada y ejecútala:

docker run --rm \
  -p 3714:3714 \
  -e STUB_MODE=true \
  ghcr.io/pete-builds/mcp-unifi:0.2.0

El servidor se inicia en modo stub por defecto, el cual devuelve datos simulados realistas y no requiere hardware UniFi. Regístralo con Claude Code:

claude mcp add unifi --transport http --scope user --url http://localhost:3714/mcp

Luego pídele a Claude Code que "liste mis dispositivos UniFi" y deberías ver dos dispositivos simulados.

Para comunicarte con un gateway real, pasa las credenciales y desactiva el modo stub:

docker run --rm \
  -p 3714:3714 \
  -e STUB_MODE=false \
  -e UNIFI_HOST=192.168.1.1 \
  -e UNIFI_API_KEY=<your-local-api-key> \
  ghcr.io/pete-builds/mcp-unifi:0.2.0

Genera la clave API en Settings → Control Plane → Integrations en el gateway.

Referencia de herramientas

Herramienta

Firma

Qué hace

list_devices

()

Lista gateways, APs y switches adoptados con estado, tiempo de actividad e información por radio.

list_networks

()

Lista todas las redes/VLANs configuradas (subred, rango DHCP, ID de VLAN).

create_vlan

(name, vlan_id, subnet, dhcp_start?, dhcp_stop?, purpose?)

Crea una nueva red con etiqueta VLAN.

update_vlan

(network_id, updates)

Parchea campos en una VLAN existente.

delete_vlan

(network_id)

Elimina una VLAN.

list_wlans

()

Lista todos los SSIDs WiFi.

create_wlan

(name, passphrase, network_id, security?, wpa_mode?, is_guest?, hide_ssid?, wlan_band?)

Crea un nuevo SSID vinculado a una VLAN específica.

update_wlan

(wlan_id, updates)

Parchea campos en un SSID existente (nombre, contraseña, hide_ssid, etc.).

delete_wlan

(wlan_id)

Elimina un SSID WiFi.

list_firewall_rules

()

Lista todas las reglas de firewall.

create_firewall_rule

(name, ruleset, action, rule_index?, protocol?, src_address?, dst_address?, src_networkconf_id?, dst_networkconf_id?, enabled?)

Crea una regla de firewall.

delete_firewall_rule

(rule_id)

Elimina una regla de firewall.

list_port_profiles

()

Lista perfiles de puertos de switch (modo PoE, VLAN nativa, reenvío).

list_clients

()

Lista clientes inalámbricos y cableados conectados actualmente (MAC, nombre de host, IP, señal/satisfacción, puerto de AP o switch, tiempo de actividad).

create_iot_network

(name, vlan_id, passphrase, main_lan_subnet?, subnet?, isolate?, hide_ssid?)

Un solo paso: VLAN + SSID + regla de aislamiento, con reversión en caso de fallo.

Cada herramienta devuelve una cadena JSON. Los errores se devuelven como un objeto estructurado {"error": "...", "stub_mode": bool} para que Claude pueda mostrar el fallo sin bloquear el bucle MCP.

Modo Stub vs modo real

Modo

Cuándo usar

Comportamiento

Stub (STUB_MODE=true, por defecto)

Desarrollo, demos, configurar flujos de Claude antes de que llegue el hardware

Máquina de estado en memoria inicializada con un gateway, un AP, una red, un SSID, una regla de firewall, dos perfiles de puerto. Crear/actualizar/eliminar persiste durante la vida del contenedor. Se reinicia al reiniciar.

Real (STUB_MODE=false)

Producción con un UCG-Fiber/UDM/otro gateway UniFi OS

Habla HTTPS con el gateway con tu clave API local. Requiere UNIFI_HOST y UNIFI_API_KEY.

Cambiar de modo es un cambio de configuración, no de código. Las mismas once herramientas, las mismas formas de respuesta.

Configuración

Toda la configuración se lee de variables de entorno (y un archivo .env cuando está presente). La configuración es validada por Pydantic al inicio; los valores no válidos fallan rápidamente con un mensaje útil.

Variable

Tipo

Por defecto

Requerido

Notas

STUB_MODE

bool

true

no

Cuando es false, se requieren credenciales de modo real.

UNIFI_HOST

string

""

solo en modo real

IP o nombre de host del gateway (sin esquema).

UNIFI_PORT

int

443

no

Puerto HTTPS para el gateway.

UNIFI_SITE

string

default

no

Identificador del sitio del controlador.

UNIFI_API_KEY

string

""

solo en modo real

Clave API local desde Settings → Control Plane → Integrations.

UNIFI_VERIFY_SSL

bool

false

no

Establecer en true si has instalado un certificado real en el gateway.

IOT_SUBNET_TEMPLATE

string

10.0.{vlan_id}.0/24

no

Debe contener el marcador de posición literal {vlan_id}.

IOT_DHCP_START_OFFSET

int (2-254)

100

no

Desplazamiento de la primera concesión DHCP dentro de la IoT /24.

IOT_DHCP_STOP_OFFSET

int (2-254)

200

no

Desplazamiento de la última concesión DHCP dentro de la IoT /24.

MCP_HOST

string

0.0.0.0

no

Dirección de enlace.

MCP_PORT

int

3714

no

Puerto de escucha.

LOG_LEVEL

enum

INFO

no

Uno de DEBUG, INFO, WARNING, ERROR, CRITICAL.

LOG_FORMAT

enum

json

no

json para producción, text para desarrollo local.

Un ejemplo completo vive en .env.example.

Configuración del cliente MCP

Claude Code

claude mcp add unifi --transport http --scope user --url http://<host>:3714/mcp

Claude Desktop

Añade lo siguiente a tu claude_desktop_config.json:

{
  "mcpServers": {
    "unifi": {
      "transport": "streamable-http",
      "url": "http://<host>:3714/mcp"
    }
  }
}

Configuración genérica

HTTP Streamable en http://<host>:3714/mcp. Cualquier cliente MCP que soporte el transporte HTTP Streamable (especificación 2025-03-26+) puede conectarse.

Arquitectura

+---------------------+         Streamable HTTP         +---------------------+
|  MCP Client         |  -------------------------->    |  mcp-unifi          |
|  (Claude Code, etc) |  <--------------------------    |  (FastMCP server)   |
+---------------------+                                 +----------+----------+
                                                                   |
                                                                   |  HTTPS + X-API-Key
                                                                   v
                                                        +----------+----------+
                                                        |  UniFi OS Gateway   |
                                                        |  /proxy/network/... |
                                                        +---------------------+

El servidor es un proxy asíncrono ligero: traduce llamadas de herramientas MCP a llamadas REST del controlador UniFi, da forma a las respuestas y devuelve JSON. No almacena estado, no llama a ninguna nube y no autentica las conexiones MCP entrantes (ejecútalo en una LAN de confianza).

Notas de seguridad

  • La UNIFI_API_KEY vive solo en el entorno del contenedor. Nunca se registra, nunca se devuelve en las respuestas MCP y nunca se escribe en el disco por este servidor.

  • Las contraseñas de WLAN se limpian ([REDACTED]) al salir de cada respuesta de herramienta, incluso en modo stub.

  • El contenedor se ejecuta como UID 1000, sin shell, sin directorio de inicio, con un sistema de archivos raíz de solo lectura (/tmp es tmpfs) y no-new-privileges.

  • La imagen base está fijada por resumen. Las dependencias de Python se instalan con pip --require-hashes desde un requirements.lock bloqueado por hash.

  • La imagen publicada es multi-arquitectura (amd64/arm64) con atestación de procedencia de compilación y SBOM a través de docker/build-push-action.

  • El servidor MCP en sí no está autenticado. Colócalo detrás de un límite de LAN de confianza, un proxy inverso con autenticación o una ACL de Tailscale.

Para informes de vulnerabilidades, consulta SECURITY.md.

Desarrollo

Requiere Python 3.13+ y Docker.

# Clone + install dev deps
git clone https://github.com/pete-builds/mcp-unifi.git
cd mcp-unifi
python -m venv .venv && source .venv/bin/activate
pip install --require-hashes -r requirements-dev.lock
pip install -e . --no-deps

# Run the test suite (101 tests, ~95% coverage)
pytest

# Lint and format
ruff check src tests
ruff format src tests

# Type check (mypy strict)
mypy src/mcp_unifi

# Run the server locally in stub mode
python -m mcp_unifi.server

# Or build the image yourself instead of pulling from GHCR
cp docker-compose.example.yml docker-compose.yml
docker compose up --build

Pruebas

======================= 101 passed in 1.5s =======================

Name                          Stmts  Miss  Branch  BrPart  Cover
-----------------------------------------------------------------
src/mcp_unifi/__init__.py         2     0       0       0   100%
src/mcp_unifi/clients/__init__    3     0       0       0   100%
src/mcp_unifi/clients/stubs.py   70     1       6       0    99%
src/mcp_unifi/clients/unifi.py   82     0      12       0   100%
src/mcp_unifi/config.py          38     1       8       0    98%
src/mcp_unifi/healthcheck.py     18     1       0       0    94%
src/mcp_unifi/logging_setup.py   33     1      12       2    93%
src/mcp_unifi/models.py           6     0       0       0   100%
src/mcp_unifi/server.py         232    15      70       5    92%
-----------------------------------------------------------------
TOTAL                           484    19     108       7    95%

La CI bloquea con un 80% de cobertura mínima, linting con ruff, formato con ruff, mypy estricto y un escaneo Trivy fs+image que falla ante cualquier hallazgo ALTO o CRÍTICO.

Actualización de dependencias

Los archivos requirements.lock y requirements-dev.lock están fijados por hash. Edita requirements.in (o requirements-dev.in), luego regenera:

uv pip compile requirements.in --output-file requirements.lock --generate-hashes --python-version 3.13
uv pip compile requirements-dev.in --output-file requirements-dev.lock --generate-hashes --python-version 3.13

Dependabot abre PRs semanales para actualizaciones a nivel de requirements.in y el resumen de la imagen base de Docker.

Agradecimientos

Las rutas de los endpoints del controlador UniFi fueron referenciadas cruzadamente contra el proyecto sirkirby/unifi-mcp. Ese repositorio se utilizó como material de investigación para la superficie de la API; no se copió código. La implementación aquí es una construcción independiente de FastMCP + httpx que sigue el patrón Forge probado.

Licencia

MIT.

Contribución

Problemas y solicitudes de extracción son bienvenidos. Antes de abrir una PR:

  1. Asegúrate de que ruff check, ruff format --check y mypy src/mcp_unifi estén limpios.

  2. Añade o actualiza pruebas, mantén la cobertura en 80% o superior.

  3. Ejecuta pytest localmente y confirma que la suite pasa.

  4. Actualiza CHANGELOG.md bajo un encabezado [Unreleased].

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
2Releases (12mo)

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pete-builds/mcp-unifi'

If you have feedback or need assistance with the MCP directory API, please join our Discord server