GNS3 network lab operations including topology management, device configuration via console, and troubleshooting workflows for routers and switches
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.
Problem: Lab configurations consume conversation context (IPs, credentials, architecture notes) Solution: Store persistent notes in per-project README
When to use:
Tools:
get_project_readme() - Retrieve project documentationupdate_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
""")
Problem: Forgetting default credentials, boot times, device-specific setup steps Solution: Templates include built-in usage notes with device info
What's included:
How to access:
projects://{id}/nodes/{node_id}/templategns3://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!
MCP resources provide browsable state via standardized URIs, replacing query tools for better IDE integration.
Resource Benefits:
gns3:// protocol)Available Resources (v0.29.0 - URI Standardization):
Project-Centric Resources:
projects:// - List all GNS3 projectsprojects://{project_id} - Get project details by IDprojects://{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 projectprojects://{project_id}/sessions/ssh/ - SSH sessions in projectQuery-parameter-based (filtered):
sessions://console/?project_id={id} - Console sessions filtered by projectsessions://ssh/?project_id={id} - SSH sessions filtered by projectUnfiltered (all sessions):
sessions://console/ - All console sessions across all projects (table mode v0.30.0)sessions://console/{node_name} - Console session for specific nodesessions://ssh/ - All SSH sessions across all projects (table mode v0.30.0)sessions://ssh/{node_name} - SSH session status for nodesessions://ssh/{node_name}/history - SSH command history (table mode v0.30.0)sessions://ssh/{node_name}/buffer - SSH continuous bufferProxy 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 projectproxies://{proxy_id} - Specific proxy detailsResource vs Tool Usage:
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}/historyssh_get_command_output() → Use resource with filteringssh_read_buffer() → Use resource sessions://ssh/{node_name}/bufferFinal Architecture (v0.34.0):
opened or closedopen_project() to activate a projectqemu (VMs), docker (containers), ethernet_switch, nat, etc.started or stoppednode_id and human-readable nameNode Deletion & Cleanup (v0.34.0):
delete_node(node_name) removes node from projectdelete_node("Router1")
# Automatically:
# 1. Deletes node from GNS3
# 2. Disconnects SSH session if active
# 3. Cleans up proxy mappings
# No manual cleanup needed!
IMPORTANT: Always prefer SSH tools when available!
Use SSH Tools For:
ssh_send_command(), ssh_send_config_set(), ssh_read_buffer(), ssh_get_history()Use Console Tools Only For:
Typical Workflow:
configure_ssh()Use node_name="@" to execute commands directly on the SSH proxy container.
Why Use Local Execution:
Available Tools:
Key Advantages:
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:
/opt/gns3-ssh-proxy/ on GNS3 hostNote: Local execution returns {success, output, exit_code} instead of SSH job format.
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 existNODE_NOT_FOUND - Node name not found in projectLINK_NOT_FOUND - Link ID doesn't existTEMPLATE_NOT_FOUND - Template name not availableDRAWING_NOT_FOUND - Drawing ID not foundSNAPSHOT_NOT_FOUND - Snapshot name doesn't existValidation Errors (400-style):
INVALID_PARAMETER - Invalid parameter valueMISSING_PARAMETER - Required parameter not providedPORT_IN_USE - Port already connected to another nodeNODE_RUNNING - Operation requires node to be stoppedNODE_STOPPED - Operation requires node to be runningINVALID_ADAPTER - Adapter name/number not valid for nodeINVALID_PORT - Port number exceeds adapter capacityConnection Errors (503-style):
GNS3_UNREACHABLE - Cannot connect to GNS3 serverGNS3_API_ERROR - GNS3 server API errorCONSOLE_DISCONNECTED - Console session lostCONSOLE_CONNECTION_FAILED - Failed to connect to consoleSSH_CONNECTION_FAILED - Failed to establish SSH sessionSSH_DISCONNECTED - SSH session lostAuthentication Errors (401-style):
AUTH_FAILED - Authentication failedTOKEN_EXPIRED - JWT token expiredINVALID_CREDENTIALS - Wrong username/passwordInternal Errors (500-style):
INTERNAL_ERROR - Server internal errorTIMEOUT - Operation timed outOPERATION_FAILED - Generic operation failureExample 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
PROJECT_NOT_FOUNDopen_project("ProjectName")Node not found: Typo in node name (case-sensitive)
NODE_NOT_FOUNDprojects://{id}/nodes/Port already in use: Trying to connect already-connected port
PORT_IN_USEset_connection([{"action": "disconnect", "link_id": "..."}])Node must be stopped: Trying to modify running node properties
NODE_RUNNINGset_node("NodeName", action="stop") then retryMCP tool annotations provide metadata to IDE/MCP clients for better UX and safety.
destructive (3 tools):
delete_node, restore_snapshot, delete_drawingidempotent (9 tools):
open_project, create_project, close_project, set_nodeconsole_disconnect, ssh_configure, ssh_disconnectupdate_drawing, export_topology_diagramread_only (1 tool):
console_readcreates_resource (5 tools):
create_project, create_node, create_snapshotexport_topology_diagram, create_drawingmodifies_topology (3 tools):
set_connection, create_node, delete_nodetelnet: CLI access (most routers/switches) - currently supportedvnc: Graphical access (desktops/servers) - not yet supportedspice+agent: Enhanced graphical - not yet supportednone: No consoleconsole_send(node_name, command) - automatically connects if neededconsole_read(node_name) - returns new output since last read (diff mode, default since v0.9.0)console_read(node_name, mode="last_page") for last ~25 linesconsole_read(node_name, mode="all") for full bufferconsole_disconnect(node_name) when doneConsole State Tracking (v0.34.0):
console_send, console_send_and_wait, console_keystroke) check access stateconsole_read("R1") - Check terminal state (are you at login? prompt? password?)console_send("R1", "command\n") - Send appropriate commandconsole_read("R1") - Verify command executed"Cannot send to console - terminal not accessed yet.
Use console_read() to check current terminal state first."
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:
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:
"Router[>#]" matches "Router>" OR "Router#"wait_pattern=None, waits 2 seconds and returns outputError Handling:
error_code="INVALID_PARAMETER"error_code="CONSOLE_DISCONNECTED"timeout_occurred=true, still returns accumulated outputWhen to Use:
console_send() + console_read() insteadssh_command() for better reliabilityFor workflows that need to execute multiple console operations efficiently:
Tool: console_batch(operations) - Execute multiple console operations with two-phase validation
Two-Phase 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:
Advantages:
npx skills add ChistokhinSV/gns3-lab-automation下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer