diff --git a/gns3server/api/routes/mcp/__init__.py b/gns3server/api/routes/mcp/__init__.py index 75c67a77b..0f1e113a6 100644 --- a/gns3server/api/routes/mcp/__init__.py +++ b/gns3server/api/routes/mcp/__init__.py @@ -409,6 +409,40 @@ async def delete_template(template_id: str = None, name: str = None) -> list[dic }) +# ── Compute tools ───────────────────────────────────────────────────── + +@mcp.tool() +async def list_computes() -> list[dict[str, Any]]: + """List all compute nodes available to the server.""" + from .computes import list_computes_handler + return await asyncio.to_thread(_run_handler_sync, list_computes_handler, {}) + + +@mcp.tool() +async def get_compute(compute_id: str = "local") -> list[dict[str, Any]]: + """Get detailed information about a compute node. + + Args: + compute_id: Compute ID (default: local) + """ + from .computes import get_compute_handler + return await asyncio.to_thread(_run_handler_sync, get_compute_handler, {"compute_id": compute_id}) + + +@mcp.tool() +async def get_compute_images(emulator: str, compute_id: str = "local") -> list[dict[str, Any]]: + """List available images for an emulator on a compute node. + + Args: + emulator: Emulator type (e.g. qemu, iou, docker) + compute_id: Compute ID (default: local) + """ + from .computes import get_compute_images_handler + return await asyncio.to_thread(_run_handler_sync, get_compute_images_handler, { + "emulator": emulator, "compute_id": compute_id, + }) + + # ── Auth‑wrapped SSE app ────────────────────────────────────────────── def _make_auth_wrapper(inner_app): diff --git a/gns3server/api/routes/mcp/computes.py b/gns3server/api/routes/mcp/computes.py new file mode 100644 index 000000000..fa6c70674 --- /dev/null +++ b/gns3server/api/routes/mcp/computes.py @@ -0,0 +1,91 @@ +# +# Copyright (C) 2026 GNS3 Technologies Inc. +# Author: Yue Guobin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +MCP tool handlers for GNS3 compute management. +""" + +from typing import Any +import logging + +log = logging.getLogger(__name__) + + +def _get_connector(gns3_ctx: dict[str, Any]): + from gns3server.agent.gns3_copilot.gns3_client.custom_gns3fy import Gns3Connector + return Gns3Connector( + url=gns3_ctx["server_url"], + jwt_token=gns3_ctx["jwt_token"], + api_version=3, + verify=False, + ) + + +def list_computes_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]: + conn = _get_connector(gns3_ctx) + computes = conn.get_computes() + return {"computes": computes, "count": len(computes)} + + +def get_compute_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]: + compute_id = params.get("compute_id", "local") + conn = _get_connector(gns3_ctx) + return conn.get_compute(compute_id=compute_id) + + +def get_compute_images_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]: + emulator = params.get("emulator") + compute_id = params.get("compute_id", "local") + if not emulator: + return {"error": "emulator is required (e.g. qemu, iou, docker)"} + conn = _get_connector(gns3_ctx) + images = conn.get_compute_images(emulator=emulator, compute_id=compute_id) + return {"images": images, "count": len(images)} + + +COMPUTE_TOOLS = [ + { + "name": "list_computes", + "description": "List all compute nodes available to the server", + "parameters": {"type": "object", "properties": {}}, + "handler": list_computes_handler, + }, + { + "name": "get_compute", + "description": "Get detailed information about a compute node", + "parameters": { + "type": "object", + "properties": { + "compute_id": {"type": "string", "description": "Compute ID (default: local)"}, + }, + }, + "handler": get_compute_handler, + }, + { + "name": "get_compute_images", + "description": "List available images for an emulator on a compute node", + "parameters": { + "type": "object", + "properties": { + "emulator": {"type": "string", "description": "Emulator type (e.g. qemu, iou, docker)"}, + "compute_id": {"type": "string", "description": "Compute ID (default: local)"}, + }, + "required": ["emulator"], + }, + "handler": get_compute_images_handler, + }, +]