Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
PNETLAB_HOSTYesThe URL of the PNETLab v6 server, e.g., http://192.168.231.128
PNETLAB_PASSWORDYesThe password for the work account
PNETLAB_USERNAMEYesThe username for the dedicated work account used by the agent
PNETLAB_VIEWER_PASSWORDNoOptional password for the viewer account
PNETLAB_VIEWER_USERNAMENoOptional username for a viewer account to view the lab in a browser

Capabilities

Features and capabilities supported by this server

CapabilityDetails
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

NameDescription
list_templatesA

List installed node templates as structured entries.

Each entry is {template, name, installed} where template is the id usable in add_node and installed is False when the image is missing (PNETLab marks these with a .missing suffix).

list_network_typesA

List available network types (bridge, pnet0..pnet9, ovs, ...).

list_imagesA

List the disk images available for a template (e.g. mikrotik-7.23.2) plus the default image. Call this before add_node to get a valid image string for a QEMU node -- without one the node starts and immediately crashes.

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. path is the lab file name with NO leading slash, e.g. "2pc_1sw.unl". Creates/reuses the lab's sandbox and binds it to this session. Must be called before add_node / start_node / get_lab / etc.

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 compact=True to drop cosmetic noise (empty style dicts, second-console fields, empty qemu_options) and thin each node to id/name/type/template/image/ ram/status/console plus an ethernet map of {if -> {name, network_id, suspend}}. Compact mode is recommended for large topologies -- the full payload can be 80-100KB.

get_node_statusA

Get per-node running status (0=stopped, 1=building/booting, 2=running).

add_nodeA

Add a node to the open lab. type/template come from list_templates (e.g. type="vpcs" template="vpcs", or type="qemu" template="mikrotik").

By default (template_defaults=True) the template's built-in defaults are auto-applied -- image, ram, cpu, qemu_arch/qemu_nic/qemu_options/qemu_version, console, icon, config_script -- exactly what a GUI-created node inherits. So a bare add_node("qemu", "mikrotik", "R1") produces a fully bootable node with the right image and console; you usually don't need list_images first. Any field you pass explicitly overrides the template default. Pass template_defaults=False to supply everything yourself.

console defaults to the template's console, falling back to telnet for qemu/iol/dynamips (needed for status reporting and the console tools). icon defaults to the template's icon (e.g. mikrotik -> Router.png), falling back to Desktop.png only when the template has none or template_defaults=False. Pass an explicit icon to override. Node is added stopped; call start_node to boot it.

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 check=True (single node only), poll status for a few seconds after starting and report a diagnostic if the node crashes back to stopped (usually a missing/invalid image or too little ram).

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. ip 192.168.1.1 24. For IOS/IOL routers use the normal hostname ... / interface ... running-config style. For interactive CLIs (e.g. RouterOS) prefer run_command.

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). up=True restores the link, up=False suspends it. This is not the same as disabling an interface inside the device CLI -- the device sees its port go down, matching a real cable pull. Only affects running nodes.

Use the network_id from connect_nodes / get_lab. Current state is readable from get_lab (each ethernet has a suspend field: 1=suspended).

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 wait_for regex matches). The session is pooled and reused across calls; call console_close when finished with a node.

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 ? for help often does not trigger under telnet; use run_command with the full command instead. For long-running monitors, pass wait_for to match the final summary line.

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 timeout seconds). Pair with console_send for interactive sessions.

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

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

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