Skip to main content

How to Use the MCP Service

MCP (Model Context Protocol) is an open standard that enables AI assistants to interact with external tools and services securely. GNS3 Server provides a standard MCP interface over SSE (Server-Sent Events) transport, allowing AI assistants like Claude Code to interact with GNS3.

With the MCP service, you can use natural language commands to manage GNS3 projects, nodes, links, templates, and compute nodes without manually using the GNS3 GUI/Web UI.

Beyond using ready-made clients, you can also build your own AI Agent based on MCP, or integrate it into existing AI workflows to enable automated testing and verification.

Prerequisites

  • GNS3 server is running
  • You have a GNS3 user account (default username/password: admin/admin)

Endpoints

PathMethodDescription
/v3/mcp/GETMCP service metadata
/v3/mcp/transport/sseGETSSE stream (MCP connection entry point)
/v3/mcp/transport/messages/POSTJSON-RPC messages

Authentication

The MCP service supports two credential types: JWT Token (24-hour expiry) or API Key (permanent, revocable).

  • After logging into the server, click the three dots button on the right side, then select the API Key option.

API Key menu option

  • In the API Keys dialog, click Create your first API key.

Create first API Key

  • Enter a name for the API Key and click Create.

Enter API Key name

  • Once created, the dialog displays the key. Copy and save it now.

API Key created

warning

This API Key is only shown once. After closing the dialog, it cannot be displayed again. Save it immediately.

  • The key appears in the list.

API Key list

  • In the Actions column, click Revoke to revoke a key.

Revoke API Key

  • After revocation, you can click Restore or Delete.

Revoked state

  • Click Restore to restore the key

Restore confirmation dialog

  • Click Delete to permanently delete

Delete confirmation dialog

Quick Start

Using with Claude Code

# Add MCP server
claude mcp add --transport sse My_GNS3_Server \
http://localhost:3080/v3/mcp/transport/sse \
-H "Authorization: Bearer $API_KEY"

Parameter explanation:

  • --transport sse — Use SSE (Server-Sent Events) transport, the standard MCP transport protocol that supports remote connections
  • My_GNS3_Server — A custom name for the MCP server, can be any name, used to identify this server in Claude Code
  • http://localhost:3080/v3/mcp/transport/sse — The GNS3 server MCP SSE endpoint URL, localhost is the GNS3 server address, 3080 is the default port
  • -H "Authorization: Bearer $API_KEY" — The authentication header carrying the API Key, replace $API_KEY with the API Key value obtained in the previous step

Once configured, you can manage GNS3 using natural language in Claude Code, for example:

  • "List all GNS3 projects"
  • "Create a new project named 'OSPF Lab'"
  • "Add a Cisco router to the project"
  • "Start the node and check its status"

Available Tools

The MCP service provides 82 tools across 12 categories:

Project (15)

ToolDescriptionRequired Parameters
project_listList all projectsnone
project_getGet project detailsproject_id
project_createCreate a projectname
project_deleteDelete a projectproject_id
project_openOpen a closed projectproject_id
project_closeClose an open projectproject_id
project_statsGet project statisticsproject_id
project_updateUpdate project propertiesproject_id
project_duplicateDuplicate a projectproject_id, name
project_readme_getGet project README contentproject_id
project_readme_updateUpdate project READMEproject_id, content_markdown
project_lockLock project (prevent edits)project_id
project_unlockUnlock projectproject_id
project_loadLoad project from pathpath
project_lockedCheck if project is lockedproject_id
note

After calling project_unlock, the project status query may still show locked=true momentarily due to status sync delay.

Node (22)

