# vm-lab-agent
🚧 Status: Work in Progress
This is an active, incomplete project — parts of it are tested andworking, parts are unverified against a real server, and there's aknown dependency bug not yet fixed (see Known Issues below).Read
SECURITY.mdbefore running this against a lab you care about.
A small, sandboxed MCP server forstudents running network engineering / SOC analyst home labs (PNETLab,VMware Workstation, Wazuh, Kali, etc.). It lets an AI agent power VMson/off, manage snapshots, build and control PNETLab topologies, andverify device configuration -- within an explicit allowlist youcontrol, with every destructive action gated behind a confirmationstep and every action logged.
Built for hands-on CCNP / Security+ / SOC-analyst practice: spin up atopology, configure it yourself in PNETLab's own console (the actualexam-relevant skill), and let the agent check your work with realshow command output afterward.
Compatible with any MCP client -- Claude Code, or any other tool thatspeaks the Model Context Protocol. Not locked to a single AI provider.
This project was designed and built with the assistance of Claude(Anthropic). See CREDITS.md. It is not an officialAnthropic product and isn't endorsed by Anthropic.
Known issues (honest, not hidden)
- requirements.txt has a real, currently-unresolved dependencyconflict. netmiko==4.7.0 requires paramiko<5.0; the two aren'tsimultaneously installable as currently pinned in this repo withoutmanual adjustment. Workaround until fixed: pin paramiko==4.0.0instead of whatever's currently in the file.
- pnetlab_lab_add_network and pnetlab_lab_connect_interface arebuilt from an inferred API pattern, not a directly-observed workingtrace -- see SECURITY.md.
- dynamips and docker image types aren't supported bypnetlab_delete_image -- their directory layout wasn't confirmedwith enough confidence to build against safely.
- VMware control tools aren't containerized the way the PNETLab SSHtools are -- vmrun needs to talk to VMware Workstation running onyour actual host. See SECURITY.md for the full explanation.
None of these block basic use (VM power/snapshot/backup, PNETLab imagesearch/install/delete, and node power/status on an existing topologyall work and are tested) -- they're specifically the rough edges leftfrom finishing this in one long build session.
Before you do anything else: read SECURITY.md
Seriously. SECURITY.md explains exactly what this agentcan and can't touch. It also covers a real, dated MCP vulnerability(OX Security's April 2026 disclosure) and exactly why this project'sdesign does and doesn't fall inside that exposure.
See REFERENCES.md for the primary sources behind everynon-obvious design decision, and LEARNING.md if you wantthis project to double as CCNP/Security+/SOC-analyst study materialrather than just a tool you install and forget.
What it does
| Tool | Confirm required? | What it does |
|---|---|---|
| list_managed_vms | No (read-only) | Lists VMs on your allowlist |
| vm_status | No (read-only) | Checks if a VM is running |
| vm_power_on | Yes | Powers on a VM |
| vm_power_off_soft | Yes | Graceful guest OS shutdown |
| vm_power_off_hard | Yes, + per-VM allow_destructive | Force power-off |
| vm_snapshot_create | Yes | Takes a snapshot |
| vm_snapshot_revert | Yes, + per-VM allow_destructive | Reverts to a snapshot |
| vm_clone_create | Yes | Creates a new VM by cloning an allowlisted one; new VM is not auto-allowlisted |
| vm_backup_to_location | Yes | Copies a VM's entire folder to a location you choose |
| vm_delete_permanently | Yes, + 3 more gates | Permanently deletes a VM. Not registered as a tool unless enable_vm_deletion: true. |
| pnetlab_search_image | No (read-only) | Searches PNETLab's ishare2 catalog |
| pnetlab_list_installed | No (read-only) | Lists images already installed, by type |
| pnetlab_pull_image | Yes | Downloads/installs an image |
| pnetlab_delete_image | Yes | Deletes an installed image (qemu + iol/bin only) |
| pnetlab_fix_permissions | Yes | Runs the standard post-install permission fix |
| device_read_config | No (read-only) | Runs a show command against a lab device -- only show commands accepted |
| pnetlab_lab_topology | No (read-only) | Reads a managed lab's current nodes |
| pnetlab_lab_node_status | No (read-only) | Reads running/stopped status of every node |
| pnetlab_lab_node_power | Yes | Starts or stops a specific node |
| pnetlab_lab_create | Yes | Creates a new empty lab; not auto-allowlisted |
| pnetlab_lab_add_node | Yes | Adds a router/switch/etc. to a lab's topology |
| pnetlab_lab_add_network | Yes | Adds a network/switch object (moderate confidence) |
| pnetlab_lab_connect_interface | Yes | Connects a node's interface to a network (moderate confidence) |
Setup
1. Prerequisites
- Python 3.12+
- VMware Workstation Pro/Player with vmrun installed
- A PNETLab server (optional -- only needed for PNETLab-related tools)
2. Install
git clone https://github.com/vikramjeet8105-engg/vm-lab-agent.git
cd vm-lab-agent
pip install -r requirements.txt
If this fails on a paramiko/netmiko conflict, open requirements.txt andchange the paramiko line to paramiko==4.0.0, then retry.
3. Configure
cp config.example.yaml config.yaml
cp .env.example .env
Edit config.yaml: list the exact VMs (and optionally labs) you want theagent to touch. Anything not listed here is invisible to the agent --read SECURITY.md for why this matters.
4. Test it locally
python -m pytest tests/ -v
5. Connect it to your MCP client
claude mcp add --transport stdio vm-lab-agent -- python -m src.server
Contributing
Issues and PRs welcome, especially fixes for anything in Known Issuesabove.
License
MIT -- see LICENSE.