Read-only MCP server for UniFi network analysis — gives LLMs safe access to controller data for diagnostics, monitoring, and capacity planning
Project description
mcp-server-unifi
Read-only MCP server for UniFi network analysis. Gives Claude (and other MCP clients) safe access to controller data for diagnostics, monitoring, and capacity planning.
Python 3.11+ | 19 tools | 4 resources | 6 prompts
Architecture
+-----------------+
| Claude / MCP |
| Client |
+--------+--------+
| stdio (JSON-RPC)
+--------+--------+
| mcp-server-unifi |
| MCP Server |
| |
| - Tools (19) |
| - Resources (4) |
| - Prompts (6) |
+--------+--------+
|
+--------+--------+
| Session Pool |
| Circuit Breaker |
+--------+--------+
| httpx (HTTPS)
+--------+--------+
| UniFi Controller|
| (Network API) |
+-----------------+
Mermaid source: docs/architecture.mmd
Install
uvx (recommended)
No install needed — runs directly from PyPI:
{
"mcpServers": {
"unifi": {
"command": "uvx",
"args": ["mcp-server-unifi"],
"env": {
"UNIFI_HOST": "https://192.168.1.1",
"UNIFI_USER": "mcp-user",
"UNIFI_PASS": "your-password-here",
"UNIFI_SITE": "default",
"UNIFI_VERIFY_SSL": "false"
}
}
}
}
Add this to .mcp.json (Claude Code) or your client's MCP config. Restart the client.
pip
pip install mcp-server-unifi
mcp-server-unifi # start server on stdio
From source
git clone https://gitlab.com/gitlab_joel/mcp-server-unifi.git
cd mcp-server-unifi
make venv
cp .env.example .env # fill in your credentials
make run
MCP Inspector
npx @modelcontextprotocol/inspector # interactive testing
Configuration
All config is via environment variables — set in .env or in the env block of .mcp.json.
| Variable | Default | Description |
|---|---|---|
UNIFI_HOST |
https://localhost:8443 |
Controller URL |
UNIFI_USER |
admin |
API username |
UNIFI_PASS |
(required) | API password |
UNIFI_SITE |
default |
UniFi site name |
UNIFI_VERIFY_SSL |
false |
Verify TLS certificate |
UNIFI_SESSION_TTL |
1800 |
Session lifetime (seconds) before re-auth |
UNIFI_MIN_LOGIN_INTERVAL |
10 |
Minimum seconds between login attempts |
UNIFI_POLL_INTERVAL |
60 |
Resource polling interval (seconds, min 15) |
Recommend creating a dedicated read-only local user on the UniFi controller for the MCP server rather than using an admin account.
Tools
Devices & Topology
| Tool | Description | Required Args |
|---|---|---|
unifi_list_devices |
List all APs, switches, gateways with status | -- |
unifi_ap_details |
Detailed AP info (radios, VAPs, load) | mac |
unifi_switch_details |
Switch info + per-port status | mac |
unifi_switch_port_stats |
Per-port error/throughput stats | mac (opt: port_idx) |
unifi_topology |
Device uplink chain for backbone paths | -- |
unifi_device_stats_history |
Historical throughput, client count, error stats | mac (opt: hours, granularity) |
Clients
| Tool | Description | Required Args |
|---|---|---|
unifi_list_clients |
Connected clients | (opt: ap_mac, limit, offset) |
unifi_client_details |
Client info by MAC | mac |
unifi_search_client |
Search by hostname pattern | hostname (opt: limit) |
Wireless / RF
| Tool | Description | Required Args |
|---|---|---|
unifi_channel_utilization |
Channel stats across all APs | -- |
unifi_wlan_config |
SSID config (DTIM, roaming, band steering) | (opt: ssid) |
unifi_ap_radio_config |
Radio config (channel, power, RSSI) | mac |
unifi_rogue_aps |
Neighboring/rogue APs for interference analysis | (opt: ap_mac, limit) |
unifi_radio_ai_settings |
Radio AI auto-channel/power settings | -- |
Events & Health
| Tool | Description | Required Args |
|---|---|---|
unifi_events |
Recent network events | (opt: limit, client_mac, event_type) |
unifi_alarms |
Active alarms | -- |
unifi_site_health |
Site health metrics for all subsystems | -- |
unifi_system_logs |
System log entries (richer than events) | (opt: limit, category, severity) |
unifi_recommend_roaming |
Best AP for roaming via AI sampling | mac |
All tools return JSON. Output exceeding ~25k tokens is automatically truncated with pagination metadata.
Resources
| URI | Description | Update |
|---|---|---|
unifi://devices |
All network devices with status | Polled, SHA-256 change detect |
unifi://clients/active |
Connected wireless + wired clients | Polled, SHA-256 change detect |
unifi://health |
Site health summary | Polled, SHA-256 change detect |
unifi://events/infrastructure |
Non-roam events (device offline, switch connect, channel change) | Polled, SHA-256 change detect |
Clients receive notifications/resources/updated when data changes. Polling interval controlled by UNIFI_POLL_INTERVAL.
Prompts
Diagnostics
troubleshoot_wifi — Diagnose WiFi issues for a specific client.
- Args:
client_identifier(required),timeframe(optional, default "last 24 hours") - Searches for client, uses elicitation if multiple match, gathers diagnostics (details, events, channel utilization), returns timeline + root cause + recommendations
incident_investigation — Correlate events with device state for incident analysis.
- Args:
timeframe(optional),device_mac(optional) - Gathers system logs, events, topology, and switch port stats. Builds chronological timeline, traces blast radius through uplink chain, identifies root cause
Assessments
deployment_assessment — Full network health assessment with structured findings.
- Args:
focus(optional: "switches", "wireless", "events", or "all") - Scans all devices, switch ports, wireless, topology, and infrastructure events. Produces a structured report with comparison anchors for delta tracking
wifi_audit — Full wireless environment audit.
- Args: none
- Scans all APs, channel utilization, rogues, client distribution, WLAN config. Returns structured findings with recommendations
Capacity Planning
capacity_report — AP load and throughput trending analysis.
- Args:
hours(optional, default 24) - Per-AP client distribution by band, hourly throughput history, channel utilization, band steering effectiveness, capacity headroom estimation
switch_health — Deep dive on switch port errors and drop rates.
- Args:
switch_mac(optional — analyzes all switches if omitted) - Per-switch port error table, drop rate computation, STP state audit, uplink chain health
Resilience
- Circuit breaker — Trips after 3 consecutive auth failures. Exponential backoff (30s → 60s → 120s → 300s max). Prevents hammering a down controller.
- Session pool — Single shared httpx session with configurable TTL (default 30 min). Auto-refreshes on expiry or 401. Avoids repeated logins.
- Login throttle — Minimum 10s between login attempts (configurable). Stays under the UniFi OS ~5 attempts/window rate limit.
- Output truncation — Binary-search truncation at ~80k chars (~20k tokens). Adds
_truncatedmetadata with item count and guidance.
Development
git clone <repo-url> && cd mcp-server-unifi
make venv # create venv + install dev deps
make test # run test suite (424 tests, 89% coverage)
make lint # ruff linter
make format # ruff auto-format
Make Targets
| Target | Description |
|---|---|
make test |
Run test suite with coverage |
make coverage |
Tests + HTML coverage report |
make lint |
Run ruff linter |
make format |
Auto-format with ruff |
make run |
Start MCP server |
make clean |
Remove build artifacts |
make docker-build |
Build Docker image |
make docker-run |
Run in Docker (uses .env) |
Testing
424 tests across unit, protocol, and behavioral categories:
- Unit — tools, resources, prompts, circuit breaker, session pool, output truncation, progress, logging
- Protocol — MCP JSON-RPC validation through real client/server stack (initialization, capabilities, tool invocation, error handling)
- Behavioral — Tool naming conventions, JSON Schema correctness, keyword-overlap tool selection scoring, response format validation
Config: asyncio_mode = "auto" in pyproject.toml. Do not use pytestmark = pytest.mark.anyio — it conflicts with pytest-asyncio.
Project Structure
src/mcp_server_unifi/
server.py MCP server, tool dispatch, create_server()
client.py UniFi API client (httpx, auth, retry)
tools.py Tool implementations (formatting, logic)
resources.py Resource handlers + ResourcePoller
prompts.py Prompt templates (troubleshoot, audit)
session_pool.py Shared session with TTL + login throttle
circuit_breaker.py CircuitBreaker (closed/open/half-open)
output.py Output truncation (binary search)
progress.py Progress notification helper
logging_handler.py MCP logging channel
tests/
conftest.py Fixtures, mock UniFi client, MCP session
test_tools.py Tool logic
test_resources.py Resource handlers
test_prompts.py Prompt workflows
test_mcp_protocol.py In-process protocol validation
test_behavioral.py Naming, schema, selection scoring
test_circuit_breaker.py
test_session_pool.py
test_client.py
test_output.py
test_progress.py
test_logging_handler.py
test_advanced.py
Known Gotchas
- Claude Code does not render progress or logging notifications — The server emits them correctly, but Claude Code's UI does not display them yet. Tracked: claude-code#4157 (progress), claude-code#3174 (logging). MCP Inspector displays both.
- UniFi OS login rate limiting —
/api/auth/loginallows ~5 attempts per window with a 5-10 min cooldown (HTTP 429). Cumulative across all clients. The session pool and login throttle mitigate this. - No switch historical stats — The UniFi API has no
stat/reportendpoint for switches. Useunifi_switch_port_statsfor real-time counters.
See IMPROVEMENTS.md for development history.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_server_unifi-0.1.0.tar.gz.
File metadata
- Download URL: mcp_server_unifi-0.1.0.tar.gz
- Upload date:
- Size: 494.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96cc33b8e40b79eb7fdda41eb14ecec5516e24e1b8202da22587246985b9de7a
|
|
| MD5 |
7a6754343a165d950e75ba3efc6a23e6
|
|
| BLAKE2b-256 |
f44e12b7fac8510197ee298d68b6b6723d8024534a66bc4b9dd7396669e54da9
|
File details
Details for the file mcp_server_unifi-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_server_unifi-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a93d4460ead2a1e6442b993ba1a215bce666cc6ff1dda0ac817d98a93a210aa6
|
|
| MD5 |
6d5a7ec1d7acd70369eaf200417d36f6
|
|
| BLAKE2b-256 |
3a12c270bd0f79f9899650b852e81d981e468ba0ec1271dd05144453e59d91a9
|