Network Lab MCP
OfficialNetwork Lab MCP provides an AI client with active lab context and controlled, observable terminal access to lab devices, without exposing private credentials or committing definition changes.
Read the active topology (devices and links where work is performed).
Read operating principles, the active scenario/reference, and metadata catalogs for stored scenarios/references; optionally inspect named scenarios/references read-only.
Open or reuse managed terminal sessions by logical device ID, with SSH/Telnet login prompts handled from private access-info when safe.
Send literal text, special keys, and Enter to an open device terminal.
Read recent terminal output/scrollback to check prompts, command results, paging, or errors.
List managed production terminal sessions, including stale sessions no longer in the active topology.
Close managed production terminal sessions, including stale ones.
Use terminal sessions for AI-driven lab investigation, troubleshooting, configuration, and verification subject to client approvals and lab safety boundaries.
Provides controlled SSH/Telnet terminal access to Cisco network lab devices, enabling AI-assisted topology discovery, configuration, troubleshooting, and verification through managed sessions while keeping private connection credentials hidden.
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 Lab MCP investigate why OSPF neighbors are down between core1 and core2"
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 Lab MCP
An AI Network Engineer Workspace for real network labs.
Describe the network. Let AI investigate, build, troubleshoot, and verify it — while you remain in control.
Network Lab MCP connects an MCP-capable AI client to real network lab devices through a small, controlled tool interface. It supplies the AI with explicit engineering context and observable terminal sessions, so the AI can follow evidence, run commands, and work through complex lab investigations instead of relying on a rigid test script.
The AI client does the reasoning; Network Lab MCP provides the context and access; the engineer retains authority over decisions and committed definitions.
Watch the demo · Why it exists · How it works · Configuration model · Quick Start · SSH jump servers · Documentation
Why Network Lab MCP?
As a network engineer, I often want to investigate or validate something in a lab, but customer work, troubleshooting, meetings, and documentation limit the time available for hands-on verification.
What if AI could do the time-consuming investigation — inspect the topology, connect to the right devices, compare outputs, follow a problem, and return evidence — without taking away the engineer's visibility or judgment?
That is the motivation behind Network Lab MCP: delegate the investigation, not the engineering responsibility.
The project explores a concept I call Vibe Networking, inspired by Vibe Coding: express the network objective in natural language, let an AI agent plan and execute work in a real lab, inspect what actually happened, and iterate. It is a direction for AI-assisted engineering, not a claim of unrestricted or fully autonomous production-network operation.
Network Lab MCP provides a lightweight AI network engineer layer for lab environments, designed to make the most of an AI client's reasoning capabilities while retaining observable, controlled device access.
Related MCP server: network-lab
What you can do
Investigate and troubleshoot: inspect live device state across a lab, correlate observations, and collect command evidence.
Discover and validate topology: collect LLDP/CDP neighbors, review a topology candidate, and explicitly commit the definition.
Build and verify lab services: give the AI engineering objectives and let it use real terminals to configure and test lab devices, subject to the AI client's permissions and human oversight.
Validate resilience and traffic: observe planned failures, traffic behavior, protocol convergence, and service continuity using available lab instruments and evidence.
Reuse engineering knowledge: guide repeated work with Scenarios and References rather than repeating every instruction from scratch.
Watch AI activity: monitor terminal output live and inspect session transcripts instead of treating the AI as a black box.
Work from your local workstation: use SSH ProxyJump for SSH devices and SSH local port forwarding for legacy Telnet-only devices, without running Network Lab MCP on the jump server.
Network Lab MCP is not a network-engineering reasoning model, a fixed test-script library, or a production network automation platform. An external AI client supplies the reasoning and decides which tool or command to use next.
How it works
Human intent: an engineer specifies the goal and the limits of the task.
Engineering context: Network Lab MCP exposes the selected topology, task instructions, principles, and applicable references — without revealing private access credentials.
AI reasoning: the AI client chooses the investigation steps and invokes MCP tools.
Controlled execution: Network Lab MCP connects to devices through managed SSH/Telnet terminal sessions, using private connection information internally.
Evidence and review: the AI analyzes device outputs and reports findings; the engineer can observe terminals and approves changes to managed definitions through the human CLI.
Safety boundary: the candidate/commit model protects Network Lab MCP's managed lab definitions and selections. It does not automatically make device CLI commands read-only or require human approval before every command sent by an AI client. Configure client permissions and use an isolated lab accordingly.
Built on Proven Tools
Network Lab MCP follows a lightweight, composable design: reuse established tools for network connectivity and terminal management, and build the AI-oriented engineering layer on top. Rather than implementing its own SSH or Telnet stack or terminal-session manager, it orchestrates OpenSSH, tmux, and a local Telnet client where legacy access is required.
OpenSSH handles SSH transport and authentication; tmux provides persistent, observable terminal sessions; and Telnet supports legacy lab devices. Network Lab MCP adds logical device resolution, private connection handling, session lifecycle and safety checks, topology discovery, and reusable engineering context. The AI client supplies reasoning; the engineer retains operational judgment and control.
This approach avoids reinventing mature protocols, but still requires careful integration around SSH host keys, jump-hop behavior, terminal ownership, and failure handling. See Connection architecture for the internal design and trade-offs.
A deliberately small MCP interface
Network Lab MCP exposes exactly seven MCP tools:
Tool | Purpose |
| Read the currently selected logical topology |
| Read selected task guidance and engineering context |
| Open a managed terminal by logical device ID |
| Send text to a managed device terminal |
| Read its output |
| Inspect managed terminal sessions |
| Close a managed terminal session |
The AI uses logical device names; it does not obtain private access-info. See the MCP tool contract.
Configuration Model
Network Lab MCP separates what is selected, how to connect, what exists, what to accomplish, and what knowledge to reuse.
Conceptual diagram: the running configuration selects definitions; it does not contain every definition's full content. The illustration's masked password is not a representation of local CLI password display behavior.
Component | Responsibility | AI visibility |
| Selects the active access-info, topology, scenario, and references | Indirect |
| Private management endpoints and authentication details | Not exposed through MCP |
| Logical devices, interfaces, and connectivity | Yes |
| Objectives, task procedures, and verification criteria | Yes |
| Reusable technical knowledge and operational guidance | Yes, when selected or inspected read-only |
running-config is a selection model, not the storage location for all definitions. Creating or changing a topology, Scenario, or Reference does not automatically select it. Selection changes become active after an explicit CLI commit.
Scenario describes what the AI is trying to accomplish now. Reference contains knowledge that can help across many tasks, such as SR-MPLS or EVPN guidance, platform-specific notes, or test-equipment procedures. Principles are separate, always-applied rules, not a substitute for task-specific scenarios or reusable references.
The AI may inspect a catalog of stored Scenarios and References, use the applicable knowledge, and propose new or refined definitions. It does not directly commit those definition changes. Engineers edit and commit them through the independent human CLI.
Three complementary configuration workflows
CLI configuration: use the IOS XR-style human CLI to manage access information, definitions, and active selections with candidate/commit behavior.
cleardiscards uncommitted changes.Topology discovery: discover LLDP/CDP neighbor relationships from actual devices and review the resulting candidate before a separate definition commit and active selection.
YAML-based engineering context: edit Topology, Scenario, and Reference definitions through the configured external editor (
$VISUAL, then$EDITOR, then Vim). Access-info uses the structured CLI.
New installations start with the fictional sample_lab access-info and topology, the onboarding getting_started Scenario, and the supporting cisco_platform_guidance Reference. Existing local selections are not automatically rewritten.
See Architecture, CLI reference, and Scenario / Reference format.
Demo
Traffic Loss Validation with Network Lab MCP
The video demonstration illustrates an AI-assisted workflow involving live terminal observation, a validation Scenario, traffic measurement, analysis, and reporting.
The demo is a concrete lab example, not a guarantee that every device, test instrument, or network design can be controlled without additional configuration.
Quick Start
Choose your platform:
Network Lab MCP currently uses a local editable installation. Keep the repository checkout: its local lab/ directory is part of the operational model. A non-editable wheel/package-index install is not the supported deployment model.
macOS installation
The following steps are designed for engineers who are familiar with network CLI tools but may be new to Python virtual environments, MCP, or Claude Code. Run the shell commands in macOS Terminal, not inside the network-lab# CLI.
Requirements
Component | Why it is needed |
macOS | Local workstation running Network Lab MCP |
Python 3.10+ | Network Lab MCP runtime; a supported Python 3.13 environment was used during validation |
Git | Clone the source repository |
| Managed terminal sessions and observable command output |
OpenSSH client ( | Direct SSH, ProxyJump, and SSH tunnels |
Vim ( | Default editor for Topology, Scenario, and Reference definitions; normally included with macOS |
Claude Code | AI client used in the macOS E2E validation; install and sign in separately |
| Only for direct Telnet or legacy Telnet-only devices via an SSH tunnel |
Homebrew is a convenient way to install missing prerequisites; it is not itself part of Network Lab MCP. See brew.sh for installation instructions. See the Claude Code setup guide for its supported installation procedure.
Step 1 — Inspect what is already installed
uname -s # Expected: Darwin
python3 --version # Must be Python 3.10 or newer
command -v git
command -v tmux
command -v ssh
command -v claudeIf any command is missing, install that dependency first. If Homebrew is available, a typical setup for Git, Python, and tmux is:
brew install git python tmuxOpenSSH is normally available on macOS; check command -v ssh rather than assuming a particular installation path. Install Claude Code separately using its official instructions. Do not expect pip install -e . to install Claude Code, tmux, OpenSSH, or Telnet.
Text editor: Network Lab MCP uses $VISUAL, then $EDITOR, then vim for its edit command. Vim is normally included with macOS, so additional installation is usually unnecessary. Check with command -v vim; if you prefer another editor, set VISUAL or EDITOR in the environment that launches the Network Lab CLI. Access-info remains editable through structured CLI commands rather than the external editor. Before launching it, edit verifies (via the C library) that the editor's environment is UTF-8 and, if not, sets LC_ALL to a verified UTF-8 locale for the editor process only; it refuses to launch otherwise. Your terminal emulator must also use UTF-8 for Japanese text to display correctly. See docs/cli_reference.md.
For a Telnet-only lab device, also check:
command -v telnet
telnet --help # Option syntax varies by client; consult its own help/man pageSome macOS installations do not include a Telnet client. Install a compatible client using a trusted package source if needed. Before using Telnet over SSH, confirm that the installed client supports the options required by your Network Lab MCP version (including -K and -E where used by the implementation). Package names, executable locations, and supported options vary; do not assume that /usr/local/bin/telnet exists on every Mac. If you only need SSH devices, Telnet is optional.
Step 2 — Clone the project
cd ~
git clone https://github.com/CiscoDevNet/network-lab-mcp-community.git network-lab-mcp
cd network-lab-mcpYou may choose a different directory. Keep a note of its absolute path; the MCP registration will use it. The example below uses ~/network-lab-mcp only because the clone command above creates that directory.
Step 3 — Create the Python environment and install
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .The (.venv) shell prefix is a useful indication that the virtual environment is active. A venv keeps Network Lab MCP's Python dependencies separate from other projects. Every new Terminal window used for ./run_cli.sh should activate this venv first, or use its Python executable explicitly.
Step 4 — Check the installation
python --version
python -m pip show network-lab-mcp
test -x .venv/bin/network-lab-mcp && echo 'MCP executable found'
command -v tmuxIf a Python environment was upgraded or moved, recreate the virtual environment and register the new executable path as needed. Do not move the repository after registering the MCP server without updating Claude Code's command path.
Step 5 — Initialize the local running configuration
if [ ! -e lab/settings.yaml ]; then
cp lab/settings.example.yaml lab/settings.yaml
fiThis deliberately does not overwrite an existing lab/settings.yaml. The checked-in sample_lab definitions use fictional documentation addresses: they let you inspect the configuration model but are not real reachable devices. Real lab access requires a private access-info definition and matching logical device IDs in the selected topology.
Step 6 — Start the human CLI
./run_cli.shThen type commands inside the Network Lab CLI:
network-lab# help
network-lab# show version
network-lab# show running-config
network-lab# configure
network-lab(config)# show running-config./run_cli.sh launches the human configuration CLI, not the MCP stdio server. A working CLI does not, by itself, prove that a real network device can be reached. Do not share show running-config from an access-info definition: it can display real passwords in plaintext.
Step 7 — Register and verify the MCP server
Follow Register the MCP server. User scope is recommended for personal macOS installation, because Claude Code often runs from a working directory other than the Network Lab MCP source tree.
Step 8 — Test from a separate working directory
mkdir -p ~/network-lab-workspace
cd ~/network-lab-workspace
claudeInside Claude Code, use /mcp and confirm that network-lab is connected. Start with a safe request, such as “Use Network Lab MCP to show the active topology; do not connect to devices or change any configuration.” After configuring a permitted lab, proceed to read-only device commands.
Linux installation
Linux remains supported. Install Python 3.10+, Git, tmux, and OpenSSH through your distribution's package manager. Install Telnet only if your lab requires it. The example below is for a Debian/Ubuntu-style system:
sudo apt-get update
sudo apt-get install -y git python3 python3-venv python3-pip tmux openssh-client
git clone https://github.com/CiscoDevNet/network-lab-mcp-community.git network-lab-mcp
cd network-lab-mcp
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
if [ ! -e lab/settings.yaml ]; then
cp lab/settings.example.yaml lab/settings.yaml
fi
./run_cli.shUse the registration instructions below for your AI client. Linux behavior depends on the distribution, OpenSSH and Telnet clients, and network configuration; see the tested Windows/WSL2 case below for additional coverage.
Windows 11 / WSL2 installation
Network Lab MCP runs inside Linux under WSL2, not as a native Windows application. Install Claude Code and Network Lab MCP in the same Ubuntu distribution, and run all Linux commands below inside the Ubuntu terminal. These steps were validated on Windows 11 Enterprise + WSL2 + Ubuntu 26.04.1 LTS, with Python 3.14.4, Claude Code 2.1.317, and Network Lab MCP 0.3.0. This is a tested configuration, not a claim that every Windows/WSL release or enterprise network works identically.
Step 1 — Install and select a WSL2 Ubuntu distribution
In Windows PowerShell, run:
wsl --install -d Ubuntu
wsl --list --verboseComplete Ubuntu's first-run username/password setup; Windows may require a reboot. If you have multiple WSL distributions, explicitly choose the one you want with wsl -d Ubuntu (using the exact name shown by wsl --list --verbose). wsl --set-default Ubuntu is optional. Each distribution has its own home directory, packages, and virtual environments; changing distributions can make a previously installed .venv appear missing. Do not unregister a distribution to fix a Python error: wsl --unregister <distribution> permanently removes its data.
Step 2 — Install prerequisites in Ubuntu
sudo apt update
sudo apt install -y git python3 python3-venv python3-pip tmux openssh-client vim
# Only if your lab requires Telnet or Telnet-over-SSH:
sudo apt install -y telnet
python3 --version
command -v tmux
command -v sshStep 3 — Clone and install Network Lab MCP in the Linux filesystem
Use a path under ~/, not /mnt/c/, for predictable Linux permissions and filesystem performance.
mkdir -p ~/tools
cd ~/tools
git clone https://github.com/CiscoDevNet/network-lab-mcp-community.git
cd network-lab-mcp-community
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
python -m pip show network-lab-mcpIf ensurepip is not available, install the python3-venv package matching the Ubuntu Python interpreter, then recreate the incomplete .venv. Activate .venv before running ./run_cli.sh in a new shell.
Step 4 — Initialize and verify the human CLI
if [ ! -e lab/settings.yaml ]; then
cp lab/settings.example.yaml lab/settings.yaml
fi
./run_cli.shIn the Network Lab CLI, run show version and show running-config, then exit. The example configuration uses fictional addresses and cannot be used to reach actual routers. Do not publish real Access-info output: local CLI commands can show passwords in plaintext.
Step 5 — Install Claude Code in the same Ubuntu distribution
Follow the official Claude Code setup documentation. For the native Linux installer used in this validation:
curl -fsSL https://claude.ai/install.sh | bash
# Only if ~/.local/bin is not already in your PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
claude --version
claude doctor
claude auth loginAn eligible Claude Code account or API setup is required. Register the server from the Network Lab MCP checkout (see Register the MCP server):
cd ~/tools/network-lab-mcp-community
claude mcp add --scope user network-lab -- \
"$(pwd)/.venv/bin/network-lab-mcp"
claude mcp listExpect network-lab: ... - ✔ Connected. Launch claude and use /mcp to verify the tools are loaded. A first safe prompt is: “Use Network Lab MCP to read the active topology and execution instructions; do not connect to devices or change settings.” lab/settings.yaml must exist or these MCP calls will report Local settings file not found.
Step 6 — Check WSL2 network reachability before real-device access
A Windows host may reach an SSH jump server while Ubuntu in WSL2 times out. Check the same authorized target and TCP port separately:
# Windows PowerShell
Test-NetConnection <jump-host-address> -Port 22# Ubuntu in WSL2 (install netcat-openbsd if nc is missing)
nc -vz -w 5 <jump-host-address> 22If Windows succeeds but WSL2 times out, Windows 11's mirrored networking may help, especially with corporate VPN/routed networks. Review existing settings and your organization's policy before editing %USERPROFILE%\.wslconfig in Windows:
[wsl2]
networkingMode=mirrored
dnsTunneling=trueThen run wsl --shutdown in Windows PowerShell, restart Ubuntu, and repeat the WSL2 TCP test. This is a troubleshooting option, not an installation prerequisite; VPN/security-software behavior varies. Do not disable the firewall or SSH host-key checking to make a connection succeed. See Microsoft WSL networking documentation.
Real-lab validation (November 3, 2026). With network reachability restored, the Windows/WSL2 setup successfully connected via Claude Code and the seven MCP tools; auto-registered first-use SSH host keys (TOFU); discovered LLDP/CDP neighbors; and opened managed terminals through an SSH jump server to an IOS XR router (ProxyJump) and a Telnet-only IOS device (SSH local port forwarding + local Telnet client). Read-only commands, two simultaneous device sessions, and session reuse were verified. This does not establish universal device/OS compatibility. Long CLI output could pause at a --More-- pager (full-output collection was not demonstrated); monitor terminal and failure/restart recovery were not validated in this Windows test. For sensitive data handling and Telnet plaintext risk, see Security and operational boundaries.
Register the MCP server
For a local stdio MCP server, register the absolute path to .venv/bin/network-lab-mcp. Do not register run_cli.sh: it is the interactive human CLI, not the MCP server entry point.
Claude Code — recommended user scope
From the Network Lab MCP repository directory:
# Run from the repository checkout, after creating .venv.
claude mcp add --scope user network-lab -- \
"$(pwd)/.venv/bin/network-lab-mcp"
claude mcp listExpected result (the path varies):
network-lab: /absolute/path/to/network-lab-mcp/.venv/bin/network-lab-mcp - ✔ Connected--scope user makes this MCP registration available to Claude Code across your working directories. A project/local-scoped registration can work in the repository directory yet be invisible from another workspace — a common source of confusion. Do not register another entry blindly if one with the same name already exists; first inspect its scope and executable path. An unrelated MCP server reporting Failed to connect does not necessarily prevent network-lab from connecting.
Restart an already-running Claude Code session after changing MCP configuration; changes may not appear in the current session. In Claude Code, use /mcp to confirm the server is loaded. The seven Network Lab MCP tools should then be available to the AI client.
Codex CLI
codex mcp add network-lab -- \
/absolute/path/to/network-lab-mcp/.venv/bin/network-lab-mcp
codex mcp listFor a local stdio server, Codex may show Auth: Unsupported; device authentication is handled privately by Network Lab MCP, not by MCP authentication. In the tested Codex environment, the following server setting was also needed in ~/.codex/config.toml:
[mcp_servers.network-lab]
command = "/absolute/path/to/network-lab-mcp/.venv/bin/network-lab-mcp"
default_tools_approval_mode = "approve"Restart Codex after changing its configuration. AI-client configuration and approval options may differ by client version.
First use and troubleshooting
Separate the three layers when diagnosing a problem:
Installation: can the human CLI start with
./run_cli.sh?MCP registration: does
claude mcp listshownetwork-lab ... ✔ Connected, and does/mcpshow it in the current Claude Code session?Device access: are the correct active access-info and topology selected, and can the allowed device actually be reached?
Symptom | Check / resolution |
| Install a supported Python 3.10+ interpreter, recreate |
| Install tmux, verify |
| Install a compatible local Telnet client and verify the supported options; SSH-only use does not require it. |
| Activate the correct venv and run |
| Register at user scope with the absolute executable path; verify the active Claude Code configuration. |
Works from the source checkout but not another directory | The server was likely registered in project/local scope. Check its scope; user scope is normally preferable for workstation use. |
| Check that the executable exists, the venv is intact, and the registration points to the current checkout. Avoid printing environment variables containing secrets. |
| Start a new Claude Code session after updating registration. |
| The active topology and active access-info have different device inventories. Add an authorized connection definition or select the intended definitions in the human CLI; never guess credentials. |
Discovery connects but produces zero managed links | Check whether observed neighbors are actually registered as managed devices. Unresolved LLDP/CDP neighbors do not become guessed topology links. |
Jump-host password prompt is rejected | Check the running version, private access-info selection, prompt/host identity, and authentication configuration. Do not disable fail-closed checks to force access. |
Host key verification failed | A first-use key is registered automatically, so this means the key of the jump server or target changed (or is of another type than the registered one) or could not be registered ( |
Important: topology and access-info are independently selected. A topology can contain Router2 while the selected access-info only contains Router1 and LegacyRouter. In that case, opening Router2 must fail rather than discovering or guessing its credentials. Discovery can create a topology definition without automatically making it the active topology. The second selection/commit step matters; see the example below.
First safe AI request:
Use Network Lab MCP to inspect the currently active topology and execution instructions. Report the logical device inventory. Do not open terminal sessions or make changes.
First authorized read-only device request:
Use Network Lab MCP tools only. Open a managed terminal to
Router1, runshow version, read the response, and close only the session you created. Do not execute configuration commands or reveal credentials.
Permissions: keep the AI client's normal approval controls enabled, particularly for device configuration and destructive operations. Bypass/never-ask modes are appropriate only when explicitly chosen for a fully controlled, isolated lab; they bypass client-side confirmation and are not prerequisites for using Network Lab MCP.
SSH Jump Server Support
Network Lab MCP can access both modern SSH-enabled network devices and legacy Telnet-only devices through an SSH jump server, directly from a local workstation. The two transport methods are deliberately distinct:
Target device | Connection method | Local requirement | Jump-server requirement |
SSH-enabled router | OpenSSH ProxyJump | OpenSSH | SSH server and reachability to target SSH |
Legacy Telnet-only device | SSH local port forwarding + local Telnet client | OpenSSH and Telnet client | SSH server and reachability to target Telnet port |
No Network Lab MCP installation and no Telnet client are required on the jump server. Network Lab MCP runs on the local workstation; it selects the connection method from the private Access-info definition. A single Access-info can describe both kinds of devices.
Local workstation (macOS, Linux, or Windows/WSL2)
Claude Code ── MCP ── Network Lab MCP
|
+── SSH ProxyJump ──────> jump1 ── SSH ──> Router1
|
+── SSH -L 127.0.0.1 ──> jump1 ── Telnet ──> LegacyRouter
+ local telnet clientThe second path is not SSH ProxyJump to a Telnet device. It uses SSH local port forwarding (a tunnel between the workstation and the jump server), followed by Telnet over the jump server's network path to the legacy device. The local forwarded port binds to 127.0.0.1, not a public interface.
Example private Access-info
The following is illustrative only, with RFC 5737 documentation addresses and no real credentials. Use the human CLI to create a private Access-info definition; actual authentication fields remain local and must never be committed to a public repository.
access-info example_lab
jump-host jump1
type host
address 192.0.2.10
transport ssh
port 22
username jumpuser
!
device Router1
type iosxr
address 192.0.2.20
transport ssh
port 22
username labuser
jump-host jump1
!
device LegacyRouter
type ios
address 192.0.2.30
transport telnet
port 23
username labuser
jump-host jump1
!Add the credentials through the private configuration workflow when needed. This example is not a claim that those documentation-only addresses are reachable. The active topology must also use the exact logical device IDs Router1 and LegacyRouter for AI terminal access.
SSH host keys: lab TOFU (trust on first use)
You do not type anything for a new device. The first time an SSH hop (the device and, for ProxyJump, the jump server) is used and no known_hosts file has an entry for it, Network Lab MCP registers its host key automatically, for discover topology and for managed terminals alike:
An authentication-free OpenSSH probe (dummy user
nlm-hostkey-probe, no password, no key, no multiplexing, a temporary known_hosts) records the key the device presents.The key is saved in the product's own known_hosts (macOS
~/Library/Application Support/Network Lab MCP/ssh/known_hosts, Linux~/.local/state/network-lab-mcp/ssh/known_hosts) and read back, before any credential is sent.The real connection then runs with
StrictHostKeyChecking=yeson every hop. Your own~/.ssh/known_hostsis read but never modified.
The CLI prints SSH host key automatically accepted (TOFU): with the device, hop and SHA256 fingerprint; every registration is also logged to logs/hostkey-tofu.log.
Already registered (any known_hosts): nothing is probed, nothing is asked.
Changed key, or a different key type than the registered one: the connection is refused before any credential is sent. A key is never replaced automatically and MCP/managed terminals cannot replace it. In an interactive terminal,
discover topologyoffers a review: it shows the old and new fingerprints and asksReplace the trusted host key? [yes/no] (default: no):on the controlling terminal. A key that lives in your own~/.ssh/known_hostsis never edited; the CLI prints thessh-keygen -Rcommand for you to run.TOFU limit: the first key cannot be verified independently; someone in the middle of the first connection would be trusted. Register keys manually if your lab network is not trusted.
Effect on the device: the probe is one failed-looking login for a user that does not exist. Some devices count that, ask AAA, or block the source address. That has not been tested on real equipment; if a device cannot be probed, register its key once with a manual
ssh.Details: SECURITY.md (section 11a) and docs/cli_reference.md.
Validation and security status
On November 2, 2026, macOS real-lab E2E checks succeeded for an SSH-enabled IOS XR device and a legacy Telnet-only IOS device, both through an SSH jump server: managed terminal open, authentication, read-only show commands, response retrieval, simultaneous sessions, independent closure, and final cleanup. Discovery also connected through both methods and collected LLDP/CDP observations. This is specific observed coverage, not a claim that all macOS/Telnet/OpenSSH combinations, unexpected disconnects, or restart/fault conditions have been tested.
The local workstation ↔ jump server SSH connection is encrypted.
The jump server ↔ legacy Telnet-only device path carries unencrypted Telnet traffic; use only an authorized, protected lab/management network and account for this risk.
Local port forwarding through
127.0.0.1is not a process-level access-control boundary.Private device and jump-server passwords are resolved internally; they must not be put in AI prompts, published logs, or repository examples.
SSH host-key verification must remain enabled. First-use keys are registered automatically (TOFU, see above); a changed or other-type key is refused and can only be replaced by a human in the CLI.
Lab TOFU, validated on macOS in a real lab: Topology Discovery through an SSH jump server reached 9 of 9 devices (including a Telnet-only device) with 7 first-use host keys registered automatically (ED25519, RSA and ECDSA) and no manual key input; a second run needed no new registration and gave the same results. In short: no manual host-key approval on first use, already-known hosts are not registered again, and a changed registered key is refused (replacement only by a human in the CLI). Details: CHANGELOG and SECURITY.md section 11a.
Not yet validated across all environments: the jump server's own first-use registration and changed-key replacement flows on real devices, effects of the authentication-free probe on AAA (failed-login counters, TACACS+/RADIUS, login block-for, source blocking), legacy SSH algorithms on real devices, and all SSH authentication methods and failure patterns. Windows/WSL2 real-lab coverage is described in Windows 11 / WSL2 installation; this does not validate other Linux distributions. Additional verification is needed before relying on them.
Example: discovering and selecting a topology
First, create a private access-info definition and select it as active through the human CLI. For example, you can start by copying the fictional template and changing it locally:
cp lab/access-info/sample_lab.yaml lab/access-info/my_lab.yamlWith my_lab already selected as the active access-info, a typical CLI flow is:
network-lab# configure
network-lab(config)# discover topology
Discovering topology from access-info 'my_lab'...
...
Discovery complete.
...
network-lab(config-topology-my_lab)# show configuration
...
network-lab(config-topology-my_lab)# commit
Commit complete.
network-lab(config-topology-my_lab)# root
network-lab(config)# running-config
network-lab(config-running)# topology my_lab
network-lab(config-running)# commit
Commit complete.The two commits serve different purposes: the first saves the discovered topology definition; the second selects it as active.
Discovery is intentionally conservative:
discover topologycollects LLDP/CDP evidence only;discover topology l3adds observed IPv4/VRF information.It rebuilds the topology candidate from the current observations instead of silently merging older links. Unobserved elements can therefore disappear from the new candidate. The committed definition remains untouched until
commit.Missing or conflicting evidence, failures, and uncommitted manual edits cause Discovery to fail closed rather than guessing or overwriting edits.
Discovery does not configure devices, enable LLDP/CDP, auto-commit, or auto-select a topology.
cleardiscards uncommitted candidate changes and restores the committed state.
See CLI reference for detailed discovery conditions and command syntax.
After the context is selected, a typical AI sequence uses:
get_active_topology()
get_execution_instructions()
terminal_open(...)
terminal_send(...)
terminal_read(...)
...Observable terminals
Engineers can observe the same managed terminal activity used by the AI, read-only, from the human CLI:
network-lab# terminal monitor R1
RP/0/RP0/CPU0:R1#show version
...
RP/0/RP0/CPU0:R1#Monitoring does not inject commands into the observed session. It can follow managed and Discovery terminal sessions, including their lifecycle changes. Exit locally with q.
Terminal transcripts are stored at logs/terminal/<device-id>/*.log. They are raw transcripts, not guaranteed-redacted records; handle them as sensitive data. See Terminal monitor.
Platform-aware engineering knowledge
The architecture is vendor-neutral, but the public examples and initial platform guidance focus on Cisco devices. The included cisco_platform_guidance Reference illustrates how reusable knowledge can be qualified by device family, software release, feature, and question type. It is selected by the sample configuration, not mandatory for all installations, and it does not fetch or validate documentation automatically.
Protocol theory may transfer across platforms, but command syntax, supported features, limitations, telemetry paths, and release-specific behavior require device-appropriate evidence. For example, telemetry paths should come from applicable YANG models, not guesses; the Cisco YANG models repository is one possible reference source.
Supported device types
| Platform | Topology Discovery |
| Cisco IOS XR | LLDP + CDP |
| Cisco IOS XE | LLDP + CDP |
| Classic Cisco IOS | CDP |
| Cisco NX-OS | Not currently supported |
| Generic host / endpoint | Skipped |
A registered type does not imply that every platform capability, command, or discovery protocol is supported.
Security and operational boundaries
See SECURITY.md for the complete trust model and vulnerability reporting guidance.
Private credentials: no MCP tool exposes
access-info. Terminal connections resolve credentials internally from the selected private definition.Local CLI visibility:
show configurationandshow running-configcan display access-info passwords in plaintext for human lab use. Do not share that output.Raw device output: terminal results and logs are not universal secret-redaction mechanisms. Remote device echoes and output can contain sensitive information.
SSH/Telnet: SSH key/agent and password authentication are supported; classic IOS-style Telnet authentication is lab-only because Telnet is unencrypted over the target leg.
Jump hosts: one SSH jump hop is supported; ProxyJump is for SSH targets, while Telnet targets use SSH local port forwarding. Multi-hop chains are not supported.
Change control: candidate/commit applies to local definition editing. Sending a configuration command to a real device through a terminal is a separate operation governed by the AI client's permissions and your lab procedures.
Repository hygiene:
.gitignoreexcludes common local operational data but is not a substitute for reviewing every change before publishing.
Current limitations
Discovery supports IOS XR, IOS XE, and classic IOS, but not NX-OS.
No SNMP, NETCONF, RESTCONF, or generic discovery-plugin framework.
No automatic stale-link pruning outside a Discovery run; Discovery itself rebuilds the candidate from current observations.
L3 enrichment records directly observed IPv4 address and VRF information, not an inferred routed topology.
Editable checkout required; no standard non-editable/wheel installation.
access-infois edited through structured CLI commands, not the external YAML editor.SSH jump-server support is limited to one hop; Telnet-through-jump requires a compatible local Telnet client.
Host keys of unregistered hops are registered on first use (TOFU, product known_hosts); changed or other-type keys are refused by managed terminals and replaced only by a human in the interactive
discover topology. For Telnet over an SSH tunnel only the jump server's key applies. Legacyssh-rsa(SHA-1) host keys are never enabled automatically (enable them for that host in your own ssh_config); the first key of a device cannot be verified independently (TOFU limit).Scenario/Reference schemas are intentionally flexible; only
topology <name>asks for confirmation on a case-only near-duplicate; on case-insensitive filesystems (default macOS) a case-only alias of an existing definition is refused for every definition kind.The November 2026 macOS and Windows/WSL2 real-lab E2E checks cover specific SSH and Telnet lab paths, not all disconnect/fault/restart scenarios, operating-system releases, or device types. Other Linux environments remain unverified for these exact jump workflows.
Full cross-vendor operation and all forms of autonomous deployment are not claimed or validated.
Project structure
network-lab-mcp/
├── README.md
├── SECURITY.md
├── CONTRIBUTING.md
├── CODE_OF_CONDUCT.md
├── AGENTS.md
├── LICENSE
├── pyproject.toml
├── run_cli.sh
├── src/network_lab_mcp/ # MCP server, terminal, discovery, human CLI
├── lab/ # Local selections, principles, definitions
│ ├── settings.example.yaml
│ ├── principles.yaml
│ ├── access-info/
│ ├── topologies/
│ ├── scenarios/
│ └── references/
├── docs/
│ ├── images/
│ │ ├── network-lab-mcp-concept.webp
│ │ ├── vibe-coding-vs-vibe-networking.webp
│ │ └── network-lab-mcp-configuration-model.webp
│ ├── architecture.md
│ ├── connection_architecture.md
│ ├── mcp_tools.md
│ ├── cli_reference.md
│ └── scenario_format.md
└── tests/Testing
Real-lab tests are opt-in and should be used only against approved lab infrastructure:
NETWORK_LAB_REAL_TESTS=1 pytest tests/test_real_lab_iosxr.py -v --tb=lineAvoid --showlocals when tests could access real credentials.
Documentation
Contributing, feedback, and license
Issues, bug reports, and suggestions are welcome through GitHub Issues. See CONTRIBUTING.md for how to contribute and CODE_OF_CONDUCT.md for community standards. Report security issues as described in SECURITY.md, not through public issues. Guidance for AI coding agents working on this repository is in AGENTS.md.
Run show version in the human CLI to inspect the local version, release date, Git revision, platform, MCP SDK version, and license information.
Licensed under the Apache License, Version 2.0 (SPDX: Apache-2.0). See LICENSE.
License history: earlier revisions of this repository's history were published under the GNU General Public License v3.0. Those revisions are not relicensed retroactively by this change; the Apache License, Version 2.0 applies to the project going forward.
Available Tools
7 toolsget_active_topologyA
Return the currently active lab topology: where the work is performed and which devices and links exist. Settings and the topology YAML are reloaded from disk on every call, so editing lab/settings.yaml takes effect immediately without restarting this server.
Inputs: no named parameters.
get_execution_instructionsA
Return the operating principles, the active scenario, and the active
reference knowledge for the current task: how to behave, what to
accomplish, and what reusable knowledge is available. Also returns
metadata-only catalogs (name + description) of every stored scenario
and reference, so existing knowledge can be discovered and reused.
Optional inspect_scenarios / inspect_references (lists of stored
definition names from those catalogs) additionally return the full
content of those definitions, read-only: inspecting never activates or
changes anything, and unknown names fail the call. Definition changes
are not made through MCP; propose them and a human reviews and commits
them in the CLI. Reloaded from disk on every call.
Inputs: inspect_scenarios, inspect_references.
terminal_closeA
Close a device's managed production terminal session. Only ever targets the production session namespace; cannot affect validation sessions. Deliberately does not require the device to still be present in the active topology, so a stale session left over from before the active topology changed can always be closed.
Inputs: device (required).
terminal_listA
List every currently managed production terminal session, regardless of whether each device is still present in the active topology -- including a stale session left over from before the active topology changed, so it remains visible and closeable via terminal_close() even though terminal_send()/terminal_read() will refuse to use it. Local validation sessions are never included, regardless of whether a device happens to be named similarly to a validation identifier.
Inputs: no named parameters.
terminal_openA
Open (or reuse) a terminal session for a device in the active topology, launching ssh or telnet inside a dedicated tmux environment. The active topology is reloaded from disk before opening the session. An interactive login prompt from the device itself is answered automatically using the active access-info definition's own private credentials, once it can be safely confirmed to belong to the target device (never a jump host) -- credentials are never returned by this tool or any other. This works for SSH (the client's own password prompt) and for Telnet (a classic-IOS-style Username:/Password: sequence); which one applies depends on the device's own configured transport. A host-key confirmation prompt, or any other situation this cannot safely resolve on its own, is still left for terminal_read()/terminal_send() to handle interactively.
Inputs: device (required).
terminal_readA
Capture recent terminal output for a device, so the caller can inspect
the current prompt, command output, a password/interactive prompt, paging
state, or unexpected errors. lines limits how much recent scrollback is
returned (default 100); the underlying tmux session retains a much larger
history buffer. The device must still be present in the active topology,
reloaded from disk on every call -- an already-open session does not
stay readable if the active topology changes to no longer include this
device.
Inputs: device (required), lines.
terminal_sendA
Send input to a device's open terminal session. The device must still be present in the active topology, reloaded from disk on every call -- an already-open session does not stay usable if the active topology changes to no longer include this device.
Execution order is fixed and deterministic: if text is given it is sent
literally first, then any keys (e.g. "C-c", "Tab", "Up") are sent in the
supplied order, then Enter is sent last if enter is true. Nothing is
deduplicated: passing keys=["Enter"] together with enter=true sends Enter
twice. text is delivered to the pane without ever passing through a
subprocess's own argv or appearing in an error message, and this MCP
server does not separately log or echo it back in any tool result. It
is not hidden from the device's own terminal transcript, though: this
project intentionally records the raw pane output via tmux pipe-pane
(see show logging), and if the remote endpoint echoes back what it
received, that echo may naturally appear in that transcript like any
other terminal output.
Inputs: device (required), keys, text, enter.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
The five terminal_* tools have crisp, non-overlapping roles (open/send/read/list/close), and the list-vs-send/read distinction around stale sessions is explicitly documented. The main soft spot is the pair get_active_topology vs get_execution_instructions, which both 'return current context' and could be conflated at a glance, though the descriptions do draw a clear line between topology/settings and operating principles/scenarios.
All names are snake_case verb_noun with predictable prefix grouping: get_* for context reads and terminal_* for the session lifecycle. No mixing of conventions or vague verbs.
Seven tools is well-scoped for a lab-interaction server: two context readers plus a complete five-verb terminal session surface. Every tool earns its place with no filler.
The terminal lifecycle is fully covered (open, send, read, list, close), including stale-session visibility and cleanup, and topology/instruction reads cover the context side. Gaps are minor and intentional: definitions/scenarios are read-only by design and there are no terminal resize or validation-session management tools, but core agent workflows are not blocked.
Maintenance
Related MCP Connectors
Governed data discovery, exact queries, decisions, simulations, and runtime utilities over MCP.
Set up and run your firm's Precision AI agents, skills and routines from any MCP client.
Tenant-scoped evidence intake and controlled AI context over MCP.
Network, domain and website diagnostics for AI clients via MCP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to investigate and manipulate live network simulations via MCP, including protocol debugging and fault injection.-
- AlicenseAqualityBmaintenanceEnables AI assistants to understand lab topologies, follow operational principles, and interact with real network devices through observable terminals while keeping private access information hidden.7Apache 2.0
- AlicenseBqualityBmaintenanceEnables AI agents to open persistent interactive terminal sessions with network devices over SSH, Telnet, TCP console, or serial, write raw commands including nested ssh/telnet transitions, and read full output without requiring a particular prompt format. It supports multiple concurrent sessions and keeps credentials/secrets out of MCP arguments or audit logs.7MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI incident-response agents to connect over MCP to a simulated service environment, receive alerts, gather diagnostic evidence, execute safe SOP actions, and verify recovery.1MIT