Claude-skill-registry gns3-lab-automation
GNS3 network lab operations including topology management, device configuration via console, and troubleshooting workflows for routers and switches
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/gns3-lab-automation" ~/.claude/skills/majiayu000-claude-skill-registry-gns3-lab-automation && rm -rf "$T"
skills/data/gns3-lab-automation/SKILL.mdGNS3 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:
- Retrieve project documentationget_project_readme()
- Save/update documentation (markdown format)update_project_readme(content)
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 (
protocol)gns3:// - Better performance with resource subscriptions
Available Resources (v0.29.0 - URI Standardization):
Project-Centric Resources:
- List all GNS3 projectsprojects://
- Get project details by IDprojects://{project_id}
- Get project README/notes (v0.23.0)projects://{project_id}/readme
- Console sessions in project (v0.29.1)projects://{project_id}/sessions/console/
- SSH sessions in project (v0.29.1)projects://{project_id}/sessions/ssh/
Object-Centric Resources:
- List nodes in project (NodeSummary, table mode v0.30.0)nodes://{project_id}/
- Get node details (full NodeInfo)nodes://{project_id}/{node_id}
- Get template usage notes for node (v0.23.0)nodes://{project_id}/{node_id}/template
- List network links in project (table mode v0.30.0)links://{project_id}/
- List drawing objects (table mode v0.30.0)drawings://{project_id}/
Diagram Resources (v0.33.0):
- Get topology diagram as SVG (visualize lab layout)diagrams://{project_id}/topology
Template Resources (Static, Not Project-Scoped):
- List all available templates (table mode v0.30.0)templates://
- Get template details with usage notes (v0.23.0)templates://{template_id}
Session Resources (Dual Access Patterns v0.29.1):
Path-based (project-scoped):
- Console sessions in projectprojects://{project_id}/sessions/console/
- SSH sessions in projectprojects://{project_id}/sessions/ssh/
Query-parameter-based (filtered):
- Console sessions filtered by projectsessions://console/?project_id={id}
- SSH sessions filtered by projectsessions://ssh/?project_id={id}
Unfiltered (all sessions):
- All console sessions across all projects (table mode v0.30.0)sessions://console/
- Console session for specific nodesessions://console/{node_name}
- All SSH sessions across all projects (table mode v0.30.0)sessions://ssh/
- SSH session status for nodesessions://ssh/{node_name}
- SSH command history (table mode v0.30.0)sessions://ssh/{node_name}/history
- SSH continuous buffersessions://ssh/{node_name}/buffer
Proxy Resources:
- Main proxy status (THREE slashes)proxies:///status
- Proxy registry (host + lab proxies, table mode v0.30.0)proxies://
- All proxy sessions (table mode v0.30.0)proxies://sessions
- Proxies for specific projectproxies://project/{project_id}
- Specific proxy detailsproxies://{proxy_id}
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):
→ Use resourcelist_projects()projects://
→ Use resourcelist_nodes()nodes://{project_id}/
→ Use resourceget_node_details()nodes://{project_id}/{node_id}
→ Use resourceget_links()links://{project_id}/
→ Use resourcelist_templates()templates://
→ Use resourcelist_drawings()drawings://{project_id}/
→ Use resourceget_console_status()sessions://console/{node_name}
→ Use resourcessh_get_status()sessions://ssh/{node_name}
→ Use resourcessh_get_history()sessions://ssh/{node_name}/history
→ Use resource with filteringssh_get_command_output()
→ Use resourcessh_read_buffer()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:
oropenedclosed - Always ensure a project is opened before working with nodes
- Use
to activate a projectopen_project()
Nodes
- Nodes represent network devices (routers, switches, servers, etc.)
- Node types:
(VMs),qemu
(containers),docker
,ethernet_switch
, etc.nat - Node status:
orstartedstopped - Each node has a unique
and human-readablenode_idname
Node Deletion & Cleanup (v0.34.0):
removes node from projectdelete_node(node_name)- 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:
- Start with console tools to configure SSH access
- Establish SSH session with
configure_ssh() - Switch to SSH tools for all automation
- 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:
- Place files in
on GNS3 host/opt/gns3-ssh-proxy/ - Access same path in container
- 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):
- No project open or project doesn't existPROJECT_NOT_FOUND
- Node name not found in projectNODE_NOT_FOUND
- Link ID doesn't existLINK_NOT_FOUND
- Template name not availableTEMPLATE_NOT_FOUND
- Drawing ID not foundDRAWING_NOT_FOUND
- Snapshot name doesn't existSNAPSHOT_NOT_FOUND
Validation Errors (400-style):
- Invalid parameter valueINVALID_PARAMETER
- Required parameter not providedMISSING_PARAMETER
- Port already connected to another nodePORT_IN_USE
- Operation requires node to be stoppedNODE_RUNNING
- Operation requires node to be runningNODE_STOPPED
- Adapter name/number not valid for nodeINVALID_ADAPTER
- Port number exceeds adapter capacityINVALID_PORT
Connection Errors (503-style):
- Cannot connect to GNS3 serverGNS3_UNREACHABLE
- GNS3 server API errorGNS3_API_ERROR
- Console session lostCONSOLE_DISCONNECTED
- Failed to connect to consoleCONSOLE_CONNECTION_FAILED
- Failed to establish SSH sessionSSH_CONNECTION_FAILED
- SSH session lostSSH_DISCONNECTED
Authentication Errors (401-style):
- Authentication failedAUTH_FAILED
- JWT token expiredTOKEN_EXPIRED
- Wrong username/passwordINVALID_CREDENTIALS
Internal Errors (500-style):
- Server internal errorINTERNAL_ERROR
- Operation timed outTIMEOUT
- Generic operation failureOPERATION_FAILED
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:
-
No project open: Most tools require an open project
- Error:
PROJECT_NOT_FOUND - Fix:
open_project("ProjectName")
- Error:
-
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/
- Error:
-
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": "..."}])
- Error:
-
Node must be stopped: Trying to modify running node properties
- Error:
NODE_RUNNING - Fix:
then retryset_node("NodeName", action="stop")
- Error:
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_snapshotdelete_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_projectset_node
,console_disconnect
,ssh_configuressh_disconnect
,update_drawingexport_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_nodecreate_snapshot
,export_topology_diagramcreate_drawing- Tool creates new resources (in GNS3 or filesystem)
modifies_topology (3 tools):
,set_connection
,create_nodedelete_node- Tool changes network topology structure
- May require project reload in GNS3 GUI
Console Access
- Nodes have console ports for CLI access
- Console types:
: CLI access (most routers/switches) - currently supportedtelnet
: Graphical access (desktops/servers) - not yet supportedvnc
: Enhanced graphical - not yet supportedspice+agent
: No consolenone
- Auto-connect workflow (v0.2.0):
- Just use
- automatically connects if neededconsole_send(node_name, command) - Read output with
- returns new output since last read (diff mode, default since v0.9.0)console_read(node_name) - Or use
for last ~25 linesconsole_read(node_name, mode="last_page") - Or use
for full bufferconsole_read(node_name, mode="all") - Disconnect with
when doneconsole_disconnect(node_name)
- Just use
- 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
) check access stateconsole_keystroke - Workflow:
- First:
- Check terminal state (are you at login? prompt? password?)console_read("R1") - Then:
- Send appropriate commandconsole_send("R1", "command\n") - Read again:
- Verify command executedconsole_read("R1")
- First:
- 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:
-
Check the prompt first - See what you're waiting for:
console_send("R1", "\n") # Wake console output = console_read("R1") # Check output: "Router#" -
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 ) -
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:
matches "Router>" OR "Router#""Router[>#]" - Pattern search is case-sensitive by default
- If
, waits 2 seconds and returns outputwait_pattern=None - 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
, still returns accumulated outputtimeout_occurred=true
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()
insteadconsole_read() - ❌ SSH-capable devices - use
for better reliabilityssh_command()
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:
- VALIDATE ALL operations (check nodes exist, required params present)
- 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:
-
"send" - Send data to console
{ "type": "send", "node_name": "R1", "data": "show version\n", "raw": false // optional } -
"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 } -
"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 } -
"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
, specify which adapter and port on each nodeset_connection()
Drawing Objects (v0.8.0 - Unified create_drawing):
- Create drawings with
where type is "rectangle", "ellipse", "line", or "text"create_drawing(drawing_type, x, y, ...) - 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:
- ends at (x+x2, y+y2)create_drawing("line", x, y, x2=100, y2=50, border_color="#000", border_width=2) - 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
to create SVG/PNG screenshotsexport_topology_diagram() - 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
(newline) first to wake up console\n - Look for prompts (>, #) in output to confirm device is ready
- Default behavior (v0.9.0):
returns only new output since last read (diff mode)read_console() - Last page mode: Use
for last ~25 linesread_console(node, mode="last_page") - Full buffer: Use
for entire console historyread_console(node, mode="all") - Before using send_and_wait_console(): First check what the prompt looks like with
read_console()- Different devices have different prompts:
,Router#
,[admin@MikroTik] >
, etc.switch> - Use the exact prompt pattern in
parameter to ensure command completionwait_pattern - Example: Send
, read output to see\n
, then useRouter#
for commandswait_pattern="Router#" - This prevents missing output or waiting for wrong prompt
- Different devices have different prompts:
- 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
, empty passwordadmin - For Arista vEOS: default user
, no passwordadmin
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
tool usageexport_topology_diagram - 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:
- Create node from template at specified coordinates
- Start node and wait for boot completion (device-specific timing)
- Configure IP address via console (device-specific commands)
- Document IP/credentials in project README
- 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)
- SSH command execution (
- 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:
- Netmiko
if available (Netmiko 4.0+)is_alive() - Lightweight empty command test (fallback)
- Netmiko
- Stale/closed connections automatically recreated
- Ensures reliable session reuse
Auto-Recovery from Stale Sessions (THE KEY FEATURE):
When commands fail with "Socket is closed":
- Stale session automatically removed from session manager
- Error response includes
anderror_code="SSH_DISCONNECTED"suggested_action - Just retry configure_ssh() with same parameters - no force needed!
- Fresh session will be created automatically
- 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
ONLY for: credential changes, manual troubleshootingforce=True - 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):
- Session closed (stale connection) → Just retry configure_ssh()SSH_DISCONNECTED
- Command timed out → Increase read_timeout parameterTIMEOUT
- Generic command failure → Check command syntaxCOMMAND_FAILED
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:
→ sendLogin: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:
(no password)admin - 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:
(user mode),Router>
(privileged)Router# - 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
or\n
to wake console\r\n - 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:
- Start nodes using
or batch operationsset_node(node_name, action='start') - Console sessions identified by node_name (no manual tracking needed)
- Configure one device at a time, verify before moving on
- Read output to get only new lines (diff mode default since v0.8.0) - avoids confusion between devices
- 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
first to check current topology and see port namesget_links() - 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:
- Start the nodeaction="start"
- Stop the nodeaction="stop"
- Suspend node (VM only)action="suspend"
- Reload nodeaction="reload"
- Stop, wait (3 retries × 5s), then startaction="restart"
Configuration Properties:
,x
- Position on canvasy
- Z-order (layer) for overlapping nodesz
- Lock position (True/False)locked
- Number of ports (ethernet switches only)ports
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:
- Stop all running nodes (optional but recommended for consistency)
- Create snapshot with descriptive name
- Make your changes
- 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:
- Call
restore_snapshot("snapshot_name") - Tool automatically:
- Stops all running nodes
- Disconnects all console sessions
- Restores project to snapshot state
- 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 (
) excludes usage to keep lightweightprojects://{id}/templates/ - Usage loaded separately only when needed to avoid context bloat
- Each node has
linking to its templatetemplate_id
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:
: Required topology type (star/mesh/linear/ring/ospf/bgp)topology_type
: Number of devices/areas/AS (topology-specific)device_count
: Device template (default: "Alpine Linux")template_name
: Target project (uses current if not specified)project_name
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
: Background shapes (behind nodes)z=0
: Foreground labels and annotationsz=1- 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:
- Setting up OSPF routing between routersospf_lab.md
- Configuring BGP peeringbgp_lab.md- Common troubleshooting procedures