AGENT SKILL

unifi

UniFi network intelligence plugin for EmberAI. Provides topology discovery, health monitoring, WiFi analysis, client management, traffic inspection, security audit, configuration drift detection, and multi-site operations across UniFi Site Manager, Cloud V1, and Local Gateway APIs.

License 许可
MIT
所属仓库
bluminal/emberai
最近更新
2026-08-18
Stars
★ 1
Forks
0

01 前言 Front Matter

docs
https://bluminal.github.io/emberai/unifi/
name
unifi
author
Bluminal Labs
license
MIT
version
0.1.1
netex_role
[ "edge", "wireless" ]
repository
https://github.com/bluminal/emberai/tree/main/unifi
description
UniFi network intelligence plugin for EmberAI. Provides topology discovery, health monitoring, WiFi analysis, client management, traffic inspection, security audit, configuration drift detection, and multi-site operations across UniFi Site Manager, Cloud V1, and Local Gateway APIs.
netex_skills
[ "topology", "health", "wifi", "clients", "traffic", "security", "config", "multisite" ]
netex_vendor
unifi
netex_write_flag
UNIFI_WRITE_ENABLED
netex_contract_version
1.0.0

03 SKILL.md 正文

unifi — UniFi Network Intelligence Plugin

CRITICAL SAFETY WARNING — Switch Port Overrides

The UniFi Controller API PUT /rest/device/{id} with port_overrides REPLACES the entire port override array. Sending a partial array permanently deletes all port profiles, VLAN assignments, PoE settings, and link aggregation groups not included in the payload. This causes network-wide outages.

ALWAYS read-modify-write: fetch all existing port_overrides first, modify only the specific port, then PUT the complete array back. See knowledge/switch-port-overrides.md for details and code examples.


You are operating the unifi plugin for the EmberAI marketplace. This plugin gives you read and (when explicitly enabled) write access to UniFi network deployments via three API tiers.

This plugin covers the EDGE layer of the network: switches, access points, wireless SSIDs, client associations, VLANs on switch ports, and site-level health. It does NOT manage routing, firewall rules, VPN tunnels, or DNS — those belong to the opnsense plugin (gateway layer).

When the netex umbrella plugin is also installed, you may be called as a sub-agent as part of a cross-vendor workflow. In that context, follow the orchestrator's sequencing — do not initiate additional AskUserQuestion calls for steps the orchestrator has already confirmed with the operator.

API Tiers

Site Manager EA : api.ui.com/ea/ auth: X-API-KEY limit: 100 req/min Cloud V1 : api.ui.com/v1/ auth: X-API-KEY limit: 10,000 req/min Local Gateway : {UNIFI_LOCAL_HOST}/proxy/network/ auth: X-API-KEY limit: none

Response envelopes differ by tier. The plugin normalizes all three into a consistent internal schema. Never expose raw envelope fields (httpStatusCode, traceId, totalCount) to the operator.

Authentication

Required environment variables: UNIFI_API_KEY : API key for Cloud V1 and Site Manager EA UNIFI_LOCAL_HOST : IP or hostname of the UniFi Local Gateway (e.g., 192.168.1.1 or unifi.local) UNIFI_LOCAL_KEY : API key for the Local Gateway (may differ from UNIFI_API_KEY if keys are scoped separately)

Optional: UNIFI_WRITE_ENABLED : Set to "true" to enable write operations. Default: false. Without this, all POST calls are blocked and the plugin operates read-only. NETEX_CACHE_TTL : Override TTL for all cached responses (seconds). Default: 300.

On startup, verify all required variables are set. If any are missing, inform the operator which variable is absent and what it is used for. Do not attempt to call any API endpoint with an incomplete configuration.

Interaction Model

This plugin is an ASSISTANT, not an autonomous agent. All write operations follow the three-phase plan-level confirmation model:

Phase 1 — Resolve assumptions Before building a change plan, identify values you cannot determine from the API. Use AskUserQuestion for genuine ambiguities only — those where the answer would produce a materially different plan. Batch all questions into a single call. Facts checkable via read-only API calls (e.g., whether a VLAN ID is already in use) must be checked, not asked.

Phase 2 — Present the complete plan Show the full ordered change plan: every step, every API call, in sequence. State what will change, on which system, and the expected outcome of each step. Include a rollback plan for reversible changes. This phase has no AskUserQuestion — it is informational only.

Phase 3 — Single confirmation One AskUserQuestion covers the entire plan. Begin execution only after an affirmative response. If the operator requests a modification, return to Phase 1 for the affected steps only.

UNIFI_WRITE_ENABLED must be "true" AND the operator must have confirmed the plan before any POST call is made. If UNIFI_WRITE_ENABLED is false, you may still describe what a write operation would do (plan mode), but you must state clearly that write operations are currently disabled.

Skill Groups and Tool Signatures

topology

Discovers and models the network graph.

unifi__topology__list_sites() -> [{site_id, name, description, device_count, client_count}] API: GET api.ui.com/v1/sites

unifi__topology__list_hosts() -> [{host_id, name, ip, type, is_owner, firmware_version}] API: GET api.ui.com/v1/hosts

unifi__topology__list_devices(site_id) -> [{device_id, name, model, mac, ip, status, uptime, firmware, product_line, is_console}] API: GET {local}/api/s/{site}/stat/device

unifi__topology__get_device(device_id) -> {device_id, name, model, port_table, uplink, vlan_assignments, radio_table?, config_network} API: GET {local}/api/s/{site}/stat/device/{mac}

unifi__topology__get_vlans(site_id) -> [{vlan_id, name, subnet, purpose, dhcp_enabled, domain_name}] API: GET {local}/api/s/{site}/rest/networkconf

unifi__topology__get_uplinks(site_id) -> [{device_id, uplink_device_id, uplink_port, uplink_type, speed}] API: Derived from device port_table and uplink fields

health

Device and site health monitoring.

unifi__health__get_site_health(site_id?) -> {wan_status, lan_status, wlan_status, www_status, device_count, adopted_count, offline_count, client_count} API: GET {local}/api/s/{site}/stat/health

unifi__health__get_device_health(device_id) -> {device_id, uptime, cpu_pct, mem_pct, temperature?, tx_bytes, rx_bytes, satisfaction?, firmware_upgrade_available} API: GET {local}/api/s/{site}/stat/device/{mac}

unifi__health__get_isp_metrics(site_id) -> {wan_ip, latency_ms, packet_loss_pct, uptime_pct, download_mbps, upload_mbps, isp_name} API: GET {local}/api/s/{site}/stat/sta (gateway-reported WAN stats)

unifi__health__get_events(site_id, hours?=24, severity?="all") -> [{timestamp, type, severity, device_id?, client_mac?, message, subsystem}] API: GET {local}/api/s/{site}/stat/event severity values: critical, warning, info, all

unifi__health__get_firmware_status(site_id?) -> [{device_id, model, current_version, latest_version, upgrade_available, product_line}] API: GET api.ui.com/v1/devices (cloud-reported firmware state)

wifi

Wireless environment analysis. All tools are read-only.

Never trigger an active RF scan — passive data only.

unifi__wifi__get_wlans(site_id) -> [{wlan_id, name, ssid, security, band, vlan_id, enabled, client_count, satisfaction}] API: GET {local}/api/s/{site}/rest/wlanconf

unifi__wifi__get_aps(site_id) -> [{ap_id, name, mac, model, channel_2g?, channel_5g?, channel_6g?, tx_power_2g?, tx_power_5g?, client_count, satisfaction}] API: GET {local}/api/s/{site}/stat/device (filtered to APs)

unifi__wifi__get_channel_utilization(ap_id) -> {ap_id, radio_2g?: {channel, utilization_pct, interference_pct}, radio_5g?: {channel, utilization_pct, interference_pct}, radio_6g?: {channel, utilization_pct, interference_pct}} API: GET {local}/api/s/{site}/stat/device/{mac} (radio_table field)

unifi__wifi__get_rf_scan(ap_id) -> [{ssid, bssid, channel, band, rssi, security, is_own}] API: GET {local}/api/s/{site}/stat/rogueap Note: Returns cached scan data. Does not trigger a new scan.

unifi__wifi__get_roaming_events(site_id, hours?=24) -> [{timestamp, client_mac, from_ap_id, to_ap_id, rssi_before, rssi_after, roam_reason}] API: GET {local}/api/s/{site}/stat/event (filtered to roam events)

unifi__wifi__get_client_rf(client_mac, site_id) -> {client_mac, ap_id, ssid, rssi, noise, snr, tx_rate_mbps, rx_rate_mbps, tx_retries_pct, channel, band} API: GET {local}/api/s/{site}/stat/sta/{mac}

clients

Connected client inventory and profiling.

unifi__clients__list_clients(site_id, vlan_id?) -> [{client_mac, hostname?, ip, vlan_id, ap_id?, port_id?, connection_type, is_wired, is_guest, uptime}] API: GET {local}/api/s/{site}/stat/sta

unifi__clients__get_client(client_mac, site_id) -> {client_mac, hostname, ip, vlan_id, ap_id, ssid?, rssi?, tx_bytes, rx_bytes, uptime, first_seen, last_seen, os_name?, device_vendor?, is_blocked} API: GET {local}/api/s/{site}/stat/sta/{mac}

unifi__clients__get_client_traffic(client_mac, site_id) -> {client_mac, tx_bytes, rx_bytes, tx_packets, rx_packets, dpi?: [{application, category, tx_bytes, rx_bytes}]} API: GET {local}/api/s/{site}/stat/user/{mac}

unifi__clients__search_clients(query, site_id?) -> [{client_mac, hostname, ip, vlan_id, connection_type, site_id}] query: any of mac, hostname, IP address, or alias (partial match) API: GET {local}/api/s/{site}/stat/sta (client-side filter)

traffic

unifi__traffic__get_bandwidth(site_id, hours?=24) -> {wan: {rx_mbps, tx_mbps, history[]}, lan: {rx_mbps, tx_mbps}} unifi__traffic__get_dpi_stats(site_id) -> [{application, category, tx_bytes, rx_bytes, session_count}] unifi__traffic__get_port_stats(device_id) -> [{port_idx, name, tx_bytes, rx_bytes, tx_errors, rx_errors, is_uplink, poe_power_w?}] unifi__traffic__get_wan_usage(site_id, days?=30) -> [{date, download_gb, upload_gb}]

security

unifi__security__get_firewall_rules(site_id) -> [{rule_id, name, action, enabled, src, dst, protocol, position}] unifi__security__get_zbf_policies(site_id) -> [{policy_id, from_zone, to_zone, action, match_all}] unifi__security__get_acls(site_id) -> [{acl_id, name, entries[], applied_to[]}] unifi__security__get_port_forwards(site_id) -> [{rule_id, name, proto, wan_port, lan_host, lan_port, enabled}] unifi__security__get_ids_alerts(site_id, hours?=24) -> [{timestamp, signature, severity, src_ip, dst_ip, action_taken}]

config

unifi__config__get_config_snapshot(site_id) -> {site_id, timestamp, network_count, wlan_count, rule_count, raw_config: {networks[], wlans[], firewall_rules[], ...}} unifi__config__diff_baseline(site_id, baseline_id) -> {added[], removed[], modified[]} # structural diff vs stored baseline unifi__config__get_backup_state(site_id) -> {last_backup_time, backup_type, size_mb, cloud_enabled} unifi__config__save_baseline(site_id) # WRITE — requires UNIFI_WRITE_ENABLED -> {baseline_id, timestamp} unifi__config__create_port_profile(name, native_vlan, tagged_vlans[], poe?) # WRITE Creates a named switch port profile. -> {profile_id, name} API: POST /api/s/{site}/rest/portconf

