← WebMCP Directory

Tool tree

alza-dev.pages.dev

Developer ToolsTools verified
Website
Draw floor plans in 2D, walk them in 3D, and let your AI agent co-edit the same live page through WebMCP. Built for the WebMCP Challenge.
Explore capabilities
    get_modelAnswer

    Read the full floor plan: walls (endpoints, thickness, height), openings (doors/windows with position along their wall), rooms (metric rects with labels), furniture, and plan name. All units are meters.

    View tool JSON
    {
      "name": "get_model",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the full floor plan: walls (endpoints, thickness, height), openings (doors/windows with position along their wall), rooms (metric rects with labels), furniture, and plan name. All units are meters.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    get_issuesAnswer

    Run the constraint checker over the plan. Detects: too-short walls, loose ends, collinear overlaps, mid-span crossings, openings overflowing their wall or overlapping each other, walls ending inside an opening, floating/overlapping/doorless rooms, furniture crossing walls, blocking doors/windows, or colliding. Use it after editing to self-repair.

    View tool JSON
    {
      "name": "get_issues",
      "kind": "answer",
      "impl": "imperative",
      "description": "Run the constraint checker over the plan. Detects: too-short walls, loose ends, collinear overlaps, mid-span crossings, openings overflowing their wall or overlapping each other, walls ending inside an opening, floating/overlapping/doorless rooms, furniture crossing walls, blocking doors/windows, or colliding. Use it after editing to self-repair.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    get_item_catalogAnswer

    List the furniture catalog: kind, label, footprint (width × depth in meters) and height.

    View tool JSON
    {
      "name": "get_item_catalog",
      "kind": "answer",
      "impl": "imperative",
      "description": "List the furniture catalog: kind, label, footprint (width × depth in meters) and height.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    get_editor_stateAnswer

    Read what the human is doing right now: 2D/3D view, camera mode, selected wall/item/room, current draw mode.

    View tool JSON
    {
      "name": "get_editor_state",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read what the human is doing right now: 2D/3D view, camera mode, selected wall/item/room, current draw mode.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    measureAction

    Measure a distance: between two points (x1,y1)-(x2,y2), or the length of a wall by id. Returns meters.

    View tool JSON
    {
      "name": "measure",
      "kind": "act",
      "impl": "imperative",
      "description": "Measure a distance: between two points (x1,y1)-(x2,y2), or the length of a wall by id. Returns meters.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "x1": {
            "type": "number"
          },
          "y1": {
            "type": "number"
          },
          "x2": {
            "type": "number"
          },
          "y2": {
            "type": "number"
          },
          "wallId": {
            "type": "string"
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    get_underlayAnswer

    Read the blueprint underlay: whether a reference plan image is loaded, the world rectangle it covers (metres), the mapping from image fractions to world coordinates — and the PROTOCOL for tracing it. Call this FIRST whenever the human gives you a plan to reproduce. Tracing needs the drawing in two places and this tool tells you which are missing: uploaded on the page (carries the scale) and pasted into your conversation (the only way you can see it). This tool never returns the pixels — it returns where the drawing sits in world metres so you can convert what you measure on your own copy. Measure in fractions of the image, not pixels: the page holds a resized copy.

    View tool JSON
    {
      "name": "get_underlay",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the blueprint underlay: whether a reference plan image is loaded, the world rectangle it covers (metres), the mapping from image fractions to world coordinates — and the PROTOCOL for tracing it. Call this FIRST whenever the human gives you a plan to reproduce. Tracing needs the drawing in two places and this tool tells you which are missing: uploaded on the page (carries the scale) and pasted into your conversation (the only way you can see it). This tool never returns the pixels — it returns where the drawing sits in world metres so you can convert what you measure on your own copy. Measure in fractions of the image, not pixels: the page holds a resized copy.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    calibrate_underlayAction

    Scale the loaded blueprint image to real-world meters. Give two points on the image as fractions (u, v in 0..1; u = right, v = down) and the REAL distance between them in meters (e.g. a dimension printed on the plan). The underlay is resized preserving aspect, keeping the first point fixed. Call after the human uploads the plan, before tracing walls over it.

    View tool JSON
    {
      "name": "calibrate_underlay",
      "kind": "act",
      "impl": "imperative",
      "description": "Scale the loaded blueprint image to real-world meters. Give two points on the image as fractions (u, v in 0..1; u = right, v = down) and the REAL distance between them in meters (e.g. a dimension printed on the plan). The underlay is resized preserving aspect, keeping the first point fixed. Call after the human uploads the plan, before tracing walls over it.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "u1": {
            "type": "number"
          },
          "v1": {
            "type": "number"
          },
          "u2": {
            "type": "number"
          },
          "v2": {
            "type": "number"
          },
          "meters": {
            "type": "number"
          },
          "opacity": {
            "type": "number"
          }
        },
        "required": [
          "u1",
          "v1",
          "u2",
          "v2",
          "meters"
        ],
        "additionalProperties": false
      }
    }
    add_wallAction

    Add a wall segment from (ax,ay) to (bx,by) in meters. Coordinates snap to a 5 cm grid. Default thickness 0.15 m (use 0.1 for interior), height 2.7 m.

    View tool JSON
    {
      "name": "add_wall",
      "kind": "act",
      "impl": "imperative",
      "description": "Add a wall segment from (ax,ay) to (bx,by) in meters. Coordinates snap to a 5 cm grid. Default thickness 0.15 m (use 0.1 for interior), height 2.7 m.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ax": {
            "type": "number"
          },
          "ay": {
            "type": "number"
          },
          "bx": {
            "type": "number"
          },
          "by": {
            "type": "number"
          },
          "thickness": {
            "type": "number"
          },
          "height": {
            "type": "number"
          }
        },
        "required": [
          "ax",
          "ay",
          "bx",
          "by"
        ],
        "additionalProperties": false
      }
    }
    edit_wallAction

    Move endpoints or change thickness/height of an existing wall (by id). Endpoints snap to 5 cm.

    View tool JSON
    {
      "name": "edit_wall",
      "kind": "act",
      "impl": "imperative",
      "description": "Move endpoints or change thickness/height of an existing wall (by id). Endpoints snap to 5 cm.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "ax": {
            "type": "number"
          },
          "ay": {
            "type": "number"
          },
          "bx": {
            "type": "number"
          },
          "by": {
            "type": "number"
          },
          "thickness": {
            "type": "number"
          },
          "height": {
            "type": "number"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    remove_wallAction

    Remove a wall by id. Its doors and windows are removed too.

    View tool JSON
    {
      "name": "remove_wall",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove a wall by id. Its doors and windows are removed too.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    add_doorAction

    Add a door on a wall. t is the position of the door CENTER along the wall (0..1). Default width 0.9 m, height 2.1 m; a door wider than 1.2 m is built as a double door with two leaves. The vano is clamped so it always fits inside the wall; too-wide doors are rejected with the wall length. hinge picks the jamb the hinges sit on ("a" = the wall's A end, the default; "b" = the B end) and side picks which way the leaf swings, as seen walking the wall from A to B: "right" (default) or "left". Match these to the swing arc drawn on the plan.

    View tool JSON
    {
      "name": "add_door",
      "kind": "act",
      "impl": "imperative",
      "description": "Add a door on a wall. t is the position of the door CENTER along the wall (0..1). Default width 0.9 m, height 2.1 m; a door wider than 1.2 m is built as a double door with two leaves. The vano is clamped so it always fits inside the wall; too-wide doors are rejected with the wall length. hinge picks the jamb the hinges sit on (\"a\" = the wall's A end, the default; \"b\" = the B end) and side picks which way the leaf swings, as seen walking the wall from A to B: \"right\" (default) or \"left\". Match these to the swing arc drawn on the plan.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "wallId": {
            "type": "string"
          },
          "t": {
            "type": "number"
          },
          "width": {
            "type": "number"
          },
          "height": {
            "type": "number"
          },
          "hinge": {
            "type": "string",
            "enum": [
              "a",
              "b"
            ]
          },
          "side": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ]
          }
        },
        "required": [
          "wallId",
          "t"
        ],
        "additionalProperties": false
      }
    }
    set_door_swingAction

    Change how an existing door opens: hinge ("a" | "b" — which jamb carries the hinges) and/or side ("left" | "right" — which way the leaf swings, walking the wall from its A endpoint to its B endpoint). Re-run build_3d to see it.

    View tool JSON
    {
      "name": "set_door_swing",
      "kind": "act",
      "impl": "imperative",
      "description": "Change how an existing door opens: hinge (\"a\" | \"b\" — which jamb carries the hinges) and/or side (\"left\" | \"right\" — which way the leaf swings, walking the wall from its A endpoint to its B endpoint). Re-run build_3d to see it.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "hinge": {
            "type": "string",
            "enum": [
              "a",
              "b"
            ]
          },
          "side": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ]
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    add_windowAction

    Add a window on a wall. t is the position of the window CENTER along the wall (0..1). Default width 1.2 m, sill 0.9 m, height 1.2 m. The vano is clamped to fit.

    View tool JSON
    {
      "name": "add_window",
      "kind": "act",
      "impl": "imperative",
      "description": "Add a window on a wall. t is the position of the window CENTER along the wall (0..1). Default width 1.2 m, sill 0.9 m, height 1.2 m. The vano is clamped to fit.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "wallId": {
            "type": "string"
          },
          "t": {
            "type": "number"
          },
          "width": {
            "type": "number"
          },
          "sill": {
            "type": "number"
          },
          "height": {
            "type": "number"
          }
        },
        "required": [
          "wallId",
          "t"
        ],
        "additionalProperties": false
      }
    }
    move_openingAction

    Move a door or window along its wall to a new center position t (0..1). Clamped to fit.

    View tool JSON
    {
      "name": "move_opening",
      "kind": "act",
      "impl": "imperative",
      "description": "Move a door or window along its wall to a new center position t (0..1). Clamped to fit.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "t": {
            "type": "number"
          }
        },
        "required": [
          "id",
          "t"
        ],
        "additionalProperties": false
      }
    }
    remove_openingAction

    Remove a door or window by id.

    View tool JSON
    {
      "name": "remove_opening",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove a door or window by id.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    add_roomAction

    Add a room: a metric rectangle (x, y = top-left corner, w, h in meters) with a label and floor finish (oak | tile | carpet | concrete).

    View tool JSON
    {
      "name": "add_room",
      "kind": "act",
      "impl": "imperative",
      "description": "Add a room: a metric rectangle (x, y = top-left corner, w, h in meters) with a label and floor finish (oak | tile | carpet | concrete).",
      "inputSchema": {
        "type": "object",
        "properties": {
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "w": {
            "type": "number"
          },
          "h": {
            "type": "number"
          },
          "label": {
            "type": "string"
          },
          "floor": {
            "type": "string"
          }
        },
        "required": [
          "x",
          "y",
          "w",
          "h",
          "label"
        ],
        "additionalProperties": false
      }
    }
    update_roomAction

    Update a room by id or label (e.g. "bedroom"): move, resize, relabel, or change floor finish.

    View tool JSON
    {
      "name": "update_room",
      "kind": "act",
      "impl": "imperative",
      "description": "Update a room by id or label (e.g. \"bedroom\"): move, resize, relabel, or change floor finish.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "w": {
            "type": "number"
          },
          "h": {
            "type": "number"
          },
          "label": {
            "type": "string"
          },
          "floor": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    remove_roomAction

    Remove a room by id or label.

    View tool JSON
    {
      "name": "remove_room",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove a room by id or label.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    place_itemAction

    Place furniture from the catalog at (x, y) = center in meters. rotation (degrees, counterclockwise) sets which way the piece FACES: 0 = faces +y (down/south on the plan), 90 = faces +x (right/east), 180 = faces -y (up/north), 270 = faces -x (left/west). The back of a sofa, bed headboard, wardrobe or counter is opposite the facing direction — so a sofa against the SOUTH wall needs rotation 180, and one against the WEST wall needs rotation 90. To sit a piece flush against a wall, offset its center by depth/2 from the wall FACE (centerline ± thickness/2), not from the centerline. Use get_item_catalog for footprints; get_issues reports crossings and blocked doors.

    View tool JSON
    {
      "name": "place_item",
      "kind": "act",
      "impl": "imperative",
      "description": "Place furniture from the catalog at (x, y) = center in meters. rotation (degrees, counterclockwise) sets which way the piece FACES: 0 = faces +y (down/south on the plan), 90 = faces +x (right/east), 180 = faces -y (up/north), 270 = faces -x (left/west). The back of a sofa, bed headboard, wardrobe or counter is opposite the facing direction — so a sofa against the SOUTH wall needs rotation 180, and one against the WEST wall needs rotation 90. To sit a piece flush against a wall, offset its center by depth/2 from the wall FACE (centerline ± thickness/2), not from the centerline. Use get_item_catalog for footprints; get_issues reports crossings and blocked doors.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "rotation": {
            "type": "number"
          }
        },
        "required": [
          "kind",
          "x",
          "y"
        ],
        "additionalProperties": false
      }
    }
    define_item_kindAction

    Create a piece of furniture that is NOT in the catalogue, then place it with place_item. Use this whenever the plan draws something the catalogue does not have, or draws it at a different size — a corner bath, an L-shaped sofa, a kitchen island, a piano. Do NOT approximate with the nearest stock item when the plan shows something specific: define the real thing. Required: kind (a stable snake_case id), label, and the true footprint w × d and height h in METRES. Optional `parts` models it in 3D from primitives; without it the piece is blocked out from its footprint. Each part is { shape: "box" | "cylinder" | "sphere", x, y, z, w, h, d, color, rotation }, in the piece's OWN local frame: x runs along its width, z along its depth, y is height above the floor and is the part's BOTTOM (a 0.4 m tall seat resting on the floor is y:0, h:0.4). The piece faces +z, so a backrest sits at negative z and the front is positive z — that keeps it consistent with the rotation convention in place_item. For a cylinder, w is the diameter and d makes it an ellipse. Sizes are metres, colours are hex.

    View tool JSON
    {
      "name": "define_item_kind",
      "kind": "act",
      "impl": "imperative",
      "description": "Create a piece of furniture that is NOT in the catalogue, then place it with place_item. Use this whenever the plan draws something the catalogue does not have, or draws it at a different size — a corner bath, an L-shaped sofa, a kitchen island, a piano. Do NOT approximate with the nearest stock item when the plan shows something specific: define the real thing. Required: kind (a stable snake_case id), label, and the true footprint w × d and height h in METRES. Optional `parts` models it in 3D from primitives; without it the piece is blocked out from its footprint. Each part is { shape: \"box\" | \"cylinder\" | \"sphere\", x, y, z, w, h, d, color, rotation }, in the piece's OWN local frame: x runs along its width, z along its depth, y is height above the floor and is the part's BOTTOM (a 0.4 m tall seat resting on the floor is y:0, h:0.4). The piece faces +z, so a backrest sits at negative z and the front is positive z — that keeps it consistent with the rotation convention in place_item. For a cylinder, w is the diameter and d makes it an ellipse. Sizes are metres, colours are hex.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "w": {
            "type": "number"
          },
          "d": {
            "type": "number"
          },
          "h": {
            "type": "number"
          },
          "color": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "enum": [
              "living",
              "bedroom",
              "kitchen",
              "bath",
              "office",
              "decor"
            ]
          },
          "parts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "shape": {
                  "type": "string",
                  "enum": [
                    "box",
                    "cylinder",
                    "sphere"
                  ]
                },
                "x": {
                  "type": "number"
                },
                "y": {
                  "type": "number"
                },
                "z": {
                  "type": "number"
                },
                "w": {
                  "type": "number"
                },
                "h": {
                  "type": "number"
                },
                "d": {
                  "type": "number"
                },
                "color": {
                  "type": "string"
                },
                "rotation": {
                  "type": "number"
                }
              },
              "required": [],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "kind",
          "label",
          "w",
          "d",
          "h"
        ],
        "additionalProperties": false
      }
    }
    move_itemAction

    Move or rotate a furniture item by id or kind (e.g. "sofa"). Same rotation convention as place_item: 0 faces +y, 90 faces +x, 180 faces -y, 270 faces -x.

    View tool JSON
    {
      "name": "move_item",
      "kind": "act",
      "impl": "imperative",
      "description": "Move or rotate a furniture item by id or kind (e.g. \"sofa\"). Same rotation convention as place_item: 0 faces +y, 90 faces +x, 180 faces -y, 270 faces -x.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "rotation": {
            "type": "number"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    remove_itemAction

    Remove a furniture item by id or kind.

    View tool JSON
    {
      "name": "remove_item",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove a furniture item by id or kind.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          }
        },
        "required": [
          "id"
        ],
        "additionalProperties": false
      }
    }
    set_plan_nameAction

    Rename the plan.

    View tool JSON
    {
      "name": "set_plan_name",
      "kind": "act",
      "impl": "imperative",
      "description": "Rename the plan.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      }
    }
    clear_modelAction

    Clear the whole plan (walls, openings, rooms, furniture, notes). Use when the user asks to start over.

    View tool JSON
    {
      "name": "clear_model",
      "kind": "act",
      "impl": "imperative",
      "description": "Clear the whole plan (walls, openings, rooms, furniture, notes). Use when the user asks to start over.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    build_3dAction

    Raise the plan into 3D: extrudes walls with real openings, resolves corner joints, builds furniture, and switches the human's view to the 3D scene. Call after drawing so the user sees the result.

    View tool JSON
    {
      "name": "build_3d",
      "kind": "act",
      "impl": "imperative",
      "description": "Raise the plan into 3D: extrudes walls with real openings, resolves corner joints, builds furniture, and switches the human's view to the 3D scene. Call after drawing so the user sees the result.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    set_cameraAction

    Move the 3D camera: "orbit" (default 3/4 view), "top" (plan view from above), "walk" (first-person at 1.6 m — the user walks with WASD). Implies switching to 3D.

    View tool JSON
    {
      "name": "set_camera",
      "kind": "act",
      "impl": "imperative",
      "description": "Move the 3D camera: \"orbit\" (default 3/4 view), \"top\" (plan view from above), \"walk\" (first-person at 1.6 m — the user walks with WASD). Implies switching to 3D.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "orbit",
              "top",
              "walk"
            ]
          }
        },
        "required": [
          "mode"
        ],
        "additionalProperties": false
      }
    }
    set_doorsAction

    Swing the door leaves in the 3D scene open or shut (build_3d must have run). state: "open", "closed" or "toggle". Pass an opening id to act on one door, or omit it to act on every door in the plan. The human can do the same by clicking a leaf in the 3D view.

    View tool JSON
    {
      "name": "set_doors",
      "kind": "act",
      "impl": "imperative",
      "description": "Swing the door leaves in the 3D scene open or shut (build_3d must have run). state: \"open\", \"closed\" or \"toggle\". Pass an opening id to act on one door, or omit it to act on every door in the plan. The human can do the same by clicking a leaf in the 3D view.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "open",
              "closed",
              "toggle"
            ]
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "state"
        ],
        "additionalProperties": false
      }
    }
    get_supplier_catalogAnswer

    Read the furniture catalogue published by the PARTNER ORIGIN (Nordika) as its own WebMCP tools — sku, name, category, real footprint in metres, price and stock. Alza discovers those tools with getTools({fromOrigins}) and calls them with executeTool(), so the data crosses origins in the browser with no server in between. Filter with category (living | bedroom | office | dining), maxPrice, maxWidth (metres) or inStock. Pair it with place_supplier_product to drop a real product into the plan at its true size.

    View tool JSON
    {
      "name": "get_supplier_catalog",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the furniture catalogue published by the PARTNER ORIGIN (Nordika) as its own WebMCP tools — sku, name, category, real footprint in metres, price and stock. Alza discovers those tools with getTools({fromOrigins}) and calls them with executeTool(), so the data crosses origins in the browser with no server in between. Filter with category (living | bedroom | office | dining), maxPrice, maxWidth (metres) or inStock. Pair it with place_supplier_product to drop a real product into the plan at its true size.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string"
          },
          "maxPrice": {
            "type": "number"
          },
          "maxWidth": {
            "type": "number"
          },
          "inStock": {
            "type": "boolean"
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    place_supplier_productAction

    Buy-in-place: fetch one product from the partner origin by sku, add it to this plan's catalogue at the supplier's REAL dimensions, and place it at (x, y) = centre in metres with the usual rotation convention. The constraint checker then treats it like any other piece, so a sofa that does not fit is caught before anyone orders it.

    View tool JSON
    {
      "name": "place_supplier_product",
      "kind": "act",
      "impl": "imperative",
      "description": "Buy-in-place: fetch one product from the partner origin by sku, add it to this plan's catalogue at the supplier's REAL dimensions, and place it at (x, y) = centre in metres with the usual rotation convention. The constraint checker then treats it like any other piece, so a sofa that does not fit is caught before anyone orders it.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "sku": {
            "type": "string"
          },
          "x": {
            "type": "number"
          },
          "y": {
            "type": "number"
          },
          "rotation": {
            "type": "number"
          }
        },
        "required": [
          "sku",
          "x",
          "y"
        ],
        "additionalProperties": false
      }
    }
    leave_noteAction

    Leave a note on the plan for the human (or read theirs): design rationale, questions, measurements to verify. Notes are visible in the Notes panel.

    View tool JSON
    {
      "name": "leave_note",
      "kind": "act",
      "impl": "imperative",
      "description": "Leave a note on the plan for the human (or read theirs): design rationale, questions, measurements to verify. Notes are visible in the Notes panel.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          }
        },
        "required": [
          "text"
        ],
        "additionalProperties": false
      }
    }
    get_notesAnswer

    Read all notes left on the plan by the human and by agents.

    View tool JSON
    {
      "name": "get_notes",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read all notes left on the plan by the human and by agents.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }