pnetlab-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PNETLAB_HOST | Yes | The URL of the PNETLab v6 server, e.g., http://192.168.231.128 | |
| PNETLAB_PASSWORD | Yes | The password for the work account | |
| PNETLAB_USERNAME | Yes | The username for the dedicated work account used by the agent | |
| PNETLAB_VIEWER_PASSWORD | No | Optional password for the viewer account | |
| PNETLAB_VIEWER_USERNAME | No | Optional username for a viewer account to view the lab in a browser |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
| logging | {} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| extensions | {
"io.modelcontextprotocol/ui": {}
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_templatesA | List installed node templates as structured entries. Each entry is |
| list_network_typesA | List available network types (bridge, pnet0..pnet9, ovs, ...). |
| list_imagesA | List the disk images available for a template (e.g. For non-QEMU types (vpcs/iol/dynamips/docker) this lists whatever images that backend offers. |
| get_templateA | Get a template's full editable options: available images, qemu versions, and all default field values. Use this when you need more than list_images (e.g. the right qemu_arch/qemu_nic/qemu_options for a node). |
| open_labA | Open a lab for editing/running. If PNETLAB_VIEWER_USERNAME is configured, the viewer account (e.g. your admin) is auto-joined to this session so you can watch the live topology in the browser at the PNETLab web UI while the agent works. |
| join_viewerA | (Re)join the configured viewer account to the agent's current lab session. Call this if you logged into the browser as the viewer before the agent opened the lab, or to refresh the viewer's binding. Lets you watch the live topology in the PNETLab web UI. |
| close_labA | Leave the current lab session (releases the session binding). Also leaves the viewer account so its browser stops tracking this session. |
| get_labA | Get the open lab's info, full topology (nodes/networks/connections) and node status. Use this to see what's running and how nodes are wired. Pass |
| get_node_statusA | Get per-node running status (0=stopped, 1=building/booting, 2=running). |
| add_nodeA | Add a node to the open lab. By default (
|
| update_nodeA | Edit an existing node's fields. Only the fields you pass are changed. Use this to fix a node that crashes on boot (e.g. set a missing image), or to tweak ram/qemu_nic without deleting and recreating. Image/ram/qemu_* changes take effect on the next (re)start, not on a running node. Accepts the same field names as add_node. |
| connect_nodesA | Connect two node interfaces with a point-to-point link. src_id/dest_id are node ids (from get_lab); src_if/dest_if are 0-based ethernet indices (0 = eth0, 1 = eth1, ...). Returns the new network_id and both endpoints (use the network_id with set_link_state/set_link_quality/ delete_link). |
| start_nodeA | Start one node, or every node in the lab if node_id is omitted. With |
| stop_nodeA | Stop one node, or every node in the lab if node_id is omitted. |
| delete_nodeA | Delete a node from the open lab (stop it first). |
| push_configA | Push a startup configuration to a node (applied on next boot). Stores the config text and enables it for boot injection. For this to take effect the node must be (re)started after the push - the config is injected during boot, not into a running node. Config format is device-specific. For VPCS use plain VPCS commands, one per
line, e.g. Note: this tool also flips the node's config flag so PNETLab actually loads the stored config on boot (without that flag the stored config is silently ignored - a known PNETLab configs/edit quirk). |
| node_consoleA | Get a node's console connection info (telnet/SSH host:port) so the agent can interact with the device CLI. For actual command execution prefer run_command / console_send + console_read, which handle the telnet handshake and login for you. |
| delete_linkA | Delete a link (p2p network) at the topology layer. Unlinks both attached interfaces. Use the network_id returned by connect_nodes (or read from get_lab). The node must be stopped or the interfaces will be hot-unplugged. |
| set_link_stateA | Bring a link up or down at the topology layer (physical-style fault
injection). Use the network_id from connect_nodes / get_lab. Current state is readable
from get_lab (each ethernet has a |
| set_link_qualityA | Inject impairment on a link: packet loss (percent), one-way delay (ms), jitter (ms), and/or bandwidth limit (kbit/s). Pass only the dimensions you want to set. Applied to both directions of the link. Only affects running nodes. Clear an impairment by passing 0 for that dimension. |
| run_commandA | Run a single CLI command on a running node and return its output. Opens a telnet console, handles the IAC handshake, logs in if the device asks
(default admin/empty password -- pass credentials for devices that differ),
sends the command, and reads until the output goes idle (or Examples: run_command(1, "/ip address print") on a MikroTik; run_command(1, "ping 10.0.0.2 count 4", wait_for="packet-loss") ; run_command(2, "show ip interface brief") on IOS; run_command(3, "ping 10.0.0.1") on VPCS. Gotcha: a single |
| console_sendA | Send raw text to a node's console (auto-opens + logs in on first use). Lower-level than run_command: use it for multi-step interactive sessions where you need to drive the prompt yourself. Set newline=False to send a partial line (e.g. before reading). Read the response with console_read. |
| console_readA | Read pending output from a node's console until it goes idle (up to
|
| console_closeA | Close a node's console session, or all of them when node_id is None. Good practice once you are done configuring a node. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/raybiko-lab/pnetlab-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server