[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GX47T042G7AGSVVCNMMGNC":3,"skill-same:01M6GX47T042G7AGSVVCNMMGNC":73},{"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":25,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":58,"install":59,"resources":72},"01M6GX47T042G7AGSVVCNMMGNC","cisco",null,"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.","bluminal\u002Femberai","bluminal","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F260166565?v=4","01M6GX3XC0W0S4DSMM3WVJC3QJ","01M6GX3XJJK9YDQEWW5M24ZRSJ",1,"MIT","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Fcisco\u002Fskills\u002Fcisco\u002FSKILL.md",[],[5,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"mac","tree","interface","port","io","drift","intelligence","main","switch","cli","write","table","health","discovery","edge","monitoring","topology","plugin","config","2026-11-10 10:12:30",false,"---\nname: cisco\nversion: 0.1.0\ndescription: >\n  Cisco SG-300 managed switch intelligence plugin for EmberAI. Provides\n  VLAN management, port configuration, MAC address table lookup, LLDP\n  topology discovery, interface counters (SNMP), configuration drift\n  detection, and health monitoring via SSH CLI (Netmiko) and SNMPv2c.\nauthor: Bluminal Labs\nlicense: MIT\nrepository: https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Ftree\u002Fmain\u002Fcisco\ndocs: https:\u002F\u002Fbluminal.github.io\u002Femberai\u002Fcisco\u002F\n\n# Vendor Plugin Contract fields (netex v1.0.0)\nnetex_vendor: cisco\nnetex_role:\n  - edge\nnetex_skills:\n  - topology\n  - interfaces\n  - clients\n  - health\n  - config\nnetex_write_flag: CISCO_WRITE_ENABLED\nnetex_contract_version: \"1.0.0\"\n---\n\n# cisco -- Cisco SG-300 Managed Switch Intelligence Plugin\n\nYou are operating the cisco plugin for the EmberAI marketplace. This plugin\ngives you read and (when explicitly enabled) write access to a Cisco SG-300\nmanaged switch via SSH CLI (Netmiko) and SNMPv2c.\n\nThis plugin covers the EDGE layer of the network: switch ports, VLANs,\nMAC address tables, LLDP neighbor discovery, interface traffic counters,\nand configuration management. It does NOT manage routing, firewall rules,\nVPN tunnels, or DNS -- those 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**IMPORTANT: The SG-300 runs Cisco Small Business firmware, NOT full IOS.**\nMany IOS commands are absent or produce differently-formatted output. The\nNetmiko device_type must be \"cisco_s300\". See the knowledge base entry\n`knowledge\u002Fsg300-cli-quirks.md` for a complete list of differences.\n\n## Communication Protocols\n\n  SSH CLI (Netmiko) : Port 22, device_type \"cisco_s300\", username\u002Fpassword auth\n  SNMPv2c           : Port 161\u002FUDP, community string auth, read-only counters\n\nSSH is used for all configuration reads and writes. SNMP is used only for\ninterface traffic counters (IF-MIB) where polling is more efficient than\nCLI parsing.\n\n## Authentication\n\nRequired environment variables:\n  CISCO_HOST           : IP or hostname of the Cisco SG-300 switch\n  CISCO_SSH_USERNAME   : SSH username for CLI access\n  CISCO_SSH_PASSWORD   : SSH password for CLI access\n\nOptional:\n  CISCO_ENABLE_PASSWORD    : Enable password for privileged EXEC mode\n                             (if configured on the switch). Default: none.\n  CISCO_SNMP_COMMUNITY     : SNMPv2c community string for interface counters.\n                             Default: none (SNMP counters disabled).\n  CISCO_WRITE_ENABLED      : Set to \"true\" to enable write operations.\n                             Default: \"false\". Without this, all write\n                             tools are blocked and the plugin operates\n                             read-only.\n  CISCO_VERIFY_SSH_HOST_KEY : Verify SSH host key. Default: \"true\".\n                              Set to \"false\" for lab\u002Ftest environments.\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 tool with an incomplete configuration.\n\nRun `cisco-server --check` to probe SSH connectivity and validate all\nenvironment variables before starting the server.\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 switch. 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 tools (e.g., whether a\n  VLAN ID already exists) must be checked, not asked.\n\nPhase 2 -- Present the complete plan\n  Show the full ordered change plan: every CLI command, in sequence. State\n  what will change, on which port or VLAN, and the expected outcome. Include\n  a rollback plan (the inverse CLI commands). 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\nCISCO_WRITE_ENABLED must be \"true\" AND the operator must have confirmed the\nplan before any write command is sent. If CISCO_WRITE_ENABLED is false, you\nmay still describe what a write operation would do (plan mode), but you must\nstate clearly that write operations are currently disabled.\n\n## Config Persistence Safety Model\n\n**CRITICAL: The SG-300 applies CLI commands IMMEDIATELY. There is no\ncandidate config, no commit, and no rollback.**\n\n- `running-config` is the live configuration (in RAM).\n- `startup-config` is the saved configuration (in flash, survives reboot).\n- `write memory` persists running-config to startup-config.\n- If you do NOT run `write memory`, a reboot restores the last saved state.\n\nSafety rules for all write operations:\n1. Capture `show running-config` BEFORE every write (pre-change snapshot).\n2. Verify the change took effect by re-reading the relevant config section.\n3. NEVER auto-save. The operator must explicitly request `save_config`.\n4. NEVER batch-save after multiple unverified changes.\n5. Check if the write could affect the SSH management session before executing.\n\nSee `knowledge\u002Fconfig-persistence.md` for the full safety model.\n\n## Skill Groups and Tool Signatures\n\n### topology\n# Discovers switch identity, VLANs, and physical neighbors.\n\ncisco__topology__get_device_info()\n  -> {hostname, model, firmware_version, serial_number,\n      uptime_seconds, mac_address}\n  CLI: show version + show running-config (for hostname)\n  Note: hostname is parsed from running-config because show version\n  does not include it on the SG-300.\n\ncisco__topology__list_vlans()\n  -> [{id, name, ports, tagged_ports}]\n  CLI: show vlan\n  Note: SG-300 show vlan output is table-formatted, not IOS-style.\n\ncisco__topology__get_lldp_neighbors()\n  -> [{local_port, remote_device, remote_port, capabilities, remote_ip}]\n  CLI: show lldp neighbors\n\n\n### interfaces\n# Port listing, detailed port configuration, and traffic counters.\n\ncisco__interfaces__list_ports()\n  -> [{id, name, status, speed, duplex, vlan_id, mode, description}]\n  CLI: show interfaces status\n\ncisco__interfaces__get_port_detail(port)\n  -> {id, name, status, speed, duplex, vlan_id, mode, description,\n      trunk_allowed_vlans, native_vlan}\n  port: Port identifier (e.g. gi1, Po1, fa2, te1)\n  CLI: show interfaces switchport {port}\n\ncisco__interfaces__get_counters()\n  -> [{port, rx_bytes, tx_bytes, rx_packets, tx_packets,\n       rx_errors, tx_errors, rx_discards, tx_discards}]\n  Protocol: SNMPv2c (IF-MIB bulk walk)\n  Requires: CISCO_SNMP_COMMUNITY to be set.\n\ncisco__interfaces__set_port_vlan(port, vlan_id, *, apply=False)  # WRITE\n  Assigns an access port to a specific VLAN.\n  port: Port identifier (e.g. gi1)\n  vlan_id: VLAN ID (1-4094)\n  CLI: interface {port} \u002F switchport access vlan {vlan_id}\n  Pre-check: Verifies VLAN exists via list_vlans.\n\ncisco__interfaces__set_trunk_port(port, native_vlan, allowed_vlans, *, apply=False)  # WRITE\n  Configures a port as a trunk with specified native and allowed VLANs.\n  port: Port identifier\n  native_vlan: Native VLAN ID\n  allowed_vlans: List of allowed VLAN IDs\n  CLI: interface {port} \u002F switchport mode trunk \u002F\n       switchport trunk native vlan {native_vlan} \u002F\n       switchport trunk allowed vlan {allowed_vlans}\n\ncisco__interfaces__set_port_description(port, description, *, apply=False)  # WRITE\n  Sets or clears the description on a port.\n  port: Port identifier\n  description: Description string (empty string to clear)\n  CLI: interface {port} \u002F description {description}\n\ncisco__interfaces__set_port_state(port, enabled, *, apply=False)  # WRITE\n  Administratively enables or disables a port.\n  port: Port identifier\n  enabled: True to enable (no shutdown), False to disable (shutdown)\n  CLI: interface {port} \u002F [no] shutdown\n\n\n### clients\n# MAC address table listing and lookup.\n\ncisco__clients__list_mac_table()\n  -> [{mac, vlan_id, interface, entry_type}]\n  CLI: show mac address-table\n  Note: Command uses space-separated form, not hyphenated.\n\ncisco__clients__find_mac(mac)\n  -> [{mac, vlan_id, interface, entry_type}]\n  mac: MAC address in any common format (aa:bb:cc:dd:ee:ff,\n       aa-bb-cc-dd-ee-ff, aabb.ccdd.eeff). Normalized before matching.\n\ncisco__clients__list_mac_by_vlan(vlan_id)\n  -> [{mac, vlan_id, interface, entry_type}]\n  vlan_id: VLAN ID to filter by (1-4094)\n  CLI: show mac address-table vlan {vlan_id}\n\ncisco__clients__list_mac_by_port(port)\n  -> [{mac, vlan_id, interface, entry_type}]\n  port: Port identifier (e.g. gi1, Po1, fa2, te1)\n  CLI: show mac address-table interface {port}\n\n\n### health\n# Composite health monitoring.\n\ncisco__health__get_status()\n  -> {device_info: {hostname, model, firmware_version, serial_number,\n                    uptime_seconds, mac_address},\n      ports: {total, up, down},\n      lldp_neighbor_count, uptime_seconds, summary}\n  CLI: show version + show running-config + show interfaces status +\n       show lldp neighbors\n  Aggregates system info, port status counts, and LLDP neighbor count\n  into a single health report with a markdown summary.\n\n\n### config\n# Configuration retrieval, drift detection, persistence, and VLAN management.\n\ncisco__config__get_running_config()\n  -> str (full running-config output)\n  CLI: show running-config\n\ncisco__config__get_startup_config()\n  -> str (full startup-config output)\n  CLI: show startup-config\n\ncisco__config__detect_drift()\n  -> {has_drift, added_lines, removed_lines, summary}\n  Compares running-config vs startup-config using unified diff.\n  Filters out timestamps and non-config noise to avoid false positives.\n\ncisco__config__save_config(*, apply=False)  # WRITE\n  Persists running-config to startup-config.\n  CLI: write memory\n  Pre-check: Runs detect_drift to show the operator exactly what\n  unsaved changes will be persisted. NEVER auto-called.\n\ncisco__config__create_vlan(vlan_id, name, *, apply=False)  # WRITE\n  Creates a new VLAN on the switch.\n  vlan_id: VLAN ID (2-4094)\n  name: VLAN name string\n  CLI: vlan database \u002F vlan {vlan_id} \u002F name {name}\n  Pre-check: Verifies VLAN ID is not already in use.\n\ncisco__config__delete_vlan(vlan_id, *, apply=False)  # WRITE\n  Deletes a VLAN from the switch.\n  vlan_id: VLAN ID (2-4094, VLAN 1 cannot be deleted)\n  CLI: vlan database \u002F no vlan {vlan_id}\n  Pre-check: Verifies no ports are actively assigned to the VLAN.\n  CAUTION: Any ports on this VLAN will lose connectivity.\n\n\n## Commands\n\n### cisco scan\nIntent: Discover the switch identity, VLAN configuration, and physical neighbors.\nCalls: topology.get_device_info -> topology.list_vlans -> topology.get_lldp_neighbors\nOutput: Switch model and firmware, VLAN summary table, LLDP neighbor table.\n\n### cisco health\nIntent: Composite health report for the switch.\nCalls: health.get_status\nOutput: System info, port status (up\u002Fdown counts), LLDP neighbor count,\n  uptime, and a markdown summary. Flags down ports as potential issues.\n\n### cisco diagnose [port|mac]\nIntent: Root-cause analysis for a specific port or client.\nCalls: interfaces.get_port_detail(port) OR clients.find_mac(mac)\n       -> interfaces.get_counters -> clients.list_mac_by_port(port)\n       -> topology.list_vlans (verify VLAN membership)\nOutput: Port status, VLAN assignment, traffic counters, connected MACs,\n  and ranked findings with probable causes.\n\n### cisco optimize [--apply]\nIntent: Generate improvement recommendations for port and VLAN configuration.\nRead phase: Calls interfaces.list_ports, topology.list_vlans,\n  interfaces.get_counters, clients.list_mac_table.\nAnalysis: Identifies unused VLANs, ports with high error rates, trunk\n  misconfigurations, and VLAN sprawl.\nWrite gate: CISCO_WRITE_ENABLED must be true and --apply must be present.\n  Without these, produce the recommendation plan only (no writes).\n\n### cisco config [--drift]\nIntent: Review configuration state. With --drift, detect unsaved changes.\nCalls: config.get_running_config -> [config.detect_drift if --drift]\nWrite (--save): config.save_config -- requires CISCO_WRITE_ENABLED.\n\n\n## Examples\n\n# Basic: First-time scan of the switch\nUser: \"Scan my Cisco switch\"\n-> call cisco__topology__get_device_info()\n-> call cisco__topology__list_vlans()\n-> call cisco__topology__get_lldp_neighbors()\n-> present: switch model\u002Ffirmware, VLAN table, neighbor table\n\n# Basic: Morning health check\nUser: \"Check the switch health\"\n-> call cisco__health__get_status()\n-> if no down ports: \"All clear -- N\u002FM ports up, K LLDP neighbors\"\n-> if down ports: flag them with port IDs\n\n# Intermediate: Find where a device is connected\nUser: \"Where is MAC aa:bb:cc:dd:ee:ff plugged in?\"\n-> call cisco__clients__find_mac(\"aa:bb:cc:dd:ee:ff\")\n-> present: port, VLAN, entry type (dynamic\u002Fstatic)\n-> call cisco__interfaces__get_port_detail(port) for full port info\n\n# Intermediate: Check for unsaved changes\nUser: \"Are there unsaved changes on the switch?\"\n-> call cisco__config__detect_drift()\n-> if drift: show added\u002Fremoved lines, recommend save or revert\n-> if no drift: \"Running config matches startup config\"\n\n# Advanced: Move a port to a different VLAN (with CISCO_WRITE_ENABLED=true)\nUser: \"Move port gi5 to VLAN 100\"\n-> Phase 1: call list_vlans (verify VLAN 100 exists),\n            call get_port_detail(\"gi5\") (current VLAN assignment)\n-> Phase 2: present plan: \"gi5 will move from VLAN 1 to VLAN 100\"\n            rollback: \"switchport access vlan 1\"\n-> Phase 3: AskUserQuestion \"Confirm moving gi5 from VLAN 1 to VLAN 100?\"\n-> on confirm: call set_port_vlan(\"gi5\", 100, apply=True)\n-> verify: call get_port_detail(\"gi5\") to confirm VLAN 100\n-> remind: \"Change is live but NOT saved. Run save_config to persist.\"\n\n# Write: Save configuration (with CISCO_WRITE_ENABLED=true)\nUser: \"Save the switch config\"\n-> call cisco__config__detect_drift() to show what will be saved\n-> Phase 2: present the diff as the plan\n-> Phase 3: AskUserQuestion \"Save these N changes to startup-config?\"\n-> on confirm: call cisco__config__save_config(apply=True)\n","# cisco -- Cisco SG-300 Managed Switch Intelligence Plugin\n\nYou are operating the cisco plugin for the EmberAI marketplace. This plugin\ngives you read and (when explicitly enabled) write access to a Cisco SG-300\nmanaged switch via SSH CLI (Netmiko) and SNMPv2c.\n\nThis plugin covers the EDGE layer of the network: switch ports, VLANs,\nMAC address tables, LLDP neighbor discovery, interface traffic counters,\nand configuration management. It does NOT manage routing, firewall rules,\nVPN tunnels, or DNS -- those 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**IMPORTANT: The SG-300 runs Cisco Small Business firmware, NOT full IOS.**\nMany IOS commands are absent or produce differently-formatted output. The\nNetmiko device_type must be \"cisco_s300\". See the knowledge base entry\n`knowledge\u002Fsg300-cli-quirks.md` for a complete list of differences.\n\n## Communication Protocols\n\n  SSH CLI (Netmiko) : Port 22, device_type \"cisco_s300\", username\u002Fpassword auth\n  SNMPv2c           : Port 161\u002FUDP, community string auth, read-only counters\n\nSSH is used for all configuration reads and writes. SNMP is used only for\ninterface traffic counters (IF-MIB) where polling is more efficient than\nCLI parsing.\n\n## Authentication\n\nRequired environment variables:\n  CISCO_HOST           : IP or hostname of the Cisco SG-300 switch\n  CISCO_SSH_USERNAME   : SSH username for CLI access\n  CISCO_SSH_PASSWORD   : SSH password for CLI access\n\nOptional:\n  CISCO_ENABLE_PASSWORD    : Enable password for privileged EXEC mode\n                             (if configured on the switch). Default: none.\n  CISCO_SNMP_COMMUNITY     : SNMPv2c community string for interface counters.\n                             Default: none (SNMP counters disabled).\n  CISCO_WRITE_ENABLED      : Set to \"true\" to enable write operations.\n                             Default: \"false\". Without this, all write\n                             tools are blocked and the plugin operates\n                             read-only.\n  CISCO_VERIFY_SSH_HOST_KEY : Verify SSH host key. Default: \"true\".\n                              Set to \"false\" for lab\u002Ftest environments.\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 tool with an incomplete configuration.\n\nRun `cisco-server --check` to probe SSH connectivity and validate all\nenvironment variables before starting the server.\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 switch. 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 tools (e.g., whether a\n  VLAN ID already exists) must be checked, not asked.\n\nPhase 2 -- Present the complete plan\n  Show the full ordered change plan: every CLI command, in sequence. State\n  what will change, on which port or VLAN, and the expected outcome. Include\n  a rollback plan (the inverse CLI commands). 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\nCISCO_WRITE_ENABLED must be \"true\" AND the operator must have confirmed the\nplan before any write command is sent. If CISCO_WRITE_ENABLED is false, you\nmay still describe what a write operation would do (plan mode), but you must\nstate clearly that write operations are currently disabled.\n\n## Config Persistence Safety Model\n\n**CRITICAL: The SG-300 applies CLI commands IMMEDIATELY. There is no\ncandidate config, no commit, and no rollback.**\n\n- `running-config` is the live configuration (in RAM).\n- `startup-config` is the saved configuration (in flash, survives reboot).\n- `write memory` persists running-config to startup-config.\n- If you do NOT run `write memory`, a reboot restores the last saved state.\n\nSafety rules for all write operations:\n1. Capture `show running-config` BEFORE every write (pre-change snapshot).\n2. Verify the change took effect by re-reading the relevant config section.\n3. NEVER auto-save. The operator must explicitly request `save_config`.\n4. NEVER batch-save after multiple unverified changes.\n5. Check if the write could affect the SSH management session before executing.\n\nSee `knowledge\u002Fconfig-persistence.md` for the full safety model.\n\n## Skill Groups and Tool Signatures\n\n### topology\n# Discovers switch identity, VLANs, and physical neighbors.\n\ncisco__topology__get_device_info()\n  -> {hostname, model, firmware_version, serial_number,\n      uptime_seconds, mac_address}\n  CLI: show version + show running-config (for hostname)\n  Note: hostname is parsed from running-config because show version\n  does not include it on the SG-300.\n\ncisco__topology__list_vlans()\n  -> [{id, name, ports, tagged_ports}]\n  CLI: show vlan\n  Note: SG-300 show vlan output is table-formatted, not IOS-style.\n\ncisco__topology__get_lldp_neighbors()\n  -> [{local_port, remote_device, remote_port, capabilities, remote_ip}]\n  CLI: show lldp neighbors\n\n\n### interfaces\n# Port listing, detailed port configuration, and traffic counters.\n\ncisco__interfaces__list_ports()\n  -> [{id, name, status, speed, duplex, vlan_id, mode, description}]\n  CLI: show interfaces status\n\ncisco__interfaces__get_port_detail(port)\n  -> {id, name, status, speed, duplex, vlan_id, mode, description,\n      trunk_allowed_vlans, native_vlan}\n  port: Port identifier (e.g. gi1, Po1, fa2, te1)\n  CLI: show interfaces switchport {port}\n\ncisco__interfaces__get_counters()\n  -> [{port, rx_bytes, tx_bytes, rx_packets, tx_packets,\n       rx_errors, tx_errors, rx_discards, tx_discards}]\n  Protocol: SNMPv2c (IF-MIB bulk walk)\n  Requires: CISCO_SNMP_COMMUNITY to be set.\n\ncisco__interfaces__set_port_vlan(port, vlan_id, *, apply=False)  # WRITE\n  Assigns an access port to a specific VLAN.\n  port: Port identifier (e.g. gi1)\n  vlan_id: VLAN ID (1-4094)\n  CLI: interface {port} \u002F switchport access vlan {vlan_id}\n  Pre-check: Verifies VLAN exists via list_vlans.\n\ncisco__interfaces__set_trunk_port(port, native_vlan, allowed_vlans, *, apply=False)  # WRITE\n  Configures a port as a trunk with specified native and allowed VLANs.\n  port: Port identifier\n  native_vlan: Native VLAN ID\n  allowed_vlans: List of allowed VLAN IDs\n  CLI: interface {port} \u002F switchport mode trunk \u002F\n       switchport trunk native vlan {native_vlan} \u002F\n       switchport trunk allowed vlan {allowed_vlans}\n\ncisco__interfaces__set_port_description(port, description, *, apply=False)  # WRITE\n  Sets or clears the description on a port.\n  port: Port identifier\n  description: Description string (empty string to clear)\n  CLI: interface {port} \u002F description {description}\n\ncisco__interfaces__set_port_state(port, enabled, *, apply=False)  # WRITE\n  Administratively enables or disables a port.\n  port: Port identifier\n  enabled: True to enable (no shutdown), False to disable (shutdown)\n  CLI: interface {port} \u002F [no] shutdown\n\n\n### clients\n# MAC address table listing and lookup.\n\ncisco__clients__list_mac_table()\n  -> [{mac, vlan_id, interface, entry_type}]\n  CLI: show mac address-table\n  Note: Command uses space-separated form, not hyphenated.\n\ncisco__clients__find_mac(mac)\n  -> [{mac, vlan_id, interface, entry_type}]\n  mac: MAC address in any common format (aa:bb:cc:dd:ee:ff,\n       aa-bb-cc-dd-ee-ff, aabb.ccdd.eeff). Normalized before matching.\n\ncisco__clients__list_mac_by_vlan(vlan_id)\n  -> [{mac, vlan_id, interface, entry_type}]\n  vlan_id: VLAN ID to filter by (1-4094)\n  CLI: show mac address-table vlan {vlan_id}\n\ncisco__clients__list_mac_by_port(port)\n  -> [{mac, vlan_id, interface, entry_type}]\n  port: Port identifier (e.g. gi1, Po1, fa2, te1)\n  CLI: show mac address-table interface {port}\n\n\n### health\n# Composite health monitoring.\n\ncisco__health__get_status()\n  -> {device_info: {hostname, model, firmware_version, serial_number,\n                    uptime_seconds, mac_address},\n      ports: {total, up, down},\n      lldp_neighbor_count, uptime_seconds, summary}\n  CLI: show version + show running-config + show interfaces status +\n       show lldp neighbors\n  Aggregates system info, port status counts, and LLDP neighbor count\n  into a single health report with a markdown summary.\n\n\n### config\n# Configuration retrieval, drift detection, persistence, and VLAN management.\n\ncisco__config__get_running_config()\n  -> str (full running-config output)\n  CLI: show running-config\n\ncisco__config__get_startup_config()\n  -> str (full startup-config output)\n  CLI: show startup-config\n\ncisco__config__detect_drift()\n  -> {has_drift, added_lines, removed_lines, summary}\n  Compares running-config vs startup-config using unified diff.\n  Filters out timestamps and non-config noise to avoid false positives.\n\ncisco__config__save_config(*, apply=False)  # WRITE\n  Persists running-config to startup-config.\n  CLI: write memory\n  Pre-check: Runs detect_drift to show the operator exactly what\n  unsaved changes will be persisted. NEVER auto-called.\n\ncisco__config__create_vlan(vlan_id, name, *, apply=False)  # WRITE\n  Creates a new VLAN on the switch.\n  vlan_id: VLAN ID (2-4094)\n  name: VLAN name string\n  CLI: vlan database \u002F vlan {vlan_id} \u002F name {name}\n  Pre-check: Verifies VLAN ID is not already in use.\n\ncisco__config__delete_vlan(vlan_id, *, apply=False)  # WRITE\n  Deletes a VLAN from the switch.\n  vlan_id: VLAN ID (2-4094, VLAN 1 cannot be deleted)\n  CLI: vlan database \u002F no vlan {vlan_id}\n  Pre-check: Verifies no ports are actively assigned to the VLAN.\n  CAUTION: Any ports on this VLAN will lose connectivity.\n\n\n## Commands\n\n### cisco scan\nIntent: Discover the switch identity, VLAN configuration, and physical neighbors.\nCalls: topology.get_device_info -> topology.list_vlans -> topology.get_lldp_neighbors\nOutput: Switch model and firmware, VLAN summary table, LLDP neighbor table.\n\n### cisco health\nIntent: Composite health report for the switch.\nCalls: health.get_status\nOutput: System info, port status (up\u002Fdown counts), LLDP neighbor count,\n  uptime, and a markdown summary. Flags down ports as potential issues.\n\n### cisco diagnose [port|mac]\nIntent: Root-cause analysis for a specific port or client.\nCalls: interfaces.get_port_detail(port) OR clients.find_mac(mac)\n       -> interfaces.get_counters -> clients.list_mac_by_port(port)\n       -> topology.list_vlans (verify VLAN membership)\nOutput: Port status, VLAN assignment, traffic counters, connected MACs,\n  and ranked findings with probable causes.\n\n### cisco optimize [--apply]\nIntent: Generate improvement recommendations for port and VLAN configuration.\nRead phase: Calls interfaces.list_ports, topology.list_vlans,\n  interfaces.get_counters, clients.list_mac_table.\nAnalysis: Identifies unused VLANs, ports with high error rates, trunk\n  misconfigurations, and VLAN sprawl.\nWrite gate: CISCO_WRITE_ENABLED must be true and --apply must be present.\n  Without these, produce the recommendation plan only (no writes).\n\n### cisco config [--drift]\nIntent: Review configuration state. With --drift, detect unsaved changes.\nCalls: config.get_running_config -> [config.detect_drift if --drift]\nWrite (--save): config.save_config -- requires CISCO_WRITE_ENABLED.\n\n\n## Examples\n\n# Basic: First-time scan of the switch\nUser: \"Scan my Cisco switch\"\n-> call cisco__topology__get_device_info()\n-> call cisco__topology__list_vlans()\n-> call cisco__topology__get_lldp_neighbors()\n-> present: switch model\u002Ffirmware, VLAN table, neighbor table\n\n# Basic: Morning health check\nUser: \"Check the switch health\"\n-> call cisco__health__get_status()\n-> if no down ports: \"All clear -- N\u002FM ports up, K LLDP neighbors\"\n-> if down ports: flag them with port IDs\n\n# Intermediate: Find where a device is connected\nUser: \"Where is MAC aa:bb:cc:dd:ee:ff plugged in?\"\n-> call cisco__clients__find_mac(\"aa:bb:cc:dd:ee:ff\")\n-> present: port, VLAN, entry type (dynamic\u002Fstatic)\n-> call cisco__interfaces__get_port_detail(port) for full port info\n\n# Intermediate: Check for unsaved changes\nUser: \"Are there unsaved changes on the switch?\"\n-> call cisco__config__detect_drift()\n-> if drift: show added\u002Fremoved lines, recommend save or revert\n-> if no drift: \"Running config matches startup config\"\n\n# Advanced: Move a port to a different VLAN (with CISCO_WRITE_ENABLED=true)\nUser: \"Move port gi5 to VLAN 100\"\n-> Phase 1: call list_vlans (verify VLAN 100 exists),\n            call get_port_detail(\"gi5\") (current VLAN assignment)\n-> Phase 2: present plan: \"gi5 will move from VLAN 1 to VLAN 100\"\n            rollback: \"switchport access vlan 1\"\n-> Phase 3: AskUserQuestion \"Confirm moving gi5 from VLAN 1 to VLAN 100?\"\n-> on confirm: call set_port_vlan(\"gi5\", 100, apply=True)\n-> verify: call get_port_detail(\"gi5\") to confirm VLAN 100\n-> remind: \"Change is live but NOT saved. Run save_config to persist.\"\n\n# Write: Save configuration (with CISCO_WRITE_ENABLED=true)\nUser: \"Save the switch config\"\n-> call cisco__config__detect_drift() to show what will be saved\n-> Phase 2: present the diff as the plan\n-> Phase 3: AskUserQuestion \"Save these N changes to startup-config?\"\n-> on confirm: call cisco__config__save_config(apply=True)\n",{"docs":42,"name":5,"author":43,"license":14,"version":44,"netex_role":45,"repository":46,"description":47,"netex_skills":48,"netex_vendor":5,"netex_write_flag":51,"netex_contract_version":52},"https:\u002F\u002Fbluminal.github.io\u002Femberai\u002Fcisco\u002F","Bluminal Labs","0.1.0",[32],"https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Ftree\u002Fmain\u002Fcisco","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.\n",[34,49,50,30,36],"interfaces","clients","CISCO_WRITE_ENABLED","1.0.0","9d6b1619ec04c0b28e3666ff6bc16f303fd1a340","cisco\u002Fskills\u002Fcisco",0,"https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai","https:\u002F\u002Fgithub.com\u002Fbluminal","2026-08-18 23:17:24",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add bluminal\u002Femberai --skill cisco",{"tool":65,"command":66},"bunx","bunx skills add bluminal\u002Femberai --skill cisco",{"tool":68,"command":69},"pnpm","pnpm dlx skills add bluminal\u002Femberai --skill cisco","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Fcisco\u002Fskills\u002Fcisco\u002FSKILL.md",true,[],[74,92,117,135,159],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":37},"01M6GX63EVRSAWS2ARXMMJEJDF","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.","https:\u002F\u002Fgithub.com\u002Fbluminal\u002Femberai\u002Fblob\u002Fmain\u002Funifi\u002Fskills\u002Funifi\u002FSKILL.md",[],[76,81,82,83,22,84,85,23,24,25,28,86,87,88,33,34,89,90,36,91],"analysis","manager","traffic","local","across","wifi","security audit","network","audit","gateway","security",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":106,"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",[98,103],{"categoryNo":99,"categoryName":100,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",{"categoryNo":104,"categoryName":105,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000016","图像与多媒体",[94,107,108,28,109,110,111,33,112,113,114,36,24,91,27,115,25,19,116,22],"component","images","node","etcd","mtls","grpc","diagnostics","status","image","cluster",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"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",[],[119,124,83,20,22,125,126,24,28,127,128,81,129,130,131,132,133,134,114,25],"unbound","tunnel","vpn","shaping","api","ips","suricata","ids","firewall","firmware","dns",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":149,"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",[141,144],{"categoryNo":142,"categoryName":143,"taxonomyType":101,"taxonomyTypeDesc":102},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":145,"categoryName":146,"taxonomyType":147,"taxonomyTypeDesc":148},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[137,134,150,35,151,91,152,81,19,153,22,154,85,24,155,25,156,157,28,158],"logs","analytics","github","profiles","control","query","log","log analysis","dashboards",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":165,"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",[],[161,76,166,19,22,167,168,25,169,170,171,30,172,88,173,174,35,175,176,152],"at","systems","coordinates","vendor","operations","synchronization","vlan","plugins","https","orchestration","policy"]