Skip to main content
Glama

UniFi MCP

PyPI ghcr.io

FastMCP server for local UniFi controller management. Exposes a single unifi action router and a unifi_help reference tool covering devices, clients, network configuration, and controller monitoring.

Overview

The server connects to a self-hosted UniFi controller (including UDM Pro) and proxies all operations through a single MCP tool. A unified action parameter replaces 31 individual tools while preserving every capability. Destructive operations require explicit confirmation. Bearer token auth protects the HTTP endpoint in production.

What this repository ships

  • unifi_mcp/: server, client, config, formatters, models, services, resources, and tools

  • skills/unifi/: client-facing skill

  • docs/: API notes, action-pattern rationale, testing notes

  • .claude-plugin/, .codex-plugin/, gemini-extension.json: client manifests

  • docker-compose.yaml, Dockerfile: container deployment

  • tests/: unit, resource, and integration tests

Tools

unifi

Single action router for all UniFi operations.

Parameters

Parameter

Type

Required

Default

Description

action

string

yes

Action to perform (see below)

site_name

string

no

"default"

UniFi site name. Ignored by get_sites, get_controller_status, get_user_info

mac

string

no

null

Device or client MAC address (any format: aa:bb:cc, AA-BB-CC, aabb.cc)

limit

int

no

varies

Maximum results to return

connected_only

bool

no

true

get_clients: return only currently connected clients

active_only

bool

no

true

get_alarms: return only unarchived alarms

by_filter

string

no

"by_app"

get_dpi_stats: "by_app" or "by_cat"

name

string

no

null

set_client_name: new display name (empty string removes it)

note

string

no

null

set_client_note: note text (empty string removes it)

minutes

int

no

480

authorize_guest: access duration in minutes

up_bandwidth

int

no

null

authorize_guest: upload limit in Kbps

down_bandwidth

int

no

null

authorize_guest: download limit in Kbps

quota

int

no

null

authorize_guest: data quota in MB

confirm

bool

no

null

Set to true to confirm destructive operations

unifi_help

Returns full markdown reference for all actions and parameters. No parameters needed.


Action Groups

Device Management

Action

MAC Required

Description

get_devices

no

List all devices on a site with status, model, IP, and uptime

get_device_by_mac

yes

Get full details for one device by MAC

restart_device

yes

Destructive — reboot the device

locate_device

yes

Activate the locate LED on the device

get_devices response fields per device: name, model, type (Access Point / Gateway / Switch), status (Online / Offline), ip, mac, uptime, version

restart_device example:

unifi action=restart_device mac=aa:bb:cc:dd:ee:ff confirm=true

Client Management

Action

MAC Required

Description

get_clients

no

List clients. connected_only=true (default) filters offline entries

reconnect_client

yes

Destructive — force a client to reconnect (kick-sta)

block_client

yes

Destructive — block a client from network access

unblock_client

yes

Re-allow a previously blocked client

forget_client

yes

Destructive — remove all historical data for a client (GDPR)

set_client_name

yes

Set or update the display alias for a client

set_client_note

yes

Set or update the note for a client

set_client_name / set_client_note: Both resolve the client by MAC against the controller user list (/list/user), then POST to /upd/user/{id}. Pass an empty string (name="") to remove the value.

Workflow — block a client:

# Step 1: find the MAC
unifi action=get_clients connected_only=true

# Step 2: block it
unifi action=block_client mac=aa:bb:cc:dd:ee:ff confirm=true

# Step 3: verify
unifi action=get_clients connected_only=false

Network Configuration

Action

Description

get_sites

List all sites on the controller with health info

get_wlan_configs

WLAN profiles: SSID, security, VLAN, guest flag, band steering

get_network_configs

Network/VLAN configs: subnet, DHCP range, purpose, guest flag

get_port_configs

Switch port profiles: native VLAN, tagged VLANs, PoE mode, port security

get_port_forwarding_rules

Port forwarding rules: protocol, external port, internal IP/port

get_firewall_rules

Firewall rules: action, protocol, source/destination, ruleset, index

get_firewall_groups

Firewall groups: type, member IPs or MACs, member count

get_static_routes

Static routes: destination network, gateway (nexthop), distance, interface

All network configuration actions accept site_name. get_sites does not use site_name.


Monitoring

Action

Key Parameters

Description

get_controller_status

Controller version and up/down status

get_events

limit (default 100), site_name

