From 8aa7f2bde5cf11b0fc8598785851d537e11eef5c Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Sun, 14 Jun 2026 00:27:49 +0800 Subject: [PATCH] feat: Jinja2 template support in device_command_run --- gns3server/api/routes/mcp/__init__.py | 5 +++++ gns3server/api/routes/mcp/device_config.py | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/gns3server/api/routes/mcp/__init__.py b/gns3server/api/routes/mcp/__init__.py index 045808fbe..90f011a75 100644 --- a/gns3server/api/routes/mcp/__init__.py +++ b/gns3server/api/routes/mcp/__init__.py @@ -1320,9 +1320,14 @@ async def device_command_run( device_configs: Annotated[list, Field( description="List of device commands. Each entry: {\"device_name\": \"R1\", \"show_commands\": [\"show ip int brief\", \"show running-config\"]}" )], + template: Annotated[str | None, Field(description="Optional Jinja2 template. Use with vars per device. Example: \"show ip route {{ protocol }}\"")] = None, ) -> list[dict[str, Any]]: """Run read-only diagnostic (show) commands on network devices via console. + Two modes: + 1. Direct commands: each device has show_commands=[...] + 2. Jinja2 template: provide template + vars per device + Use this to inspect device status, view configurations, or verify changes. Devices must be started first. """ diff --git a/gns3server/api/routes/mcp/device_config.py b/gns3server/api/routes/mcp/device_config.py index c64430070..4369ddf77 100644 --- a/gns3server/api/routes/mcp/device_config.py +++ b/gns3server/api/routes/mcp/device_config.py @@ -97,9 +97,15 @@ def device_command_run_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) """Run read-only diagnostic (show) commands on network devices.""" project_id = params.get("project_id") device_configs = params.get("device_configs") + template = params.get("template") if not project_id or not device_configs: return [{"error": "project_id and device_configs (list of {device_name, show_commands}) are required"}] + if template: + device_configs = _render_template(template, device_configs) + if len(device_configs) == 1 and "error" in device_configs[0]: + return device_configs + from gns3server.agent.gns3_copilot.tools_v2.display_tools_nornir import ExecuteMultipleDeviceCommands tool = ExecuteMultipleDeviceCommands()