mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-09-27 22:30:11 +03:00
- Slim custom_gns3fy.py to connector-only Gns3Connector and rename to connector.py; delete the unused Node/Link/Project dataclasses and endpoint wrapper methods (~3000 lines) - Move the MCP node/link handler implementations into gns3_client/api_handlers.py as the shared REST client layer consumed by both the MCP service and copilot tools; add available_filters handler (exposed as link_available_filters MCP tool) and build_gns3_ctx() for copilot callers - Rewrite the tools_v2 node/link tools on top of the handlers: batch lifecycle actions now run in parallel, node creation is a single POST, project-wide status reads replace per-node GETs - Port Project.nodes_inventory/links_summary aggregation into project_inventory.py (output shape preserved) and rewrite the topology reader / project info tools on it, dropping the unused stats/snapshots/drawings calls - Delete the dead mcp/nodes.py and mcp/links.py (NODE_TOOLS/LINK_TOOLS had no consumers; __init__ imports handlers from api_handlers) - Retarget mcp handler tests to patch api_handlers._get_connector and replace test_custom_gns3fy.py with inventory contract tests
3.6 KiB
3.6 KiB
name, description, metadata
| name | description | metadata | ||
|---|---|---|---|---|
| mcp-service-design | MCP (Model Context Protocol) service architecture and tool design for GNS3 server |
|
MCP (Model Context Protocol) Service Design
Background
Provide a standard MCP interface for GNS3 Server, allowing AI assistants (Claude Code, Claude Desktop) to interact with GNS3 network simulations through the Model Context Protocol.
Decision/Implementation
Transport
- SSE (Server-Sent Events) with JWT token authentication
- Endpoint:
/v3/mcp/transport/sse - Message endpoint:
/v3/mcp/transport/messages/
Authentication
- JWT token obtained via
/v3/access/users/authenticate - Two ways to pass token:
Authorization: Bearer <jwt>header (Claude Code via-H)?token=<jwt>query param (Claude Desktop, EventSource limitation)
- Token validated using GNS3's existing
auth_service - Token stored in
contextvars.ContextVarfor per-session isolation - Python ≥ 3.9
asyncio.to_threadpropagates contextvars to threads
Architecture
Claude Code / Desktop → SSE → Auth Wrapper → FastMCP Server → Tool Handler → Gns3Connector → GNS3 REST API
Tool Organization
Tools are separated by domain into individual files under gns3server/api/routes/mcp/:
| File | Domain | Tool Count |
|---|---|---|
projects.py |
Project CRUD, open/close/stats | 7 |
nodes.py |
Node CRUD, start/stop/reload/suspend, console WS | 10 |
links.py |
Link CRUD | 5 |
templates.py |
Template CRUD | 5 |
computes.py |
Compute list/get/images | 3 |
Total: 30 tools
Handler Pattern
- Synchronous functions receiving
(params: dict, gns3_ctx: dict) - Run via
asyncio.to_thread()to avoid blocking the event loop gns3_ctxcontainsserver_urlandjwt_tokenGns3Connectoris created per-handler fromgns3_client.connector(per-handler instantiation keeps each tool call isolated)
Token Lifetime
- Default: 1440 minutes (24 hours)
- Configurable via
jwt_access_token_expire_minutesingns3_server.conf
Rationale
- Why not Direct Controller calls: MCP layer calls GNS3's own REST API through Gns3Connector, keeping full decoupling and supporting future multi-user/multi-instance scenarios
- Why not Streamable HTTP: Claude Code supports SSE natively via
--transport ssewith custom headers; Streamable HTTP session manager lifecycle conflicts with FastAPI mount - Why not stdio: stdio is local-only; SSE supports both local and remote deployments
Related Files
gns3server/agent/mcp/__init__.py— FastMCP server,@mcp.tool()decorators, auth wrapper (_resolve_tokenexchanges API keys for JWTs)gns3server/agent/mcp/*.py— tool handlers for projects/templates/computes/snapshots/drawings/symbols/appliances/imagesgns3server/agent/gns3_copilot/gns3_client/api_handlers.py— shared node/link handler layer (single implementation, consumed by both MCP tools and copilottools_v2; tests must patch_get_connectorHERE, not in mcp modules)gns3server/agent/gns3_copilot/gns3_client/connector.py— Gns3Connector (JWT auth + http_call only; the oldcustom_gns3fy.pyNode/Link/Project wrappers were removed)gns3server/agent/gns3_copilot/gns3_client/project_inventory.py— nodes/links aggregation feeding the topology context and Nornir inventory
Configuration
Claude Code
claude mcp add --transport sse My_GNS3_Server \
http://host:3080/v3/mcp/transport/sse \
-H "Authorization: Bearer <jwt>"
Claude Desktop
{
"mcpServers": {
"My_GNS3_Server": {
"url": "http://host:3080/v3/mcp/transport/sse?token=<jwt>"
}
}
}