netplex. Early Access is open. Join the list to get in first.

Control netplex. from Claude with MCP

Reference5 min readUpdated September 2026

netplex. includes a Model Context Protocol (MCP) server. MCP is the way Claude Desktop, Claude Code and claude.ai use tools. Point an AI agent that supports MCP at it, and it can build a lab and check its own work. It can read the topology, connect devices, power them on and run commands. Then it can pull real numbers from the links and ports to prove traffic is really moving.

Every tool below is real and shipped in tools/netplex-mcp/server.py - not illustrative pseudocode. Here is the full list, grouped by what the tools do:

78 tools as of the current release, generated straight from the server's own tool list.

Build & wire a lab:

ToolWhat it does
list_labsList all labs accessible to the current user.
create_labCreate a new empty lab.
delete_labPermanently delete a whole lab (every node, link and saved config in it).
get_labGet a lab's full declarative definition as a .npx document (JSON text) - the same content Export -> .npx downloads.
get_topologyGet the full topology of a lab (nodes, links, status).
describe_topologyGenerate a human-readable description of a lab's topology.
add_nodeAdd a node to a lab.
add_linkConnect two nodes with a link.
move_nodeMove a node on the canvas (layout).
delete_nodeRemove a node from a lab (also removes its links).
delete_linkRemove a link from a lab.
update_nodeChange a node's settings - the Inspector's General/Resources tabs.
update_linkChange a link's settings - the link Inspector.
import_containerlabImport a ContainerLab topology (YAML) as a new netplex.
import_labImport a .npx JSON document as a brand-new lab.
export_labExport a lab in a given format.
clone_labDuplicate a lab's definition (topology + configs + canvas layout) as a new, stopped lab - runtime state (running nodes) is not copied.
plan_labPreview what applying a .npx document to a lab would change - NO write happens.
apply_labRedeem a plan_hash from plan_lab and actually write the change to the LIVE lab - new nodes are created (and started, if the lab is running),
get_taskPoll a long-running task (from apply_lab/clone_lab) for its current progress, final result, or error.

Power & control:

ToolWhat it does
start_labStart all nodes in a lab.
stop_labStop all nodes in a lab.
start_nodePower on a single node (the rest of the lab is untouched).
stop_nodePower off a single node (the rest of the lab keeps running).
restart_nodeRestart a single running node.
get_node_statusGet the current runtime status of a node.
wait_for_node_readyWait, server-side, until a node's console shows a real prompt (or a container reports running), so you never have to guess whether a box is up.
get_node_capabilitiesWhat this node can do: its runtime capabilities (config capture/apply, disk snapshot, logs, ...) PLUS the honest three-way config story and its
list_hostsList every host in this cluster (name, health, cpu/mem, running-node count) - the same fleet `GET /api/v1/cluster/nodes` the Cluster/Compute Fleet
place_nodePin a node to a specific cluster host, or move it back to the local controller (host="orchestrator" / "local" / "").

Configure & run:

ToolWhat it does
get_node_configRead a node's saved startup config, or its live running config.
set_node_configSave a node's startup config; optionally push it to the running device.
clear_node_configRemove a node's saved startup config (the node boots factory-default next time).
get_running_configRead a node's LIVE running config, distinct from its saved startup config.
save_running_configCapture a node's current running config and persist it as its saved startup config.
run_commandRun a command on a running node and return the output.
run_device_commandExecute a vendor-specific CLI command on a running node and return output.
connect_sshRun a command on a node over SSH to its management IP if it has one and SSH answers there (faster, no console lock contention) - otherwise falls
get_console_logGet the last N lines of a node's serial console log.
get_node_logsRead a node's own runtime log stream - Docker/LXC/microVM stdout+stderr, or a QEMU node's serial console log.

Look & feel:

ToolWhat it does
get_lab_appearanceRead a lab's appearance (canvas theme/background/pattern + console font/scheme), RESOLVED - the per-lab override (if any) merged on top of the
set_lab_appearanceSet this lab's own canvas and/or console appearance override (any subset of keys - only the ones you pass are changed, the rest of the lab's
set_node_appearanceSet one node's visual override (shell/scale/glyph/border/stripe/layout/label/ colour) - the same per-node overrides the canvas Node-appearance
set_link_styleSet a link's visual style override (colour/width/dashed/...) - the same `ui_state.link_overrides[link_id]` bucket the Link-appearance popover writes.
list_iconsList built-in vendor icons PLUS (when lab_id is given) that lab's own uploaded assets - each with the exact string to pass as `glyph=` to
arrange_labAuto-arrange node positions - server-side, same mechanism Studio's own "Auto-layout" toolbar button/G-shortcut uses (`POST .../topology/layout`),
annotate_labAdd/update/remove/list canvas annotations (shapes/lines/text/images drawn on the lab, the same `ui_state.annotations` bucket the canvas annotation
hide_showHide or show canvas elements by plane or tag - the same `ui_state.hidden_planes`/`hidden_tags` lists the canvas plane/tag legend checkboxes write.

Images & your own code:

ToolWhat it does
list_imagesList images available in the local library.
get_catalogBrowse the community appliance catalog to find images to use in labs.
download_imageInstall a FREE appliance from the catalog so it can be used in labs.
push_codeBuild a real image from your OWN project code and register it in the netplex Library, ready for run_my_image - the "push your code" pipeline.
build_statusCheck the status of your most recent push_code build for an image name.
get_build_logGet the last N lines of your most recent push_code build's log for an image name.
list_my_imagesList your own push_code images (owner=me) as they appear in the Library.
run_my_imageAdd a node to a lab using ONE OF YOUR OWN push_code images, start it if the lab is already running, and report its /data folder - the persistent,

Diagnose & prove it works:

ToolWhat it does
get_link_statsGet real-time statistics for a link: operstate, carrier, byte/packet counters.
get_interface_countersGet all interfaces and their packet/byte counters for a running node.
diagnose_linkRun diagnostic checks on a link: combines stats + interface info + highlights asymmetries.
start_captureStart packet capture on a link.
stop_captureStop packet capture on a link.
get_capture_summaryGet a summary of captured packets on a link.
list_capturesList every packet capture recorded for this lab - capture_id, which link, when it ran.
download_captureGet a tshark-style summary of one capture - protocol counts, not raw pcap bytes, so you can read "12 ARP requests, 0 replies" instead of parsing
get_lab_eventsRead this lab's own event log - node crashed, link down, config inject failed, and so on.
assert_protocol_stateCheck a real protocol-state claim about a running node and get real evidence, not a guess.
test_under_networkClone a git repo and run its test command against a peer service under simulated network conditions - latency, jitter, packet loss.

Fault-finding, no AI required:

ToolWhat it does
lint_labRun netplex's deterministic (no-AI) lint checks against a lab and report any findings - duplicate MACs/IPs, unwired ports, down links, stopped
get_lab_healthOne-call lab health summary: node/link/host state plus lint error/warning counts - the tool an AI should start with before deciding whether to dig

Read-only operator tools:

ToolWhat it does
showRun a READ-ONLY vendor CLI command on a node - the safe subset an AI/ automation token can use WITHOUT the `nodes:exec` scope and WITHOUT ever
get_mac_tableRead a node's MAC address table (which port/VLAN learned which MAC), via `show`.
get_arp_tableRead a node's ARP/neighbor table (IP-to-MAC mappings), via `show`.
pingPing a target FROM a node, over its console.
tracerouteTraceroute to a target FROM a node, over its console.
get_interface_stateRead a node's interface admin/oper state summary, via `show`.

Approvals:

ToolWhat it does
check_approvalCheck the status of one pending approval by id (given to you in the "Waiting for a human to approve" message a gated tool call returned).
list_pending_approvalsList this AI client's own pending "ask first" approvals - changes this session tried to make that a human has not yet allowed or denied.

Hardware tools:

ToolWhat it does
list_tool_instancesList the hardware-tool instances (traffic generator, RFC 2544 tester, scanner, ...) the current user owns - in labs and in the Tools workbench -
Which AI tools have we actually tested? netplex.'s MCP server speaks the standard Model Context Protocol, so any MCP-compatible AI tool should be able to connect - but as of September 2026, we have a real, live, automated connection proof for Claude Code and Qwen Code only. Claude Desktop, ChatGPT, Cursor, VS Code Copilot, Codex CLI, Gemini CLI, Windsurf, Zed, Kimi, Antigravity, and Claude in the browser are expected to work (they all speak the same protocol) but have not yet been individually verified end to end - we'd rather say that plainly than claim support we haven't proven. Instructions below (e.g. for Claude Desktop) describe the standard MCP setup, not a netplex.-specific integration we've tested against that client.

Configure Claude Desktop - add to claude_desktop_config.json:

{
  "mcpServers": {
    "netplex": {
      "command": "python3",
      "args": ["/path/to/netplex/tools/netplex-mcp/server.py"],
      "env": {
        "NETPLEX_URL": "http://localhost:8088",
        "NETPLEX_USER": "admin",
        "NETPLEX_PASS": "netplex"
      }
    }
  }
}

Restart Claude Desktop and the tools above become available to the model automatically - ask it to "list my labs" or "create a lab called staging with two Alpine hosts" and it calls the real REST API underneath, exactly like the Studio UI does.

Run it standalone (stdio transport, the MCP default):

NETPLEX_URL=http://localhost:8088 NETPLEX_USER=admin NETPLEX_PASS=netplex \
  python3 tools/netplex-mcp/server.py

Or over SSE for a web-facing client: python3 server.py --transport sse --port 9999.

Because every tool call is just the REST API underneath, anything the MCP server can do, the CLI or SDK can also do directly - see "CLI quickstart" and "The Python SDK" for the non-AI equivalents of the same operations.

Build and debug a lab with your own AI agent

Building a topology is the easy half. The harder, more useful thing an agent can do is tell you why a link isn't passing traffic - not "the API call succeeded" but "port A is transmitting and port B is receiving nothing." That's what the diagnose tools are for, and they read the numbers straight from Linux (the counters it keeps for every network port), not from a config file that could be wrong.

A typical debug turn looks like this:

$ agent "why can't leaf01 reach leaf02?"

→ diagnose_link(lab_id="l-9f2", link_id="lnk-14")
{
  "link_id": "lnk-14",
  "stats": {
    "interface_a": { "name": "eth1", "operstate": "up", "carrier": 1, "tx_bytes": 48210, "rx_bytes": 0 },
    "interface_b": { "name": "eth1", "operstate": "up", "carrier": 1, "tx_bytes": 0, "rx_bytes": 0 }
  },
  "asymmetries": [
    "A→B: A transmitting but B not receiving"
  ]
}

That's a real response shape from diagnose_link - it composites the link's raw sysfs counters from both ends into one call and flags the asymmetry itself, so the agent doesn't have to hand-roll the comparison. Under the hood it's calling the same GET /labs/{lab_id}/links/{link_id}/stats route get_link_stats exposes directly, plus each node's live interface list via get_interface_counters - both are also callable on their own when you want raw numbers instead of a diagnosis.

If the counters alone aren't enough, the agent can go one level deeper and look at the actual frames: start_capture(lab_id, link_id), reproduce the issue, stop_capture(lab_id, link_id), then get_capture_summary(lab_id, link_id) for a protocol/source/destination breakdown of what actually crossed the wire - the same capture pipeline the Studio UI's Captures tab uses, just callable from the agent's own loop. All six diagnose/capture tools are read-only-annotated, so they work even when the MCP server is locked down with NETPLEX_MCP_READONLY=1 for an operator who should be able to look but not touch.

Since September 2026, wait_for_node_ready waits until a node's console shows its real vendor prompt (or the container reports healthy) instead of an agent hand-rolling a poll loop - and ping/assert_protocol_state answer "can node A reach node B" directly. The full, current tool list is larger than the categories above show; a complete refresh of this page's tool catalogue is tracked as a follow-up.