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.
Metadata
Release files for mcp-server-unifi 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mcp_server_unifi-0.1.0.tar.gz | 494.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_server_unifi-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 536.3 kB
Release files / mcp_server_unifi-0.1.0.tar.gz
| Download URL | mcp_server_unifi-0.1.0.tar.gz |
|---|---|
| Size | 494.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
96cc33b8e40b79eb7fdda41eb14ecec5516e24e1b8202da22587246985b9de7a
|
|
BLAKE2b-256 checksum How to use checksums |
f44e12b7fac8510197ee298d68b6b6723d8024534a66bc4b9dd7396669e54da9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / mcp_server_unifi-0.1.0-py3-none-any.whl
| Download URL | mcp_server_unifi-0.1.0-py3-none-any.whl |
|---|---|
| Size | 41.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a93d4460ead2a1e6442b993ba1a215bce666cc6ff1dda0ac817d98a93a210aa6
|
|
BLAKE2b-256 checksum How to use checksums |
3a12c270bd0f79f9899650b852e81d981e468ba0ec1271dd05144453e59d91a9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Security for mcp-server-unifi 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.