Agent skill

gns3-lab-automation

GNS3 network lab operations including topology management, device configuration via console, and troubleshooting workflows for routers and switches

Stars 163
Forks 31

Install this agent skill to your Project

npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/productivity/gns3-lab-automation

SKILL.md

GNS3 Lab Automation Skill

Overview

GNS3 (Graphical Network Simulator-3) is a network emulation platform for building complex network topologies. This skill provides knowledge for automating GNS3 lab operations through the MCP server.

Key Features (Must Know!)

🗒️ Project Notes/Memory System

Problem: Lab configurations consume conversation context (IPs, credentials, architecture notes) Solution: Store persistent notes in per-project README

When to use:

  • ✅ Always read notes when starting work on a project
  • ✅ Update notes after configuring new devices
  • ✅ Document IP schemes, credentials, topology changes
  • ✅ Record troubleshooting findings and solutions

Tools:

  • get_project_readme() - Retrieve project documentation
  • update_project_readme(content) - Save/update documentation (markdown format)

Resource: projects://{id}/readme (read-only browsing)

Example Workflow:

python
# 1. Always start by reading existing notes
notes = get_project_readme()

# 2. Do your work (configure router, add nodes, etc.)
# ...

# 3. Update notes with new information
update_project_readme("""
# Lab Configuration

## Network Topology
- Router1: 10.1.0.1/24 (GigabitEthernet0/0)
- Router2: 10.1.0.2/24 (GigabitEthernet0/0)

## Credentials
- Username: admin
- Password: cisco123

## Last Updated
2025-10-26: Added Router2, configured OSPF
""")

📋 Template Usage Notes

Problem: Forgetting default credentials, boot times, device-specific setup steps Solution: Templates include built-in usage notes with device info

What's included:

  • Default credentials (username/password)
  • Boot timing estimates ("First boot takes 60 seconds...")
  • Persistent storage locations ("/root directory persists")
  • Console availability and device-specific quirks

How to access:

  • For specific node: projects://{id}/nodes/{node_id}/template
  • For template: gns3://templates/{template_id}

Example:

python
# Get usage notes for a MikroTik node you just created
usage = read_resource("projects://{id}/nodes/{node_id}/template")
# Returns: "The login is admin, with no password by default.
#           On first boot, RouterOS is actually being installed..."

Pro Tip: Check template usage before configuring new devices to avoid common mistakes!

Core Concepts

MCP Resources (v0.13.0 - NEW)

MCP resources provide browsable state via standardized URIs, replacing query tools for better IDE integration.

