From 2d00be71bbf0ce8f181d9e8169396847cac37ccd Mon Sep 17 00:00:00 2001 From: Nicola Bottini Date: Thu, 9 Jul 2026 15:01:28 -0400 Subject: [PATCH] feat: add create_design tool so the MCP can create canvases Wrap POST /api/v1/designs so AI clients can create a new design (canvas) and get its id back for use as design_id. Completes the create-and-target canvas workflow alongside list_designs. Co-authored-by: Cursor --- mcp/app/tools.py | 12 ++++++++++++ mcp/tests/test_tools.py | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/mcp/app/tools.py b/mcp/app/tools.py index c3f4326..399dae2 100644 --- a/mcp/app/tools.py +++ b/mcp/app/tools.py @@ -134,6 +134,15 @@ def _build_tools() -> list[Tool]: "type": "object", "properties": {}, }), + Tool(name="create_design", description="Create a new design (canvas) and return it, including its id for use as design_id", inputSchema={ + "type": "object", + "required": ["name"], + "properties": { + "name": {"type": "string", "description": "Name of the new canvas."}, + "icon": {"type": "string", "description": "Icon name for the canvas (default: dashboard)."}, + "design_type": {"type": "string", "description": "Design type (default: network)."}, + }, + }), ] @@ -220,4 +229,7 @@ async def _dispatch(name: str, args: dict) -> dict: if name == "list_designs": return await backend.get("/api/v1/designs") + if name == "create_design": + return await backend.post("/api/v1/designs", args) + raise ValueError(f"Unknown tool: {name}") diff --git a/mcp/tests/test_tools.py b/mcp/tests/test_tools.py index 5d903a7..db5ad1f 100644 --- a/mcp/tests/test_tools.py +++ b/mcp/tests/test_tools.py @@ -249,6 +249,19 @@ async def test_list_designs(mock_backend): assert result == [{"id": "d1", "name": "Network Topology", "node_count": 12}] +@pytest.mark.anyio +async def test_create_design(mock_backend): + mock_backend.post = AsyncMock(return_value={"id": "d2", "name": "Scan Devices"}) + result = await _dispatch("create_design", {"name": "Scan Devices"}) + mock_backend.post.assert_called_once_with("/api/v1/designs", {"name": "Scan Devices"}) + assert result == {"id": "d2", "name": "Scan Devices"} + + +def test_create_design_schema_requires_name(): + tool = next(t for t in TOOLS if t.name == "create_design") + assert tool.inputSchema["required"] == ["name"] + + @pytest.mark.anyio async def test_unknown_tool(): with pytest.raises(ValueError, match="Unknown tool"):