Control netplex. from Claude with MCP
netplex. ships a Model Context Protocol (MCP) server - the same protocol Claude Desktop, Claude Code and claude.ai use to call tools. Point an MCP-aware AI agent at it and it can both build a lab and check its own work: read the topology, wire and power nodes on, run commands - and then pull real link and interface evidence to prove traffic is actually moving, not just that the API calls returned 200.
Every tool below is real and shipped in tools/netplex-mcp/server.py - not illustrative pseudocode. It's 32 tools today, grouped by what they do:
Build & wire a lab: list_labs, create_lab, get_topology, describe_topology (human-readable summary), add_node, add_link, move_node, delete_node, delete_link, import_containerlab.
Power & control: start_lab, stop_lab, start_node, stop_node, restart_node, get_node_status.
Configure & run: get_node_config, set_node_config, clear_node_config, run_command (exec on a running node), run_device_command, get_console_log.
Images: list_images, get_catalog (browse the vendor image catalog), download_image.
Diagnose & prove it's working: get_link_stats, get_interface_counters, diagnose_link, start_capture, stop_capture, get_capture_summary - see the worked example below.
Testing: test_under_network (clone a repo, run its tests against a peer under simulated latency/jitter/loss, report pass/fail - fully ephemeral, it creates and tears down its own lab).
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 straight from Linux (sysfs interface counters), not from a config file that could be lying to you.
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.
What this does not do yet: there's no single MCP call that blocks until a lab or node finishes booting (wait_for_lab_ready) or that answers "can node A reach node B's IP" as one primitive (check_reachability) - today an agent hand-rolls a poll loop over get_node_status and reasons about reachability from interface state itself. Both are on the roadmap.