Content
<p align="center">
<img src="assets/icon.png" width="80" height="80" alt="UniFi">
</p>
<h1 align="center">UniFi MCP Server</h1>
<p align="center">
<strong>Complete UniFi Network controller management through the Model Context Protocol</strong>
</p>
<p align="center">
<code>310 tools</code> •
<code>16 categories</code> •
<code>3 API layers</code> •
<code>Network 5.x – 10.x</code>
</p>
<p align="center">
<a href="https://www.npmjs.com/package/ames-unifi-mcp"><img src="https://img.shields.io/npm/v/ames-unifi-mcp?style=flat-square&color=f5a542" alt="npm"></a>
<a href="https://github.com/oliverames/ames-unifi-mcp/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/oliverames/ames-unifi-mcp/ci.yml?branch=main&style=flat-square&label=CI&color=f5a542" alt="CI"></a>
<a href="https://github.com/oliverames/ames-unifi-mcp/releases/tag/v1.0.7"><img src="https://img.shields.io/github/v/release/oliverames/ames-unifi-mcp?style=flat-square&color=f5a542&label=MCPB" alt="MCPB release"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-f5a542?style=flat-square" alt="License"></a>
<a href="https://www.buymeacoffee.com/oliverames"><img src="https://img.shields.io/badge/Buy_Me_a_Coffee-support-f5a542?style=flat-square&logo=buy-me-a-coffee&logoColor=white" alt="Buy Me a Coffee"></a>
</p>
<p align="center">
<a href="#quick-start">Quick Start</a> •
<a href="#install-with-mcpb">MCPB Download</a> •
<a href="#tool-coverage">Tool Coverage</a> •
<a href="#architecture">Architecture</a> •
<a href="#configuration">Configuration</a>
</p>
---
A Go-based MCP server that gives AI assistants deep, safe access to UniFi Network controllers. Built for UniFi OS devices (Dream Machine, Cloud Gateway) and the `unifi.ui.com` cloud interface.
## Why This Exists
Managing a UniFi network through natural language means your AI assistant needs to understand every corner of the controller API. This server exposes **310 tools** spanning the complete API surface — from basic device listing to zone-based firewall policy ordering, from hotspot voucher generation to MC-LAG domain management.
Every mutating operation passes through a **confirm gate** that returns a dry-run preview before execution. The assistant sees exactly what will change and asks you before proceeding.
## Quick Start
### Install with MCPB
For Claude Desktop and other MCPB-compatible clients, download the local bundle from the [v1.0.7 release](https://github.com/oliverames/ames-unifi-mcp/releases/tag/v1.0.7):
[Download `ames-unifi-mcp-1.0.7.mcpb`](https://github.com/oliverames/ames-unifi-mcp/releases/download/v1.0.7/ames-unifi-mcp-1.0.7.mcpb)
The bundle includes the UniFi favicon, production runtime binaries for macOS and Linux, and setup prompts for host, authentication, site, SSL, tool mode, and permission profile.
Add to your MCP client configuration:
```json
{
"mcpServers": {
"unifi": {
"command": "ames-unifi-mcp",
"env": {
"UNIFI_HOST": "https://192.168.1.1",
"UNIFI_API_KEY": "your-api-key-here",
"UNIFI_SITE": "default",
"UNIFI_VERIFY_SSL": "false"
}
}
}
}
```
Generate an API key at **Settings → Control Plane → Integrations** (requires Network 9.1.105+). For older firmware, use username/password authentication instead.
## How It Works
### Lazy Mode (Default)
Instead of flooding the context window with 310 tool definitions, the server exposes just **3 meta-tools**:
| Meta-Tool | Purpose |
|-----------|---------|
| `tool_index` | Browse the tool catalog, optionally filtered by category |
| `tool_execute` | Run any tool by name with input parameters |
| `tool_batch` | Run multiple tools in parallel for efficiency |
The assistant discovers tools on demand, keeping context lean (~200 tokens vs ~30,000 in eager mode).
### Confirm Gate
Every write operation requires explicit confirmation. Without `confirm: true`, the tool returns a dry-run preview showing what *would* happen:
```
You: "Restart the office access point"
Assistant: Let me preview that first.
→ device_restart {"mac": "aa:bb:cc:dd:ee:ff"}
← Preview: This would restart "Office AP" (soft reboot). Confirm?
You: "Yes"
Assistant: → device_restart {"mac": "aa:bb:cc:dd:ee:ff", "confirm": true}
← Device restarting.
```
### Permission Profiles
Control what the assistant can do:
| Profile | Capabilities |
|---------|-------------|
| **read-only** | Query everything, change nothing |
| **standard** | Reads + safe mutations (WLAN, clients, networks). No PoE cycling, system restarts, or firewall deletes |
| **admin** | Full access including destructive and system-level operations |
Permission-denied tools still appear in `tool_index` (marked `[PERMISSION DENIED]`) so the assistant can explain what's unavailable and why.
### Version Detection
On startup, the server queries the controller version and automatically gates tools by firmware requirements:
| Feature | Minimum Version |
|---------|----------------|
| Legacy API (full) | 5.x+ |
| Zone-Based Firewall | Network 9.0+ |
| Integration API | Network 9.0+ |
| API Key Authentication | Network 9.1.105+ |
| DNS Policies, ACL Rules | Network 10.0+ |
| Switch Stacks, LAGs, MC-LAGs | Network 10.0+ |
| VPN Server/Tunnel CRUD | Network 10.1+ |
If a tool isn't in the index, the controller firmware is too old to support it.
---
## Tool Coverage
### 310 tools across 16 categories
<table>
<tr>
<td width="50%" valign="top">
**Devices** — 63 tools
```
device_list device_restart
device_get device_adopt
device_upgrade device_upgrade_all
device_locate_on/off device_force_provision
device_spectrum_scan device_rolling_upgrade_*
device_migrate device_port_action
device_list_v2 device_stats_latest
device_unadopt device_pending_list
system_device_tags system_tag_*
switching_stack_* switching_lag_*
switching_mclag_* cloud_device_list
```
**Clients** — 16 tools
```
client_list_active client_block/unblock
client_get client_reconnect
client_forget client_sessions
client_rename client_update
client_list_v2 client_action
```
**Networks** — 39 tools
```
network_list network_create
network_get network_update
network_delete network_*_v2
system_network_references
system_radius_profiles_v2
dns_policy_* system_portprofile_*
```
**Wireless (WLAN + WiFi)** — 14 tools
```
wlan_list wlan_create/update/delete
wlan_enable wlan_disable
wifi_broadcast_list/get/create/update/delete
```
**Firewall** — 30 tools
```
firewall_rule_* (legacy CRUD)
firewall_group_* (address/port groups)
firewall_zone_* (ZBF zones, 9.0+)
firewall_policy_* (ZBF policies + ordering)
acl_rule_* acl_rule_ordering_*
```
**QoS** — 10 tools
```
traffic_matching_list_* (10.0+)
```
**Routing** — 10 tools
```
traffic_rule_* (v2 API rules)
traffic_route_* (v2 API routes)
system_static_route_*
```
**VPN** — 10 tools
```
vpn_server_list/get/create/update/delete
vpn_tunnel_list/get/create/update/delete
```
</td>
<td width="50%" valign="top">
**Stats** — 20 tools
```
stats_site_health stats_sysinfo
stats_dashboard stats_report
stats_speedtest_* stats_ips_events
stats_rogueap stats_spectrumscan
```
**DPI** — 11 tools
```
stats_dpi_site stats_dpi_client
stats_dpi_apps stats_dpi_categories
misc_dpigroup_*
```
**Events** — 8 tools
```
event_list alarm_list
alarm_count alarm_archive
alarm_archive_all
```
**Hotspot** — 27 tools
```
hotspot_authorize/unauthorize_guest
hotspot_create_voucher hotspot_extend
hotspot_voucher_*_v2 (Integration API)
hotspot_config hotspot_packages
misc_hotspotop_* hotspot_2_0_package_*
```
**System** — 27 tools
```
system_reboot/poweroff system_settings
system_firmware_* admin_site_*
admin_invite/revoke cloud_host_list/get
cloud_site_list cloud_sdwan_*
```
**Settings** — 19 tools
```
system_setting_* system_led_toggle
system_ips_update misc_scheduletask_*
misc_cnt_resource
```
**Backup** — 5 tools
```
system_backup_* backup_restore
```
**PoE** — 1 tool
```
poe_power_cycle
```
</td>
</tr>
</table>
### API Layer Coverage
The server covers all three UniFi API layers:
| API Layer | Path Prefix | Auth | Coverage |
|-----------|-------------|------|----------|
| **Legacy API** | `/api/s/{site}/...` | Session cookie | Full — stat, cmd, rest, set, get, upd, list, cnt, guest, dl |
| **v2 API** | `/v2/api/site/{site}/...` | Session cookie | Full — traffic rules, traffic routes, AP groups, system logs |
| **Integration API** | `/integration/v1/...` | API key or session | Full — devices, clients, networks, WiFi, firewall, VPN, switching, hotspot, DPI |
| **Cloud Site Manager** | `api.ui.com/v1/...` | API key | Full — hosts, sites, devices, ISP metrics, SD-WAN |
---
## Configuration
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `UNIFI_HOST` | * | — | Controller URL (`https://192.168.1.1`) |
| `UNIFI_API_KEY` | * | — | API key (preferred, requires 9.1.105+) |
| `UNIFI_USERNAME` | * | — | Username (if no API key) |
| `UNIFI_PASSWORD` | * | — | Password (if no API key) |
| `UNIFI_HOST_OP_REF` | No | empty | Caller-owned 1Password reference for the controller URL |
| `UNIFI_API_KEY_OP_REF` | No | empty | Caller-owned 1Password reference for the API key |
| `UNIFI_USERNAME_OP_REF` | No | empty | Caller-owned 1Password reference for the username |
| `UNIFI_PASSWORD_OP_REF` | No | empty | Caller-owned 1Password reference for the password |
| `UNIFI_SITE` | No | `default` | Site name |
| `UNIFI_VERIFY_SSL` | No | `true` | `false` for self-signed certs |
| `UNIFI_TOOL_MODE` | No | `lazy` | `lazy` (3 meta-tools) or `eager` (all 310 tools) |
| `UNIFI_PERMISSION_PROFILE` | No | `standard` | `read-only`, `standard`, or `admin` |
<sub>* `UNIFI_HOST` plus either `UNIFI_API_KEY` or both `UNIFI_USERNAME` + `UNIFI_PASSWORD` are required for the server to actually call the controller. If they are absent, the server still starts and registers all tools (so the plugin appears installed), but every tool call returns a structured "credentials not configured" error pointing the user at the env vars or 1Password fallback. This lets the connector live in a clean "needs authentication" state instead of a hard startup error.</sub>
### 1Password fallback
The server can resolve credentials through 1Password CLI, but it does not assume a vault or item name. Set the reference variables to paths you own:
```bash
UNIFI_HOST_OP_REF="op://Your Vault/Your Item/host"
UNIFI_API_KEY_OP_REF="op://Your Vault/Your Item/api_key"
```
Plaintext environment variables take priority. The server calls `op read` only when a plaintext value is empty and its matching reference variable is set. This keeps the public package neutral and prevents unexpected 1Password lookups.
### Authentication Methods
**API Key** (recommended) — Generate at Settings → Control Plane → Integrations. Supports both legacy and Integration API endpoints. No session management overhead.
**Username/Password** — Uses session cookies with automatic re-login on expiry. The server includes a single-flight re-login mechanism that prevents thundering-herd issues when batch operations encounter session timeouts simultaneously.
See [integration testing](docs/INTEGRATION_TESTING.md) for a safe controller test sequence and [release guidance](docs/RELEASING.md) for the checks that produce the npm package, MCPB bundle, checksums, and SBOM.
---
## Architecture
```
cmd/ames-unifi-mcp/main.go Entry point, server wiring
internal/
config/ Environment config loading
client/ HTTP client
- Session auth with auto re-login (single-flight)
- API key auth (X-API-Key header)
- CSRF token management (thread-safe)
- Retry with backoff (429, 5xx)
- Legacy envelope parsing (meta.rc/data)
- Raw response passthrough (Integration/v2 APIs)
version/ Controller version detection
permissions/ Permission profiles
tools/
tool.go Tool interface
registry.go Tool registry with version/permission gating
confirm.go Confirm gate (dry-run preview pattern)
metatools.go tool_index, tool_execute, tool_batch
core/ Core tool implementations
devices.go clients.go networks.go
wlan.go wifi.go firewall.go
acl.go dns.go traffic.go
wan.go switching.go stats.go
events.go system.go
extended/ Extended tool implementations
poe.go hotspot.go cloud.go
admin.go syslog.go apgroups.go
misc.go
```
### Key Design Decisions
**Lazy mode by default.** An LLM calling 310 tools directly wastes context and confuses tool selection. The 3-meta-tool pattern lets the assistant discover tools on demand, typically using < 200 tokens of context for the tool definitions.
**Confirm gate on all mutations.** Rather than relying on the MCP client to prevent unintended actions, every mutating tool returns a preview by default. The `confirm: true` parameter is an explicit opt-in. This is baked into the tool schema — the LLM sees it as a required step, not an optional flag.
**Version gating at registration.** Tools for newer API features aren't hidden or errored — they simply don't register if the controller is too old. The tool index only shows what's actually available.
**Permission gating with visibility.** Denied tools appear in the index with a `[PERMISSION DENIED]` suffix. This lets the assistant explain to the user why something isn't available, rather than returning a cryptic "unknown tool" error.
---
## Building
```bash
go build -o ames-unifi-mcp ./cmd/ames-unifi-mcp/
```
### Cross-compilation
```bash
# Linux ARM64 (e.g., Raspberry Pi, Docker on NAS)
GOOS=linux GOARCH=arm64 go build -o ames-unifi-mcp ./cmd/ames-unifi-mcp/
# Linux AMD64
GOOS=linux GOARCH=amd64 go build -o ames-unifi-mcp ./cmd/ames-unifi-mcp/
```
### Running Tests
```bash
go test ./...
```
---
## Common Operations
Here's what natural-language network management looks like:
**"How's my network doing?"**
```
→ tool_batch: stats_site_health + client_list_active + alarm_count
← WAN: healthy, 47 clients connected, 0 active alarms
```
**"Block that sketchy device"**
```
→ client_get {"mac": "aa:bb:cc:dd:ee:ff"}
← Device "Unknown-IoT" on VLAN 30, 2.3 GB today
→ client_block {"mac": "aa:bb:cc:dd:ee:ff"}
← Preview: Would block Unknown-IoT. Confirm?
→ client_block {"mac": "aa:bb:cc:dd:ee:ff", "confirm": true}
← Blocked.
```
**"Create a guest voucher for 24 hours"**
```
→ hotspot_create_voucher {"expire_minutes": 1440, "quota": 1}
← Preview: Would create 1 single-use voucher, 24h validity. Confirm?
→ hotspot_create_voucher {"expire_minutes": 1440, "quota": 1, "confirm": true}
← Voucher created: 83927-10458
```
**"Which APs are on old firmware?"**
```
→ device_list_basic
← 12 devices. Filtering by upgrade_available...
- Lobby AP (U6-Pro) — current: 6.6.55, available: 7.0.83
- Garage AP (U6-Lite) — current: 6.6.55, available: 7.0.83
```
---
## License
MIT — Not affiliated with Ubiquiti Inc.
---
<p align="center">
<a href="https://www.buymeacoffee.com/oliverames">
<img src="https://img.shields.io/badge/Buy_Me_a_Coffee-support-f5a542?style=for-the-badge&logo=buy-me-a-coffee&logoColor=white" alt="Buy Me a Coffee">
</a>
</p>
<p align="center">
<sub>
Built by <a href="https://ames.consulting">Oliver Ames</a> in Vermont
• <a href="https://github.com/oliverames">GitHub</a>
• <a href="https://linkedin.com/in/oliverames">LinkedIn</a>
• <a href="https://bsky.app/profile/oliverames.bsky.social">Bluesky</a>
</sub>
</p>
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
markitdown
Python tool for converting files and office documents to Markdown.
Filesystem
Node.js MCP Server for filesystem operations with dynamic access control.
TrendRadar
TrendRadar: Your hotspot assistant for real news in just 30 seconds.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.
mempalace
The highest-scoring AI memory system ever benchmarked. And it's free.