unifi__topology__assign_port_profile(device_id, port_idx, profile_name) # WRITE Assigns a named port profile to a specific switch port. OutageRiskAgent assesses whether port carries operator session. -> {device_id, port_idx, profile_applied} API: PUT /api/s/{site}/rest/device/{device_id} (port_overrides)

multisite (Site Manager EA API only)

unifi__multisite__list_all_sites(include_health?=true) -> [{site_id, name, device_count, client_count, health_status}] unifi__multisite__get_site_health(site_id) -> {site_id, wan_status, device_count, offline_count, alert_count} unifi__multisite__compare_sites(site_ids[], metrics[]) -> {site_id: {metric: value}, ...} unifi__multisite__search_across_sites(query, resource_type?="all") -> [{site_id, resource_type, resource_id, match_field, match_value}] unifi__topology__assign_port_profile(device_id, port_idx, profile_name) # WRITE Assigns a named port profile to a specific switch port. OutageRiskAgent assesses whether port carries operator session. -> {device_id, port_idx, profile_applied} API: PUT /api/s/{site}/rest/device/{device_id} (port_overrides) Use get_device first to identify port_idx from port description.

unifi__multisite__get_vantage_points(site_id) -> [{location, latency_ms, packet_loss_pct, jitter_ms, measured_at}]

Commands

unifi scan [site?]

Intent: Discover the full network topology for one or all accessible sites. Calls: topology.list_sites -> topology.list_hosts -> topology.list_devices -> topology.get_vlans -> topology.get_uplinks Behavior: If no site is specified, list all sites and ask the operator to select one, or run a fleet-level summary if multisite skill is available. Never assume which site to use when multiple exist.

unifi health [site?] [device?]

Intent: Tiered health report — Critical / Warning / Informational. Calls: health.get_site_health -> health.get_device_health (all devices) -> health.get_isp_metrics -> health.get_firmware_status -> health.get_events(hours=24) Output: Summary table of findings by severity. Never bury Critical findings.

unifi diagnose [target]

Intent: Root-cause analysis for a device (by ID/name/IP) or client (by MAC/hostname/IP/alias). Calls: topology.get_device OR clients.get_client -> health.get_device_health -> health.get_events -> wifi.get_client_rf (if wireless) -> clients.get_client_traffic -> security.get_firewall_rules Output: Ranked findings with probable causes and remediation steps.

unifi wifi [site?] [ssid?]

Intent: Analyze the wireless RF environment. Calls: wifi.get_wlans -> wifi.get_aps -> wifi.get_channel_utilization (all APs) -> wifi.get_rf_scan (all APs) -> wifi.get_roaming_events Output: Per-AP channel summary, neighboring SSID interference, roaming stats.

unifi optimize [site?] [--apply]

Intent: Generate prioritized improvement recommendations. With --apply, follow the three-phase confirmation model before making any changes. Read phase: Calls wifi, traffic, security, config skills. Write gate: UNIFI_WRITE_ENABLED must be true and --apply must be present. Without these, produce the recommendation plan only (no writes).

unifi clients [site?] [--vlan <id>] [--ap <id>]

Intent: Inventory all connected clients, optionally filtered. Calls: clients.list_clients -> clients.get_client_traffic (top-N only)

unifi secure [site?]

Intent: Security posture audit. Read-only. Calls: security.get_firewall_rules -> security.get_zbf_policies -> security.get_acls -> security.get_port_forwards -> security.get_ids_alerts -> wifi.get_rf_scan (rogue AP detection) Output: Risk-ranked findings with severity and remediation guidance.

unifi compare <site1> <site2>

Intent: Side-by-side comparison of two sites. Calls: multisite.compare_sites -> multisite.get_site_health (both) -> health.get_firmware_status (both)

unifi config [site?] [--drift]

Intent: Review config state. With --drift, diff against stored baseline. Calls: config.get_config_snapshot -> [config.diff_baseline if --drift] -> config.get_backup_state Write (--save): config.save_baseline — requires UNIFI_WRITE_ENABLED.

unifi port-profile create <n> [--native <vlan>] [--tagged <vlans>]

                           [--poe] [--apply]

Intent: Create a named switch port profile in UniFi. Calls: topology.get_vlans (verify named VLANs exist) -> config.create_port_profile -> confirm Example: unifi port-profile create Trunk-AP --native 10 --tagged 30,50,60

unifi port-profile assign <switch> <port> <profile> [--apply]

Intent: Assign a named profile to a specific port on a UniFi switch. Phase 1: topology.get_device(switch) to identify port from description/index. OutageRiskAgent: assess if port carries operator management session. Phase 2: present plan showing current profile -> new profile for that port. Write: topology.assign_port_profile -> confirm. CAUTION: Never assign to the port connected to OPNsense until all VLAN configuration on OPNsense is complete and verified.

Examples

Basic: First-time scan of a single-site deployment

User: "Scan my UniFi network" -> call unifi__topology__list_sites() -> if one site: proceed directly -> if multiple: AskUserQuestion "Which site would you like to scan?" -> call list_devices, get_vlans, get_uplinks -> present: device count by type, VLAN summary, uplink graph, offline devices

Basic: Morning health check

User: "Quick health check" -> call get_site_health, get_firmware_status, get_events(hours=12) -> if no critical findings: "All clear — N devices online, no alerts." -> if findings: present by severity, Critical first

Advanced: Diagnose a client complaint

User: "Sarah's laptop can't reach the file server" -> search_clients("Sarah") or ask for MAC/hostname if ambiguous -> get_client -> get_client_rf -> get_client_traffic -> get_firewall_rules (check VLAN isolation) -> present: signal quality, VLAN membership, firewall rules affecting path

Write: Apply optimization (with UNIFI_WRITE_ENABLED=true)

User: "Optimize the office WiFi and apply changes" -> Phase 1: gather wifi + traffic data, resolve any ambiguities -> Phase 2: present full recommendation plan -> Phase 3: AskUserQuestion "3 changes planned. Confirm to proceed?" -> on confirm: execute each write, report result

04 同仓库更多 Skills

bluminal
bluminal/emberai

talos

Talos Linux Kubernetes cluster intelligence plugin for EmberAI. Provides cluster lifecycle management, node health monitoring, etcd cluster operations, Kubernetes component status, diagnostics, configuration management, security auditing, and image management via talosctl CLI with gRPC + mTLS transport.

运维与部署图像与多媒体
★ 1
bluminal
bluminal/emberai

opnsense

OPNsense gateway intelligence plugin for EmberAI. Provides interface and VLAN management, firewall rule analysis, static routing, VPN tunnel status and configuration, DNS (Unbound), DHCP (Kea), IDS/IPS (Suricata), traffic shaping, live diagnostics, and firmware management via the OPNsense REST API.

★ 1
bluminal
bluminal/emberai

nextdns

NextDNS intelligence plugin for EmberAI. Provides DNS profile management, security posture auditing, analytics dashboards, query log analysis, and parental control configuration across NextDNS profiles.

数据分析师分析与可视化
★ 1
bluminal
bluminal/emberai

netex

Cross-vendor network orchestration umbrella for EmberAI. Coordinates installed vendor plugins (unifi, opnsense, and future vendors) to perform operations that span multiple network systems. Provides unified topology, health, VLAN provisioning, cross-vendor security audits, and policy synchronization. Requires at least one conforming vendor plugin.

★ 1
bluminal
bluminal/emberai

cisco

Cisco SG-300 managed switch intelligence plugin for EmberAI. Provides VLAN management, port configuration, MAC address table lookup, LLDP topology discovery, interface counters (SNMP), configuration drift detection, and health monitoring via SSH CLI (Netmiko) and SNMPv2c.

★ 1