workspace/skills/pyats-config-mgmt/SKILL.md
Network change management - pre-change baselines, configuration deployment, post-change verification, rollback procedures, and compliance validation. Use when pushing config to a device, planning a network change, rolling back a configuration, or running compliance checks.
npx skillsauth add automateyournetwork/netclaw pyats-config-mgmtInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
NEVER apply configuration without first capturing a baseline. If the change goes wrong, you need to know what to roll back to.
Capture the current state of everything the change might affect.
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_show_running_config '{"device_name":"R1"}'
Store this output — it is the rollback reference.
Depending on the change type, capture the appropriate state:
For interface changes:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_run_show_command '{"device_name":"R1","command":"show ip interface brief"}'
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_run_show_command '{"device_name":"R1","command":"show interfaces"}'
For routing changes:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_run_show_command '{"device_name":"R1","command":"show ip route"}'
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_run_show_command '{"device_name":"R1","command":"show ip ospf neighbor"}'
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_run_show_command '{"device_name":"R1","command":"show ip bgp summary"}'
For ACL/security changes:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_run_show_command '{"device_name":"R1","command":"show ip access-lists"}'
Ping critical targets before the change:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_ping_from_network_device '{"device_name":"R1","command":"ping 8.8.8.8 repeat 10"}'
Before applying any config, explicitly state:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_configure_device '{"device_name":"R1","config_commands":["interface Loopback99","ip address 99.99.99.99 255.255.255.255","description NetClaw-Managed","no shutdown"]}'
Configuration best practices:
configure terminal or end — the tool handles thisexit when changing config context (e.g., exiting an interface)Common configuration patterns:
Interface configuration:
["interface GigabitEthernet2", "description WAN-Link-to-ISP", "ip address 203.0.113.1 255.255.255.252", "no shutdown"]
OSPF configuration:
["router ospf 1", "router-id 1.1.1.1", "network 10.0.0.0 0.0.255.255 area 0", "passive-interface default", "no passive-interface GigabitEthernet1"]
BGP configuration:
["router bgp 65001", "neighbor 10.1.1.2 remote-as 65002", "neighbor 10.1.1.2 description ISP-Peer", "address-family ipv4 unicast", "neighbor 10.1.1.2 activate", "neighbor 10.1.1.2 route-map ISP-IN in", "neighbor 10.1.1.2 route-map ISP-OUT out", "exit-address-family"]
ACL configuration:
["ip access-list extended MGMT-ACCESS", "permit tcp 10.0.0.0 0.0.0.255 any eq 22", "permit tcp 10.0.0.0 0.0.0.255 any eq 443", "deny ip any any log"]
Route-map configuration:
["route-map ISP-IN permit 10", "match ip address prefix-list ALLOWED-IN", "set local-preference 200", "exit", "route-map ISP-IN deny 99"]
Static route:
["ip route 0.0.0.0 0.0.0.0 203.0.113.2 name DEFAULT-TO-ISP"]
NTP configuration:
["ntp server 10.0.0.1 prefer", "ntp server 10.0.0.2", "ntp source Loopback0"]
Immediately after applying config, verify:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_show_logging '{"device_name":"R1"}'
Look for new error messages that appeared after the change timestamp.
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_show_running_config '{"device_name":"R1"}'
Compare with the pre-change config to confirm only intended changes were made.
Re-run the same show commands from Phase 1B and compare:
Re-ping all targets from Phase 1C:
PYATS_TESTBED_PATH=$PYATS_TESTBED_PATH python3 $MCP_CALL "${PYATS_PYTHON:-python3} -u $PYATS_MCP_SCRIPT" pyats_ping_from_network_device '{"device_name":"R1","command":"ping 8.8.8.8 repeat 10"}'
Compare success rate and RTT with baseline.
If verification fails, roll back by applying the inverse configuration:
To remove added config:
["no interface Loopback99"]
To restore changed config: Apply the original configuration lines from the Phase 1A baseline.
For complex rollbacks, apply the entire relevant section from the saved running config.
After rollback, re-verify that the device returned to its baseline state.
After every change, produce a change report:
Change Report — YYYY-MM-DD HH:MM UTC
Device: R1 (devnetsandboxiosxec8k.cisco.com)
Requestor: [who requested the change]
Change Description:
Added Loopback99 (99.99.99.99/32) for OSPF router-id migration
Config Applied:
interface Loopback99
ip address 99.99.99.99 255.255.255.255
description OSPF-RID-Migration
no shutdown
Pre-Change State:
- Routing table: 47 routes
- OSPF neighbors: 2 (FULL)
- Connectivity: 100% to 8.8.8.8
Post-Change State:
- Routing table: 48 routes (+1 connected 99.99.99.99/32)
- OSPF neighbors: 2 (FULL) — no change
- Connectivity: 100% to 8.8.8.8 — no change
- New log entries: %LINEPROTO-5-UPDOWN: Loopback99 up/up
Verification: PASSED
Rollback Required: No
[
"service timestamps debug datetime msec localtime",
"service timestamps log datetime msec localtime",
"service password-encryption",
"no ip source-route",
"no ip http server",
"ip http secure-server",
"ip ssh version 2",
"ip ssh time-out 60",
"ip ssh authentication-retries 3",
"login on-failure log",
"login on-success log",
"banner login ^ Authorized access only. All activity is monitored. ^"
]
[
"line vty 0 4",
"transport input ssh",
"exec-timeout 15 0",
"login local",
"exit",
"line vty 5 15",
"transport input ssh",
"exec-timeout 15 0",
"login local"
]
When ServiceNow is available ($SERVICENOW_MCP_SCRIPT is set), every configuration change MUST be gated by an approved Change Request.
Before any config push, create a Change Request:
python3 $MCP_CALL "python3 -u $SERVICENOW_MCP_SCRIPT" create_change_request '{"short_description":"Configure SSH hardening on R1","description":"Apply VTY line hardening: SSH-only transport, exec timeout 15 min, login local. Affects R1 management plane.","category":"Network","priority":"3","risk":"low","impact":"low"}'
python3 $MCP_CALL "python3 -u $SERVICENOW_MCP_SCRIPT" submit_change_for_approval '{"change_number":"CHG0012345"}'
Check if the CR is approved before proceeding:
python3 $MCP_CALL "python3 -u $SERVICENOW_MCP_SCRIPT" get_change_request_details '{"change_number":"CHG0012345"}'
STOP if state is not "Approved". Inform the human and wait.
Verify no open Priority 1 or 2 incidents on affected CIs:
python3 $MCP_CALL "python3 -u $SERVICENOW_MCP_SCRIPT" list_incidents '{"urgency":"1","state":"open"}'
If P1/P2 incidents exist on affected devices, do NOT proceed. Escalate to human.
If verification passes:
python3 $MCP_CALL "python3 -u $SERVICENOW_MCP_SCRIPT" update_change_request '{"change_number":"CHG0012345","updates":{"state":"closed","close_code":"successful","close_notes":"Change applied and verified. Post-change baseline matches expected state."}}'
If verification fails:
python3 $MCP_CALL "python3 -u $SERVICENOW_MCP_SCRIPT" update_change_request '{"change_number":"CHG0012345","updates":{"state":"review","close_notes":"Post-change verification FAILED. Rollback initiated. Human review required."}}'
For emergency changes (network outage, security incident):
Record every phase of the change in GAIT:
python3 $MCP_CALL "python3 -u $GAIT_MCP_SCRIPT" gait_record_turn '{"input":{"role":"assistant","content":"Config change on R1: Phase 1 baseline captured. Phase 2 plan approved. Phase 3 config applied. Phase 4 verification PASSED. ServiceNow CR CHG0012345 closed successful.","artifacts":[]}}'
The 5-phase workflow with GAIT creates an immutable record:
tools
Zoom meeting intelligence — correlates a live or referenced Zoom meeting discussion against NetClaw's historical meeting record (via the official Zoom Meetings MCP) and today's actual network state. Use when someone in a Zoom meeting references a past discussion or incident ('didn't we have this issue before?'), or asks to search prior meetings for a topic. Does not itself recognize live in-meeting questions — that happens automatically inside zoom-rtms-mcp's own extractor (spec 118) before this skill is ever invoked.
tools
Manage Lantronix out-of-band (OOB) infrastructure via Percepxion central management platform: device inventory, serial port inspection via SLC CLI, firmware compliance, config management, security auditing, and closed-loop incident remediation. Use during outages, maintenance windows, compliance cycles, and AI-assisted automation workflows.
tools
Federate your NetClaw with other NetClaw operators over the BGP mesh — exchange capability inventories and ask your claw what a peer can do. (US1; remote invocation and chat land in later phases.)
tools
Track token consumption, enforce session budgets, and display cost for every NetClaw interaction.