Recent controller events sorted newest-first. On UDM Pro tries the v2 API (/proxy/network/v2/api/site/{site}/events) then falls back to /stat/event. Returns an informative error if the firmware has removed the legacy endpoint.

get_alarms

active_only (default true), site_name

Active or all alarms. Severity comes from catname.

get_dpi_stats

by_filter (default "by_app"), site_name

Deep Packet Inspection usage by application or category. Bandwidth values are in bytes (raw) in the structured response; the text summary formats them as human-readable (KB / MB / GB).

get_rogue_aps

limit (default 20, max 50), site_name

Detected foreign APs sorted by signal strength. Threat level: High > -60 dBm, Medium > -80 dBm, Low otherwise.

start_spectrum_scan

mac (AP), site_name

Trigger an RF spectrum scan on an access point.

get_spectrum_scan_state

mac (AP), site_name

Poll scan state and results for an AP.

authorize_guest

mac, minutes, up_bandwidth, down_bandwidth, quota, site_name

Grant a guest client timed network access. up_bandwidth / down_bandwidth are in Kbps. quota is in MB (converted to bytes before sending). Default duration is 480 minutes (8 hours).

get_speedtest_results

limit (default 20), site_name

Historical speed tests from the last 30 days. Download/upload fields are in Mbps; latency and jitter in ms.

get_ips_events

limit (default 50), site_name

IPS/IDS threat events from the last 7 days: source/destination IP, protocol, signature, category, severity, action.

Workflow — authorize a guest with bandwidth cap:

unifi action=authorize_guest mac=aa:bb:cc:dd:ee:ff minutes=120 down_bandwidth=5000 up_bandwidth=2000 quota=500

Workflow — view DPI stats by category:

unifi action=get_dpi_stats by_filter=by_cat site_name=default

Identity

Action

Description

get_user_info

Return the MCP OAuth token claims (email, name, picture, expiry)

get_user_info requires MCP OAuth (e.g. Google provider). UniFi controller credentials are separate. Returns an error if OAuth is not configured.


Destructive Operation Policy

Four actions require confirmation before executing:

Action

What it does

restart_device

Reboots the device — causes brief network outage

block_client

Denies network access to the client

reconnect_client

Forces disconnect/reconnect (kick-sta)

forget_client

Permanently removes all historical data for the client

Confirmation is checked in this order. The first matching rule wins:

  1. UNIFI_MCP_ALLOW_DESTRUCTIVE=true — all destructive actions run without prompting (CI / automation)

  2. UNIFI_MCP_ALLOW_YOLO=true — same bypass, broader semantics (skips all elicitation prompts)

  3. confirm=true parameter — per-call confirmation in the tool invocation

If none of the above apply, the tool returns error: confirmation_required with instructions to add confirm=true.


Installation

Marketplace

/plugin marketplace add jmagar/claude-homelab
/plugin install unifi-mcp @jmagar-claude-homelab

Local development

uv sync
uv run python -m unifi_mcp.main

Console script entrypoints:

uv run unifi-mcp
uv run unifi-local-mcp

Docker

just up
just logs

Configuration

Copy .env.example to .env and fill in the values:

cp .env.example .env

Environment variables

Variable

Required

Default

Description

UNIFI_URL

yes

Controller URL, e.g. https://192.168.1.1:443. No trailing slash. UNIFI_CONTROLLER_URL accepted as legacy fallback.

UNIFI_USERNAME

yes

Controller admin username

UNIFI_PASSWORD

yes

Controller admin password

UNIFI_IS_UDM_PRO

no

true

Set to true for UDM Pro / UniFi OS controllers. Changes the API base path and auth flow (see below).

UNIFI_VERIFY_SSL

no

false

Set to true to verify TLS certificates. Most self-hosted controllers use self-signed certs; leave false unless you have a valid cert.

UNIFI_MCP_HOST

no

0.0.0.0

Server bind address

UNIFI_MCP_PORT

no

8001

Server port. UNIFI_LOCAL_MCP_PORT is a legacy fallback.

UNIFI_MCP_TRANSPORT

no

http

"http" or "stdio"

UNIFI_MCP_TOKEN

no*

Bearer token for HTTP auth. Generate with openssl rand -hex 32. *Required unless UNIFI_MCP_NO_AUTH=true.

UNIFI_MCP_NO_AUTH

no

false

Disable Bearer auth (use only behind a trusted reverse proxy)

UNIFI_MCP_LOG_LEVEL

no

INFO

