unifi-mcp-server

v2026.09.25

MCP server for UniFi Network Controller API - manage devices, clients, networks, WiFi, firewall rules, QoS, backups, and multi-site deployments

GitHub
安装命令
npx skhub add reason-machines/unifi-mcp-server
Markdown
SKILL.md

unifi-mcp-server

Skill by ara.so — MCP Skills collection.

A Model Context Protocol (MCP) server exposing the UniFi Network Controller API. Provides 74+ tools for managing UniFi devices, clients, networks, WiFi, firewall rules, QoS, backups, port profiles, RADIUS, guest portals, and multi-site orchestration.

What It Does

  • Device Management: List, monitor, restart, locate, upgrade UniFi devices (APs, switches, gateways)
  • Network Configuration: Create/update/delete networks, VLANs, subnets with DHCP
  • Client Management: Query, block, unblock, reconnect clients with analytics
  • WiFi/SSID Management: Create wireless networks with WPA2/WPA3, guest networks, VLAN isolation
  • Firewall Rules: Create/manage firewall rules, port forwarding, traffic filtering
  • QoS Management: Traffic prioritization, bandwidth control, traffic shaping
  • Backup & Restore: Automated scheduling, verification, download/upload
  • Port Profiles: Switch port configuration with PoE, VLAN trunking, 802.1X
  • RADIUS & Guest Portal: 802.1X authentication, hotspot packages
  • Multi-Site: Cross-site aggregation, analytics, site provisioning
  • Network Topology: Complete topology mapping and visualization

Installation

Via pip (Recommended)

pip install unifi-mcp-server

Via uv

uv pip install unifi-mcp-server

From source

git clone https://github.com/enuno/unifi-mcp-server.git
cd unifi-mcp-server
pip install -e .

API Modes

Three distinct API modes with different capabilities:

Local Gateway API (Recommended) ✅

Full feature support with real-time data and configuration changes.

Required Environment Variables:

export UNIFI_API_TYPE=local
export UNIFI_LOCAL_HOST=192.168.2.1  # Your gateway IP
export UNIFI_USERNAME=admin
export UNIFI_PASSWORD=your_password
export UNIFI_SITE=default

Cloud Early Access API ⚠️

Site-centric access with limited read-only capabilities.

Required Environment Variables:

export UNIFI_API_TYPE=cloud-ea
export UNIFI_API_KEY=your_cloud_api_key
export UNIFI_SITE_MANAGER_ENABLED=true  # Optional: multi-site aggregation

Cloud V1 API ⚠️

Limited to aggregate statistics only.

Required Environment Variables:

export UNIFI_API_TYPE=cloud-v1
export UNIFI_API_KEY=your_cloud_api_key

Transport Modes

STDIO (Default)

For local AI clients (Claude Desktop, Cursor):

export MCP_SERVER_TRANSPORT=stdio
unifi-mcp-server

SSE (Server-Sent Events)

For network access and MCP gateways:

export MCP_SERVER_TRANSPORT=sse
export MCP_SERVER_PORT=3000
unifi-mcp-server

HTTP / Streamable HTTP

export MCP_SERVER_TRANSPORT=http  # or streamable_http
export MCP_SERVER_PORT=3000
unifi-mcp-server

Configuration

Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "unifi": {
      "command": "unifi-mcp-server",
      "env": {
        "UNIFI_API_TYPE": "local",
        "UNIFI_LOCAL_HOST": "192.168.2.1",
        "UNIFI_USERNAME": "admin",
        "UNIFI_PASSWORD": "your_password",
        "UNIFI_SITE": "default",
        "MCP_SERVER_TRANSPORT": "stdio"
      }
    }
  }
}

MCP Gateway (SSE Mode)

{
  "mcpServers": {
    "unifi": {
      "url": "http://your-server-ip:3000/sse"
    }
  }
}

Docker Compose

services:
  unifi-mcp:
    image: ghcr.io/enuno/unifi-mcp-server:latest
    environment:
      UNIFI_API_TYPE: local
      UNIFI_LOCAL_HOST: 192.168.2.1
      UNIFI_USERNAME: admin
      UNIFI_PASSWORD: ${UNIFI_PASSWORD}
      UNIFI_SITE: default
      MCP_SERVER_TRANSPORT: sse
      MCP_SERVER_PORT: 3000
    ports:
      - "3000:3000"

Core MCP Tools

Device Management

# List all devices
devices = await call_tool("list_devices")

# Get device details
device = await call_tool("get_device", {"device_id": "abc123"})

# Restart device
result = await call_tool("restart_device", {"device_id": "abc123"})

# Locate device (blink LEDs)
await call_tool("locate_device", {
    "device_id": "abc123",
    "enabled": True
})

# Upgrade device firmware
await call_tool("upgrade_device", {"device_id": "abc123"})

# Force provision device
await call_tool("force_provision_device", {"device_id": "abc123"})

Client Management

# List all clients
clients = await call_tool("list_clients")

# Get client details
client = await call_tool("get_client", {"client_id": "aa:bb:cc:dd:ee:ff"})

# Block client
await call_tool("block_client", {
    "client_id": "aa:bb:cc:dd:ee:ff",
    "blocked": True
})

# Reconnect client
await call_tool("reconnect_client", {"client_id": "aa:bb:cc:dd:ee:ff"})

# Get client statistics
stats = await call_tool("get_client_stats", {"client_id": "aa:bb:cc:dd:ee:ff"})

Network Configuration

# Create network
network = await call_tool("create_network", {
    "name": "IoT Network",
    "vlan_id": 20,
    "subnet": "192.168.20.0/24",
    "dhcp_enabled": True,
    "dhcp_start": "192.168.20.10",
    "dhcp_stop": "192.168.20.250",
    "gateway": "192.168.20.1"
})

# Update network
await call_tool("update_network", {
    "network_id": "abc123",
    "name": "IoT Network Updated",
    "dhcp_dns": ["8.8.8.8", "8.8.4.4"]
})

# Delete network
await call_tool("delete_network", {"network_id": "abc123"})

# List networks
networks = await call_tool("list_networks")

WiFi/SSID Management

# Create SSID
ssid = await call_tool("create_ssid", {
    "name": "Guest WiFi",
    "password": "SecurePass123!",
    "security": "wpapsk",
    "vlan_id": 30,
    "guest_network": True,
    "hide_ssid": False
})

# Update SSID
await call_tool("update_ssid", {
    "ssid_id": "abc123",
    "name": "Guest WiFi Updated",
    "enabled": True
})

# Delete SSID
await call_tool("delete_ssid", {"ssid_id": "abc123"})

# List SSIDs
ssids = await call_tool("list_ssids")

Firewall Rules

# Create firewall rule
rule = await call_tool("create_firewall_rule", {
    "name": "Block IoT to LAN",
    "action": "drop",
    "rule_index": 2000,
    "protocol": "all",
    "src_network_id": "iot_network_id",
    "dst_network_id": "lan_network_id",
    "enabled": True
})

# Update firewall rule
await call_tool("update_firewall_rule", {
    "rule_id": "abc123",
    "enabled": False
})

# Delete firewall rule
await call_tool("delete_firewall_rule", {"rule_id": "abc123"})

# List firewall rules
rules = await call_tool("list_firewall_rules")

Port Forwarding

# Create port forward
forward = await call_tool("create_port_forward", {
    "name": "Web Server",
    "enabled": True,
    "protocol": "tcp",
    "src_port": "80",
    "dst_ip": "192.168.1.100",
    "dst_port": "8080",
    "log": True
})

# Update port forward
await call_tool("update_port_forward", {
    "forward_id": "abc123",
    "enabled": False
})

# Delete port forward
await call_tool("delete_port_forward", {"forward_id": "abc123"})

QoS Management

# Create QoS rule
qos = await call_tool("create_qos_rule", {
    "name": "Video Conference Priority",
    "enabled": True,
    "priority": "high",
    "bandwidth_limit": 10000,
    "protocol": "tcp",
    "dst_port": "443"
})

# Update QoS rule
await call_tool("update_qos_rule", {
    "rule_id": "abc123",
    "priority": "medium"
})

# Delete QoS rule
await call_tool("delete_qos_rule", {"rule_id": "abc123"})

# List QoS rules
rules = await call_tool("list_qos_rules")

Port Profile Management

# Create port profile
profile = await call_tool("create_port_profile", {
    "name": "VoIP Phones",
    "poe_mode": "auto",
    "vlan_id": 40,
    "native_network_id": "voice_network_id",
    "dot1x_ctrl": "auto",
    "lldpmed_enabled": True,
    "lldpmed_notify_enabled": True
})

# Update port profile
await call_tool("update_port_profile", {
    "profile_id": "abc123",
    "poe_mode": "pasv24"
})

# Delete port profile
await call_tool("delete_port_profile", {"profile_id": "abc123"})

# List port profiles
profiles = await call_tool("list_port_profiles")

Device Port Overrides

# Override device port
override = await call_tool("override_device_port", {
    "device_id": "switch123",
    "port_idx": 5,
    "port_profile_id": "voip_profile_id",
    "poe_mode": "auto",
    "name": "Conference Room Phone"
})

# Remove port override
await call_tool("remove_device_port_override", {
    "device_id": "switch123",
    "port_idx": 5
})

# Get device port configuration
config = await call_tool("get_device_port_config", {
    "device_id": "switch123",
    "port_idx": 5
})

Backup & Restore

# Create backup
backup = await call_tool("create_backup", {
    "name": "weekly-backup",
    "include_settings": True
})

# List backups
backups = await call_tool("list_backups")

# Download backup
content = await call_tool("download_backup", {"backup_id": "abc123"})

# Restore from backup
await call_tool("restore_backup", {"backup_id": "abc123"})

# Schedule backup
schedule = await call_tool("schedule_backup", {
    "frequency": "daily",
    "time": "02:00",
    "enabled": True
})

RADIUS & Guest Portal

# Create RADIUS account
account = await call_tool("create_radius_account", {
    "name": "employee1",
    "password": "SecurePass123!",
    "vlan_id": 10,
    "enabled": True
})

# Update RADIUS account
await call_tool("update_radius_account", {
    "account_id": "abc123",
    "enabled": False
})

# Create hotspot package
package = await call_tool("create_hotspot_package", {
    "name": "1 Hour Guest",
    "duration": 3600,
    "bandwidth_up": 5000,
    "bandwidth_down": 10000
})

Multi-Site Management

# List sites
sites = await call_tool("list_sites")

# Get site details
site = await call_tool("get_site", {"site_id": "default"})

# Create site
new_site = await call_tool("create_site", {
    "name": "Branch Office",
    "description": "Remote branch location"
})

# Get cross-site statistics
stats = await call_tool("get_cross_site_stats")

Network Topology

# Get network topology
topology = await call_tool("get_network_topology")

# Get topology map (visualization data)
map_data = await call_tool("get_topology_map")

# Get device connections
connections = await call_tool("get_device_connections", {
    "device_id": "abc123"
})

# Trace route between clients
trace = await call_tool("trace_route", {
    "source_client_id": "aa:bb:cc:dd:ee:ff",
    "dest_client_id": "11:22:33:44:55:66"
})

DPI Statistics

# Get DPI statistics
dpi_stats = await call_tool("get_dpi_stats", {
    "type": "by_app",
    "start_time": 1640000000,
    "end_time": 1640086400
})

# Get DPI categories
categories = await call_tool("get_dpi_categories")

Common Patterns

Creating a Complete Network Setup

# 1. Create network
network = await call_tool("create_network", {
    "name": "IoT Network",
    "vlan_id": 20,
    "subnet": "192.168.20.0/24",
    "dhcp_enabled": True,
    "dhcp_start": "192.168.20.10",
    "dhcp_stop": "192.168.20.250"
})

# 2. Create WiFi for the network
ssid = await call_tool("create_ssid", {
    "name": "IoT WiFi",
    "password": "SecurePass123!",
    "security": "wpapsk",
    "vlan_id": 20
})

# 3. Create firewall rule to isolate
rule = await call_tool("create_firewall_rule", {
    "name": "Isolate IoT",
    "action": "drop",
    "rule_index": 2000,
    "protocol": "all",
    "src_network_id": network["_id"],
    "dst_network_id": "lan_network_id"
})

# 4. Create QoS rule for bandwidth limiting
qos = await call_tool("create_qos_rule", {
    "name": "IoT Bandwidth Limit",
    "enabled": True,
    "bandwidth_limit": 1000,
    "network_id": network["_id"]
})

Managing Guest Access

# 1. Create guest network
guest_net = await call_tool("create_network", {
    "name": "Guest Network",
    "vlan_id": 99,
    "subnet": "192.168.99.0/24",
    "dhcp_enabled": True,
    "dhcp_start": "192.168.99.10",
    "dhcp_stop": "192.168.99.250"
})

# 2. Create guest SSID
guest_ssid = await call_tool("create_ssid", {
    "name": "Guest WiFi",
    "password": "GuestPass123",
    "security": "wpapsk",
    "vlan_id": 99,
    "guest_network": True
})

# 3. Create hotspot package
package = await call_tool("create_hotspot_package", {
    "name": "Daily Guest",
    "duration": 86400,
    "bandwidth_up": 5000,
    "bandwidth_down": 10000
})

# 4. Isolate guest network
await call_tool("create_firewall_rule", {
    "name": "Isolate Guests",
    "action": "drop",
    "protocol": "all",
    "src_network_id": guest_net["_id"],
    "dst_network_id": "lan_network_id"
})

Switch Port Configuration

# 1. Create port profile for VoIP
voip_profile = await call_tool("create_port_profile", {
    "name": "VoIP Phones",
    "poe_mode": "auto",
    "vlan_id": 40,
    "dot1x_ctrl": "auto",
    "lldpmed_enabled": True
})

# 2. Apply to specific switch port
await call_tool("override_device_port", {
    "device_id": "switch123",
    "port_idx": 5,
    "port_profile_id": voip_profile["_id"],
    "name": "Conference Room Phone"
})

