From 8b014693a85f39cf3d33b2fc4f629dda07d88a03 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Wed, 10 Jun 2026 22:38:38 +0800 Subject: [PATCH] fix: Type compute_id as uuid.UUID to reject non-UUID values at MCP input layer Previously compute_id was typed as str, so 'local' would pass MCP validation and reach the controller API where it crashed. Now uuid.UUID type ensures Pydantic rejects any non-UUID string before the handler runs. --- gns3server/api/routes/mcp/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gns3server/api/routes/mcp/__init__.py b/gns3server/api/routes/mcp/__init__.py index 0a90b745e..a5c905b07 100644 --- a/gns3server/api/routes/mcp/__init__.py +++ b/gns3server/api/routes/mcp/__init__.py @@ -31,6 +31,7 @@ import json import asyncio import logging import socket +import uuid from typing import Any, Annotated from urllib.parse import parse_qs @@ -610,7 +611,7 @@ async def compute_list() -> list[dict[str, Any]]: @mcp.tool() async def compute_get( - compute_id: Annotated[str, Field(description="Compute UUID from compute_list output")], + compute_id: Annotated[uuid.UUID, Field(description="Compute UUID from compute_list output")], ) -> list[dict[str, Any]]: """Get detailed information about a compute node. Use compute_list first to get the UUID.""" return await asyncio.to_thread(_run_handler_sync, get_compute_handler, {"compute_id": compute_id}) @@ -619,7 +620,7 @@ async def compute_get( @mcp.tool() async def compute_images( emulator: Annotated[str, Field(description="Emulator type (e.g. qemu, iou, docker)")], - compute_id: Annotated[str, Field(description="Compute UUID from compute_list output")], + compute_id: Annotated[uuid.UUID, Field(description="Compute UUID from compute_list output")], ) -> list[dict[str, Any]]: """List available images for an emulator on a compute node.""" return await asyncio.to_thread(_run_handler_sync, get_compute_images_handler, {