Skip to main content
Glama

ptlab

English | Espanol

CI License: GPL-3.0-or-later Python 3.10+

MCP server that exposes the libraries to build Cisco Packet Tracer labs and generate the .pkt file without opening Packet Tracer: the AI (or you) describes the lab with devices, cables, IPs, VLANs and routing, and the engine produces a .pkt that already ships the devices cabled and configured.

The MCP is the project's toolbox: everything is exposed as tools and driven by whatever agent you already use (Command Code, Claude, Copilot...), with no extra LLM cost. There is no UI of its own and no preset templates or topologies: every device, name, cable and address is decided by whoever uses the MCP.

Demo

ptlab preview on a two-router lab (OSPF, Server-PT with DHCP and three hosts):

lab preview

Related MCP server: Packet Tracer MCP Server

Current scope

  • Explicit topology: nodes (devices) + links (port-to-port cables), no templates.

  • MCP primitives: create/edit a .pkt device by device (add/remove/clone/rename, move, power on/off, copper/crossover/serial cables, raw IOS config, modules, wireless, config-register, OS) and inspect existing labs.

  • Services and security: Server-PT services (HTTP/HTTPS, DNS, TFTP, NTP, email, syslog, AAA/RADIUS, DHCP pools) and ACL/NAT (static, overload) as tools.

  • .pka activities: guided practice (HTML instructions, initial and answer networks, password, permissions, timer). No grading tree: the vendor derives it from a reference activity.

  • Local library: harvest device models from your own .pkt files (pt_harvest); after that pt_add_device accepts them like any factory model.

  • Catalog: routers (2911/1941/2901/2811), L2 switches (2960-24TT/2950-24), L3 switch (3560-24PS), hosts (PC-PT/Server-PT/Laptop-PT) and Hub-PT; the primitives accept every model in the vendor template library (100+).

  • Per-interface IPs (CIDR), dot1Q subinterfaces (router-on-a-stick), static or DHCP host IPs.

  • VLANs with access / trunk / SVI and router-on-a-stick; L3 switch with ip routing.

  • Routing none/static/rip/ospf/eigrp/bgp (global or per device, computed on the graph).

  • DHCP: pools on the router, or a Server-PT with pools + ip helper-address (relay).

  • SVG preview of the canvas (real Packet Tracer icons, read from the local installation).

Requirements

  • Python 3.10+ (the .pkt codec is pure Python: no native dependencies).

  • Packet Tracer 9.x (only to open the result).

  • Tested against Packet Tracer 9.0.1 producing files that open and route.

Install

git clone --recurse-submodules git@github.com:samu-jpg/lab-pkt.git
cd lab-pkt
pip install -e ".[mcp]"

The mcp extra installs the MCP server SDK. The project reuses the GPL-3.0 codec/generator packet-tracer-pkt-format, integrated as a git submodule under vendor/ (cloned without submodules? run git submodule update --init). Hence the project is GPL-3.0-or-later.

Usage — MCP server (main interface)

Server command (after install): ptlab-mcp (or python3 -m ptlab.mcp_server). The agent talks and operates everything through tools.

Spec -> .pkt / .svg (describe the lab in one shot):

  • pt_schema — JSON schema of the spec (accepted fields).

  • pt_list_models — spec catalog + every vendor model and module.

  • pt_plan — validate/plan and return the summary with addressing.

  • pt_preview — render the SVG.

  • pt_build — generate the .pkt.

Primitives on a .pkt (the agent does whatever it wants, including opening and editing):

  • pt_new — create an empty .pkt; pt_devices — list devices.

  • pt_add_device / pt_remove_device — add/remove devices (any model, with IOS config and host network); pt_add_link — copper/crossover/serial cables (DCE with clock rate).

  • pt_clone_device / pt_rename_device / pt_move_device / pt_set_power — clone (config included), rename, place and power devices.

  • pt_config — raw IOS lines; pt_set_host / pt_set_dhcp — host network.

  • pt_set_wireless — SSID/security (AP, router or client); pt_install_module — modules (HWIC...).

  • pt_set_config_register / pt_set_os — config register and boot image.

  • pt_inspect — read a .pkt: devices, IPs, configs, pools and links.

Services and security:

  • pt_set_service — enable/disable and configure services (http, https, dns, tftp, ntp, syslog, email, aaa, dhcp) with raw fields.

  • pt_add_dhcp_pool, pt_add_dns_record, pt_add_aaa_user, pt_add_aaa_client — DHCP pool, DNS records and AAA (RADIUS) users/clients on the Server-PT.

  • pt_add_acl / pt_apply_acl — standard/extended ACLs (numbered or named) and ip access-group.

  • pt_nat_static, pt_nat_overload, pt_nat_interface — static NAT, PAT and ip nat inside/outside.

Activities and local library:

  • pt_activity — build a .pka with initial/answer networks, instructions, password, permissions and timer.

  • pt_harvest — harvest models from your .pkt files into the local library (pt_add_device accepts them afterwards).

Example registration in Command Code (cmd mcp add):

cmd mcp add ptlab -- ptlab-mcp

Or in .mcp.json:

{ "mcpServers": { "ptlab": { "command": "ptlab-mcp", "env": { "PTLAB_OUT_DIR": "/mnt/d/PT-Labs" } } } }

Same pattern for Claude Code / Copilot / Cursor (stdio transport).

Usage — CLI (debug helper)

ptlab build mi_lab.yaml -o /mnt/d/PT-Labs/mi_lab.pkt   # generate the .pkt
ptlab preview mi_lab.yaml -o /mnt/d/PT-Labs/mi_lab.svg # preview
ptlab schema                                           # spec fields

Spec format

name: mi_lab
routing: ospf        # none | static | rip | ospf | eigrp | bgp (global; any node can override)
ospf_process: 1      # per-protocol parameters
ospf_area: 0
eigrp_as: 100
bgp_as_base: 65000   # BGP base AS when the node has no as_number
dns: 8.8.8.8         # default DNS for Server-PT pools
nodes:
  - name: R1
    model: 2911
    x: 200             # optional; without x/y the planner lays out by layers
    y: 300
    interfaces:
      - {port: GigabitEthernet0/0, ip: 10.0.0.1/30}                    # WAN link
      - {port: GigabitEthernet0/1.10, ip: 192.168.10.1/24, dot1q: 10}  # router-on-a-stick
      - {port: GigabitEthernet0/2, ip: 192.168.1.1/24, helper: 192.168.2.100}  # DHCP relay
    routing: ospf      # optional: overrides global routing
    as_number: 65010   # for bgp
    dhcp: true         # /24 pools per router interface
    config: []         # extra raw IOS lines (escape hatch)
  - name: SW1
    model: 2960-24TT
    vlans: [{id: 10, name: VENTAS}, {id: 20, name: ADMIN}]
    access: [{port: FastEthernet0/1, vlan: 10}]
    trunks: [GigabitEthernet0/1]
    interfaces: [{port: Vlan10, ip: 192.168.10.2/24}]    # SVI (management)
  - {name: PC1, model: PC-PT, ip: 192.168.1.10/24, gateway: 192.168.1.1, dhcp: false}
  - name: SRV1
    model: Server-PT
    ip: 192.168.30.11/24
    gateway: 192.168.30.1
    pools: [{network: 192.168.30.0/24, gateway: 192.168.30.1}]
links:
  - {a: R1, a_port: GigabitEthernet0/0, b: R2, b_port: GigabitEthernet0/0}
  - {a: PC1, a_port: FastEthernet0, b: SW1, b_port: FastEthernet0/1, cable: straight}
  - {a: R1, a_port: GigabitEthernet0/1, b: SW1, b_port: GigabitEthernet0/1}

Validations (Spanish messages): unique names, catalog model, existing ports without duplicates, CIDR IPs without duplicates, VLAN 1-4094 declared before use, dot1q only on subinterfaces, hosts with ip+gateway or dhcp: true.

Note: routers with few ports (1941/2811/2901/2911: 2-3) limit how many links each device can have; use 3560-24PS for demanding topologies (26 ports, configured with ip routing and no switchport).

How it works

spec (YAML/JSON: nodes + links)
  -> planner   : validates, builds devices/ports, IOS configs and layout
  -> builder   : real device templates (vendor) -> XML -> encrypted -> .pkt
  -> preview   : SVG of the canvas

primitives:
  pt_new/open -> lab_api (add devices, cables, configs) -> .pkt

The .pkt is an encrypted XML (zlib + XOR + Twofish-EAX). <RUNNINGCONFIG> blocks for every device and the host network config are generated; Packet Tracer applies them on open.

Repository layout

src/ptlab/     spec, planner, builder, ios, preview, lab, activity, library, vendorlib,
               codec, catalog, cli, mcp_server
vendor/        packet-tracer-pkt-format (submodule, GPL-3.0) — reused codec and templates
docs/          roadmap and demo
spike/         codec feasibility spikes

Limitations / next steps

  • No ACL/NAT in the spec yet (available through the ACL/NAT tools).

  • In the spec: serial cables and L3 switch with VLANs are pending (primitives already do serial).

  • The Server-PT DHCP service is configured with pools and gateway/DNS; no reservations yet.

  • No "live" deployment straight into Packet Tracer (file based for now).

  • Full roadmap (PT coverage, CI and the other MCPs) in docs/ROADMAP.md.

It reuses a reverse-engineering project of the .pkt format. Use with your own files, for interoperability and practice. Do not use it to tamper with grading keys or assessments.

Related MCP Connectors

Related MCP Servers