Log verbosity: DEBUG, INFO, WARNING, ERROR

UNIFI_MCP_LOG_FILE

no

/tmp/unifi-mcp.log

Log file path. File is cleared when it reaches 10 MB.

UNIFI_MCP_ALLOW_DESTRUCTIVE

no

false

Skip confirmation for all destructive actions

UNIFI_MCP_ALLOW_YOLO

no

false

Skip all elicitation prompts including destructive confirmation

PUID / PGID

no

1000 / 1000

UID/GID for Docker container process

DOCKER_NETWORK

no

jakenet

Docker network name

UDM Pro vs traditional controller (UNIFI_IS_UDM_PRO)

UDM Pro (true)

Traditional (false)

API base path

/proxy/network/api

/api

Login endpoint

/api/auth/login

{api_base}/login

CSRF token

Extracted from JWT TOKEN cookie and sent as X-CSRF-Token

Not required

Events API

Tries v2 (/proxy/network/v2/api/site/{site}/events) first

Legacy /stat/event only

UNIFI_VERIFY_SSL=false

Self-hosted controllers typically use self-signed TLS certificates. Setting UNIFI_VERIFY_SSL=false disables certificate validation so the client can connect without a CA bundle. This is the safe choice for internal-network deployments. If your controller has a certificate issued by a public CA (e.g. via Let's Encrypt), set this to true.

Multi-site support

Every action that is site-scoped accepts a site_name parameter (default: "default"). Use get_sites to list available site names. Pass the name field (not the description) as site_name.

unifi action=get_sites
# returns: name="default", name="branch-office", ...

unifi action=get_devices site_name=branch-office

Usage examples

List all connected clients

unifi action=get_clients connected_only=true

Get a device by MAC

unifi action=get_device_by_mac mac=aa:bb:cc:dd:ee:ff

Block a client

unifi action=block_client mac=aa:bb:cc:dd:ee:ff confirm=true

Unblock a client

unifi action=unblock_client mac=aa:bb:cc:dd:ee:ff

Label a client

unifi action=set_client_name mac=aa:bb:cc:dd:ee:ff name="Living Room TV"
unifi action=set_client_note mac=aa:bb:cc:dd:ee:ff note="Guest device, 2026-04"

Authorize a guest (2 hours, 5 Mbps down, 500 MB cap)

unifi action=authorize_guest mac=aa:bb:cc:dd:ee:ff minutes=120 down_bandwidth=5000 quota=500

View DPI stats

unifi action=get_dpi_stats by_filter=by_app site_name=default

Check IPS threat events

unifi action=get_ips_events limit=20 site_name=default

Check controller status

unifi action=get_controller_status

View recent speed tests

unifi action=get_speedtest_results limit=5

Get inline help

unifi_help

Development

Commands

just dev          # Start server with auto-reload
just lint         # Lint with ruff
just fmt          # Format with ruff
just typecheck    # Type-check with ty
just check        # lint + typecheck
just build        # Editable install (uv pip install -e .)
just test         # Run unit tests
just test-live    # Health check against running server
just up           # docker compose up -d
just down         # docker compose down
just logs         # Tail container logs
just health       # curl /health endpoint
just gen-token    # Generate a secure random token
just check-contract  # Lint skill/server contract
just clean        # Remove build artifacts and caches

Generate a bearer token

just gen-token
# or
openssl rand -hex 32

Verification

just lint
just typecheck
just test

For a running-server check:

just health
just test-live

Plugin

Category

Description

homelab-core

core

Core agents, commands, skills, and setup/health workflows for homelab management.

overseerr-mcp

media

Search movies and TV shows, submit requests, and monitor failed requests via Overseerr.

unraid-mcp

infrastructure

Query, monitor, and manage Unraid servers: Docker, VMs, array, parity, and live telemetry.

gotify-mcp

utilities

Send and manage push notifications via a self-hosted Gotify server.

swag-mcp

infrastructure

Create, edit, and manage SWAG nginx reverse proxy configurations.

synapse-mcp

infrastructure

Docker management (Flux) and SSH remote operations (Scout) across homelab hosts.

arcane-mcp

infrastructure

Manage Docker environments, containers, images, volumes, networks, and GitOps via Arcane.

syslog-mcp

infrastructure

Receive, index, and search syslog streams from all homelab hosts via SQLite FTS5.

plugin-lab

dev-tools

Scaffold, review, align, and deploy homelab MCP plugins with agents and canonical templates.

License

MIT