Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GNS3_HOSTYesGNS3 server IP/hostname
GNS3_PORTYesGNS3 server port80
GNS3_USERYesGNS3 username
HTTP_PORTNoMCP server port for HTTP mode8000
LOG_LEVELNoLogging levelINFO
MCP_API_KEYNoAPI key for HTTP mode authentication
GNS3_PASSWORDYesGNS3 password
GNS3_USE_HTTPSNoUse HTTPS for GNS3false
GNS3_VERIFY_SSLNoVerify SSL certstrue

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
gns3_connectionA

Manage GNS3 server connection

CRUD-style connection management tool.

Actions: - check: Check connection status (connection state, error details, last attempt time) - retry: Force immediate re-authentication (bypasses exponential backoff) - reconnect: Full reconnect - re-authenticate AND clear all console/SSH/notification sessions. Use after GNS3 server restart, project switch, or when sessions are stale.

Args: action: Connection action to perform

Returns: JSON with connection status or reconnection result

Examples: # Check connection status >>> gns3_connection(action="check") {"connected": false, "server": "http://192.168.1.20:80", "error": "Connection timeout", "last_attempt": "08:15:42 30.10.2025"}

# Force re-authentication only
>>> gns3_connection(action="retry")

# Full reconnect (clears all sessions)
>>> gns3_connection(action="reconnect")
{"success": true, "sessions_cleared": {"console": 3, "notification": true}}
notificationA

Subscribe to GNS3 server event notifications and read buffered events.

GNS3 streams real-time events: node state changes, link updates, log messages, etc. This tool subscribes to the stream in background and buffers events for on-demand reading.

Actions: - subscribe: Start listening to notification stream (controller or project-level) - read: Read buffered events (supports diff/all/last modes with optional action filter) - unsubscribe: Stop listening and clear buffer - status: Check subscription status and buffer stats

Event types (action field): Controller: compute., project., template.*, log.error, log.warning, log.info, ping Project: node.created/updated/deleted, link.created/updated/deleted, drawing.created/updated/deleted, snapshot.restored, ping

Examples: # Subscribe to all events >>> notification(action="subscribe")

# Subscribe to specific project events
>>> notification(action="subscribe", project_id="abc-123")

# Read new events since last read
>>> notification(action="read")

# Read only node events
>>> notification(action="read", filter_action="node.")

# Read only log errors
>>> notification(action="read", filter_action="log.error")

# Check status
>>> notification(action="status")
projectA

Manage GNS3 projects

CRUD-style project management tool.

Actions: - list: List all projects - open: Open a project by name - create: Create a new project and auto-open it - close: Close the currently opened project

Args: action: Project action to perform name: Project name (required for open/create) path: Optional project directory path (create only) format: Output format for 'list' action

Returns: JSON with ProjectInfo for created project, or list of projects

Examples: # List all projects >>> project(action="list") >>> project(action="list", format="json")

# Open existing project
>>> project(action="open", name="My Lab")

# Create new project
>>> project(action="create", name="Production Lab")
>>> project(action="create", name="Test Lab", path="/opt/gns3/projects")

# Close current project
>>> project(action="close")
nodeA

Manage GNS3 nodes (CRUD operations)

v0.47.0: CRUD-style consolidation of create_node, delete_node, and set_node. v0.40.0: Enhanced with wildcard and bulk operation support.

Actions: - list: List nodes in a project - create: Create new node from template at specified coordinates - delete: Delete node from project (WARNING: destructive, cannot be undone) - set: Configure node properties and/or control state (supports wildcards/bulk)

Wildcard Patterns (for 'set' and 'delete'): - Single node: "Router1" - All nodes: "" - Prefix match: "Router" (matches Router1, Router2, RouterCore) - Suffix match: "*-Core" (matches Router-Core, Switch-Core) - Character class: "R[123]" (matches R1, R2, R3) - JSON array: '["Router1", "Router2", "Switch1"]'

Validation Rules: - name parameter requires node to be stopped - Hardware properties (ram, cpus, hdd_disk_image, adapters) apply to QEMU/IOU/Docker/Dynamips - For IOU nodes, 'adapters' maps to 'ethernet_adapters' automatically - ports parameter applies to ethernet_switch nodes only - state_action values: start, stop, suspend, reload, restart

Returns: Single node: Status message Multiple nodes: BatchOperationResult JSON with per-node success/failure

Examples: # List nodes in project >>> node(action="list", project_id="abc-123") >>> node(action="list", project_id="abc-123", format="json")

# Create new node
>>> node(action="create", template_name="Alpine Linux", x=100, y=200)
>>> node(action="create", template_name="Cisco IOSv", x=300, y=400, node_name="R1", properties={"ram": 1024})

# Delete node
>>> node(action="delete", node_name="Router1")

# Start all nodes
>>> node(action="set", node_name="*", state_action="start")

# Stop all routers
>>> node(action="set", node_name="Router*", state_action="stop")

# Configure node properties
>>> node(action="set", node_name="R1", x=100, y=200, ram=2048)
consoleA

Execute console operations (BATCH-ONLY)

v0.47.0: Batch-only console tool. Individual console tools removed (aggressive consolidation).

IMPORTANT: Prefer SSH tools when available! Console tools are primarily for:

  • Initial device configuration (enabling SSH, creating users)

  • Troubleshooting when SSH is unavailable

  • Devices without SSH support (VPCS, simple switches)

Two-phase execution:

  1. VALIDATE ALL operations (check nodes exist, required params present)

  2. EXECUTE ALL operations (only if all valid, sequential execution)

Each operation supports all parameters from the underlying console tool:

  • "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", // optional (v0.49.0: omit for wait-only mode) "wait_pattern": "Router#", // optional "timeout": 30, // optional "raw": false, // optional "handle_pagination": true, // optional (v0.53.4: auto-handle --More--) "pagination_patterns": ["--More--", "---(more)---"], // optional (custom patterns) "pagination_key": " " // optional (default: space, can use "\n" for enter) } Wait-only mode (v0.49.0): Omit "command" to just wait for pattern without sending anything. Useful for monitoring boot sequences or waiting for specific output to appear.

  • "read": Read console output (NOTE: returns empty if nothing sent yet - this is normal) { "type": "read", "node_name": "R1", "mode": "diff", // optional: diff/last_page/num_pages/all "pages": 1, // optional, only with mode="num_pages" "pattern": "error", // optional grep pattern "case_insensitive": true, // optional "invert": false, // optional "before": 0, // optional context lines "after": 0, // optional context lines "context": 0 // optional context lines (overrides before/after) } IMPORTANT: Console buffer may be empty on first read (QEMU nodes don't output until prompted). Use 'send_and_wait' to explicitly send a command and read the response, or send commands first with 'send'.

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

Args: operations: List of operation dictionaries (see examples above)

Returns: JSON with execution results: { "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": {...} // Operation-specific result }, ... ], "total_operations": 4, "execution_time": 5.3 }

Examples: # Multiple commands on one node: >>> console(operations=[ ... {"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": "read", "node_name": "R1", "mode": "diff"} ... ])

# Same command on multiple nodes:
>>> console(operations=[
...     {"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": "#"}
... ])

# Mixed operations:
>>> console(operations=[
...     {"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
... ])
linkA

Manage network connections (links)

v0.47.0: Renamed from set_network_connections to link (CRUD consolidation).

Actions: - list: List all links in a project - batch: Execute multiple connect/disconnect operations with two-phase validation

Two-phase execution for batch operations prevents partial topology changes:

  1. VALIDATE ALL operations (check nodes exist, ports free, adapters valid)

  2. EXECUTE ALL operations (only if all valid - atomic)

Connection Operations (for 'batch' action): Connect: {action: "connect", node_a, node_b, port_a, port_b, adapter_a, adapter_b} Disconnect: {action: "disconnect", link_id}

Examples: # List links >>> link(action="list", project_id="abc-123") >>> link(action="list", project_id="abc-123", format="json")

# Connect two nodes (batch)
>>> link(action="batch", connections=[{
...     "action": "connect",
...     "node_a": "Router1",
...     "node_b": "Router2",
...     "port_a": 0,
...     "port_b": 0,
...     "adapter_a": 0,
...     "adapter_b": 0
... }])

# Disconnect link (batch)
>>> link(action="batch", connections=[{"action": "disconnect", "link_id": "abc123"}])

Returns: JSON with OperationResult (completed and failed operations) or list of links

node_fileA

Manage Docker node files (CRUD operations)

v0.47.0: CRUD-style consolidation of get_node_file, write_node_file, and configure_node_network.

Actions: - read: Read file from Docker node filesystem - write: Write file to Docker node filesystem (WARNING: does NOT restart node) - configure_network: Configure network interfaces (full workflow: write + restart)

IMPORTANT: Use 'configure_network' for network configuration as it handles the complete workflow (write config → restart node → apply changes).

Returns: JSON with file contents, confirmation message, or configured interfaces

Examples: # Read file >>> node_file(action="read", node_name="A-PROXY", file_path="etc/network/interfaces")

# Write file
>>> node_file(action="write", node_name="A-PROXY",
...           file_path="etc/network/interfaces",
...           content="auto eth0\niface eth0 inet dhcp")

# Configure network (recommended)
>>> node_file(action="configure_network", node_name="A-PROXY", interfaces=[{
...     "name": "eth0",
...     "mode": "static",
...     "address": "10.199.0.254",
...     "netmask": "255.255.255.0",
...     "gateway": "10.199.0.1"
... }])
project_docsA

Manage project documentation (CRUD operations)

v0.47.0: CRUD-style consolidation of get_project_readme and update_project_readme.

Actions: - get: Read project README/notes (markdown format) - update: Write project README/notes

Project documentation typically includes: - IP addressing schemes and VLANs - Node credentials (usernames, password vault keys) - Architecture diagrams (text-based) - Configuration templates and snippets - Troubleshooting notes and runbooks

Returns: JSON with project_id and markdown content or success confirmation

Examples: # Get README >>> project_docs(action="get") >>> project_docs(action="get", project_id="a920c77d-6e9b-41b8-9311-b4b866a2fbb0")

# Update README
>>> project_docs(action="update", content="""
... # HA PowerDNS
... ## IPs
... - B-Rec1: 10.2.0.1/24
... - B-Rec2: 10.2.0.2/24
... """)
export_topology_diagramA

Export topology diagram to SVG/PNG files on disk. For agents: use diagrams://{project_id}/topology resource for direct access without saving files.

drawingA

Manage drawings (CRUD operations)

v0.47.0: CRUD-style consolidation of create_drawing, update_drawing, delete_drawing, and create_drawings_batch.

Actions: - list: List all drawings in a project - create: Create new drawing (rectangle, ellipse, line, text) - update: Update existing drawing properties - delete: Delete drawing (WARNING: destructive, cannot be undone) - batch: Create multiple drawings with two-phase validation

Returns: JSON with drawing info or batch operation results

Examples: # List drawings >>> drawing(action="list", project_id="abc-123") >>> drawing(action="list", project_id="abc-123", format="json")

# Create rectangle
>>> drawing(action="create", drawing_type="rectangle", x=100, y=100, width=200, height=100)

# Create text label
>>> drawing(action="create", drawing_type="text", x=175, y=140, text="Router1", z=1)

# Update drawing position
>>> drawing(action="update", drawing_id="abc123", x=200, y=200)

# Delete drawing
>>> drawing(action="delete", drawing_id="abc123")

# Create multiple drawings
>>> drawing(action="batch", drawings=[
...     {"drawing_type": "rectangle", "x": 100, "y": 100, "width": 200, "height": 100},
...     {"drawing_type": "text", "x": 175, "y": 140, "text": "Router1", "z": 1}
... ])
sshA

Execute SSH operations (BATCH-ONLY)

v0.47.0: Batch-only SSH tool. Individual SSH tools removed (aggressive consolidation). v0.28.0: Local execution support with node_name="@"

Local Execution Support:

  • Use node_name="@" in any operation for local execution on SSH proxy container

  • Mix local and remote operations in same batch

  • Useful for: connectivity tests before device access, ansible playbooks

SSH Proxy Services (v0.3.0):

  • TFTP Server: Available on port 69/udp at /opt/gns3-ssh-proxy/tftp (use tftp tool)

  • HTTP/HTTPS Reverse Proxy: Access device web UIs at http://proxy:8023/http-proxy/:/

  • HTTP Client Tool: Make GET requests to device APIs (use http_client tool)

Two-phase execution prevents partial failures:

  1. VALIDATE ALL operations (check required params, valid types)

  2. EXECUTE ALL operations (only if all valid, sequential execution)

Supported operation types:

  • "configure": Configure SSH session (equivalent to old ssh_configure)

  • "command": Execute command (equivalent to old ssh_command, supports local with "@")

  • "disconnect": Disconnect SSH session

Args: operations: List of operation dicts, each with: - type (str): Operation type (required) - node_name (str): Node name (or "@" for local execution) (required) - Additional params specific to operation type

Returns: JSON with execution results including completed/failed indices

Examples: # Configure session + run commands: >>> ssh(operations=[ ... {"type": "configure", "node_name": "R1", "device_dict": { ... "device_type": "cisco_ios", "host": "10.1.0.1", ... "username": "admin", "password": "cisco123" ... }}, ... {"type": "command", "node_name": "R1", "command": "show version"}, ... {"type": "command", "node_name": "R1", "command": "show ip route"} ... ])

# Same command on multiple nodes:
>>> ssh(operations=[
...     {"type": "command", "node_name": "R1", "command": "show ip int brief"},
...     {"type": "command", "node_name": "R2", "command": "show ip int brief"}
... ])

# Configuration commands:
>>> ssh(operations=[{
...     "type": "command",
...     "node_name": "R1",
...     "command": [
...         "interface GigabitEthernet0/0",
...         "ip address 10.1.1.1 255.255.255.0",
...         "no shutdown"
...     ]
... }])

# Local execution - test connectivity before device access:
>>> ssh(operations=[
...     {"type": "command", "node_name": "@", "command": "ping -c 2 10.1.1.1"},
...     {"type": "command", "node_name": "@", "command": "ping -c 2 10.1.1.2"},
...     {"type": "command", "node_name": "R1", "command": "show ip int brief"},
...     {"type": "command", "node_name": "R2", "command": "show ip int brief"}
... ])
tftpA

Manage TFTP server files (CRUD-style)

v0.3.0: TFTP server integration for device firmware/config file serving

TFTP server runs on SSH proxy (port 69/udp) with root directory /opt/gns3-ssh-proxy/tftp. Provides read-write access for devices to upload/download files.

Actions: - list: List all files in TFTP root directory - upload: Upload file to TFTP server (requires filename and content) - download: Download file from TFTP server (requires filename) - delete: Delete file from TFTP server (requires filename) - status: Check TFTP server status

File Content Handling: - Upload: Provide raw bytes in content parameter (base64 encoded automatically) - Download: Returns file content as base64 encoded string

Returns: JSON response with success status, action, and results

Examples: # List TFTP files >>> tftp(action="list") { "success": true, "action": "list", "files": [ {"filename": "config.txt", "size": 1024, "modified": "2025-01-15 10:30:00"}, {"filename": "firmware.bin", "size": 5242880, "modified": "2025-01-14 09:15:00"} ] }

# Upload configuration file
>>> tftp(action="upload", filename="startup-config.txt", content=b"hostname Router1\n...")
{"success": true, "action": "upload", "message": "Uploaded startup-config.txt"}

# Download file
>>> tftp(action="download", filename="config.txt")
{"success": true, "action": "download", "content": "aG9zdG5hbWUgUm91dGVyMQo="}

# Delete file
>>> tftp(action="delete", filename="old-config.txt")
{"success": true, "action": "delete", "message": "Deleted old-config.txt"}

# Check TFTP server status
>>> tftp(action="status")
{
  "success": true,
  "action": "status",
  "tftp_enabled": true,
  "tftp_port": 69,
  "tftp_root": "/opt/gns3-ssh-proxy/tftp",
  "file_count": 5,
  "total_size": 10485760
}
http_clientA

HTTP/HTTPS client for lab device web interfaces (CRUD-style)

v0.3.0: HTTP client integration for accessing device APIs and web UIs

Reverse HTTP/HTTPS proxy available at http://proxy:8023/http-proxy/:/ for external device web UI access without SSH tunnel.

Actions: - get: Send HTTP GET request to device and return response - status: Check if device web interface is reachable (HEAD request)

SSL Certificate Handling: - verify_ssl=False (default): Ignore self-signed certificates - verify_ssl=True: Verify SSL certificates (may fail for lab devices)

Reverse Proxy Alternative: Instead of using this tool, you can also access device web UIs through the reverse proxy at http://proxy:8023/http-proxy/:/

Example: http://proxy:8023/http-proxy/10.1.1.1:443/ for HTTPS device

The reverse proxy handles SSL termination and provides persistent access
without needing to make API calls.

Returns: JSON response with success status, action, and results

Examples: # Get device web interface >>> http_client(action="get", url="http://10.1.1.1") { "success": true, "action": "get", "status_code": 200, "content": "...", "headers": {"content-type": "text/html", ...} }

# Check device HTTPS API reachability
>>> http_client(action="status", url="https://10.1.1.2:443", verify_ssl=False)
{
  "success": true,
  "action": "status",
  "reachable": true,
  "status_code": 200
}

# Get JSON API with custom headers
>>> http_client(
...     action="get",
...     url="http://10.1.1.3/api/v1/status",
...     headers={"Authorization": "Bearer token123", "Accept": "application/json"}
... )
{
  "success": true,
  "action": "get",
  "status_code": 200,
  "content": "{\"status\": \"online\", ...}",
  "headers": {"content-type": "application/json"}
}

# Alternative: Use reverse proxy (no tool needed)
# Access: http://proxy:8023/http-proxy/10.1.1.1:443/dashboard
query_resourceC

Universal resource query tool - access any GNS3 MCP resource.

See tool implementation docstring for comprehensive URI pattern documentation.

search_toolsA

Discover GNS3 MCP tools (v0.47.0 - Tool Discovery)

Search and filter available tools by category, capability, or resource URI. Returns tool metadata including description, actions, and applicable resources.

Categories:

  • project: Project management (open, create, close)

  • node: Node management (create, delete, configure)

  • connection: Network connections and GNS3 server

  • console: Console access to devices

  • ssh: SSH access to devices

  • drawing: Topology visualization

  • resource: Resource query tools

  • docker: Docker-specific operations

  • docs: Documentation management

  • topology: Topology operations

  • management: Management operations

  • device-access: Device access (console/SSH)

  • visualization: Visual elements

  • discovery: Tool discovery

Capabilities:

  • CRUD: Supports create/read/update/delete operations via action parameter

  • batch: Supports batch operations (multiple operations in one call)

  • wildcard: Supports wildcard patterns (, Router, R[123])

  • parallel: Supports parallel execution

  • idempotent: Multiple executions produce same result

Resource Mapping:

  • projects://: project, list_projects, query_resource

  • nodes://{project_id}/: node, list_nodes, query_resource

  • links://{project_id}/: link, query_resource

  • drawings://{project_id}/: drawing, query_resource

  • sessions://console/: console, query_resource

  • sessions://ssh/: ssh, query_resource

  • topology://{project_id}: get_topology, query_resource

Returns: JSON with matching tools and their metadata

Examples: # Find all CRUD tools >>> search_tools(capability="CRUD")

# Find tools for working with nodes
>>> search_tools(category="node")

# Find tools that work with projects:// resources
>>> search_tools(resource_uri="projects://")

# Find batch operation tools
>>> search_tools(capability="batch")

# Find tools with wildcard support
>>> search_tools(capability="wildcard")

Prompts

Interactive templates invoked by user choice

NameDescription
SSH Setup WorkflowDevice-specific SSH configuration for 6 device types with multi-proxy support
Topology Discovery WorkflowDiscover nodes, links, templates, drawings using resources - includes visual diagram guidance for agents
Troubleshooting WorkflowOSI model-based troubleshooting with README checks, diagnostic tools, log collection
Lab Setup WorkflowCreate complete topologies (star/mesh/linear/ring/ospf/bgp) with nodes, links, IPs, and README documentation
Node Setup WorkflowEnd-to-end node setup: create, configure IP, document in README, establish SSH, connect to network

Resources

Contextual data attached and managed by the client

NameDescription
ProjectsList all GNS3 projects with their statuses and IDs
TemplatesList all available GNS3 device templates (routers, switches, Docker containers, VMs)
Console sessionsList all console sessions (optionally filtered by ?project_id=xxx query parameter)
SSH sessionsList all SSH sessions (optionally filtered by ?project_id=xxx query parameter)
Main proxy statusHealth status and version of the main SSH proxy on GNS3 host (default proxy for ssh_configure)
Lab proxy registryAll discovered SSH proxy containers in GNS3 lab projects - use proxy_id for routing through isolated networks
All proxy sessionsAggregated list of ALL active SSH sessions from main proxy and lab proxies - global lab infrastructure view

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ChistokhinSV/gns3-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server