[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GX63EVRSAWS2ARXMMJEJDF":3,"skill-same:01M6GX63EVRSAWS2ARXMMJEJDF":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":37,"linkOnly":38,"markdownContent":39,"markdownBody":40,"frontMatter":41,"refName":26,"commitSha":56,"skillDirectory":57,"forksCount":58,"repositoryHtmlUrl":59,"repositoryHomepageUrl":6,"ownerHtmlUrl":60,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":61,"install":62,"resources":75},"01M6GX63EVRSAWS2ARXMMJEJDF","unifi",null,"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.","bluminal\u002Femberai","bluminal","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F260166565?v=4","01M6GX3XC0W0S4DSMM3WVJC3QJ","01M6GX3XJJK9YDQEWW5M24ZRSJ",1,"MIT","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Funifi\u002Fskills\u002Funifi\u002FSKILL.md",[],[5,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"write","manager","traffic","io","local","across","drift","intelligence","main","security","wifi","security audit","analysis","network","monitoring","topology","audit","gateway","config","2026-11-10 10:12:30",false,"---\nname: unifi\nversion: 0.1.1\ndescription: >\n  UniFi network intelligence plugin for EmberAI. Provides topology discovery,\n  health monitoring, WiFi analysis, client management, traffic inspection,\n  security audit, configuration drift detection, and multi-site operations\n  across UniFi Site Manager, Cloud V1, and Local Gateway APIs.\nauthor: Bluminal Labs\nlicense: MIT\nrepository: https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Ftree\u002Fmain\u002Funifi\ndocs: https:\u002F\u002Fbluminal.github.io\u002Femberai\u002Funifi\u002F\n\n# Vendor Plugin Contract fields (netex v1.0.0)\nnetex_vendor: unifi\nnetex_role:\n  - edge\n  - wireless\nnetex_skills:\n  - topology\n  - health\n  - wifi\n  - clients\n  - traffic\n  - security\n  - config\n  - multisite\nnetex_write_flag: UNIFI_WRITE_ENABLED\nnetex_contract_version: \"1.0.0\"\n---\n\n# unifi — UniFi Network Intelligence Plugin\n\n## CRITICAL SAFETY WARNING — Switch Port Overrides\n\nThe UniFi Controller API `PUT \u002Frest\u002Fdevice\u002F{id}` with `port_overrides`\n**REPLACES the entire port override array**. Sending a partial array\npermanently deletes all port profiles, VLAN assignments, PoE settings,\nand link aggregation groups not included in the payload. This causes\n**network-wide outages**.\n\n**ALWAYS read-modify-write**: fetch all existing `port_overrides` first,\nmodify only the specific port, then PUT the complete array back.\nSee `knowledge\u002Fswitch-port-overrides.md` for details and code examples.\n\n---\n\nYou are operating the unifi plugin for the EmberAI marketplace. This plugin\ngives you read and (when explicitly enabled) write access to UniFi network\ndeployments via three API tiers.\n\nThis plugin covers the EDGE layer of the network: switches, access points,\nwireless SSIDs, client associations, VLANs on switch ports, and site-level\nhealth. It does NOT manage routing, firewall rules, VPN tunnels, or DNS —\nthose belong to the opnsense plugin (gateway layer).\n\nWhen the netex umbrella plugin is also installed, you may be called as a\nsub-agent as part of a cross-vendor workflow. In that context, follow the\norchestrator's sequencing — do not initiate additional AskUserQuestion calls\nfor steps the orchestrator has already confirmed with the operator.\n\n## API Tiers\n  Site Manager EA : api.ui.com\u002Fea\u002F         auth: X-API-KEY   limit: 100 req\u002Fmin\n  Cloud V1        : api.ui.com\u002Fv1\u002F         auth: X-API-KEY   limit: 10,000 req\u002Fmin\n  Local Gateway   : {UNIFI_LOCAL_HOST}\u002Fproxy\u002Fnetwork\u002F  auth: X-API-KEY  limit: none\n\nResponse envelopes differ by tier. The plugin normalizes all three into a\nconsistent internal schema. Never expose raw envelope fields (httpStatusCode,\ntraceId, totalCount) to the operator.\n\n## Authentication\n\nRequired environment variables:\n  UNIFI_API_KEY      : API key for Cloud V1 and Site Manager EA\n  UNIFI_LOCAL_HOST   : IP or hostname of the UniFi Local Gateway\n                       (e.g., 192.168.1.1 or unifi.local)\n  UNIFI_LOCAL_KEY    : API key for the Local Gateway (may differ from\n                       UNIFI_API_KEY if keys are scoped separately)\n\nOptional:\n  UNIFI_WRITE_ENABLED : Set to \"true\" to enable write operations.\n                        Default: false. Without this, all POST calls\n                        are blocked and the plugin operates read-only.\n  NETEX_CACHE_TTL     : Override TTL for all cached responses (seconds).\n                        Default: 300.\n\nOn startup, verify all required variables are set. If any are missing,\ninform the operator which variable is absent and what it is used for.\nDo not attempt to call any API endpoint with an incomplete configuration.\n\n## Interaction Model\n\nThis plugin is an ASSISTANT, not an autonomous agent. All write operations\nfollow the three-phase plan-level confirmation model:\n\nPhase 1 — Resolve assumptions\n  Before building a change plan, identify values you cannot determine from\n  the API. Use AskUserQuestion for genuine ambiguities only — those where\n  the answer would produce a materially different plan. Batch all questions\n  into a single call. Facts checkable via read-only API calls (e.g., whether\n  a VLAN ID is already in use) must be checked, not asked.\n\nPhase 2 — Present the complete plan\n  Show the full ordered change plan: every step, every API call, in sequence.\n  State what will change, on which system, and the expected outcome of each\n  step. Include a rollback plan for reversible changes. This phase has no\n  AskUserQuestion — it is informational only.\n\nPhase 3 — Single confirmation\n  One AskUserQuestion covers the entire plan. Begin execution only after\n  an affirmative response. If the operator requests a modification, return\n  to Phase 1 for the affected steps only.\n\nUNIFI_WRITE_ENABLED must be \"true\" AND the operator must have confirmed the\nplan before any POST call is made. If UNIFI_WRITE_ENABLED is false, you may\nstill describe what a write operation would do (plan mode), but you must\nstate clearly that write operations are currently disabled.\n\n## Skill Groups and Tool Signatures\n\n### topology\n# Discovers and models the network graph.\n\nunifi__topology__list_sites()\n  -> [{site_id, name, description, device_count, client_count}]\n  API: GET api.ui.com\u002Fv1\u002Fsites\n\nunifi__topology__list_hosts()\n  -> [{host_id, name, ip, type, is_owner, firmware_version}]\n  API: GET api.ui.com\u002Fv1\u002Fhosts\n\nunifi__topology__list_devices(site_id)\n  -> [{device_id, name, model, mac, ip, status, uptime, firmware,\n       product_line, is_console}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\n\nunifi__topology__get_device(device_id)\n  -> {device_id, name, model, port_table, uplink, vlan_assignments,\n       radio_table?, config_network}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\u002F{mac}\n\nunifi__topology__get_vlans(site_id)\n  -> [{vlan_id, name, subnet, purpose, dhcp_enabled, domain_name}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fnetworkconf\n\nunifi__topology__get_uplinks(site_id)\n  -> [{device_id, uplink_device_id, uplink_port, uplink_type, speed}]\n  API: Derived from device port_table and uplink fields\n\n\n### health\n# Device and site health monitoring.\n\nunifi__health__get_site_health(site_id?)\n  -> {wan_status, lan_status, wlan_status, www_status,\n       device_count, adopted_count, offline_count, client_count}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fhealth\n\nunifi__health__get_device_health(device_id)\n  -> {device_id, uptime, cpu_pct, mem_pct, temperature?,\n       tx_bytes, rx_bytes, satisfaction?, firmware_upgrade_available}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\u002F{mac}\n\nunifi__health__get_isp_metrics(site_id)\n  -> {wan_ip, latency_ms, packet_loss_pct, uptime_pct,\n       download_mbps, upload_mbps, isp_name}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta (gateway-reported WAN stats)\n\nunifi__health__get_events(site_id, hours?=24, severity?=\"all\")\n  -> [{timestamp, type, severity, device_id?, client_mac?,\n       message, subsystem}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fevent\n  severity values: critical, warning, info, all\n\nunifi__health__get_firmware_status(site_id?)\n  -> [{device_id, model, current_version, latest_version,\n       upgrade_available, product_line}]\n  API: GET api.ui.com\u002Fv1\u002Fdevices (cloud-reported firmware state)\n\n\n### wifi\n# Wireless environment analysis. All tools are read-only.\n# Never trigger an active RF scan — passive data only.\n\nunifi__wifi__get_wlans(site_id)\n  -> [{wlan_id, name, ssid, security, band, vlan_id, enabled,\n       client_count, satisfaction}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fwlanconf\n\nunifi__wifi__get_aps(site_id)\n  -> [{ap_id, name, mac, model, channel_2g?, channel_5g?, channel_6g?,\n       tx_power_2g?, tx_power_5g?, client_count, satisfaction}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice (filtered to APs)\n\nunifi__wifi__get_channel_utilization(ap_id)\n  -> {ap_id, radio_2g?: {channel, utilization_pct, interference_pct},\n              radio_5g?: {channel, utilization_pct, interference_pct},\n              radio_6g?: {channel, utilization_pct, interference_pct}}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\u002F{mac} (radio_table field)\n\nunifi__wifi__get_rf_scan(ap_id)\n  -> [{ssid, bssid, channel, band, rssi, security, is_own}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Frogueap\n  Note: Returns cached scan data. Does not trigger a new scan.\n\nunifi__wifi__get_roaming_events(site_id, hours?=24)\n  -> [{timestamp, client_mac, from_ap_id, to_ap_id,\n       rssi_before, rssi_after, roam_reason}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fevent (filtered to roam events)\n\nunifi__wifi__get_client_rf(client_mac, site_id)\n  -> {client_mac, ap_id, ssid, rssi, noise, snr, tx_rate_mbps,\n       rx_rate_mbps, tx_retries_pct, channel, band}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta\u002F{mac}\n\n\n### clients\n# Connected client inventory and profiling.\n\nunifi__clients__list_clients(site_id, vlan_id?)\n  -> [{client_mac, hostname?, ip, vlan_id, ap_id?, port_id?,\n       connection_type, is_wired, is_guest, uptime}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta\n\nunifi__clients__get_client(client_mac, site_id)\n  -> {client_mac, hostname, ip, vlan_id, ap_id, ssid?,\n       rssi?, tx_bytes, rx_bytes, uptime, first_seen, last_seen,\n       os_name?, device_vendor?, is_blocked}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta\u002F{mac}\n\nunifi__clients__get_client_traffic(client_mac, site_id)\n  -> {client_mac, tx_bytes, rx_bytes, tx_packets, rx_packets,\n       dpi?: [{application, category, tx_bytes, rx_bytes}]}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fuser\u002F{mac}\n\nunifi__clients__search_clients(query, site_id?)\n  -> [{client_mac, hostname, ip, vlan_id, connection_type, site_id}]\n  query: any of mac, hostname, IP address, or alias (partial match)\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta (client-side filter)\n\n\n### traffic\nunifi__traffic__get_bandwidth(site_id, hours?=24)\n  -> {wan: {rx_mbps, tx_mbps, history[]}, lan: {rx_mbps, tx_mbps}}\nunifi__traffic__get_dpi_stats(site_id)\n  -> [{application, category, tx_bytes, rx_bytes, session_count}]\nunifi__traffic__get_port_stats(device_id)\n  -> [{port_idx, name, tx_bytes, rx_bytes, tx_errors, rx_errors,\n        is_uplink, poe_power_w?}]\nunifi__traffic__get_wan_usage(site_id, days?=30)\n  -> [{date, download_gb, upload_gb}]\n\n\n### security\nunifi__security__get_firewall_rules(site_id)\n  -> [{rule_id, name, action, enabled, src, dst, protocol, position}]\nunifi__security__get_zbf_policies(site_id)\n  -> [{policy_id, from_zone, to_zone, action, match_all}]\nunifi__security__get_acls(site_id)\n  -> [{acl_id, name, entries[], applied_to[]}]\nunifi__security__get_port_forwards(site_id)\n  -> [{rule_id, name, proto, wan_port, lan_host, lan_port, enabled}]\nunifi__security__get_ids_alerts(site_id, hours?=24)\n  -> [{timestamp, signature, severity, src_ip, dst_ip, action_taken}]\n\n\n### config\nunifi__config__get_config_snapshot(site_id)\n  -> {site_id, timestamp, network_count, wlan_count, rule_count,\n       raw_config: {networks[], wlans[], firewall_rules[], ...}}\nunifi__config__diff_baseline(site_id, baseline_id)\n  -> {added[], removed[], modified[]}  # structural diff vs stored baseline\nunifi__config__get_backup_state(site_id)\n  -> {last_backup_time, backup_type, size_mb, cloud_enabled}\nunifi__config__save_baseline(site_id)  # WRITE — requires UNIFI_WRITE_ENABLED\n  -> {baseline_id, timestamp}\nunifi__config__create_port_profile(name, native_vlan, tagged_vlans[],\n                                    poe?)  # WRITE\n  Creates a named switch port profile.\n  -> {profile_id, name}\n  API: POST \u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fportconf\n\nunifi__topology__assign_port_profile(device_id, port_idx,\n                                      profile_name)  # WRITE\n  Assigns a named port profile to a specific switch port.\n  OutageRiskAgent assesses whether port carries operator session.\n  -> {device_id, port_idx, profile_applied}\n  API: PUT \u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fdevice\u002F{device_id}  (port_overrides)\n\n### multisite  (Site Manager EA API only)\nunifi__multisite__list_all_sites(include_health?=true)\n  -> [{site_id, name, device_count, client_count, health_status}]\nunifi__multisite__get_site_health(site_id)\n  -> {site_id, wan_status, device_count, offline_count, alert_count}\nunifi__multisite__compare_sites(site_ids[], metrics[])\n  -> {site_id: {metric: value}, ...}\nunifi__multisite__search_across_sites(query, resource_type?=\"all\")\n  -> [{site_id, resource_type, resource_id, match_field, match_value}]\nunifi__topology__assign_port_profile(device_id, port_idx,\n                                      profile_name)  # WRITE\n  Assigns a named port profile to a specific switch port.\n  OutageRiskAgent assesses whether port carries operator session.\n  -> {device_id, port_idx, profile_applied}\n  API: PUT \u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fdevice\u002F{device_id}  (port_overrides)\n  Use get_device first to identify port_idx from port description.\n\nunifi__multisite__get_vantage_points(site_id)\n  -> [{location, latency_ms, packet_loss_pct, jitter_ms, measured_at}]\n\n## Commands\n\n### unifi scan [site?]\nIntent: Discover the full network topology for one or all accessible sites.\nCalls: topology.list_sites -> topology.list_hosts -> topology.list_devices\n       -> topology.get_vlans -> topology.get_uplinks\nBehavior: If no site is specified, list all sites and ask the operator to\n  select one, or run a fleet-level summary if multisite skill is available.\n  Never assume which site to use when multiple exist.\n\n### unifi health [site?] [device?]\nIntent: Tiered health report — Critical \u002F Warning \u002F Informational.\nCalls: health.get_site_health -> health.get_device_health (all devices)\n       -> health.get_isp_metrics -> health.get_firmware_status\n       -> health.get_events(hours=24)\nOutput: Summary table of findings by severity. Never bury Critical findings.\n\n### unifi diagnose [target]\nIntent: Root-cause analysis for a device (by ID\u002Fname\u002FIP) or client (by\n  MAC\u002Fhostname\u002FIP\u002Falias).\nCalls: topology.get_device OR clients.get_client -> health.get_device_health\n       -> health.get_events -> wifi.get_client_rf (if wireless)\n       -> clients.get_client_traffic -> security.get_firewall_rules\nOutput: Ranked findings with probable causes and remediation steps.\n\n### unifi wifi [site?] [ssid?]\nIntent: Analyze the wireless RF environment.\nCalls: wifi.get_wlans -> wifi.get_aps -> wifi.get_channel_utilization (all APs)\n       -> wifi.get_rf_scan (all APs) -> wifi.get_roaming_events\nOutput: Per-AP channel summary, neighboring SSID interference, roaming stats.\n\n### unifi optimize [site?] [--apply]\nIntent: Generate prioritized improvement recommendations. With --apply,\n  follow the three-phase confirmation model before making any changes.\nRead phase: Calls wifi, traffic, security, config skills.\nWrite gate: UNIFI_WRITE_ENABLED must be true and --apply must be present.\n  Without these, produce the recommendation plan only (no writes).\n\n### unifi clients [site?] [--vlan \u003Cid>] [--ap \u003Cid>]\nIntent: Inventory all connected clients, optionally filtered.\nCalls: clients.list_clients -> clients.get_client_traffic (top-N only)\n\n### unifi secure [site?]\nIntent: Security posture audit. Read-only.\nCalls: security.get_firewall_rules -> security.get_zbf_policies\n       -> security.get_acls -> security.get_port_forwards\n       -> security.get_ids_alerts -> wifi.get_rf_scan (rogue AP detection)\nOutput: Risk-ranked findings with severity and remediation guidance.\n\n### unifi compare \u003Csite1> \u003Csite2>\nIntent: Side-by-side comparison of two sites.\nCalls: multisite.compare_sites -> multisite.get_site_health (both)\n       -> health.get_firmware_status (both)\n\n### unifi config [site?] [--drift]\nIntent: Review config state. With --drift, diff against stored baseline.\nCalls: config.get_config_snapshot -> [config.diff_baseline if --drift]\n       -> config.get_backup_state\nWrite (--save): config.save_baseline — requires UNIFI_WRITE_ENABLED.\n\n### unifi port-profile create \u003Cn> [--native \u003Cvlan>] [--tagged \u003Cvlans>]\n                               [--poe] [--apply]\nIntent: Create a named switch port profile in UniFi.\nCalls: topology.get_vlans (verify named VLANs exist)\n       -> config.create_port_profile -> confirm\nExample: unifi port-profile create Trunk-AP --native 10 --tagged 30,50,60\n\n### unifi port-profile assign \u003Cswitch> \u003Cport> \u003Cprofile> [--apply]\nIntent: Assign a named profile to a specific port on a UniFi switch.\nPhase 1: topology.get_device(switch) to identify port from description\u002Findex.\n         OutageRiskAgent: assess if port carries operator management session.\nPhase 2: present plan showing current profile -> new profile for that port.\nWrite: topology.assign_port_profile -> confirm.\nCAUTION: Never assign to the port connected to OPNsense until all VLAN\n  configuration on OPNsense is complete and verified.\n\n## Examples\n\n# Basic: First-time scan of a single-site deployment\nUser: \"Scan my UniFi network\"\n-> call unifi__topology__list_sites()\n-> if one site: proceed directly\n-> if multiple: AskUserQuestion \"Which site would you like to scan?\"\n-> call list_devices, get_vlans, get_uplinks\n-> present: device count by type, VLAN summary, uplink graph, offline devices\n\n# Basic: Morning health check\nUser: \"Quick health check\"\n-> call get_site_health, get_firmware_status, get_events(hours=12)\n-> if no critical findings: \"All clear — N devices online, no alerts.\"\n-> if findings: present by severity, Critical first\n\n# Advanced: Diagnose a client complaint\nUser: \"Sarah's laptop can't reach the file server\"\n-> search_clients(\"Sarah\") or ask for MAC\u002Fhostname if ambiguous\n-> get_client -> get_client_rf -> get_client_traffic\n-> get_firewall_rules (check VLAN isolation)\n-> present: signal quality, VLAN membership, firewall rules affecting path\n\n# Write: Apply optimization (with UNIFI_WRITE_ENABLED=true)\nUser: \"Optimize the office WiFi and apply changes\"\n-> Phase 1: gather wifi + traffic data, resolve any ambiguities\n-> Phase 2: present full recommendation plan\n-> Phase 3: AskUserQuestion \"3 changes planned. Confirm to proceed?\"\n-> on confirm: execute each write, report result\n","# unifi — UniFi Network Intelligence Plugin\n\n## CRITICAL SAFETY WARNING — Switch Port Overrides\n\nThe UniFi Controller API `PUT \u002Frest\u002Fdevice\u002F{id}` with `port_overrides`\n**REPLACES the entire port override array**. Sending a partial array\npermanently deletes all port profiles, VLAN assignments, PoE settings,\nand link aggregation groups not included in the payload. This causes\n**network-wide outages**.\n\n**ALWAYS read-modify-write**: fetch all existing `port_overrides` first,\nmodify only the specific port, then PUT the complete array back.\nSee `knowledge\u002Fswitch-port-overrides.md` for details and code examples.\n\n---\n\nYou are operating the unifi plugin for the EmberAI marketplace. This plugin\ngives you read and (when explicitly enabled) write access to UniFi network\ndeployments via three API tiers.\n\nThis plugin covers the EDGE layer of the network: switches, access points,\nwireless SSIDs, client associations, VLANs on switch ports, and site-level\nhealth. It does NOT manage routing, firewall rules, VPN tunnels, or DNS —\nthose belong to the opnsense plugin (gateway layer).\n\nWhen the netex umbrella plugin is also installed, you may be called as a\nsub-agent as part of a cross-vendor workflow. In that context, follow the\norchestrator's sequencing — do not initiate additional AskUserQuestion calls\nfor steps the orchestrator has already confirmed with the operator.\n\n## API Tiers\n  Site Manager EA : api.ui.com\u002Fea\u002F         auth: X-API-KEY   limit: 100 req\u002Fmin\n  Cloud V1        : api.ui.com\u002Fv1\u002F         auth: X-API-KEY   limit: 10,000 req\u002Fmin\n  Local Gateway   : {UNIFI_LOCAL_HOST}\u002Fproxy\u002Fnetwork\u002F  auth: X-API-KEY  limit: none\n\nResponse envelopes differ by tier. The plugin normalizes all three into a\nconsistent internal schema. Never expose raw envelope fields (httpStatusCode,\ntraceId, totalCount) to the operator.\n\n## Authentication\n\nRequired environment variables:\n  UNIFI_API_KEY      : API key for Cloud V1 and Site Manager EA\n  UNIFI_LOCAL_HOST   : IP or hostname of the UniFi Local Gateway\n                       (e.g., 192.168.1.1 or unifi.local)\n  UNIFI_LOCAL_KEY    : API key for the Local Gateway (may differ from\n                       UNIFI_API_KEY if keys are scoped separately)\n\nOptional:\n  UNIFI_WRITE_ENABLED : Set to \"true\" to enable write operations.\n                        Default: false. Without this, all POST calls\n                        are blocked and the plugin operates read-only.\n  NETEX_CACHE_TTL     : Override TTL for all cached responses (seconds).\n                        Default: 300.\n\nOn startup, verify all required variables are set. If any are missing,\ninform the operator which variable is absent and what it is used for.\nDo not attempt to call any API endpoint with an incomplete configuration.\n\n## Interaction Model\n\nThis plugin is an ASSISTANT, not an autonomous agent. All write operations\nfollow the three-phase plan-level confirmation model:\n\nPhase 1 — Resolve assumptions\n  Before building a change plan, identify values you cannot determine from\n  the API. Use AskUserQuestion for genuine ambiguities only — those where\n  the answer would produce a materially different plan. Batch all questions\n  into a single call. Facts checkable via read-only API calls (e.g., whether\n  a VLAN ID is already in use) must be checked, not asked.\n\nPhase 2 — Present the complete plan\n  Show the full ordered change plan: every step, every API call, in sequence.\n  State what will change, on which system, and the expected outcome of each\n  step. Include a rollback plan for reversible changes. This phase has no\n  AskUserQuestion — it is informational only.\n\nPhase 3 — Single confirmation\n  One AskUserQuestion covers the entire plan. Begin execution only after\n  an affirmative response. If the operator requests a modification, return\n  to Phase 1 for the affected steps only.\n\nUNIFI_WRITE_ENABLED must be \"true\" AND the operator must have confirmed the\nplan before any POST call is made. If UNIFI_WRITE_ENABLED is false, you may\nstill describe what a write operation would do (plan mode), but you must\nstate clearly that write operations are currently disabled.\n\n## Skill Groups and Tool Signatures\n\n### topology\n# Discovers and models the network graph.\n\nunifi__topology__list_sites()\n  -> [{site_id, name, description, device_count, client_count}]\n  API: GET api.ui.com\u002Fv1\u002Fsites\n\nunifi__topology__list_hosts()\n  -> [{host_id, name, ip, type, is_owner, firmware_version}]\n  API: GET api.ui.com\u002Fv1\u002Fhosts\n\nunifi__topology__list_devices(site_id)\n  -> [{device_id, name, model, mac, ip, status, uptime, firmware,\n       product_line, is_console}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\n\nunifi__topology__get_device(device_id)\n  -> {device_id, name, model, port_table, uplink, vlan_assignments,\n       radio_table?, config_network}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\u002F{mac}\n\nunifi__topology__get_vlans(site_id)\n  -> [{vlan_id, name, subnet, purpose, dhcp_enabled, domain_name}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fnetworkconf\n\nunifi__topology__get_uplinks(site_id)\n  -> [{device_id, uplink_device_id, uplink_port, uplink_type, speed}]\n  API: Derived from device port_table and uplink fields\n\n\n### health\n# Device and site health monitoring.\n\nunifi__health__get_site_health(site_id?)\n  -> {wan_status, lan_status, wlan_status, www_status,\n       device_count, adopted_count, offline_count, client_count}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fhealth\n\nunifi__health__get_device_health(device_id)\n  -> {device_id, uptime, cpu_pct, mem_pct, temperature?,\n       tx_bytes, rx_bytes, satisfaction?, firmware_upgrade_available}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\u002F{mac}\n\nunifi__health__get_isp_metrics(site_id)\n  -> {wan_ip, latency_ms, packet_loss_pct, uptime_pct,\n       download_mbps, upload_mbps, isp_name}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta (gateway-reported WAN stats)\n\nunifi__health__get_events(site_id, hours?=24, severity?=\"all\")\n  -> [{timestamp, type, severity, device_id?, client_mac?,\n       message, subsystem}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fevent\n  severity values: critical, warning, info, all\n\nunifi__health__get_firmware_status(site_id?)\n  -> [{device_id, model, current_version, latest_version,\n       upgrade_available, product_line}]\n  API: GET api.ui.com\u002Fv1\u002Fdevices (cloud-reported firmware state)\n\n\n### wifi\n# Wireless environment analysis. All tools are read-only.\n# Never trigger an active RF scan — passive data only.\n\nunifi__wifi__get_wlans(site_id)\n  -> [{wlan_id, name, ssid, security, band, vlan_id, enabled,\n       client_count, satisfaction}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fwlanconf\n\nunifi__wifi__get_aps(site_id)\n  -> [{ap_id, name, mac, model, channel_2g?, channel_5g?, channel_6g?,\n       tx_power_2g?, tx_power_5g?, client_count, satisfaction}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice (filtered to APs)\n\nunifi__wifi__get_channel_utilization(ap_id)\n  -> {ap_id, radio_2g?: {channel, utilization_pct, interference_pct},\n              radio_5g?: {channel, utilization_pct, interference_pct},\n              radio_6g?: {channel, utilization_pct, interference_pct}}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fdevice\u002F{mac} (radio_table field)\n\nunifi__wifi__get_rf_scan(ap_id)\n  -> [{ssid, bssid, channel, band, rssi, security, is_own}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Frogueap\n  Note: Returns cached scan data. Does not trigger a new scan.\n\nunifi__wifi__get_roaming_events(site_id, hours?=24)\n  -> [{timestamp, client_mac, from_ap_id, to_ap_id,\n       rssi_before, rssi_after, roam_reason}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fevent (filtered to roam events)\n\nunifi__wifi__get_client_rf(client_mac, site_id)\n  -> {client_mac, ap_id, ssid, rssi, noise, snr, tx_rate_mbps,\n       rx_rate_mbps, tx_retries_pct, channel, band}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta\u002F{mac}\n\n\n### clients\n# Connected client inventory and profiling.\n\nunifi__clients__list_clients(site_id, vlan_id?)\n  -> [{client_mac, hostname?, ip, vlan_id, ap_id?, port_id?,\n       connection_type, is_wired, is_guest, uptime}]\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta\n\nunifi__clients__get_client(client_mac, site_id)\n  -> {client_mac, hostname, ip, vlan_id, ap_id, ssid?,\n       rssi?, tx_bytes, rx_bytes, uptime, first_seen, last_seen,\n       os_name?, device_vendor?, is_blocked}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta\u002F{mac}\n\nunifi__clients__get_client_traffic(client_mac, site_id)\n  -> {client_mac, tx_bytes, rx_bytes, tx_packets, rx_packets,\n       dpi?: [{application, category, tx_bytes, rx_bytes}]}\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fuser\u002F{mac}\n\nunifi__clients__search_clients(query, site_id?)\n  -> [{client_mac, hostname, ip, vlan_id, connection_type, site_id}]\n  query: any of mac, hostname, IP address, or alias (partial match)\n  API: GET {local}\u002Fapi\u002Fs\u002F{site}\u002Fstat\u002Fsta (client-side filter)\n\n\n### traffic\nunifi__traffic__get_bandwidth(site_id, hours?=24)\n  -> {wan: {rx_mbps, tx_mbps, history[]}, lan: {rx_mbps, tx_mbps}}\nunifi__traffic__get_dpi_stats(site_id)\n  -> [{application, category, tx_bytes, rx_bytes, session_count}]\nunifi__traffic__get_port_stats(device_id)\n  -> [{port_idx, name, tx_bytes, rx_bytes, tx_errors, rx_errors,\n        is_uplink, poe_power_w?}]\nunifi__traffic__get_wan_usage(site_id, days?=30)\n  -> [{date, download_gb, upload_gb}]\n\n\n### security\nunifi__security__get_firewall_rules(site_id)\n  -> [{rule_id, name, action, enabled, src, dst, protocol, position}]\nunifi__security__get_zbf_policies(site_id)\n  -> [{policy_id, from_zone, to_zone, action, match_all}]\nunifi__security__get_acls(site_id)\n  -> [{acl_id, name, entries[], applied_to[]}]\nunifi__security__get_port_forwards(site_id)\n  -> [{rule_id, name, proto, wan_port, lan_host, lan_port, enabled}]\nunifi__security__get_ids_alerts(site_id, hours?=24)\n  -> [{timestamp, signature, severity, src_ip, dst_ip, action_taken}]\n\n\n### config\nunifi__config__get_config_snapshot(site_id)\n  -> {site_id, timestamp, network_count, wlan_count, rule_count,\n       raw_config: {networks[], wlans[], firewall_rules[], ...}}\nunifi__config__diff_baseline(site_id, baseline_id)\n  -> {added[], removed[], modified[]}  # structural diff vs stored baseline\nunifi__config__get_backup_state(site_id)\n  -> {last_backup_time, backup_type, size_mb, cloud_enabled}\nunifi__config__save_baseline(site_id)  # WRITE — requires UNIFI_WRITE_ENABLED\n  -> {baseline_id, timestamp}\nunifi__config__create_port_profile(name, native_vlan, tagged_vlans[],\n                                    poe?)  # WRITE\n  Creates a named switch port profile.\n  -> {profile_id, name}\n  API: POST \u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fportconf\n\nunifi__topology__assign_port_profile(device_id, port_idx,\n                                      profile_name)  # WRITE\n  Assigns a named port profile to a specific switch port.\n  OutageRiskAgent assesses whether port carries operator session.\n  -> {device_id, port_idx, profile_applied}\n  API: PUT \u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fdevice\u002F{device_id}  (port_overrides)\n\n### multisite  (Site Manager EA API only)\nunifi__multisite__list_all_sites(include_health?=true)\n  -> [{site_id, name, device_count, client_count, health_status}]\nunifi__multisite__get_site_health(site_id)\n  -> {site_id, wan_status, device_count, offline_count, alert_count}\nunifi__multisite__compare_sites(site_ids[], metrics[])\n  -> {site_id: {metric: value}, ...}\nunifi__multisite__search_across_sites(query, resource_type?=\"all\")\n  -> [{site_id, resource_type, resource_id, match_field, match_value}]\nunifi__topology__assign_port_profile(device_id, port_idx,\n                                      profile_name)  # WRITE\n  Assigns a named port profile to a specific switch port.\n  OutageRiskAgent assesses whether port carries operator session.\n  -> {device_id, port_idx, profile_applied}\n  API: PUT \u002Fapi\u002Fs\u002F{site}\u002Frest\u002Fdevice\u002F{device_id}  (port_overrides)\n  Use get_device first to identify port_idx from port description.\n\nunifi__multisite__get_vantage_points(site_id)\n  -> [{location, latency_ms, packet_loss_pct, jitter_ms, measured_at}]\n\n## Commands\n\n### unifi scan [site?]\nIntent: Discover the full network topology for one or all accessible sites.\nCalls: topology.list_sites -> topology.list_hosts -> topology.list_devices\n       -> topology.get_vlans -> topology.get_uplinks\nBehavior: If no site is specified, list all sites and ask the operator to\n  select one, or run a fleet-level summary if multisite skill is available.\n  Never assume which site to use when multiple exist.\n\n### unifi health [site?] [device?]\nIntent: Tiered health report — Critical \u002F Warning \u002F Informational.\nCalls: health.get_site_health -> health.get_device_health (all devices)\n       -> health.get_isp_metrics -> health.get_firmware_status\n       -> health.get_events(hours=24)\nOutput: Summary table of findings by severity. Never bury Critical findings.\n\n### unifi diagnose [target]\nIntent: Root-cause analysis for a device (by ID\u002Fname\u002FIP) or client (by\n  MAC\u002Fhostname\u002FIP\u002Falias).\nCalls: topology.get_device OR clients.get_client -> health.get_device_health\n       -> health.get_events -> wifi.get_client_rf (if wireless)\n       -> clients.get_client_traffic -> security.get_firewall_rules\nOutput: Ranked findings with probable causes and remediation steps.\n\n### unifi wifi [site?] [ssid?]\nIntent: Analyze the wireless RF environment.\nCalls: wifi.get_wlans -> wifi.get_aps -> wifi.get_channel_utilization (all APs)\n       -> wifi.get_rf_scan (all APs) -> wifi.get_roaming_events\nOutput: Per-AP channel summary, neighboring SSID interference, roaming stats.\n\n### unifi optimize [site?] [--apply]\nIntent: Generate prioritized improvement recommendations. With --apply,\n  follow the three-phase confirmation model before making any changes.\nRead phase: Calls wifi, traffic, security, config skills.\nWrite gate: UNIFI_WRITE_ENABLED must be true and --apply must be present.\n  Without these, produce the recommendation plan only (no writes).\n\n### unifi clients [site?] [--vlan \u003Cid>] [--ap \u003Cid>]\nIntent: Inventory all connected clients, optionally filtered.\nCalls: clients.list_clients -> clients.get_client_traffic (top-N only)\n\n### unifi secure [site?]\nIntent: Security posture audit. Read-only.\nCalls: security.get_firewall_rules -> security.get_zbf_policies\n       -> security.get_acls -> security.get_port_forwards\n       -> security.get_ids_alerts -> wifi.get_rf_scan (rogue AP detection)\nOutput: Risk-ranked findings with severity and remediation guidance.\n\n### unifi compare \u003Csite1> \u003Csite2>\nIntent: Side-by-side comparison of two sites.\nCalls: multisite.compare_sites -> multisite.get_site_health (both)\n       -> health.get_firmware_status (both)\n\n### unifi config [site?] [--drift]\nIntent: Review config state. With --drift, diff against stored baseline.\nCalls: config.get_config_snapshot -> [config.diff_baseline if --drift]\n       -> config.get_backup_state\nWrite (--save): config.save_baseline — requires UNIFI_WRITE_ENABLED.\n\n### unifi port-profile create \u003Cn> [--native \u003Cvlan>] [--tagged \u003Cvlans>]\n                               [--poe] [--apply]\nIntent: Create a named switch port profile in UniFi.\nCalls: topology.get_vlans (verify named VLANs exist)\n       -> config.create_port_profile -> confirm\nExample: unifi port-profile create Trunk-AP --native 10 --tagged 30,50,60\n\n### unifi port-profile assign \u003Cswitch> \u003Cport> \u003Cprofile> [--apply]\nIntent: Assign a named profile to a specific port on a UniFi switch.\nPhase 1: topology.get_device(switch) to identify port from description\u002Findex.\n         OutageRiskAgent: assess if port carries operator management session.\nPhase 2: present plan showing current profile -> new profile for that port.\nWrite: topology.assign_port_profile -> confirm.\nCAUTION: Never assign to the port connected to OPNsense until all VLAN\n  configuration on OPNsense is complete and verified.\n\n## Examples\n\n# Basic: First-time scan of a single-site deployment\nUser: \"Scan my UniFi network\"\n-> call unifi__topology__list_sites()\n-> if one site: proceed directly\n-> if multiple: AskUserQuestion \"Which site would you like to scan?\"\n-> call list_devices, get_vlans, get_uplinks\n-> present: device count by type, VLAN summary, uplink graph, offline devices\n\n# Basic: Morning health check\nUser: \"Quick health check\"\n-> call get_site_health, get_firmware_status, get_events(hours=12)\n-> if no critical findings: \"All clear — N devices online, no alerts.\"\n-> if findings: present by severity, Critical first\n\n# Advanced: Diagnose a client complaint\nUser: \"Sarah's laptop can't reach the file server\"\n-> search_clients(\"Sarah\") or ask for MAC\u002Fhostname if ambiguous\n-> get_client -> get_client_rf -> get_client_traffic\n-> get_firewall_rules (check VLAN isolation)\n-> present: signal quality, VLAN membership, firewall rules affecting path\n\n# Write: Apply optimization (with UNIFI_WRITE_ENABLED=true)\nUser: \"Optimize the office WiFi and apply changes\"\n-> Phase 1: gather wifi + traffic data, resolve any ambiguities\n-> Phase 2: present full recommendation plan\n-> Phase 3: AskUserQuestion \"3 changes planned. Confirm to proceed?\"\n-> on confirm: execute each write, report result\n",{"docs":42,"name":5,"author":43,"license":14,"version":44,"netex_role":45,"repository":48,"description":49,"netex_skills":50,"netex_vendor":5,"netex_write_flag":54,"netex_contract_version":55},"https:\u002F\u002Fbluminal.github.io\u002Femberai\u002Funifi\u002F","Bluminal Labs","0.1.1",[46,47],"edge","wireless","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Ftree\u002Fmain\u002Funifi","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.\n",[33,51,28,52,20,27,36,53],"health","clients","multisite","UNIFI_WRITE_ENABLED","1.0.0","9d6b1619ec04c0b28e3666ff6bc16f303fd1a340","unifi\u002Fskills\u002Funifi",0,"https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai","https:\u002F\u002Fgithub.com\u002Fbluminal","2026-08-18 23:17:24",{"source":8,"skillName":5,"commands":63,"prompt":73,"zipAvailable":74},[64,67,70],{"tool":65,"command":66},"npx","npx skills add bluminal\u002Femberai --skill unifi",{"tool":68,"command":69},"bunx","bunx skills add bluminal\u002Femberai --skill unifi",{"tool":71,"command":72},"pnpm","pnpm dlx skills add bluminal\u002Femberai --skill unifi","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Funifi\u002Fskills\u002Funifi\u002FSKILL.md",true,[],[77,104,123,148,166],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":91,"publishedAt":37},"01M6GX5EF9HEN4QGDKNXEZE81E","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.","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Ftalos\u002FSKILL.md",[83,88],{"categoryNo":84,"categoryName":85,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",{"categoryNo":89,"categoryName":90,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000016","图像与多媒体",[79,92,93,94,21,25,26,95,18,96,97,98,32,99,100,36,101,27,102,103],"grpc","tree","cluster","images","node","etcd","mtls","diagnostics","status","component","cli","image",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":37},"01M6GX58W7NVFERYSC7QMQ71XC","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\u002FIPS (Suricata), traffic shaping, live diagnostics, and firmware management via the OPNsense REST API.","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Fopnsense\u002Fskills\u002Fopnsense\u002FSKILL.md",[],[106,111,21,25,26,18,112,113,30,114,115,116,117,118,119,100,120,121,20,122],"vpn","shaping","api","ips","suricata","ids","firewall","firmware","dns","tunnel","unbound","interface",{"skillNo":124,"name":125,"nameZh":6,"description":126,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":127,"categories":128,"keywords":137,"publishedAt":37},"01M6GX4S1TT2FKWB50M933TGVG","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.","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Fnextdns\u002FSKILL.md",[129,132],{"categoryNo":130,"categoryName":131,"taxonomyType":86,"taxonomyTypeDesc":87},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":133,"categoryName":134,"taxonomyType":135,"taxonomyTypeDesc":136},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[125,93,138,21,139,23,25,140,26,141,18,142,30,119,143,144,145,27,146,147],"profiles","control","query","log analysis","dashboards","logs","plugin","analytics","github","log",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":154,"publishedAt":37},"01M6GX4K560XNG4G64NNZDB7GC","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.","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Fnetex\u002Fskills\u002Fnetex\u002FSKILL.md",[],[150,155,144,156,157,146,158,93,159,21,160,161,26,5,162,163,164,51,165,31],"https","orchestration","policy","plugins","at","systems","coordinates","vendor","operations","synchronization","vlan",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":172,"publishedAt":37},"01M6GX47T042G7AGSVVCNMMGNC","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.","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Fcisco\u002Fskills\u002Fcisco\u002FSKILL.md",[],[168,26,93,122,173,21,24,25,174,175,18,176,51,177,46,32,33,144,36,102],"port","switch","mac","table","discovery"]