fix: accept the 'local' compute id in compute tools

The compute_get/compute_images MCP tools typed compute_id as a UUID, so
passing 'local' (the actual id of the built-in compute, which the
compute_images description itself pointed to) was rejected by schema
validation. Both tools now take a string defaulting to 'local', and the
compute_get REST route resolves 'local' through the controller since the
local compute has no database entry.
This commit is contained in:
YueGuobin committed 2026-08-26 00:44:57 +08:00
1 parent 6703e50487
commit df25e037ea
5 files changed
+63 -16

No files matched your search

+8 -9
View File
@@ -31,7 +31,6 @@ import json
import asyncio
import logging
import socket
import uuid
from uuid import UUID
import bcrypt
from typing import Any, Annotated
@@ -772,12 +771,12 @@ async def compute_list() -> list[dict[str, Any]]:
@mcp.tool()
async def compute_get(
compute_id: Annotated[uuid.UUID, Field(description="Compute UUID from compute_list output")],
compute_id: Annotated[str, Field(description="Compute ID: 'local' (default) for the built-in local compute, or a compute UUID from compute_list")] = "local",
) -> list[dict[str, Any]]:
"""Get detailed information about a registered remote compute node.
"""Get detailed information about a compute node.
NOTE: Only works for computes registered in the database (returned by compute_list).
For the built-in local compute info, use server_statistics instead.
Accepts 'local' for the built-in local compute or a UUID from compute_list
for a registered remote compute.
"""
return await asyncio.to_thread(_run_handler_sync, get_compute_handler, {"compute_id": compute_id})
@@ -785,12 +784,12 @@ 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[uuid.UUID, Field(description="Compute UUID from compute_list output")],
compute_id: Annotated[str, Field(description="Compute ID: 'local' (default) for the built-in local compute, or a compute UUID from compute_list")] = "local",
) -> list[dict[str, Any]]:
"""List available images for an emulator on a registered compute node.
"""List available images for an emulator on a compute node.
NOTE: Only works for computes registered in the database.
For the local compute, the default compute_id is typically found via server_statistics.
Accepts 'local' for the built-in local compute or a UUID from compute_list
for a registered remote compute.
"""
return await asyncio.to_thread(_run_handler_sync, get_compute_images_handler, {
"emulator": emulator, "compute_id": compute_id,
+2 -6
View File
@@ -42,20 +42,16 @@ def list_computes_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> d
def get_compute_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]:
compute_id = params.get("compute_id")
if not compute_id:
return {"error": "compute_id is required (use compute_list to get the UUID)"}
compute_id = params.get("compute_id") or "local"
conn = _get_connector(gns3_ctx)
return conn.http_call("get", f"{conn.base_url}/computes/{compute_id}").json()
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")
compute_id = params.get("compute_id") or "local"
if not emulator:
return {"error": "emulator is required (e.g. qemu, iou, docker)"}
if not compute_id:
return {"error": "compute_id is required (use compute_list to get the UUID)"}
conn = _get_connector(gns3_ctx)
images = conn.http_call("get", f"{conn.base_url}/computes/{compute_id}/{emulator}/images").json()
return {"images": images, "count": len(images)}