diff --git a/gns3server/api/routes/mcp/__init__.py b/gns3server/api/routes/mcp/__init__.py index bf52d9c51..bd522d473 100644 --- a/gns3server/api/routes/mcp/__init__.py +++ b/gns3server/api/routes/mcp/__init__.py @@ -600,6 +600,10 @@ async def link_create( link_type: Annotated[str, Field(description="Link type - ethernet or serial")] = "ethernet", filters: Annotated[dict | None, Field(description="Optional packet filters")] = None, links: Annotated[list | None, Field(description="Batch mode: [{nodes, link_type?, filters?}] — creates multiple links in parallel")] = None, + fields: Annotated[list[str] | None, Field(description="Response fields to include (default: [link_id, link_type, nodes]). " + "Available: link_id, project_id, link_type, nodes, suspend, " + "link_style, filters, show_filters_icon, capturing, " + "capture_file_name, capture_file_path, capture_compute_id, wireshark")] = None, ) -> list[dict[str, Any]]: """Create one or more links between nodes. @@ -608,9 +612,9 @@ async def link_create( """ if links: return await asyncio.to_thread(_run_handler_sync, create_link_handler, { - "project_id": project_id, "links": links, + "project_id": project_id, "links": links, "fields": fields, }) - params = {"project_id": project_id, "nodes": nodes, "link_type": link_type} + params = {"project_id": project_id, "nodes": nodes, "link_type": link_type, "fields": fields} if filters: params["filters"] = filters return await asyncio.to_thread(_run_handler_sync, create_link_handler, params) diff --git a/gns3server/api/routes/mcp/links.py b/gns3server/api/routes/mcp/links.py index cae2b07db..2e2f94b79 100644 --- a/gns3server/api/routes/mcp/links.py +++ b/gns3server/api/routes/mcp/links.py @@ -90,6 +90,8 @@ def create_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic if not project_id: return {"error": "project_id is required"} + fields = params.get("fields") + links = params.get("links") # Batch mode: links=[{nodes, link_type?, filters?, suspend?}] if links is not None: @@ -110,7 +112,7 @@ def create_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic body["suspend"] = link_data["suspend"] url = f"{conn.base_url}/projects/{project_id}/links" resp = conn.http_call("post", url, json_data=body).json() - return {"status": "success", "link": resp} + return {"status": "success", "link": _filter_link_response(resp, fields)} except Exception as e: return {"status": "error", "error": str(e)} with ThreadPoolExecutor(max_workers=min(len(links), BATCH_MAX_WORKERS)) as pool: @@ -132,7 +134,8 @@ def create_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic if "suspend" in params: data["suspend"] = params["suspend"] url = f"{conn.base_url}/projects/{project_id}/links" - return conn.http_call("post", url, json_data=data).json() + resp = conn.http_call("post", url, json_data=data).json() + return _filter_link_response(resp, fields) def delete_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dict[str, Any]: