ptlab
by fn-cafeina
README.md
# ptlab
English | [**Espanol**](README.es.md)
[](https://github.com/samu-jpg/lab-pkt/actions/workflows/ci.yml)
[](LICENSE)
[](https://www.python.org/)
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):

## 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
```bash
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`):
```bash
cmd mcp add ptlab -- ptlab-mcp
```
Or in `.mcp.json`:
```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)
```bash
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
```yaml
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`.
## Legal
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.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues