network-aiops
It provides governed, audited multi-vendor network device operations and NetBox lookups for AI agents.
Read device facts, interfaces, counters, IPs, BGP/LLDP neighbors, ARP/MAC tables, VLANs, routes, environment, optics, NTP, users, SNMP info, VRFs, and aggregated health.
Run read-only RCA diagnostics for interface health and BGP neighbor issues, with worst-first findings.
Back up running config, dry-run diffs, merge or replace config, confirm commit-confirm changes, and roll back changes.
Use NetBox to list devices, get device details, and list device interfaces for source-of-truth checks.
List and apply recorded undo tokens, with dry-run support and single-use enforcement.
Enforce local audit logging, encrypted credential storage, secret redaction, risk labels, and token/runaway budget guardrails.
Supports Cisco network devices (IOS, IOS-XE, NX-OS, IOS-XR) for reading operational data (facts, interfaces, BGP, LLDP, ARP) and performing configuration operations (backup, diff, merge, replace, rollback).
Supports Huawei VRP devices for reading operational data and performing configuration operations via NAPALM community drivers (not officially tested).
Supports Nokia SR OS and SR Linux devices for reading operational data and performing configuration operations via NAPALM community drivers (not officially tested).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@network-aiops What are the facts for core-sw1?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
network-aiops
Audit availability: Real writes require a committed
pendingaudit row and stop before contacting the platform if storage is unavailable. Reads and previews may continue with a warning; new audit rows store outcome summaries rather than full responses.
Disclaimer: This is a community-maintained open-source project and is not affiliated with, endorsed by, or sponsored by Cisco, Arista, Juniper, NetBox Labs, or any network vendor. Vendor and product names are trademarks of their respective owners. Source code is publicly auditable at github.com/AIops-tools/Network-AIops under the MIT license.
Governed multi-vendor network device operations for AI agents — 33 MCP tools,
every one wrapped with the bundled @governed_tool harness: a local unified audit
log under ~/.network-aiops/, token/runaway budget guard, undo-token recording,
and descriptive risk-tier labels. Credentials (device passwords + the NetBox token)
are kept in an encrypted store (secrets.enc), never plaintext on disk.
Devices are reached over NAPALM; an optional NetBox block adds source-of-truth lookups.
Standalone: the governance harness is bundled in the package (
network_aiops.governance) — network-aiops has no external skill-family dependency. Coverage focuses on common device operations and is not yet exhaustive.
Verification status: the test suite is mock-based; not yet validated against live devices — self-testable with cEOS / vMX / containerlab. See docs/VERIFICATION.md.
What works
Read device facts, interfaces (+ counters/IP), BGP/LLDP neighbors (summary and
detail), ARP/MAC tables, VLANs, route lookups, hardware environment, optics, NTP,
users, SNMP info, VRFs, and an aggregated device_health; run read-only RCA
diagnostics that flag down/erroring/flapping interfaces and unhealthy BGP
neighbors — each finding citing the measured number that tripped it; back up the
running config, dry-run a config diff, and merge/replace/rollback config — across the five
core NAPALM platforms below. Optional NetBox lookups (devices + interfaces) confirm
intended state before a change.
NAPALM does not implement every getter on every platform; an unsupported getter
returns a teaching error ("not supported by the <driver> driver") rather than
crashing. Secrets are never returned — get_users redacts password hashes and
get_snmp_information redacts community strings.
Related MCP server: Cisco Meraki MCP Server
Supported devices
Platform | NAPALM driver | Transport |
Cisco IOS / IOS-XE |
| SSH |
Cisco Nexus NX-OS |
| HTTPS / SSH |
Cisco IOS-XR |
| SSH (XML agent) |
Arista EOS |
| eAPI (HTTPS) |
Juniper Junos |
| NETCONF (SSH) |
Additional platforms (Nokia SR OS / SR Linux, Huawei VRP, etc.) are reachable via NAPALM community drivers but are not officially tested here. Need one? See Contributing.
Supported actions
Action | Tool | R/W | Risk |
Device facts (hostname/vendor/model/OS/serial/uptime) |
| R | low |
Interfaces (up/down, speed, description) |
| R | low |
Interface traffic + error counters |
| R | low |
Interface IP addresses |
| R | low |
BGP neighbors (summary / detail) |
| R | low |
LLDP neighbors (summary / detail) |
| R | low |
ARP table |
| R | low |
MAC address table |
| R | low |
VLANs |
| R | low |
Route lookup |
| R | low |
Hardware environment (fans/temp/power/CPU/mem) |
| R | low |
Optical transceiver levels |
| R | low |
NTP servers / sync stats |
| R | low |
Local users (hashes redacted) |
| R | low |
SNMP info (communities redacted) |
| R | low |
Network instances (VRFs) |
| R | low |
Aggregated device health |
| R | low |
Interface health RCA (down / errors / discards / flaps) |
| R | low |
BGP neighbor RCA (down / shut / reset / route-less) |
| R | low |
Back up running config |
| R | low |
Diff a candidate (dry-run) |
| R | low |
Merge config + commit |
| W | medium |
Replace full config + commit |
| W | high |
Roll back last commit |
| W | medium |
NetBox list devices |
| R | low |
NetBox get device |
| R | low |
NetBox device interfaces |
| R | low |
List recorded reversible writes |
| R | low |
Apply a recorded inverse (governed, single-use, dry-run capable) |
| W | medium |
What this tool does, and does not, decide
It delivers multi-vendor network device (NAPALM) + NetBox operations — reads and writes — accurately and efficiently, and records every one of them. It does not decide whether a write is allowed to happen. That is the agent's judgement, or the permission of the account you connect it with: log in with a device account at a read-only privilege level (and give NetBox a read-only API token), and the writes fail at the server — the place that actually owns the permission.
So there is no read-only switch, no policy file, no approval gate to configure. The one thing the
tool guarantees is that nothing is silent: every call, over MCP and over the CLI alike, lands an
audit row in ~/.network-aiops/audit.db, and destructive writes still capture their before-state
and record an inverse where one exists.
Each tool declares a
risk_level, carried into the audit row as a descriptive tier (none/confirm/review) — so a reviewer can see at a glance that a row was a high-risk delete. It is a label, not a gate.
Running a smaller / local model? See agent-guardrails.md — it lists the guardrails this tool enforces for you (so you don't spend prompt budget restating them) and gives a ready-made system prompt for what's left.
Quick Start
As a Claude Code plugin
One install gives an agent both the skill and the MCP server:
/plugin marketplace add AIops-tools/marketplace
/plugin install network-aiops@aiops-toolsThe MCP server is fetched with uv and pinned to the
package version this plugin declares, so an audit row can be traced back to the
code that wrote it. Credentials are still configured with network-aiops init — see below.
As an OpenClaw plugin
The same bundle is published on ClawHub, where one install delivers the skill and its MCP server together:
openclaw plugins install clawhub:@zw008/network-aiops
openclaw skills info network-aiops # expect: Visible to model: yesRestart the OpenClaw gateway afterwards so it loads the plugin. The MCP server is
fetched with uv, pinned to this exact release, so
uvx has to be on PATH — without it the skill still installs but reports
Visible to model: no. Credentials are configured exactly as below.
As a CLI or standalone MCP server
uv tool install network-aiops
network-aiops init # wizard: device + driver + host + encrypted password
network-aiops doctor
network-aiops device facts -t core-sw1
network-aiops device health -t core-sw1
network-aiops diagnose interface-health -t core-sw1 # worst-first interface RCA
network-aiops diagnose bgp -t core-sw1 # worst-first BGP-neighbor RCA
network-aiops config backup -t core-sw1 -o core-sw1.cfgPlaybook: triage a flaky uplink before touching config
# 1. Ask the device what's actually wrong — findings are ranked worst-first and
# each cites the measured value (error count, last-flap seconds, uptime).
network-aiops diagnose interface-health -t core-sw1
network-aiops diagnose bgp -t core-sw1
# 2. If interface-health flags a link admin-up/oper-down with climbing errors and
# BGP shows the peer on that path recently reset, you have your root cause: a
# physical-layer fault (cable/optic) resetting the session — not routing.
# 3. Confirm intended state, then remediate with the governed, audited path.
network-aiops device counters -t core-sw1
network-aiops config diff -t core-sw1 -f fix.cfg # dry-run the change firstCreate ~/.network-aiops/config.yaml:
devices:
- name: core-sw1 # used as -t core-sw1
driver: eos # ios | nxos | nxos_ssh | iosxr | eos | junos
host: 10.0.0.1
username: admin
optional_args: # passed verbatim to NAPALM (optional)
secret: enable-pw # enable/secret
port: 443
# Optional source-of-truth:
netbox:
url: https://netbox.example.comSecrets are stored encrypted in ~/.network-aiops/secrets.enc (Fernet/AES +
scrypt-derived key; chmod 600) — never in config.yaml or a plaintext .env.
Device passwords are keyed by device name; the NetBox token uses the reserved
name netbox-token:
network-aiops init # interactive wizard (recommended)
network-aiops secret set core-sw1 # store a device password (hidden prompt)
network-aiops secret set netbox-token # store the NetBox API token
network-aiops secret list # names only — values are never printed
network-aiops secret migrate # import a legacy plaintext .env, then delete itExport NETWORK_AIOPS_MASTER_PASSWORD to unlock the store non-interactively (MCP
server / cron). Legacy plaintext env vars (NETWORK_<TARGET_UPPER>_PASSWORD,
NETWORK_NETBOX_TOKEN) remain a deprecated fallback. An empty device password is
allowed for key-based SSH auth.
MCP
{
"command": "network-aiops",
"args": ["mcp"],
"env": {
"NETWORK_AIOPS_CONFIG": "~/.network-aiops/config.yaml",
"NETWORK_AIOPS_MASTER_PASSWORD": "…" // unlocks the encrypted secret store
}
}Audit & Safety
Every tool call is logged to
~/.network-aiops/audit.db(local SQLite; relocate withNETWORK_AIOPS_HOME).config_merge/config_replacecapture the pre-change running config and record an inverseconfig_replace-to-backup undo descriptor.config_replaceisrisk_level=high; CLI destructive commands (config merge/replace/rollback) require double confirmation and support--dry-run(which prints the diff without committing).All device text passes through
sanitize()(output hygiene: control/format-char stripping + truncation).Device passwords and the NetBox token live only in the encrypted
secrets.enc(chmod 600); tools never return passwords, SNMP community strings, or hashes.
See skills/network-aiops/SKILL.md and SECURITY.md for details.
Companion Skills
If you want… | Use |
Network device config / facts (Cisco/Arista/Juniper) | network-aiops (this) |
Kubernetes cluster operations | a cluster ops skill |
Hypervisor VM lifecycle | a hypervisor ops skill |
Contributing & feature requests
Coverage is intentionally focused. Need a device or action that isn't here yet? Open an issue or pull request at github.com/AIops-tools/Network-AIops — contributions, feature requests, and comments are all welcome.
License
Available Tools
33 toolsbgp_neighbor_rcaARead-only
[READ] Flag BGP neighbors that are down, shut, recently reset, or route-less.
Pulls get_bgp_neighbors and reports worst-first findings, each citing the session state (is_up / is_enabled) or uptime, with a cause and an action (check peer reachability / ACL / MD5 auth).
Args: target: Device name from config; omit to use the default device.
Inputs: target.
config_backupARead-only
[READ] Return the device running config, credential values masked by default.
Password/secret hashes, SNMP communities, SNMPv3 auth+priv keys, IKE pre-shared keys and RADIUS/TACACS/keychain keys are replaced with ""; every other line comes back untouched, so interface, routing and policy config reads exactly as the device wrote it.
The result always carries a "redaction" block saying how many lines were changed. Redaction is pattern-based across five vendor syntaxes, so it REDUCES exposure rather than guaranteeing none remains — in particular it cannot see multi-line PKI key blocks.
Prefer the CLI's '-o ' flag over include_secrets when a human needs the real config: it writes the raw text to a file instead of into this transcript.
Args: include_secrets: True to return the verbatim config, credentials and all. Every secret in it then lives wherever this result is stored. target: Device name from config; omit to use the default device.
Inputs: target, include_secrets.
config_diffARead-only
[READ] DRY-RUN: stage a candidate, return the diff, then discard it.
Nothing is committed. This is the dry-run primitive for previewing a change.
The diff is credential-redacted like config_backup, and for the same reason: a diff that ADDS 'snmp-server community X' contains X, and one that removes a line quotes the credential the device already had. The result carries a "redaction" block with the count.
Args: config_text: The configuration snippet (merge) or full config (replace). replace: True to diff as a full-config replacement; False (default) to merge. include_secrets: True to return the verbatim diff — use when verifying that the literal key you are pushing is the one that will land. target: Device name from config.
Inputs: config_text (required), target, replace, include_secrets.
config_mergeADestructive
[WRITE] Merge a config snippet and commit under a device-side revert timer.
The device REVERTS the change by itself after revert_in seconds unless
confirm_commit follows — so a change that severs your own management access
heals without anyone having to reach the box. Verify reachability, THEN call
confirm_commit. Check commit.safetyNet in the result: drivers that
cannot arm a timer commit permanently and say so in commit.warning.
Returns diff and a backup digest (size + sha256). The full config is
deliberately NOT returned — it carries credential hashes and PSKs — but the
raw text is retained in undo.db for the recorded rollback. The diff is
credential-redacted with no opt-out (see the redaction block); use
config_diff(include_secrets=True) first if you must verify a literal key.
dry_run=True stages the candidate, returns the diff, discards it, and runs the SAME refusal the real commit would — so a green preview is never followed by a refusal.
Args: config_text: The configuration snippet to merge. revert_in: Device-side revert timer in seconds (default 300). 0 disables it, leaving the recorded undo as the only rollback path. dry_run: If True, preview the diff + safety assessment without committing. target: Device name from config.
Inputs: config_text (required), target, dry_run, revert_in.
config_replaceADestructive
[WRITE] Replace the full config and commit under a revert timer. HIGH RISK.
Same commit-confirm contract as config_merge: the device reverts after
revert_in seconds unless confirm_commit follows. Verify reachability
first, then confirm. Check commit.safetyNet — when no timer could be
armed the change is permanent on landing.
Returns diff and a backup digest; the raw pre-change config is kept
in undo.db (0600) for the recorded rollback, not echoed back here. The
diff is credential-redacted with no opt-out (see the redaction
block); use config_diff(include_secrets=True) first if you must verify a
literal key.
dry_run=True previews the diff and runs the same refusal the real commit would, so the preview can never disagree with the commit.
Args: config_text: The full replacement configuration. revert_in: Device-side revert timer in seconds (default 300). 0 disables it, leaving the recorded undo as the only rollback path. dry_run: If True, preview the diff + safety assessment without committing. target: Device name from config.
Inputs: config_text (required), target, dry_run, revert_in.
config_rollbackADestructive
[WRITE] Revert the last committed change via NAPALM rollback(). No undo.
Device support varies (rollback depth is platform-dependent).
dry_run=True cannot predict the resulting config without the device, so it opens a session (verifying reachability) and reports a digest of the current running config — the state rollback would replace — without rolling back.
Args: dry_run: If True, verify reachability and state what rollback would attempt. target: Device name from config.
Inputs: target, dry_run.
confirm_commitADestructive
[WRITE] Confirm a pending commit-confirm change, cancelling its revert timer.
The second half of the commit-confirm workflow. Run it only AFTER verifying the device is still reachable and healthy — doing nothing is the safe alternative, because the device then reverts on its own.
dry_run=True reads whether a commit-confirm is actually pending (nothing is confirmed; the revert timer keeps running).
Args: dry_run: If True, report whether a pending commit exists without confirming. target: Device name from config.
Inputs: target, dry_run.
device_factsARead-only
[READ] Core device facts: hostname, vendor, model, OS version, serial, uptime.
Also returns the interface name list. Use get_interfaces for per-interface state/speed.
Args: target: Device name from config; omit to use the default device.
Inputs: target.
device_healthARead-only
[READ] Aggregated health: facts + interface up/down counts + environment.
Resilient to drivers lacking get_environment (that section becomes a note). Returns a 'healthy' flag and an 'issues' list summarising attention points.
Args: target: Device name from config; omit to use the default device.
Inputs: target.
get_arp_tableBRead-only
[READ] ARP table entries: interface, IP, MAC, age.
Args: target: Device name from config.
Inputs: target.
get_bgp_neighborsBRead-only
[READ] BGP neighbors per VRF: peer, remote AS, up state, prefix counts.
Args: target: Device name from config.
Inputs: target.
get_bgp_neighbors_detailARead-only
[READ] Detailed BGP neighbors per VRF: state, router id, AS, prefix stats.
Args: target: Device name from config; omit to use the default device.
Inputs: target.
get_environmentARead-only
[READ] Hardware environment: fans, temperature, power, CPU, memory.
Args: target: Device name from config; omit to use the default device.
Inputs: target.
get_interfacesBRead-only
[READ] Interfaces with up/down state, enabled flag, speed, and description.
Args: target: Device name from config.
Inputs: target.
get_interfaces_countersBRead-only
[READ] Per-interface traffic + error counters (octets, packets, errors, discards).
Args: target: Device name from config.
Inputs: target.
get_interfaces_ipBRead-only
[READ] Per-interface IPv4/IPv6 addresses and prefix lengths.
Args: target: Device name from config.
Inputs: target.
get_lldp_neighborsBRead-only
[READ] LLDP neighbors: local port, remote hostname, remote port.
Args: target: Device name from config.
Inputs: target.
get_lldp_neighbors_detailBRead-only
[READ] Detailed LLDP neighbors: chassis id, system name/description, capabilities.
Args: target: Device name from config.
Inputs: target.
get_mac_address_tableBRead-only
[READ] MAC address table: MAC, interface, VLAN, static/active flags.
Args: target: Device name from config.
Inputs: target.
get_network_instancesBRead-only
[READ] Network instances (VRFs): name, type, state, member interfaces.
Args: target: Device name from config.
Inputs: target.
get_ntp_serversARead-only
[READ] Configured NTP servers.
Args: target: Device name from config.
Inputs: target.
get_ntp_statsBRead-only
[READ] NTP peer synchronization stats (stratum, offset, jitter, reachability).
Args: target: Device name from config.
Inputs: target.
get_opticsBRead-only
[READ] Optical transceiver levels per interface/channel (rx/tx power, bias).
Args: target: Device name from config.
Inputs: target.
get_route_toARead-only
[READ] Routing-table lookup for a destination prefix (optionally by protocol).
Args: destination: The destination prefix to look up (e.g. 10.0.0.0/24). protocol: Optional protocol filter (e.g. bgp, ospf, static). target: Device name from config.
Inputs: destination (required), target, protocol.
get_snmp_informationARead-only
[READ] SNMP metadata: chassis id, contact, location. Community strings redacted.
Args: target: Device name from config.
Inputs: target.
get_usersARead-only
[READ] Local users and privilege levels. Password hashes are NOT returned.
Args: target: Device name from config.
Inputs: target.
get_vlansBRead-only
[READ] VLANs: id, name, and member interfaces (driver support varies).
Args: target: Device name from config.
Inputs: target.
interface_health_rcaARead-only
[READ] Flag admin-up/oper-down, erroring, discarding, or flapping interfaces.
Pulls get_interfaces + get_interfaces_counters and reports worst-first findings — each citing the measured number (error/discard count, last-flap seconds) that tripped it, with a cause and a concrete action.
Args: target: Device name from config; omit to use the default device.
Inputs: target.
netbox_device_interfacesARead-only
[READ] List a NetBox device's interfaces (name, type, enabled, description).
The intended interface inventory from source-of-truth — compare against live device state (get_interfaces) to spot drift.
Returns {"interfaces": [...], "returned": N, "limit": L, "truncated": bool}.
Do NOT report drift from a truncated list — re-run with a higher limit.
Args: device: Exact NetBox device name (see netbox_list_devices). limit: Maximum interfaces to return (default 100).
Inputs: device (required), limit.
netbox_get_deviceARead-only
[READ] Return a single NetBox device by exact name.
Args: name: Exact NetBox device name (see netbox_list_devices).
Inputs: name (required).
netbox_list_devicesARead-only
[READ] List NetBox devices (name, role, site, status, primary IP).
Requires a configured NetBox block. Use this to confirm intended state before pushing config to a device.
Returns {"devices": [...], "returned": N, "limit": L, "truncated": bool}.
When truncated is true the estate is larger than what you were shown —
re-run with a higher limit before concluding anything about coverage.
Args: name: Optional name filter (contains match). limit: Maximum devices to return (default 50).
Inputs: name, limit.
undo_applyADestructive
[WRITE][risk=medium] Apply a recorded undo by dispatching its inverse tool.
The inverse runs through its own governed tool, so its real risk tier is recorded in that tool's audit row. Pass dry_run=True to preview the inverse call without executing it. A token can only be applied once.
Args:
undo_id: The undoId from undo_list (or an _undo_id in a write result).
dry_run: If True, preview the inverse tool + params without running it.
target: Passed through to the inverse tool when it accepts a target.
Inputs: undo_id (required), target, dry_run.
undo_listARead-only
[READ] List recorded, not-yet-applied undo tokens (most recent first).
Each entry names the original tool, the inverse tool that undo_apply
would run, and a human note. Use the undoId with undo_apply.
Returns {"undos": [...], "returned": N, "limit": L, "truncated": bool}.
truncated is measured (one extra row is fetched), not guessed from a
length coincidence: when it is true there are MORE tokens than shown, so
re-run with a higher limit rather than reporting the list as complete.
Each entry carries effectVerified. False means the original write lost
its response, so the change it reverses is PROBABLE, not confirmed — check
the live state before applying, and do not report the result as a restore
of a state that may never have been reached.
Args: limit: Max rows to return (default 50, capped at 500). target: Unused (undo state is host-local); accepted for CLI uniformity.
Inputs: limit, target.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 33 tools
Several tool families overlap in purpose: get_bgp_neighbors vs get_bgp_neighbors_detail vs bgp_neighbor_rca, get_lldp_neighbors vs get_lldp_neighbors_detail, config_diff vs config_merge/replace dry_run, and device_health vs its underlying getters. Descriptions clarify the distinctions, but an agent still faces non-trivial choices among near-equivalent read/diagnostic tools.
Names are all snake_case and mostly follow domain prefixes (get_, config_, netbox_, undo_, *_rca, device_). Minor deviations exist, such as device_facts/device_health lacking get_, and netbox_device_interfaces lacking a verb while netbox_list_devices and netbox_get_device include one.
33 tools is high for a single MCP server and exceeds the 25-tool threshold where count becomes unwieldy. Though the network domain is broad, several tools are redundant variants of summary/detail or aggregate/raw operations, suggesting consolidation is possible.
The surface covers config lifecycle, wide read telemetry, targeted RCA, NetBox inventory, and undo tokens, which is strong for network AIOps. Gaps remain, including OSPF/ISIS neighbor state, an explicit ping/reachability test for safe commits, and a tool to list locally configured target devices.
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Manage CloudPepper servers, Odoo instances, backups, and deployments over MCP.
One OAuth connector for your team's remote MCP servers, with Tool Packs, guardrails and logs.
Authenticated MCP server for ClearPolicy policy and compliance workflows.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server for interacting with Nautobot, enabling network source of truth queries, device management, IPAM, and data quality audits via tools and prompts.MIT
- FlicenseNot gradedqualityDmaintenanceProvides MCP tools for Cisco Meraki Dashboard API, enabling management of networks, configuration templates, and health checks via natural language commands.-
- FlicenseAqualityDmaintenanceProvides MCP tools to query, compare, and analyze network device configurations managed by Oxidized, such as listing devices, viewing backup status, and generating diffs between configuration versions.8-
- AlicenseNot gradedqualityDmaintenanceEnables safe interaction with Juniper Junos devices (SRX firewalls) via MCP, providing operational read tools and a configuration change flow with device-side diff preview and automated rollback.Apache 2.0