# 3. Verify configuration
config = await call_tool("get_device_port_config", {
    "device_id": "switch123",
    "port_idx": 5
})

Monitoring and Analytics

# 1. Get all device statistics
devices = await call_tool("list_devices")
for device in devices:
    stats = await call_tool("get_device_stats", {
        "device_id": device["_id"]
    })

# 2. Get client bandwidth usage
clients = await call_tool("list_clients")
for client in clients:
    stats = await call_tool("get_client_stats", {
        "client_id": client["mac"]
    })

# 3. Get DPI analytics
dpi_stats = await call_tool("get_dpi_stats", {
    "type": "by_app"
})

# 4. Get topology for visualization
topology = await call_tool("get_network_topology")

Troubleshooting

Connection Issues

Problem: Cannot connect to UniFi controller

Solution:

# Verify environment variables
echo $UNIFI_API_TYPE
echo $UNIFI_LOCAL_HOST
echo $UNIFI_USERNAME

# Test connectivity
ping $UNIFI_LOCAL_HOST

# Check credentials
curl -k https://$UNIFI_LOCAL_HOST:8443/api/login \
  -d "{\"username\":\"$UNIFI_USERNAME\",\"password\":\"$UNIFI_PASSWORD\"}"

SSL Certificate Errors

Problem: SSL verification failures

Solution:

# Disable SSL verification (local only)
export UNIFI_VERIFY_SSL=false

# Or provide custom CA bundle
export UNIFI_SSL_CERT_PATH=/path/to/ca-bundle.crt

API Rate Limiting

Problem: Rate limit exceeded errors

Solution:

# Cloud-EA: 100 req/min, Cloud-V1: 10,000 req/min
# Use local API for high-frequency operations
export UNIFI_API_TYPE=local

# Add delays between bulk operations
import asyncio
for device in devices:
    await call_tool("restart_device", {"device_id": device["_id"]})
    await asyncio.sleep(1)  # 1 second delay

Site Not Found

Problem: Site ID mismatch errors

Solution:

# List all sites first
sites = await call_tool("list_sites")

# Find correct site ID
for site in sites:
    print(f"Site: {site['name']}, ID: {site['_id']}")

# Use correct site in environment
export UNIFI_SITE=correct_site_id

Empty Response Data

Problem: Tools return empty arrays or None

Solution:

# Cloud APIs have limited visibility
# Switch to local API for full access
export UNIFI_API_TYPE=local
export UNIFI_LOCAL_HOST=192.168.2.1

# Verify site parameter
export UNIFI_SITE=default

Transport Mode Issues

Problem: MCP client cannot connect in SSE mode

Solution:

# Verify server is listening
netstat -an | grep 3000

# Check firewall rules
sudo ufw allow 3000/tcp

# Test endpoint
curl http://localhost:3000/sse

# Use correct URL in gateway config
{
  "url": "http://server-ip:3000/sse"
}

Advanced Configuration

Environment Variables Reference

# API Configuration
UNIFI_API_TYPE=local|cloud-ea|cloud-v1
UNIFI_API_KEY=                    # Cloud API key
UNIFI_LOCAL_HOST=192.168.2.1     # Gateway IP (local mode)
UNIFI_USERNAME=admin              # Username (local mode)
UNIFI_PASSWORD=                   # Password (local mode)
UNIFI_SITE=default                # Site ID
UNIFI_PORT=8443                   # Controller port
UNIFI_VERIFY_SSL=true             # SSL verification
UNIFI_SSL_CERT_PATH=              # Custom CA bundle

# Transport Configuration
MCP_SERVER_TRANSPORT=stdio|sse|http|streamable_http
MCP_SERVER_PORT=3000              # Network transport port
MCP_SERVER_HOST=0.0.0.0           # Bind address

# Optional Features
UNIFI_SITE_MANAGER_ENABLED=true   # Multi-site aggregation

Logging Configuration

import logging

# Enable debug logging
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Filter specific loggers
logging.getLogger('unifi_mcp_server').setLevel(logging.DEBUG)
logging.getLogger('httpx').setLevel(logging.WARNING)

Documentation References

  • Architecture: See SPEC.md for architecture target
  • Roadmap: See DEVELOPMENT_PLAN.md for phase roadmap
  • API Details: See API.md and docs/UNIFI_API.md
  • Runbooks: See NETWORK_PLAYBOOK.md, HARBOR_SETUP.md, MULTI_CONTROLLER.md, METRICS.md, WEBHOOK_SETUP.md, A2A.md
  • Releases: See RELEASE_CHECKLIST.md and docs/RELEASE_PROCESS.md
发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.25

发布时间

2026年9月25日

分类

未分类

许可证

NOASSERTION

源路径

skills/unifi-mcp-server

默认分支

main

最新提交

329e67c

Tree SHA

01fd22f