The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Unifi MCP listing page.
mcp-name: io.github.mikeholownych/unifi-mcp
An MCP (Model Context Protocol) server that provides AI assistants like Claude with access to UniFi Network and Protect infrastructure management and analysis capabilities. It uses the native MCP SDK 2 MCPServer API (not FastMCP 3) and communicates over stdio by default.
Credits: This project started as a fork of gbassaragh/Unifi-mcp and has since evolved into a fully independent project. Thanks to @gbassaragh for the excellent starting point.
UNIFI_MODE=local, requests now correctly use the traditional controller API (/proxy/network) with cookie + CSRF session auth. Upstream always routed through the Integration API regardless of mode.api_base_url now respects the configured auth mode instead of unconditionally returning the Integration API endpoint.device parameterpoll_events, retry_webhook_deliveries, capture_observations, and prune_runtime_data| Mode | Auth | Best for |
|---|---|---|
local_api_key | Integration API key | Recommended default; broad read access |
local | Username/password session | Full feature access: firewall rules, WLAN configs, site settings, events, alarms, DPI |
cloud | api.ui.com key | Remote/cloud-managed controllers |
When API keys are used (Integration API), a subset of controller features is only available via legacy session auth (UNIFI_MODE=local): network events, alarms, DPI statistics, speed tests, WLAN configs, firewall rules, port profiles, and routing tables. Tools for these features return a clear error explaining how to enable them rather than failing silently. Insight tools degrade gracefully and report data limitations.
Note on local accounts: SSO/Ubiquiti-account admins protected by MFA cannot complete session login. Create a local admin on your console (Restrict to Local Access Only) for
UNIFI_MODE=local.
Bundled skills (in skills/) teach agents proven workflows for this server — including
controller-specific gotchas (Network 10 removed endpoints, zone-pair rules, WPA3 transition).
Full documentation: See SKILLS.md for usage guide, expected results, troubleshooting, and how to request new functionality.
| Skill | Type | Purpose |
|---|---|---|
unifi-network-audit | read-only | Full site audit: devices, clients, WiFi posture, firewall, structured report |
unifi-troubleshoot-client | read-only | Diagnose a misbehaving device: RF, roaming, blocking, IP layer |
unifi-wifi-optimize | write-gated | Channel plan, widths, WPA3 transition, band steering — approval-gated |
unifi-grant-device-access | write-gated | Give a device a reserved IP + scoped zone-firewall access |
unifi-internet-down | read-only triage | "Internet is dead!" — plain-English outage diagnosis, ISP escalation script |
unifi-whos-home | read-only | "Who's on my WiFi?" — friendly inventory, intruder checks with randomized-MAC awareness |
unifi-setup-new-device | write-gated | Get any new gadget online: pairing pitfalls (2.4GHz/WPA3), naming, IP reservation |
unifi-dns-triage | read-only | "Site won't load but ping works" — resolution vs connectivity split, forced-internal-DNS patterns |
unifi-mdns-discovery | read-only+ | AirPrint/Cast broken across VLANs — mDNS reflection, IGMP/IPTV cautions |
unifi-port-forwarding | write-gated | Self-hosted service exposure incl. hairpin NAT, CGNAT detection, zone-policy pairing |
unifi-vpn | write-gated | WireGuard/Teleport setup + failure ladder (handshake/MTU/zone-policies) |
unifi-firmware-campaign | write-gated | Staged firmware updates: snapshot, canary, verify, stuck-device ladder |
unifi-mesh-backhaul | read-only | Slow far-room WiFi: wireless-uplink/hop diagnosis, wired-backhaul guidance |
unifi-ids-ips-triage | read-only+ | Threat alerts: false-positive vs real, suppression, IPS throughput cost |
unifi-backup-migration | write-gated | What backups contain, migration rules of thumb, pre-migration snapshots |
unifi-network-map | doc-writer | Persistent labeled topology (zones/VLANs/deps) that sharpens every other skill |
Just describe your problem naturally — the agent matches your request to the right skill and follows its workflow:
unifi-internet-down diagnoses WAN, modem, gatewayunifi-whos-home lists devices, flags unknownsunifi-network-audit produces a full health reportunifi-setup-new-device guides WiFi pairingWrite-gated skills (marked above) modify your network — they always ask approval before applying changes.
Skills for non-technical users avoid jargon, translate every technical term, and require confirmation before disruptive actions.
Install (per project): copy into .claude/skills/:
See SKILLS.md for full usage guide, expected results, troubleshooting, and how to request new functionality.
Skills reference MCP tools by their plain names (get_firewall_policies, …);
your MCP client prefixes them automatically.
This server is built for operation on a trusted local network, talking to UniFi consoles by IP address. With that in mind:
UNIFI_VERIFY_SSL=false). UniFi OS
ships self-signed certificates, and controllers are reached by IP on the LAN, so
certificate verification is expected to fail. Enable UNIFI_VERIFY_SSL=true only
when your controller presents a CA-trusted certificate.UNIFI_* credentials are supplied (e.g. when deployed and
configured via environment variables). Device-bound tool calls then return a clear
No device configured error until a device is set.tools/call is gated by read/write/admin OIDC scopes, and
startup fails if any tool is unclassified. Over stdio (local IPC) no auth is
required — stdio is assumed to be a trusted local process.UNIFI_MODE=local): network events, alarms,
DPI statistics, speed tests, WLAN/firewall configs, port profiles, and routing
tables. Tools for these return a clear error explaining how to enable them.Create a .env file in the project root (or set environment variables). See .env.example for all options.
UNIFI_CACHE_TTL controls the shared GET cache lifetime across client instances (default: 30
seconds). Mutation verification defaults to five fresh reads with exponential delays of 0.5, 1,
2, and 2 seconds. Tune this with UNIFI_MUTATION_VERIFY_ATTEMPTS,
UNIFI_MUTATION_VERIFY_INITIAL_DELAY, and UNIFI_MUTATION_VERIFY_MAX_DELAY when a controller
converges more slowly or quickly.
SQLite-backed runtime persistence is disabled by default. Enable it only when persistent runtime state is needed:
By default, the database is runtime.db under UNIFI_DATA_DIR. If UNIFI_DATA_DIR is not set, the server follows the XDG data convention: $XDG_DATA_HOME/unifi-mcp when XDG_DATA_HOME is an absolute path, otherwise ~/.local/share/unifi-mcp. The resulting default database is therefore $XDG_DATA_HOME/unifi-mcp/runtime.db or ~/.local/share/unifi-mcp/runtime.db.
Set an explicit data directory or database path when needed:
UNIFI_DATA_DIR and UNIFI_RUNTIME_DATABASE must resolve to absolute paths. UNIFI_RUNTIME_DATABASE overrides the database derived from UNIFI_DATA_DIR.
Runtime persistence enables event storage and management tools, but does not start background work. Enable the scheduler separately:
Event ingestion is capability-based polling, not a claim of universal UniFi push support:
UNIFI_MODE=local.username and password for each Protect device.Schedules can invoke only poll_events, retry_webhook_deliveries, capture_observations, or prune_runtime_data. Schedule and webhook mutations require confirm=true; arbitrary MCP tool names, commands, imports, and expressions are rejected.
Webhook destinations use HTTPS, do not follow redirects, and are resolved and checked before every attempt. Loopback, private, link-local, multicast, and reserved addresses are rejected unless UNIFI_WEBHOOK_ALLOW_PRIVATE=true. The dedicated webhook client retains certificate verification even when a UniFi controller uses a self-signed certificate.
Signing secrets never enter SQLite or MCP arguments. Set a secret in the server environment, then pass only its variable name as secret_env_name:
Useful tools include get_event_polling_status, poll_events_now, list_runtime_events, create_interval_schedule, run_schedule_now, list_job_runs, create_webhook_destination, test_webhook_destination, and list_webhook_deliveries. Retryable jobs and webhook failures use bounded exponential backoff; exhausted deliveries enter dead_letter state.
Portable snapshots are versioned, canonical JSON exports assembled from supported read APIs. They include source scope, explicit data limitations, Network/Protect inventory, networks, WLAN metadata, and firewall rule/policy metadata. Credentials, API keys, cookies, authorization headers, and WLAN passphrases are structurally excluded.
Export tools accept a plain filename rather than an arbitrary path, reject traversal and symlinks, and atomically write files with 0600 permissions. export_portable_snapshot includes a SHA-256 content checksum; verify_snapshot detects malformed, truncated, or modified snapshots. export_network_report renders the same strict model as escaped standalone HTML or formula-safe CSV.
Native controller backup download and restore are intentionally reported as unavailable until controller-family endpoints and safe restore verification are validated. Portable snapshots support assessment and assisted reconstruction; they are not represented as restorable native controller backups.
With runtime persistence enabled, capture_observations_now stores bounded aggregate site health, device/client counts, traffic totals, and Protect camera health. It never stores per-client history or packet-flow telemetry. query_observation_trends returns bounded UTC buckets with present=false for missed collections rather than inventing interpolated values.
Prometheus support is not part of the base dependency set and starts no listener by default:
Metrics use fixed names without controller, site, client, MAC, IP, or SSID labels. Binding beyond loopback additionally requires UNIFI_PROMETHEUS_ALLOW_REMOTE=true and UNIFI_PROMETHEUS_BEARER_TOKEN_ENV naming an environment variable that contains the bearer token. The token value is read at request time and is never persisted.
With runtime persistence enabled, clients can have multiple local tags and at most one local group. Membership is keyed by a controller/site-scoped SHA-256 value derived from the stable client MAC; raw MACs and mutable client names are not stored. Exact names and hostnames can be used as transient lookup hints, but ambiguous matches are rejected and the exact MAC must be supplied. Tags and groups survive client renames and do not change controller configuration.
Organization mutations require confirm=true. Use set_client_tags, create_client_group, assign_client_group, list_client_groups, and list_clients_by_organization to manage or query local metadata.
plan_client_qos_policy persists a one-hour deterministic target snapshot selected by one client, tag, or group. The target ledger contains only scoped one-way client keys and supports future resumable per-target apply state. This release has no validated controller QoS adapter: get_client_qos_capabilities reports that limitation, and apply_client_qos_policy returns without making a controller mutation. Local tags never imply a QoS policy.
Plugins are disabled unless their Python entry-point name is explicitly listed in UNIFI_PLUGIN_ALLOWLIST. They execute as trusted local code in the server process and are not sandboxed. Required plugins must also be allowlisted and are listed in UNIFI_PLUGIN_REQUIRED; missing, incompatible, duplicate, or failed required plugins stop startup. Optional failures are isolated and visible through get_plugin_status.
Plugins use API version 1 and the unifi_mcp.plugins entry-point group:
The loaded object declares api_version = 1 and implements register(registry). The registry supports register_tool with an explicit read, write, or admin scope, plus named collectors, JobDefinition jobs, notification sinks, and byte-returning report renderers. Plugin names cannot shadow core tools or jobs.
Stdio remains the default local process transport and requires no identity-provider configuration. Remote MCP starts only when UNIFI_TRANSPORT=streamable-http; install the declared authentication capability with uv sync --extra oidc and provide complete OIDC settings:
Discovery and JWKS data are fetched over HTTPS with bounded timeouts, cached for five minutes by default, and refreshed once for an unknown signing key. Tokens are validated locally for allowed asymmetric algorithm, signature, issuer, audience, expiry, subject, and scopes. Authorization headers, tokens, claims, and signing keys are not logged or persisted.
All HTTP tool calls require UNIFI_OIDC_READ_SCOPE (unifi:read by default). Mutations additionally require UNIFI_OIDC_WRITE_SCOPE; runtime administration and plugin status require UNIFI_OIDC_ADMIN_SCOPE. Existing confirm=true gates still apply. Non-loopback binding additionally requires UNIFI_HTTP_ALLOW_REMOTE=true; production TLS should terminate at the declared HTTPS public URL.
Configure multiple UniFi devices with different services:
Device configuration fields:
| Field | Description | Default |
|---|---|---|
name | Friendly name for targeting the device | (required) |
url | Base URL of the UniFi device | (required) |
api_key | API key from UniFi OS Control Plane | (required) |
services | Array: ["network"], ["protect"], or both | ["network"] |
site | Site name for network operations | "default" |
verify_ssl | Verify SSL certificates | false |
username | Username for Protect events (optional) | null |
password | Password for Protect events (optional) | null |
Note: The username and password fields are only required for Protect event tools (motion events, smart detections). Basic camera operations work with just the API key.
To create an API key:
For backwards compatibility, single-device configuration is still supported:
For full-feature access with username/password authentication:
For Ubiquiti Cloud API access:
Get your API key from unifi.ui.com → API section.
Add to your Claude Desktop configuration (~/.config/claude/claude_desktop_config.json on Linux or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
Or in opencode.json:
get_server_health - Report the server version, stdio transport, configured service counts, and optional persistence status. The response deliberately omits credentials, controller addresses, device names, and database paths.list_unifi_devices - List all configured UniFi devices and their serviceslist_devices - List all UniFi network devicesget_device_details - Get detailed device informationrestart_device - Restart a devicelocate_device - Blink LED to locate deviceget_device_stats - Get performance statisticsupgrade_device - Upgrade firmwareprovision_device - Force re-provisionget_device_ports - List switch/gateway port configuration and link stateset_device_port - Configure one port; requires confirm=true and verifies controller read-backlist_clients - List connected clientslist_all_clients - List all known clients (including offline)get_client_details - Get client detailsblock_client / unblock_client - Block/unblock clientskick_client - Disconnect a clientforget_client - Remove from known clientsget_client_traffic - Get traffic statisticsreserve_client_ip - Reserve IP via DHCP reservationget_client_organization / set_client_tags - Read or replace durable local tagscreate_client_group / delete_client_group - Manage local-only groupsassign_client_group / list_client_groups - Manage and inspect single-group membershiplist_clients_by_organization - Resolve deterministic tag or group target setsget_client_qos_capabilities - Report validated controller QoS supportplan_client_qos_policy / apply_client_qos_policy - Preview QoS targets and apply only when a validated adapter existslist_sites - List all sitesget_site_health - Get site health statusget_site_settings - Get site settingsget_sysinfo - Get system informationget_networks - Get network/VLAN configsget_wlans - Get wireless network configsget_port_profiles - Get switch port profilesget_firewall_rules - Get legacy firewall rulesget_firewall_policies - Get zone-based firewall policies (UniFi Network 9+)get_routing_table - Get routing tableget_port_forwards - Get port forwarding rulescreate_port_forward / delete_port_forward - Manage port forwardscreate_network / update_network / delete_network - Manage networks and VLANs; each requires confirm=true and verifies controller read-backcreate_wlan / update_wlan / delete_wlan - Manage wireless networkscreate_firewall_policy / set_firewall_policy_enabled / delete_firewall_policy - Manage zone-based firewall policiesexport_camera_clip - Export an MP4 beneath UNIFI_EXPORT_DIR; requires confirm=trueget_all_sites_health - Health overview across all sitesWrite tools that remove data or cause disruption are confirm-gated or flagged destructive via MCP annotations.
get_network_health - Overall network healthget_recent_events - Recent eventsget_alarms - Active alarmsarchive_all_alarms - Archive all alarmsrun_speed_test - Start speed testget_speed_test_status - Get speed test resultsget_dpi_stats - DPI statisticsget_traffic_summary - Traffic summaryanalyze_network_issues - Comprehensive issue analysisget_optimization_recommendations - Configuration recommendationsget_client_experience_report - Client quality metricsget_device_health_summary - Device health overviewget_traffic_analysis - Traffic pattern analysisget_all_sites_health - Health overview across all sitesget_global_inventory - Unified device inventory across all controllersget_global_health - Aggregated health report across all controllersget_global_client_summary - Client counts, top talkers, blocked clients across all controllerstroubleshoot_client - Deep-dive client troubleshootinglist_cameras - List all cameras with connection statusget_camera_details - Get detailed camera informationget_camera_snapshot - Get live snapshot (base64 JPEG)get_protect_system_info - Get NVR system informationget_camera_health_summary - Camera health overview with issuesget_liveviews - Get configured liveview layoutsget_protect_accessories - List lights, sensors, chimes, viewersget_motion_events - Get recent motion eventsget_smart_detections - Get smart detection events (person, vehicle, animal, package)get_protect_event_summary - Summary of all events by typeget_recent_protect_activity - Quick overview of recent activityAfter connecting the MCP server, you can ask Claude:
To enable optional runtime persistence, mount a named volume at the image's writable /data directory:
--rm removes the stopped container, but the unifi-mcp-data named volume remains and preserves /data/runtime.db for subsequent runs.
[Skill] prefix — describe the problem, workflow, and expected output[Skill: skill-name] prefix — what's missing or broken[Tool] prefix — include the UniFi API endpoint and expected formatSee SKILLS.md for detailed contribution guidelines.
See CHANGELOG.md for release history and CONTRIBUTING.md to contribute.
.envUNIFI_VERIFY_SSL=false) because the
server is designed to run on a trusted LAN against UniFi consoles reached by IP
with self-signed certificates. Enable it only with a CA-trusted certificate.MIT License
Contributions are welcome! Please open an issue or submit a pull request.