ToolDescriptionRequired Parameters
node_listList all nodes in a project (fields to filter columns, e.g. ["name","status"])project_id
node_getGet node details (fields to filter columns)project_id, node_id
node_createCreate node(s) — single via template_id or batch via nodes array. In batch mode the top-level template_id is the default and each entry can set name; coordinates use a canvas-center origin (X right-positive, Y down-positive)project_id, template_id
node_deleteDelete a nodeproject_id, node_id
node_updateUpdate node propertiesproject_id, node_id
node_startStart node(s) — node_id or node_ids arrayproject_id, node_id
node_stopStop node(s) — node_id or node_ids arrayproject_id, node_id
node_reloadReload node(s) — node_id or node_ids arrayproject_id, node_id
node_suspendSuspend node(s) — node_id or node_ids arrayproject_id, node_id
node_consoleGet WebSocket console URLproject_id, node_id
node_file_listList files in node directoryproject_id, node_id
node_file_getRead a file (with offset/limit)project_id, node_id, path
node_file_writeWrite a fileproject_id, node_id, path, content
node_file_deleteDelete a fileproject_id, node_id, path
node_start_allStart all nodes in a projectproject_id
node_stop_allStop all nodes in a projectproject_id
node_suspend_allSuspend all nodes in a projectproject_id
node_reload_allReload all nodes in a projectproject_id
node_duplicateDuplicate a nodeproject_id, node_id
node_isolateIsolate a node (suspend its links)project_id, node_id
node_unisolateUn-isolate a node (resume links)project_id, node_id
node_linksList links connected to a nodeproject_id, node_id
note

The WebSocket URL returned by node_console requires the websocat tool to connect. Make sure it is installed on the system running Claude Code. Install via: cargo install websocat (requires Rust toolchain) or download a prebuilt binary from GitHub Releases.

The node_console tool returns a WebSocket URL for connecting to a node's console. The URL includes a short-lived JWT (10 minutes) — reconnect if it expires. This endpoint is protocol-agnostic — it works for telnet, ssh, and vnc console types alike. The WebSocket simply proxies raw byte streams between the client and the compute node; protocol negotiation (e.g. SSH key exchange) happens on the compute side.

warning

node_suspend behavior varies by node type:

  • Docker / Dynamips / QEMU: Full suspend supported — status changes to suspended
  • VPCS / IOU: Suspend not supported — returns 405 (swallowed by controller, status remains started)
  • Cloud / NAT / Ethernet switch: No independent process to suspend — only status is marked, no actual effect Check node type before using suspend and verify via the status field.
ToolDescriptionRequired Parameters
link_listList all links in a projectproject_id
link_getGet link detailsproject_id, link_id
link_createCreate link(s) — single via nodes or batch via links array. Nodes support a compact format [id, ad, pt, id, ad, pt] (i.e. node_id, adapter_number, port_number)project_id, nodes
link_deleteDelete link(s) — link_id or link_ids arrayproject_id, link_id/link_ids
link_updateUpdate link (suspend, filters)project_id, link_id
link_resetReset link(s) — link_id or link_ids arrayproject_id, link_id/link_ids
link_capture_startStart capture(s) — link_id or link_ids arrayproject_id, link_id/link_ids
link_capture_stopStop capture(s) — link_id or link_ids arrayproject_id, link_id/link_ids
link_capture_downloadGet PCAP download URL(s) — link_id or link_ids arrayproject_id, link_id/link_ids
note

link_reset does not clear existing filter settings — only the UDP connection is torn down and rebuilt. Node connections and filters are preserved.

Template (5)

ToolDescriptionRequired Parameters
template_listList all templates (fields to filter columns)none
template_getGet template detailstemplate_id or name
template_createCreate a template (Docker needs image)name, template_type
template_updateUpdate a templatetemplate_id or name
template_deleteDelete a templatetemplate_id or name

Compute (3)

ToolDescriptionRequired Parameters
compute_listList registered remote computesnone
compute_getGet compute detailscompute_id
compute_imagesList emulator images on a computecompute_id, emulator
note

compute_images is designed for remote compute nodes. For images on the local compute, use image_list instead.

Snapshot (4)

