Claude Code Plugins

Community-maintained marketplace

Feedback

gns3-lab-automation

@ChistokhinSV/gns3-mcp
4
0

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

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name gns3-lab-automation
description GNS3 network lab operations including topology management, device configuration via console, and troubleshooting workflows for routers and switches

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:

# 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:

# 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:
    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:

# 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:

{
  "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:

# 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:

    {
        "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

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

    {
        "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

    {
        "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

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

Use Case 1: Multiple Commands on One Node

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)

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)

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:

{
    "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:

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:

{
  "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:

# 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:

# 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:

# 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:

## 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:

## 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:

## 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:

## 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

# 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