Resource Benefits:

  • Browsable in MCP-aware tools (inspectors, IDEs)
  • Automatic discovery and autocomplete
  • Consistent URI scheme (gns3:// protocol)
  • Better performance with resource subscriptions

Available Resources (v0.29.0 - URI Standardization):

Project-Centric Resources:

  • projects:// - List all GNS3 projects
  • projects://{project_id} - Get project details by ID
  • projects://{project_id}/readme - Get project README/notes (v0.23.0)
  • projects://{project_id}/sessions/console/ - Console sessions in project (v0.29.1)
  • projects://{project_id}/sessions/ssh/ - SSH sessions in project (v0.29.1)

Object-Centric Resources:

  • nodes://{project_id}/ - List nodes in project (NodeSummary, table mode v0.30.0)
  • nodes://{project_id}/{node_id} - Get node details (full NodeInfo)
  • nodes://{project_id}/{node_id}/template - Get template usage notes for node (v0.23.0)
  • links://{project_id}/ - List network links in project (table mode v0.30.0)
  • drawings://{project_id}/ - List drawing objects (table mode v0.30.0)

Diagram Resources (v0.33.0):

  • diagrams://{project_id}/topology - Get topology diagram as SVG (visualize lab layout)

Template Resources (Static, Not Project-Scoped):

  • templates:// - List all available templates (table mode v0.30.0)
  • templates://{template_id} - Get template details with usage notes (v0.23.0)

Session Resources (Dual Access Patterns v0.29.1):

Path-based (project-scoped):

  • projects://{project_id}/sessions/console/ - Console sessions in project
  • projects://{project_id}/sessions/ssh/ - SSH sessions in project

Query-parameter-based (filtered):

  • sessions://console/?project_id={id} - Console sessions filtered by project
  • sessions://ssh/?project_id={id} - SSH sessions filtered by project

Unfiltered (all sessions):

  • sessions://console/ - All console sessions across all projects (table mode v0.30.0)
  • sessions://console/{node_name} - Console session for specific node
  • sessions://ssh/ - All SSH sessions across all projects (table mode v0.30.0)
  • sessions://ssh/{node_name} - SSH session status for node
  • sessions://ssh/{node_name}/history - SSH command history (table mode v0.30.0)
  • sessions://ssh/{node_name}/buffer - SSH continuous buffer

Proxy Resources:

  • proxies:///status - Main proxy status (THREE slashes)
  • proxies:// - Proxy registry (host + lab proxies, table mode v0.30.0)
  • proxies://sessions - All proxy sessions (table mode v0.30.0)
  • proxies://project/{project_id} - Proxies for specific project
  • proxies://{proxy_id} - Specific proxy details

Resource vs Tool Usage:

  • Resources: Query state (read-only) - use for browsing, monitoring
  • Tools: Modify state (actions) - use for changes, commands, configuration

Example Resource Workflow:

# Browse resources (read-only)
1. List all projects: projects://
2. Pick project ID from list
3. View nodes: nodes://{project_id}/
4. Check topology diagram: diagrams://{project_id}/topology
5. Check SSH sessions: sessions://ssh/?project_id={project_id}
6. Check SSH session for specific node: sessions://ssh/R1

# Use tools to modify (actions)
7. Call ssh_configure() to create SSH session
8. Call ssh_command() to execute commands
9. Call set_node() to change node state
10. Call export_topology_diagram() to save diagram as PNG/SVG

Removed in v0.14.0 (use MCP resources instead):

  • list_projects() → Use resource projects://
  • list_nodes() → Use resource nodes://{project_id}/
  • get_node_details() → Use resource nodes://{project_id}/{node_id}
  • get_links() → Use resource links://{project_id}/
  • list_templates() → Use resource templates://
  • list_drawings() → Use resource drawings://{project_id}/
  • get_console_status() → Use resource sessions://console/{node_name}
  • ssh_get_status() → Use resource sessions://ssh/{node_name}
  • ssh_get_history() → Use resource sessions://ssh/{node_name}/history
  • ssh_get_command_output() → Use resource with filtering
  • ssh_read_buffer() → Use resource sessions://ssh/{node_name}/buffer

Final Architecture (v0.34.0):

  • 27 Action Tools: Modify state (create, delete, configure, execute commands)
  • 21 MCP Resources: Browse state (projects, nodes, sessions, diagrams, proxies) with table mode
  • 5 MCP Prompts: Guided workflows (ssh_setup, topology_discovery, troubleshooting, lab_setup, node_setup)
  • Clear separation: Tools change things, Resources view things, Prompts guide workflows
  • Table Mode (v0.30.0): All list resources use simple table format for readability

Projects

  • Projects are isolated network topologies with their own nodes, links, and configuration
  • Projects have status: opened or closed
  • Always ensure a project is opened before working with nodes
  • Use open_project() to activate a project

Nodes

  • Nodes represent network devices (routers, switches, servers, etc.)
  • Node types: qemu (VMs), docker (containers), ethernet_switch, nat, etc.
  • Node status: started or stopped
  • Each node has a unique node_id and human-readable name

Node Deletion & Cleanup (v0.34.0):

  • delete_node(node_name) removes node from project
  • Automatic SSH session cleanup: When a node is deleted, all SSH sessions are automatically cleaned up:
    • Disconnects SSH sessions on ALL registered proxies (host proxy + lab proxies)
    • Cleans up internal session mappings
    • Best-effort cleanup - won't block deletion if cleanup fails
  • Why: Prevents orphaned SSH sessions consuming resources
  • Example:
    python
    delete_node("Router1")
    # Automatically:
    # 1. Deletes node from GNS3
    # 2. Disconnects SSH session if active
    # 3. Cleans up proxy mappings
    # No manual cleanup needed!
    

Choosing Between SSH and Console Tools

IMPORTANT: Always prefer SSH tools when available!

Use SSH Tools For:

  • Production automation workflows
  • Configuration management
  • Command execution on network devices
  • Better reliability with automatic prompt detection
  • Structured output and error handling
  • Available SSH tools: ssh_send_command(), ssh_send_config_set(), ssh_read_buffer(), ssh_get_history()

Use Console Tools Only For:

  • Initial device configuration (enabling SSH, creating users, generating keys)
  • Troubleshooting when SSH is unavailable or broken
  • Devices without SSH support (VPCS, simple switches)
  • Interactive TUI navigation (vim, menu systems)

Typical Workflow:

  1. Start with console tools to configure SSH access
  2. Establish SSH session with configure_ssh()
  3. Switch to SSH tools for all automation
  4. Return to console only if SSH fails

Local Execution on SSH Proxy Container (v0.28.0)

Use node_name="@" to execute commands directly on the SSH proxy container.

Why Use Local Execution:

  • Test connectivity before accessing devices (ping, traceroute)
  • Run ansible playbooks from /opt/gns3-ssh-proxy mount
  • Execute diagnostic tools not available on network devices
  • Orchestrate multi-device operations with custom scripts

Available Tools:

  • Network diagnostics: ping, traceroute, ip, ss, netstat
  • DNS queries: dig, nslookup
  • HTTP client: curl
  • Automation: ansible-core, python3, bash
  • Working directory: /opt/gns3-ssh-proxy (shared with host)

Key Advantages:

  • No ssh_configure() needed
  • Direct access to diagnostic tools
  • Ansible playbooks can orchestrate multiple devices
  • Mix local and remote commands in ssh_batch()

Examples:

python
# Test connectivity before device access
ssh_command("@", "ping -c 3 10.10.10.1")

# Run ansible playbook (mounted from host)
ssh_command("@", "ansible-playbook /opt/gns3-ssh-proxy/backup.yml -i inventory")

# DNS lookup for lab devices
ssh_command("@", "dig router1.lab.local")

# Bash script (list of commands)
ssh_command("@", [
    "cd /opt/gns3-ssh-proxy",
    "python3 backup_configs.py",
    "ls -la backups/"
])

# Batch operations - test connectivity then configure devices
ssh_batch([
    {"type": "send_command", "node_name": "@", "command": "ping -c 2 10.1.1.1"},
    {"type": "send_command", "node_name": "@", "command": "ping -c 2 10.1.1.2"},
    {"type": "send_command", "node_name": "R1", "command": "show ip int brief"},
    {"type": "send_command", "node_name": "R2", "command": "show ip int brief"}
])

File Sharing with Host:

  1. Place files in /opt/gns3-ssh-proxy/ on GNS3 host
  2. Access same path in container
  3. Useful for: ansible playbooks, Python scripts, configuration templates

Note: Local execution returns {success, output, exit_code} instead of SSH job format.

Error Responses

All tools return standardized error responses (v0.20.0) with machine-readable error codes and actionable guidance.

Error Response Structure:

json
{
  "error": "Human-readable error message",
  "error_code": "MACHINE_READABLE_CODE",
  "details": "Additional error details",
  "suggested_action": "How to fix the error",
  "context": {
    "parameter": "value",
    "debugging_info": "..."
  },
  "server_version": "0.20.0",
  "timestamp": "2025-10-25T14:30:00.000Z"
}

Error Code Categories:

Resource Not Found (404-style):

  • PROJECT_NOT_FOUND - No project open or project doesn't exist
  • NODE_NOT_FOUND - Node name not found in project
  • LINK_NOT_FOUND - Link ID doesn't exist
  • TEMPLATE_NOT_FOUND - Template name not available
  • DRAWING_NOT_FOUND - Drawing ID not found
  • SNAPSHOT_NOT_FOUND - Snapshot name doesn't exist

Validation Errors (400-style):

  • INVALID_PARAMETER - Invalid parameter value
  • MISSING_PARAMETER - Required parameter not provided
  • PORT_IN_USE - Port already connected to another node
  • NODE_RUNNING - Operation requires node to be stopped
  • NODE_STOPPED - Operation requires node to be running
  • INVALID_ADAPTER - Adapter name/number not valid for node
  • INVALID_PORT - Port number exceeds adapter capacity

Connection Errors (503-style):

  • GNS3_UNREACHABLE - Cannot connect to GNS3 server
  • GNS3_API_ERROR - GNS3 server API error
  • CONSOLE_DISCONNECTED - Console session lost
  • CONSOLE_CONNECTION_FAILED - Failed to connect to console
  • SSH_CONNECTION_FAILED - Failed to establish SSH session
  • SSH_DISCONNECTED - SSH session lost

Authentication Errors (401-style):

  • AUTH_FAILED - Authentication failed
  • TOKEN_EXPIRED - JWT token expired
  • INVALID_CREDENTIALS - Wrong username/password

Internal Errors (500-style):

  • INTERNAL_ERROR - Server internal error
  • TIMEOUT - Operation timed out
  • OPERATION_FAILED - Generic operation failure

Example Error Handling:

python
# Attempt to start a node
result = set_node("Router1", action="start")

# Check for errors
if "error" in result:
    error = json.loads(result)
    if error["error_code"] == "NODE_NOT_FOUND":
        # Use suggested_action to fix
        print(error["suggested_action"])  # "Use list_nodes() to see all available nodes"
        # Check available nodes from context
        print(error["context"]["available_nodes"])  # ["Router2", "Router3", "Switch1"]
    elif error["error_code"] == "GNS3_UNREACHABLE":
        # Server connection issue
        print(f"Cannot reach GNS3 at {error['context']['host']}:{error['context']['port']}")

Common Error Scenarios:

  1. No project open: Most tools require an open project

    • Error: PROJECT_NOT_FOUND
    • Fix: open_project("ProjectName")
  2. Node not found: Typo in node name (case-sensitive)

    • Error: NODE_NOT_FOUND
    • Fix: Check available_nodes in error context or use resource projects://{id}/nodes/
  3. Port already in use: Trying to connect already-connected port

    • Error: PORT_IN_USE
    • Fix: Disconnect existing link first with set_connection([{"action": "disconnect", "link_id": "..."}])
  4. Node must be stopped: Trying to modify running node properties

    • Error: NODE_RUNNING
    • Fix: set_node("NodeName", action="stop") then retry

Tool Annotations (v0.19.0)

MCP tool annotations provide metadata to IDE/MCP clients for better UX and safety.

destructive (3 tools):

  • delete_node, restore_snapshot, delete_drawing
  • IDE may show warnings or require confirmation
  • These operations delete data or make irreversible changes
  • Always create backups before using destructive tools

idempotent (9 tools):

  • open_project, create_project, close_project, set_node
  • console_disconnect, ssh_configure, ssh_disconnect
  • update_drawing, export_topology_diagram
  • Safe to retry - same operation produces same result
  • Example: Opening already-opened project is safe

read_only (1 tool):

  • console_read
  • Tool only reads data, makes no state changes
  • May be cached by MCP clients

creates_resource (5 tools):

  • create_project, create_node, create_snapshot
  • export_topology_diagram, create_drawing
  • Tool creates new resources (in GNS3 or filesystem)

modifies_topology (3 tools):

  • set_connection, create_node, delete_node
  • Tool changes network topology structure
  • May require project reload in GNS3 GUI

Console Access

  • Nodes have console ports for CLI access
  • Console types:
    • telnet: CLI access (most routers/switches) - currently supported
    • vnc: Graphical access (desktops/servers) - not yet supported
    • spice+agent: Enhanced graphical - not yet supported
    • none: No console
  • Auto-connect workflow (v0.2.0):
    1. Just use console_send(node_name, command) - automatically connects if needed
    2. Read output with console_read(node_name) - returns new output since last read (diff mode, default since v0.9.0)
    3. Or use console_read(node_name, mode="last_page") for last ~25 lines
    4. Or use console_read(node_name, mode="all") for full buffer
    5. Disconnect with console_disconnect(node_name) when done
  • Sessions are managed automatically by node name
  • Session timeout: 30 minutes of inactivity

Console State Tracking (v0.34.0):

  • IMPORTANT: Must read console BEFORE sending commands
  • Why: Ensures you understand current terminal state (prompt, login screen, etc.)
  • Enforced: All send operations (console_send, console_send_and_wait, console_keystroke) check access state
  • Workflow:
    1. First: console_read("R1") - Check terminal state (are you at login? prompt? password?)
    2. Then: console_send("R1", "command\n") - Send appropriate command
    3. Read again: console_read("R1") - Verify command executed
  • Error: If you try to send without reading first, you'll get:
    "Cannot send to console - terminal not accessed yet.
     Use console_read() to check current terminal state first."
    
  • Best Practice: Always read → send → read pattern for reliable automation

Interactive Console Automation (v0.21.1)

For workflows that need to wait for specific prompts before proceeding:

Tool: console_send_and_wait(node_name, command, wait_pattern, timeout, raw)

Best Practice Workflow:

  1. Check the prompt first - See what you're waiting for:

    console_send("R1", "\n")  # Wake console
    output = console_read("R1")  # Check output: "Router#"
    
  2. Use that pattern in console_send_and_wait:

    result = console_send_and_wait(
        "R1",
        "show ip interface brief\n",
        wait_pattern="Router#",  # Wait for this exact prompt
        timeout=10
    )
    
  3. Check the result:

    json
    {
        "output": "Interface    IP-Address   ...\nGi0/0        192.168.1.1  ...\nRouter#",
        "pattern_found": true,
        "timeout_occurred": false,
        "wait_time": 0.8
    }
    

Use Cases:

  • Interactive logins: Wait for "Login:" prompt
  • Command completion: Wait for prompt to return before next command
  • Configuration mode: Wait for "(config)#" before sending configs
  • Reboots: Wait for boot messages to complete

Examples:

# Wait for login prompt
console_send_and_wait("R1", "\n", wait_pattern="Login:", timeout=30)

# Wait for enable prompt
console_send_and_wait("R1", "enable\n", wait_pattern="#", timeout=5)

# Configuration mode
console_send_and_wait("R1", "configure terminal\n", wait_pattern="(config)#", timeout=5)

# No pattern - just wait 2 seconds and return output
console_send_and_wait("R1", "save config\n")

Pattern Matching:

  • Supports regex patterns: "Router[>#]" matches "Router>" OR "Router#"
  • Pattern search is case-sensitive by default
  • If wait_pattern=None, waits 2 seconds and returns output
  • Polls console every 0.5 seconds until pattern found or timeout

Error Handling:

  • Invalid regex: Returns error with error_code="INVALID_PARAMETER"
  • Console disconnected: Returns error with error_code="CONSOLE_DISCONNECTED"
  • Timeout without pattern: Sets timeout_occurred=true, still returns accumulated output

When to Use:

  • ✅ Interactive console workflows (logins, menus, confirmations)
  • ✅ Ensuring command completion before next step
  • ✅ Boot sequences with specific prompts
  • ❌ Simple command execution - use console_send() + console_read() instead
  • ❌ SSH-capable devices - use ssh_command() for better reliability

Batch Console Operations (v0.22.0)

For workflows that need to execute multiple console operations efficiently:

Tool: console_batch(operations) - Execute multiple console operations with two-phase validation

Two-Phase Execution:

  1. VALIDATE ALL operations (check nodes exist, required params present)
  2. EXECUTE ALL operations (only if all valid, sequential execution)

Supported Operation Types: Each operation in the batch can be any of these types with full parameter support:

  1. "send" - Send data to console

    json
    {
        "type": "send",
        "node_name": "R1",
        "data": "show version\n",
        "raw": false  // optional
    }
    
  2. "send_and_wait" - Send command and wait for pattern

    json
    {
        "type": "send_and_wait",
        "node_name": "R1",
        "command": "show ip interface brief\n",
        "wait_pattern": "Router#",  // optional
        "timeout": 30,  // optional
        "raw": false  // optional
    }
    
  3. "read" - Read console output

    json
    {
        "type": "read",
        "node_name": "R1",
        "mode": "diff",  // optional: diff/last_page/num_pages/all
        "pattern": "error",  // optional grep pattern
        "case_insensitive": true  // optional
    }
    
  4. "keystroke" - Send special keystroke

    json
    {
        "type": "keystroke",
        "node_name": "R1",
        "key": "enter"  // up/down/enter/ctrl_c/etc
    }
    

Use Case 1: Multiple Commands on One Node

json
console_batch([
    {"type": "send_and_wait", "node_name": "R1", "command": "show version\n", "wait_pattern": "Router#"},
    {"type": "send_and_wait", "node_name": "R1", "command": "show ip route\n", "wait_pattern": "Router#"},
    {"type": "send_and_wait", "node_name": "R1", "command": "show running-config\n", "wait_pattern": "Router#"}
])

Use Case 2: Same Command on Multiple Nodes (Parallel Analysis)

json
console_batch([
    {"type": "send_and_wait", "node_name": "R1", "command": "show ip int brief\n", "wait_pattern": "#"},
    {"type": "send_and_wait", "node_name": "R2", "command": "show ip int brief\n", "wait_pattern": "#"},
    {"type": "send_and_wait", "node_name": "R3", "command": "show ip int brief\n", "wait_pattern": "#"}
])

Use Case 3: Mixed Operations (Interactive Workflow)

json
console_batch([
    {"type": "send", "node_name": "R1", "data": "\n"},  // Wake console
    {"type": "read", "node_name": "R1", "mode": "last_page"},  // Check prompt
    {"type": "send_and_wait", "node_name": "R1", "command": "show version\n", "wait_pattern": "#"},
    {"type": "keystroke", "node_name": "R1", "key": "ctrl_c"}  // Cancel if needed
])

Return Format:

json
{
    "completed": [0, 1, 2],  // Indices of successful operations
    "failed": [3],  // Indices of failed operations
    "results": [
        {
            "operation_index": 0,
            "success": true,
            "operation_type": "send_and_wait",
            "node_name": "R1",
            "result": {
                "output": "...",
                "pattern_found": true,
                "timeout_occurred": false,
                "wait_time": 1.2
            }
        },
        {
            "operation_index": 3,
            "success": false,
            "operation_type": "send_and_wait",
            "node_name": "R4",
            "error": {
                "error": "Node not found: R4",
                "error_code": "NODE_NOT_FOUND",
                "suggested_action": "..."
            }
        }
    ],
    "total_operations": 4,
    "execution_time": 5.3
}

When to Use:

  • ✅ Running same diagnostic command on multiple routers
  • ✅ Executing multi-step workflows on one device
  • ✅ Gathering data from multiple nodes for comparison/analysis
  • ✅ Interactive sequences with validation checks between steps
  • ❌ Single operations - use individual tools for simplicity
  • ❌ SSH-capable devices - consider SSH batch operations for better reliability

Advantages:

  • Validation: All operations validated before execution (prevents partial failures)
  • Structured Results: Clear success/failure status per operation
  • Timing: Execution time tracking for performance analysis
  • Flexibility: Mix different operation types in one batch
  • Error Isolation: Failed operations don't stop the batch, all results returned

Coordinate System and Topology Layout

GNS3 uses a specific coordinate system for positioning elements:

Node Positioning:

  • Node coordinates (x, y) represent the top-left corner of the node icon
  • Icon sizes:
    • PNG images: 78×78 pixels (custom device icons)
    • SVG/internal icons: 58×58 pixels (built-in icons)
  • Node center is at (x + icon_size/2, y + icon_size/2)
  • Example: Node at (100, 100) with PNG icon has center at (139, 139)

Label Positioning:

  • Node labels are stored as offsets from node top-left to label box top-left
  • GNS3 API returns: label: {x: -10, y: -25, text: "Router1", rotation: 0, style: "..."}
  • The offset (x, y) represents: node_top_left → label_box_top_left
  • Label box contains text that is right-aligned and vertically centered within the box
  • Text alignment: text-anchor: end; dominant-baseline: central

Link Connections:

  • Links connect to the center of nodes, not the top-left corner
  • Connection point: (node_x + icon_size/2, node_y + icon_size/2)
  • When using set_connection(), specify which adapter and port on each node

Drawing Objects (v0.8.0 - Unified create_drawing):

  • Create drawings with create_drawing(drawing_type, x, y, ...) where type is "rectangle", "ellipse", "line", or "text"
  • All drawing coordinates (x, y) represent the top-left corner of bounding box
  • Rectangle: create_drawing("rectangle", x, y, width=W, height=H, fill_color="#fff", border_color="#000")
  • Ellipse: create_drawing("ellipse", x, y, rx=50, ry=30, fill_color="#fff", border_color="#000")
  • Line: create_drawing("line", x, y, x2=100, y2=50, border_color="#000", border_width=2) - ends at (x+x2, y+y2)
  • Text: create_drawing("text", x, y, text="Label", font_size=10, color="#000", font_weight="normal")
  • Z-order: 0 = behind nodes (backgrounds), 1 = in front of nodes (labels)

Topology Export:

  • Use export_topology_diagram() to create SVG/PNG screenshots
  • Renders nodes with actual icons, links, drawings, and labels
  • All positioning respects the coordinate system above
  • Output includes:
    • Visual status indicators on nodes (started=green, stopped=red)
    • Port status indicators on links (active=green circles, shutdown=red circles)
    • Preserved fonts and styling from GNS3

Layout Best Practices:

  • Minimum spacing to avoid overlaps:
    • Horizontal: 150-200px between node icons
    • Vertical: 100-150px between node icons
    • Site rectangles: 250-350px wide, 200-300px tall
    • Padding around elements: 50px minimum
  • Site organization:
    • Place background rectangles at z=0 (behind nodes)
    • Place site labels at z=1 (in front of rectangles)
    • Position site labels 30px above rectangle top edge
    • Center nodes within site rectangles for clean layout
  • Node positioning:
    • PNG icons (78×78): Need more spacing than SVG icons (58×58)
    • Account for label width when positioning adjacent nodes
    • Estimated label width: text_length * font_size * 0.6
  • Connection planning:
    • Consider link paths when positioning nodes
    • Avoid crossing links where possible for clarity
    • Star topologies: Central node with radial connections
    • Mesh topologies: Triangular or grid layouts work best

Common Workflows

Starting a Lab Environment

1. List projects to find your lab
2. Open the target project
3. List nodes to see topology
4. Start nodes in order (usually: core switches → routers → endpoints)
5. Wait ~30-60s for devices to boot
6. Verify status with list_nodes

Configuring a Router via Console

1. Ensure node is started (use set_node if needed)
2. Send initial newline to wake console: send_console("Router1", "\n")
3. Read output to see prompt: read_console("Router1")
4. Send configuration commands one at a time
5. Always read output after each command to verify
6. Default behavior (v0.8.0): returns only new output since last read
7. Disconnect when done: disconnect_console("Router1")

Example:

send_console("R1", "\n")
read_console("R1")  # See prompt (diff mode default since v0.9.0)
send_console("R1", "show ip interface brief\n")
read_console("R1")  # See command output (only new lines)
disconnect_console("R1")  # Clean up when done

Using send_and_wait_console for Automation

For automated workflows, send_and_wait_console() simplifies command execution by waiting for specific prompts:

Workflow:
1. First, identify the prompt pattern
   - Send \n and read output to see what prompt looks like
   - Note the exact prompt: "Router#", "[admin@MikroTik] >", "switch>", etc.

2. Use the prompt pattern in automated commands
   - send_and_wait_console(node, command, wait_pattern=<prompt>)
   - Tool waits until prompt appears, then returns all output

3. No need to manually wait or read - tool handles timing

Example - Automated configuration:

# Step 1: Identify the prompt
send_console("R1", "\n")
output = read_console("R1")  # Output shows "Router#"

# Step 2: Use prompt pattern for automation
result = send_and_wait_console("R1",
    "show ip interface brief\n",
    wait_pattern="Router#",
    timeout=10)
# Returns when "Router#" appears - command is complete

# Step 3: Continue with more commands
result = send_and_wait_console("R1",
    "configure terminal\n",
    wait_pattern="Router\\(config\\)#",  # Prompt changes in config mode
    timeout=10)

When to use send_and_wait_console:

  • Automated scripts where you know the expected prompts
  • Long-running commands that need completion confirmation
  • Interactive menus where you need to wait for specific text

When to use send_console + read_console:

  • Interactive troubleshooting where prompts may vary
  • Exploring unknown device states
  • When you need fine-grained control over timing

Console Best Practices

  • Always read console output after sending commands
  • Wait 1-2 seconds between commands for device processing
  • Send \n (newline) first to wake up console
  • Look for prompts (>, #) in output to confirm device is ready
  • Default behavior (v0.9.0): read_console() returns only new output since last read (diff mode)
  • Last page mode: Use read_console(node, mode="last_page") for last ~25 lines
  • Full buffer: Use read_console(node, mode="all") for entire console history
  • Before using send_and_wait_console(): First check what the prompt looks like with read_console()
    • Different devices have different prompts: Router#, [admin@MikroTik] >, switch>, etc.
    • Use the exact prompt pattern in wait_pattern parameter to ensure command completion
    • Example: Send \n, read output to see Router#, then use wait_pattern="Router#" for commands
    • This prevents missing output or waiting for wrong prompt
  • No need to manually connect - auto-connects on first send/read
  • Disconnect when done to free resources (30min timeout otherwise)
  • For RouterOS (MikroTik): default user admin, empty password
  • For Arista vEOS: default user admin, no password

Troubleshooting Connectivity

1. Check node status (all started?)
2. Verify console access (can you connect?)
3. Check interfaces: send "show ip interface brief" or equivalent
4. Check routing: send "show ip route"
5. Test ping: send "ping <target_ip>"
6. Read output after each command

Topology Visualization (v0.33.0)

Viewing Diagrams: Use the diagram resource to quickly visualize lab topology:

# Get topology as SVG
diagram = read_resource("diagrams://{project_id}/topology")

Exporting Diagrams: Use export_topology_diagram() tool to save diagrams as files:

# Export as both SVG and PNG
export_topology_diagram(
    output_path="/path/to/topology",
    format="both"  # or "svg", "png"
)

# Export with crop region
export_topology_diagram(
    output_path="/path/to/cropped",
    format="png",
    crop_x=100, crop_y=100,
    crop_width=800, crop_height=600
)

Diagram Features:

  • Node positions, status indicators (color-coded by status)
  • Network links with connection information
  • Drawing objects (labels, shapes, annotations)
  • Automatic layout based on node coordinates
  • SVG format: scalable, text-based, ideal for AI analysis
  • PNG format: rasterized for sharing/presentation

Use Cases:

  • Document lab topology
  • Visual topology review before making changes
  • Share lab configuration with team
  • Analyze network layout and connectivity patterns

MCP Prompts - Guided Workflows (v0.17.0)

MCP prompts provide step-by-step guidance for complex multi-step operations.

Available Prompts

ssh_setup - Device-Specific SSH Configuration

  • Covers 6 device types: Cisco IOS, NX-OS, MikroTik, Juniper, Arista, Linux
  • Step-by-step instructions from console configuration to SSH session establishment
  • Device-specific commands with parameter placeholders
  • Troubleshooting guidance for common SSH issues

Usage:

Call the ssh_setup prompt with device_type parameter
Example: ssh_setup(device_type="cisco_ios", node_name="R1")

topology_discovery - Network Topology Discovery and Visualization

  • Guides through using MCP resources to browse projects/nodes/links
  • Instructions for export_topology_diagram tool usage
  • Topology pattern analysis (hub-and-spoke, mesh, tiered, etc.)
  • Common topology questions to answer during discovery

Usage:

Call the topology_discovery prompt to start guided discovery
The prompt walks through resource browsing and diagram export

troubleshooting - OSI Model-Based Systematic Troubleshooting

  • Layer 1-7 troubleshooting methodology
  • Common issues and resolutions for each layer
  • Console and SSH troubleshooting workflows
  • Performance analysis and log collection

Usage:

Call the troubleshooting prompt for systematic diagnosis
Example: troubleshooting(node_name="R1", issue="connectivity")

lab_setup - Automated Topology Creation (v0.18.0)

  • Creates complete topologies with single command
  • 6 topology types: star, mesh, linear, ring, OSPF, BGP
  • Automatic node positioning using layout algorithms
  • IP addressing schemes

Topology types:

  • star: Hub-and-spoke (parameter: spoke_count)
  • mesh: Full mesh (parameter: router_count)
  • linear: Chain topology (parameter: router_count)
  • ring: Circular topology (parameter: router_count)
  • ospf: Multi-area OSPF (parameter: area_count, 3 routers per area)
  • bgp: Multiple AS (parameter: AS_count, 2 routers per AS)

Usage:

Call the lab_setup prompt with topology_type and device_count
Example: lab_setup(topology_type="ospf", device_count=3)

node_setup - Complete Node Setup Workflow (v0.23.0)

  • End-to-end workflow for adding new node to lab
  • Covers: create, boot, configure IP, document, establish SSH
  • Device-specific configuration commands (Cisco IOS, Linux, MikroTik)
  • Automatic project README documentation updates
  • SSH session verification

Workflow steps:

  1. Create node from template at specified coordinates
  2. Start node and wait for boot completion (device-specific timing)
  3. Configure IP address via console (device-specific commands)
  4. Document IP/credentials in project README
  5. Establish and verify SSH session for automation

Usage:

Call the node_setup prompt to get guided workflow
Example: node_setup(template_name="Cisco IOSv", node_name="R1",
                    x=100, y=100, ip_address="10.1.1.1/24")

SSH Automation (v0.12.0)

SSH automation via Netmiko for advanced device management. Requires SSH proxy container deployed to GNS3 host.

Prerequisites

SSH must be enabled on device first using console tools:

Cisco IOS:

send_console('R1', 'configure terminal\n')
send_console('R1', 'username admin privilege 15 secret cisco123\n')
send_console('R1', 'crypto key generate rsa modulus 2048\n')
send_console('R1', 'ip ssh version 2\n')
send_console('R1', 'line vty 0 4\n')
send_console('R1', 'login local\n')
send_console('R1', 'transport input ssh\n')
send_console('R1', 'end\n')

MikroTik RouterOS:

send_console('MT1', '/user add name=admin password=admin123 group=full\n')
send_console('MT1', '/ip service enable ssh\n')

Basic SSH Workflow

1. Configure SSH Session:

configure_ssh('R1', {
    'device_type': 'cisco_ios',
    'host': '10.10.10.1',
    'username': 'admin',
    'password': 'cisco123'
})

2. Execute Commands:

# Show commands
ssh_send_command('R1', 'show ip interface brief')
ssh_send_command('R1', 'show running-config')

# Configuration commands
ssh_send_config_set('R1', [
    'interface GigabitEthernet0/0',
    'ip address 192.168.1.1 255.255.255.0',
    'no shutdown'
])

3. Review History:

# List recent commands
ssh_get_history('R1', limit=10)

# Search history
ssh_get_history('R1', search='interface')

# Get specific command output
ssh_get_command_output('R1', job_id='...')

Session Management (v0.1.6)

SSH sessions are automatically managed with the following features:

30-Minute Session TTL:

  • Sessions automatically expire after 30 minutes of inactivity
  • Activity timestamp updated on every operation:
    • SSH command execution (ssh_send_command, ssh_send_config_set)
    • Buffer reads (via resources)
    • Session configuration (reuse of existing session)
  • Expired sessions are automatically detected and recreated
  • No manual intervention required

Session Health Checks:

  • Before reusing existing sessions, health checks verify connection is still alive
  • Health check methods:
    1. Netmiko is_alive() if available (Netmiko 4.0+)
    2. Lightweight empty command test (fallback)
  • Stale/closed connections automatically recreated
  • Ensures reliable session reuse

Auto-Recovery from Stale Sessions (THE KEY FEATURE):

When commands fail with "Socket is closed":

  1. Stale session automatically removed from session manager
  2. Error response includes error_code="SSH_DISCONNECTED" and suggested_action
  3. Just retry configure_ssh() with same parameters - no force needed!
  4. Fresh session will be created automatically
  5. Retry your ssh_command() - it will work

Recovery Workflow:

# 1. Command fails with "Socket is closed"
result = ssh_send_command('R1', 'show version')
# Returns: error_code="SSH_DISCONNECTED",
#          suggested_action="Session was stale and has been removed. Reconnect..."

# 2. Simply retry configure_ssh() - NO force parameter needed
#    Stale session already cleaned up, new session will be created
configure_ssh('R1', device_dict)

# 3. Retry command - works now
result = ssh_send_command('R1', 'show version')  # ✅ Works

Force Recreation Parameter (rarely needed):

  • Use force=True ONLY for: credential changes, manual troubleshooting
  • NOT needed for stale session recovery (auto-cleanup handles it)
  • Example:
# Force recreation to change credentials (uncommon use case)
configure_ssh('R1', device_dict, force=True)

Error Codes (v0.1.6):

  • SSH_DISCONNECTED - Session closed (stale connection) → Just retry configure_ssh()
  • TIMEOUT - Command timed out → Increase read_timeout parameter
  • COMMAND_FAILED - Generic command failure → Check command syntax

Adaptive Async for Long Commands

For long-running operations (firmware upgrades, backups):

# Start command, return job_id immediately
result = ssh_send_command('R1', 'copy running-config tftp:', wait_timeout=0)
job_id = result['job_id']

# Poll for completion
status = ssh_get_job_status(job_id)
# Returns: {completed, output, execution_time}

# For 15+ minute commands:
ssh_send_command('R1', 'upgrade firmware', read_timeout=900, wait_timeout=0)

Supported Device Types

200+ device types via Netmiko:

  • cisco_ios - Cisco IOS/IOS-XE
  • cisco_nxos - Cisco Nexus
  • juniper - Juniper JunOS
  • arista_eos - Arista EOS
  • mikrotik_routeros - MikroTik RouterOS
  • linux - Linux/Alpine
  • See Netmiko documentation for complete list

SSH Best Practices

  • Enable SSH first using console tools
  • Use job history for audit trails and debugging
  • Set wait_timeout=0 for long commands to avoid blocking
  • Poll with ssh_get_job_status() for async operations
  • Review ssh_get_history() to verify command execution
  • Clean sessions with ssh_cleanup_sessions() when changing lab topology
  • Check status with ssh_get_status() to verify connection before commands

Device-Specific Commands

MikroTik RouterOS

  • Login prompt: Login: → send admin\n
  • Password: just press enter (empty)
  • Prompt: [admin@MikroTik] >
  • Show interfaces: /interface print
  • Show IP addresses: /ip address print
  • Show routes: /ip route print

Arista vEOS

  • Login: admin (no password)
  • Prompt: switch>
  • Enable mode: enableswitch#
  • Show interfaces: show interfaces status
  • Show IP: show ip interface brief
  • Config mode: configure terminal

Cisco IOS (CSR1000v, IOSv)

  • Prompt: Router> (user mode), Router# (privileged)
  • Enable: enable
  • Show interfaces: show ip interface brief
  • Show routes: show ip route
  • Config: configure terminal

Error Handling

Node Won't Start

  • Check node details for errors
  • Verify compute resources available
  • Some nodes (Windows) take 5+ minutes to boot

Console Not Responding

  • Check node is actually started
  • Try sending \n or \r\n to wake console
  • Some consoles have startup delay (30-60s after node start)

Session Timeout

  • Console sessions expire after 30 minutes of inactivity
  • Always disconnect when done to free resources
  • Sessions managed by node_name (no manual tracking needed)

Multi-Node Operations

When working with multiple nodes:

  1. Start nodes using set_node(node_name, action='start') or batch operations
  2. Console sessions identified by node_name (no manual tracking needed)
  3. Configure one device at a time, verify before moving on
  4. Read output to get only new lines (diff mode default since v0.8.0) - avoids confusion between devices
  5. Disconnect sessions when done: disconnect_console(node_name)

Example - Configure multiple routers:

# Start all routers
set_node("R1", action="start")
set_node("R2", action="start")

# Configure R1
send_console("R1", "\n")
read_console("R1")  # Diff mode default - only new output
send_console("R1", "configure terminal\n")
read_console("R1")  # Only new output since last read
# ... more commands ...
disconnect_console("R1")

# Configure R2 (same pattern)
send_console("R2", "\n")
# ... configure R2 ...
disconnect_console("R2")

Managing Network Connections

Link Management with set_connection

Use set_connection(connections) for batch link operations. Operations execute sequentially (top-to-bottom) with predictable state on failure.

Connection Format:

python
connections = [
    # Disconnect a link
    {"action": "disconnect", "link_id": "abc123"},

    # Connect two nodes (using adapter names - recommended)
    {"action": "connect",
     "node_a": "R1", "adapter_a": "eth0", "port_a": 0,
     "node_b": "R2", "adapter_b": "GigabitEthernet0/0", "port_b": 1},

    # Or using adapter numbers (legacy)
    {"action": "connect",
     "node_a": "R1", "adapter_a": 0, "port_a": 0,
     "node_b": "R2", "adapter_b": 0, "port_b": 1}
]

Adapter Names vs Numbers:

  • Adapter names (recommended): Use port names like "eth0", "GigabitEthernet0/0", "Ethernet0"
  • Adapter numbers (legacy): Use numeric adapter index (0, 1, 2, ...)
  • Response always shows both: "adapter_a": 0, "port_a_name": "eth0"

Returns:

json
{
  "completed": [
    {"index": 0, "action": "disconnect", "link_id": "abc123"},
    {"index": 1, "action": "connect", "link_id": "new-id",
     "node_a": "R1", "node_b": "R2",
     "adapter_a": 0, "port_a": 0, "port_a_name": "eth0",
     "adapter_b": 0, "port_b": 1, "port_b_name": "GigabitEthernet0/0"}
  ],
  "failed": null
}

Best Practices:

  • Always call get_links() first to check current topology and see port names
  • Use adapter names for readability (e.g., "eth0" instead of 0)
  • Get link IDs from output (in brackets) for disconnection
  • Disconnect existing links before connecting to occupied ports
  • Operations stop at first failure for predictable state

Example - Rewire topology:

python
# 1. Check current topology
get_links()
# Output shows port names: eth0, GigabitEthernet0/0, etc.

# 2. Disconnect old link and create new one (using port names)
set_connection([
    {"action": "disconnect", "link_id": "abc-123"},
    {"action": "connect",
     "node_a": "R1", "adapter_a": "eth0", "port_a": 0,
     "node_b": "Switch1", "adapter_b": "Ethernet3", "port_b": 3}
])

Node Positioning & Configuration

Unified Node Control with set_node

Use set_node(node_name, ...) for both control and configuration:

Control Actions:

  • action="start" - Start the node
  • action="stop" - Stop the node
  • action="suspend" - Suspend node (VM only)
  • action="reload" - Reload node
  • action="restart" - Stop, wait (3 retries × 5s), then start

Configuration Properties:

  • x, y - Position on canvas
  • z - Z-order (layer) for overlapping nodes
  • locked - Lock position (True/False)
  • ports - Number of ports (ethernet switches only)

Examples:

python
# Start a node
set_node("R1", action="start")

# Restart with retry logic
set_node("R1", action="restart")  # Waits for clean stop

# Move and lock position
set_node("R1", x=100, y=200, locked=True)

# Configure switch ports
set_node("Switch1", ports=16)

# Combined operation
set_node("R1", action="start", x=150, y=300)

Restart Behavior:

  • Stops node and polls status (3 attempts × 5 seconds)
  • Waits for confirmed stop before starting
  • Returns all retry attempts in result
  • Use for nodes that need clean restart

Snapshot Management (v0.18.0)

Snapshots capture complete project state for version control and rollback.

Creating Snapshots

Before major changes, create a snapshot for safe rollback:

Workflow:

  1. Stop all running nodes (optional but recommended for consistency)
  2. Create snapshot with descriptive name
  3. Make your changes
  4. If issues occur, restore to snapshot

Example:

create_snapshot("Before OSPF Configuration",
                "Working baseline before adding OSPF")

Best Practices:

  • Use descriptive names with dates: "2025-10-26 Working OSPF Config"
  • Stop nodes before snapshot for consistent state
  • Document what each snapshot represents
  • Create snapshots at major milestones

Restoring Snapshots

Rollback to previous state (⚠️ DESTRUCTIVE - all changes since snapshot are lost):

Restore Process:

  1. Call restore_snapshot("snapshot_name")
  2. Tool automatically:
    • Stops all running nodes
    • Disconnects all console sessions
    • Restores project to snapshot state
  3. All changes since snapshot are permanently lost

Example:

restore_snapshot("Before OSPF Configuration")

Warning: Destructive operation - creates backup before testing restore procedure.

Browsing Snapshots

List available snapshots via resource:

projects://{project_id}/snapshots/

View snapshot details:

projects://{project_id}/snapshots/{snapshot_id}

Project Notes/Memory (v0.23.0)

Store project-specific context to avoid consuming conversation context. Agent can maintain persistent notes about IPs, credentials, and architecture.

Features

  • Per-Project Storage: Each lab has separate README.txt file
  • Zero Context Cost: Notes loaded only on explicit tool call
  • Markdown Format: Human-readable, supports formatting
  • Native GNS3 Storage: Uses built-in README.txt via API
  • Persistent: Saved with project, portable

Tools

get_project_readme(project_id?)

  • Retrieve project documentation
  • Returns markdown content
  • Uses current project if ID not specified

update_project_readme(content, project_id?)

  • Save project documentation
  • Markdown format
  • Creates README.txt if doesn't exist

MCP Resource

projects://{project_id}/readme

Browsable resource for read-only access to project notes.

Common Use Cases

IP Addressing Documentation:

markdown
# Network Lab

## IP Addressing
- Router1: 10.1.0.1/24 (GigabitEthernet0/0)
- Router2: 10.1.0.2/24 (GigabitEthernet0/0)
- Management VLAN: 192.168.100.0/24

## VLANs
- VLAN 10: Users (10.10.0.0/24)
- VLAN 20: Servers (10.20.0.0/24)
- VLAN 100: Management (192.168.100.0/24)

Credentials & Access:

markdown
## Device Credentials
- Router1: admin / vault:router1-pass
- Router2: admin / vault:router2-pass
- Switches: admin / vault:switch-default

## SSH Access
- Router1: ssh://10.1.0.1:22
- Router2: ssh://10.1.0.2:22

Architecture Notes:

markdown
## Lab Architecture

### Topology
Router1 ← → Router2 (OSPF backbone)
  |            |
Switch1     Switch2
  |            |
Clients     Servers

### Protocols
- OSPF Area 0: Backbone between routers
- HSRP: VIP 10.1.0.254 (priority R1=110, R2=100)
- STP: Root bridge is Switch1

Configuration Snippets:

markdown
## Standard Configs

### OSPF Template

router ospf 1 network 10.0.0.0 0.255.255.255 area 0 passive-interface default no passive-interface GigabitEthernet0/0


### HSRP Template

interface GigabitEthernet0/1 standby 1 ip 10.1.0.254 standby 1 priority 110 standby 1 preempt

Troubleshooting Notes:

markdown
## Known Issues

### Router1 High CPU
- **Symptom**: CPU >80% after OSPF config
- **Cause**: Debug logging enabled
- **Fix**: `no debug all`

### Switch1 Port Flapping
- **Symptom**: Port Gi0/1 up/down
- **Cause**: Bad cable in lab
- **Fix**: Use port Gi0/2 instead

Workflow Example

python
# Agent discovers lab setup
# Get current notes
notes = get_project_readme()

# Agent configures new router, updates notes
update_project_readme("""
# Lab Update 2025-10-26

## New Router Added
- Router3: 10.1.0.3/24
- SSH: admin / vault:router3-pass
- Role: Border router for internet access

## OSPF Updated
- Added Router3 to Area 0
- Redistributing default route from Router3

## Next Steps
- Configure NAT on Router3
- Test internet connectivity from clients
""")

Template Usage Notes (v0.23.0)

Templates have built-in usage notes with default credentials, setup instructions, and important information about persistent storage.

What Template Usage Contains

  • Default Credentials - Username/password for pre-configured images
    • Example: "Username: ubuntu, Password: ubuntu"
    • Example: "The login is admin, with no password by default"
  • Setup Instructions - First-boot procedures and installation details
    • Boot timing estimates (e.g., "On first boot, RouterOS is actually being installed...")
    • Console availability notes
  • Persistent Storage Info - Which directories persist across reboots
    • Example: "The /root directory is persistent."
  • Configuration Guidance - Device-specific quirks and recommendations

Accessing Template Usage (Read-Only)

For a specific template:

Resource: gns3://templates/{template_id}
Returns: Full template details including usage field

For a specific node (most common):

Resource: projects://{project_id}/nodes/{node_id}/template
Returns: Template usage notes for that node

Lazy Loading Pattern:

  • Template list (projects://{id}/templates/) excludes usage to keep lightweight
  • Usage loaded separately only when needed to avoid context bloat
  • Each node has template_id linking to its template

Usage Examples

Check default credentials before connecting:

1. Get node details: projects://{id}/nodes/{node_id}
2. Note template_id from node
3. Check template usage: gns3://templates/{template_id}
4. See "Username: admin" in usage field
5. Use those credentials with ssh_configure()

Find persistent storage directories:

1. Browse node's template: projects://{id}/nodes/{node_id}/template
2. Look for "persistent" in usage field
3. Note which directories survive reboots
4. Store important data in those locations

Best Practice: Always check template usage before initial configuration to find default credentials and understand device-specific setup requirements.

Lab Setup Automation (v0.18.0)

Use lab_setup prompt to create complete topologies automatically.

Creating a Lab

The lab_setup prompt creates:

  • Nodes positioned using layout algorithms
  • Network links between nodes
  • IP addressing schemes
  • Complete topology diagrams

Topology Types

Star Topology (Hub-and-Spoke):

lab_setup(topology_type="star", device_count=4)
  • Creates: 1 hub router + 4 spoke routers
  • Links: Hub-to-each-spoke
  • IP: 10.0.{spoke}.0/24 per link

Mesh Topology (Full Mesh):

lab_setup(topology_type="mesh", device_count=4)
  • Creates: 4 routers, all interconnected
  • Links: N*(N-1)/2 point-to-point links
  • IP: 10.0.{subnet}.0/30 per link

Linear Topology (Chain):

lab_setup(topology_type="linear", device_count=4)
  • Creates: 4 routers in series (R1-R2-R3-R4)
  • Links: Sequential connections
  • IP: 10.0.{link}.0/30

Ring Topology (Circular):

lab_setup(topology_type="ring", device_count=4)
  • Creates: 4 routers in a ring
  • Links: Each router connects to two neighbors
  • Closes the loop for redundancy

OSPF Topology (Multi-Area):

lab_setup(topology_type="ospf", device_count=3)
  • Creates: 3 areas with Area 0 backbone
  • Nodes: 3 routers per area + ABRs
  • IP: 10.{area}.0.{router}/32 loopbacks

BGP Topology (Multiple AS):

lab_setup(topology_type="bgp", device_count=3)
  • Creates: 3 autonomous systems
  • Nodes: 2 routers per AS (iBGP peering)
  • Links: eBGP between adjacent AS
  • IP: 10.{AS}.1.0/30 (iBGP), 172.16.{link}.0/30 (eBGP)

Customizing Labs

Parameters:

  • topology_type: Required topology type (star/mesh/linear/ring/ospf/bgp)
  • device_count: Number of devices/areas/AS (topology-specific)
  • template_name: Device template (default: "Alpine Linux")
  • project_name: Target project (uses current if not specified)

Example:

lab_setup("ospf", device_count=2,
          template_name="Cisco IOSv",
          project_name="OSPF Lab")

Drawing Tools (v0.19.0 - Hybrid Architecture)

Create visual annotations on topology diagrams using drawing tools.

Hybrid Pattern:

  • READ: Browse drawings via resource projects://{id}/drawings/
  • WRITE: Modify drawings via tools (create_drawing, update_drawing, delete_drawing)

Available Drawing Types

Rectangle - For site boundaries, network segments

create_drawing("rectangle", x=100, y=100, width=300, height=200,
               fill_color="#f0f0f0", border_color="#000000", z=0)

Ellipse - For cloud/WAN representations, circles

create_drawing("ellipse", x=200, y=200, rx=50, ry=50,
               fill_color="#ffffff", border_color="#0000ff", z=0)

Line - For connections, arrows, dividers

create_drawing("line", x=100, y=100, x2=200, y2=150,
               color="#ff0000", border_width=3, z=1)

Text - For labels, site names, annotations

create_drawing("text", x=150, y=50, text="Data Center A",
               font_size=14, font_weight="bold", color="#000000", z=1)

Updating Drawings

Modify drawing properties:

update_drawing(drawing_id="abc123", x=120, y=80, rotation=45)

Deleting Drawings

Remove drawing (⚠️ DESTRUCTIVE):

delete_drawing(drawing_id="abc123")

Z-order Layers

  • z=0: Background shapes (behind nodes)
  • z=1: Foreground labels and annotations
  • Higher z values appear in front

Automation Tips

  • Always check status before operations (is node started? is project open?)
  • Read before write to console (check current state first)
  • Verify each step before proceeding (don't assume success)
  • Handle errors gracefully (node might not start immediately)
  • Clean up console sessions when done
  • Use set_node for node lifecycle operations (replaces start/stop)
  • Use set_connection for topology changes (batch operations)

Example Workflows

See examples/ folder for:

  • ospf_lab.md - Setting up OSPF routing between routers
  • bgp_lab.md - Configuring BGP peering
  • Common troubleshooting procedures

Didn't find tool you were looking for?

Be as detailed as possible for better results