ToolDescriptionRequired Parameters
snapshot_listList snapshotsproject_id
snapshot_createCreate a snapshotproject_id, name
snapshot_deleteDelete a snapshotproject_id, snapshot_id
snapshot_restoreRestore a snapshotproject_id, snapshot_id

Drawing (5)

ToolDescriptionRequired Parameters
drawing_listList drawings on canvasproject_id
drawing_getGet drawing detailsproject_id, drawing_id
drawing_createCreate drawing (SVG label/shape/image)project_id, svg
drawing_updateUpdate drawing (position, rotation, SVG)project_id, drawing_id
drawing_deleteDelete a drawingproject_id, drawing_id
warning

GNS3's SVG renderer handles some SVG features differently from the standard:

  • <rect> must have a valid color fill value (e.g. fill="#FF0000"), otherwise it won't display. fill="none" is not supported.
  • <ellipse> does not have this limitation.
  • <path> Z (close) command may not be properly supported. Keep these differences in mind when creating custom drawing SVGs.

Symbol (6)

ToolDescriptionRequired Parameters
symbol_listList all symbolsnone
symbol_getGet symbol download URLsymbol_id
symbol_dimensionsGet symbol dimensionssymbol_id
symbol_defaultsGet default symbol mappingnone
symbol_uploadUpload a custom symbol (SVG content)symbol_id, svg_content
symbol_deleteDelete a custom symbolsymbol_id

Appliance (3)

ToolDescriptionRequired Parameters
appliance_listList appliances from template library (fields to filter, e.g. ["name","category"])none
appliance_getGet appliance detailsappliance_id
appliance_installCreate template from applianceappliance_id

Image (5)

ToolDescriptionRequired Parameters
image_listList all imagesnone
image_getGet image detailsimage_id
image_deleteDelete an imageimage_id
image_pruneRemove images not referenced by any templatenone
image_installAuto-create templates from uploaded imagesnone
warning

Before using image_install, image files must be manually placed in the ~/GNS3/images/ directory on the server. The tool does not download images automatically — it only creates templates from existing image files by checksum matching.

Server (2)

ToolDescriptionRequired Parameters
server_versionGet GNS3 server versionnone
server_statisticsGet server statistics (computes, projects, nodes)none

Device Config (3)

ToolDescriptionRequired Parameters
device_config_sendPush config commands to devices via console (Nornir + Netmiko). Supports Jinja2 template + varsproject_id, device_name, config_commands
device_show_runRun read-only show commands on devices. Supports Jinja2 template + varsproject_id, device_name, commands
vpcs_config_setConfigure VPCS devices (IP, gateway, etc.)project_id, device_name, ip, netmask, gateway
note

You must start the node before you can configure the device. Device type is auto-detected from the node's device_type:<type> tag.

Device Config Workflow

Jinja2 Template Mode

device_config_send and device_show_run both support an optional template parameter. When provided, each device's vars dict is rendered against the template to produce commands. Entries with the same device_name are merged into a single session.

# Direct commands (single/batch)
device_config_send(project_id, device_configs=[
{"device_name": "R1", "config_commands": ["int lo0", "ip add 1.1.1.1 255.255.255.255"]},
])

# Jinja2 template (reduces token usage for batch)
device_config_send(project_id,
template="interface lo{{ n }}\nip address {{ ip }} 255.255.255.255",
device_configs=[
{"device_name": "R1", "vars": {"n": 0, "ip": "1.1.1.1"}},
{"device_name": "R2", "vars": {"n": 0, "ip": "2.2.2.2"}},
])

Best Practices

  • Prefer template over direct commands for batch — when ≥2 nodes share the same config structure with different values, use template + vars instead of writing config_commands per node. This reduces token usage and transcription errors.
  • Don't rely on status: success alone — it only means the commands entered config mode. IOS errors (% Invalid input, % overlaps, % Incomplete command) appear inside the output text — always scan for % lines.
  • Pilot before full rollout — test template + vars on 1–2 devices first to verify rendering and syntax, then expand to all nodes.

Config Backup via File Operations

IOU and Dynamips nodes save the startup config as a plain text file (startup-config.cfg) in the node directory after write memory. Back up and restore it via node_file_get / node_file_write.

# Save config on the device
device_show_run(project_id, device_configs=[
{"device_name": "R1", "commands": ["write memory"]},
])
# Backup
config = node_file_get(project_id, node_id, "startup-config.cfg")
# Restore if config breaks
node_file_write(project_id, node_id, "startup-config.cfg", config)
node_reload(project_id, node_id)

Test Report

Full 82-tool test results are available in the gns3-api-mcp-test repository:

Demo Video

📺 Watch the English Demo

Architecture Overview

The sequence diagram below illustrates how a client connects, authenticates, discovers tools, and invokes them:

Transport Security Configuration

By default, the GNS3 Server MCP service allows connections from all hosts, consistent with GNS3 server's policy of listening on 0.0.0.0 (all network interfaces).

To restrict access sources, enable DNS rebinding protection in gns3_server.conf. mcp_allowed_hosts should be set to the address clients use to reach the GNS3 server, not the client's own address:

[Server]

; Enable MCP transport security (default False)
mcp_enable_dns_rebinding_protection = True

; GNS3 server addresses that clients are allowed to connect to ("host:port" format)
; e.g. if GNS3 server IP is 192.168.1.3, add 192.168.1.3:*
mcp_allowed_hosts = 127.0.0.1:*,localhost:*,192.168.1.3:*

; Allowed origin list (CORS Origin)
mcp_allowed_origins = http://127.0.0.1:*,http://localhost:*,http://192.168.1.3:*
tip

With the default configuration, all hosts can connect — suitable for most scenarios. Only enable protection when you need to strictly restrict access sources.

Internal Implementation

The MCP service is built on FastMCP (Anthropic MCP SDK) and mounted as a Starlette sub-application under /v3/mcp/transport; tool handlers call GNS3's own REST API via Gns3Connector, keeping the MCP layer decoupled from business logic. JWT tokens are validated by GNS3's existing auth_service and propagated to asyncio.to_thread (Python ≥ 3.9) worker threads via a contextvars.ContextVar.

The WebSocket URL returned by node_console is constructed by the server's _server_url(), whose host resolution works as follows (affects the reachable address for remote connections):

Server.host valueResolved host in URL
Specific IP or hostname (e.g. 192.168.1.3)Used as-is
0.0.0.0 (IPv4 any, default)Detected via default route interface IP
:: (IPv6 any)Detected via default route interface IP
Detection failureFallback to 127.0.0.1

When Server.host is 0.0.0.0, the server discovers the default route interface IP via a UDP socket connect to 8.8.8.8:80 (no data is actually sent), ensuring the returned address is reachable:

websocat ws://192.168.1.3:3080/v3/projects/{project_id}/nodes/{node_id}/console/ws?token=<jwt>

Frequently Asked Questions

What's the difference between MCP and GNS3 Copilot?

  • GNS3 Copilot (AI Assistant): Built-in AI feature within the GNS3 GUI that provides topology management, fault diagnosis, and automated configuration through LLMs
  • MCP Service: Provides a standardized MCP protocol interface for external AI clients (like Claude Code) to interact with GNS3 functionality in a unified way

They can be used together: MCP is for tool-calling scenarios, while the AI Assistant is for in-GUI interactive usage.

Is remote connection supported?

Yes. Replace localhost with the actual IP address or domain name of your GNS3 server. Ensure network reachability and that the server port (default 3080, GNS3 VM default 80) is open.

Feature Contributor

The MCP service feature was developed and contributed by YueGuobin.

License

This document is licensed under CC BY-NC-ND 4.0 (Attribution-NonCommercial-NoDerivatives). Author: YueGuobin