← WebMCP Directory

Tool tree

groundwork-delta-murex.vercel.app

Productivity & BusinessTools verified
Website
A floor-plan drawing tool where you and an AI agent work on the same canvas. Walls, doors and furniture that understand clearance, circulation and what actually fits.
Explore capabilities
    describe_sceneAnswer

    Read the whole floor plan: rooms with sizes, areas and compass-mapped walls, what each contains, which rooms connect through which doors, free space, and any problems. Call this first, and whenever you need to re-orient.

    View tool JSON
    {
      "name": "describe_scene",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the whole floor plan: rooms with sizes, areas and compass-mapped walls, what each contains, which rooms connect through which doors, free space, and any problems. Call this first, and whenever you need to re-orient.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "detail": {
            "type": "string",
            "description": "'summary' omits contents and free space; 'full' is the default.",
            "enum": [
              "summary",
              "full"
            ]
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    list_symbolsAnswer

    Browse or search the symbol library. Call with no arguments for an overview of every category and what is in it; with a category to list that group; or with a query to search. Queries understand what things are called ('couch', 'loo', 'fridge') and what they are for ('sit', 'sleep', 'wash', 'cook').

    View tool JSON
    {
      "name": "list_symbols",
      "kind": "answer",
      "impl": "imperative",
      "description": "Browse or search the symbol library. Call with no arguments for an overview of every category and what is in it; with a category to list that group; or with a query to search. Queries understand what things are called ('couch', 'loo', 'fridge') and what they are for ('sit', 'sleep', 'wash', 'cook').",
      "inputSchema": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "description": "Search terms, e.g. 'queen bed' or 'somewhere to sit'."
          },
          "category": {
            "type": "string",
            "description": "List one category instead of searching.",
            "enum": [
              "seating",
              "beds",
              "tables",
              "storage",
              "kitchen",
              "bath",
              "structure",
              "outdoor",
              "misc"
            ]
          },
          "measured_only": {
            "type": "boolean",
            "description": "Only symbols whose real size was measured rather than estimated. Use when clearances matter."
          },
          "limit": {
            "type": "number",
            "description": "Maximum results (default 25)."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    get_elementAnswer

    Everything known about one element, room or node, as structured data. Walls come back with their endpoints, length, the openings they hold and the runs still free — which is what you need before adding a door. Node ids (n1, n7) resolve too.

    View tool JSON
    {
      "name": "get_element",
      "kind": "answer",
      "impl": "imperative",
      "description": "Everything known about one element, room or node, as structured data. Walls come back with their endpoints, length, the openings they hold and the runs still free — which is what you need before adding a door. Node ids (n1, n7) resolve too.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "description": "Element id (W15, D2, F7), node id (n11), room id or name."
          }
        },
        "required": [
          "ref"
        ],
        "additionalProperties": false
      }
    }
    find_free_spaceAnswer

    Where something would fit in a room, accounting for furniture, walls, door swings and door approaches. Pass 'symbol' rather than width/height wherever you can: the answer then already accounts for the rotation that 'against' implies, and the position it returns is one place_furniture will accept. Raw width/height are read as world axes, before any rotation.

    View tool JSON
    {
      "name": "find_free_space",
      "kind": "answer",
      "impl": "imperative",
      "description": "Where something would fit in a room, accounting for furniture, walls, door swings and door approaches. Pass 'symbol' rather than width/height wherever you can: the answer then already accounts for the rotation that 'against' implies, and the position it returns is one place_furniture will accept. Raw width/height are read as world axes, before any rotation.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "room": {
            "type": "string",
            "description": "Room name or id."
          },
          "symbol": {
            "type": "string",
            "description": "Symbol id. Preferred over width/height."
          },
          "width": {
            "type": "number",
            "description": "Width in mm, along the world x axis."
          },
          "height": {
            "type": "number",
            "description": "Depth in mm, along the world y axis."
          },
          "against": {
            "type": "string",
            "description": "Prefer positions hugging this side.",
            "enum": [
              "N",
              "E",
              "S",
              "W",
              "any"
            ]
          },
          "rotation": {
            "type": "number",
            "description": "Rotation the object will be placed at. Ignored when 'against' is given."
          },
          "clearance": {
            "type": "number",
            "description": "Extra clear space to leave all round, in mm."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    measureAction

    Distance between two points, or the size of an element.

    View tool JSON
    {
      "name": "measure",
      "kind": "act",
      "impl": "imperative",
      "description": "Distance between two points, or the size of an element.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "object",
            "description": "Start point.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          },
          "to": {
            "type": "object",
            "description": "End point.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          },
          "ref": {
            "type": "string",
            "description": "Element to measure instead of two points."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    draw_wallsAction

    Draw a connected run of walls through a list of points, in mm. Set closed:true to form a loop, which creates a room. Walls automatically share junctions and split where they cross.

    View tool JSON
    {
      "name": "draw_walls",
      "kind": "act",
      "impl": "imperative",
      "description": "Draw a connected run of walls through a list of points, in mm. Set closed:true to form a loop, which creates a room. Walls automatically share junctions and split where they cross.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "points": {
            "type": "array",
            "description": "Points in order, at least two.",
            "items": {
              "type": "object",
              "description": "A point in mm.",
              "properties": {
                "x": {
                  "type": "number"
                },
                "y": {
                  "type": "number"
                }
              },
              "required": [
                "x",
                "y"
              ]
            }
          },
          "closed": {
            "type": "boolean",
            "description": "Join the last point back to the first."
          },
          "thickness": {
            "type": "number",
            "description": "Wall thickness in mm (default 200)."
          },
          "exterior": {
            "type": "boolean",
            "description": "Mark as an external wall."
          }
        },
        "required": [
          "points"
        ],
        "additionalProperties": false
      }
    }
    draw_room_rectAction

    Draw a rectangular SHELL — the outer envelope of a building or a floor. Use this once per building, then divide it with subdivide_room. Do NOT call it repeatedly to make individual rooms: separate rectangles share no walls, so they come out as free-floating boxes with gaps between them rather than a floor plan. x,y is the top-left corner in mm; north is negative y.

    View tool JSON
    {
      "name": "draw_room_rect",
      "kind": "act",
      "impl": "imperative",
      "description": "Draw a rectangular SHELL — the outer envelope of a building or a floor. Use this once per building, then divide it with subdivide_room. Do NOT call it repeatedly to make individual rooms: separate rectangles share no walls, so they come out as free-floating boxes with gaps between them rather than a floor plan. x,y is the top-left corner in mm; north is negative y.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "x": {
            "type": "number",
            "description": "Left edge in mm."
          },
          "y": {
            "type": "number",
            "description": "Top edge in mm."
          },
          "width": {
            "type": "number",
            "description": "Width in mm."
          },
          "height": {
            "type": "number",
            "description": "Height in mm."
          },
          "thickness": {
            "type": "number",
            "description": "Wall thickness in mm (default 200)."
          },
          "name": {
            "type": "string",
            "description": "Name for the resulting room."
          }
        },
        "required": [
          "x",
          "y",
          "width",
          "height"
        ],
        "additionalProperties": false
      }
    }
    move_nodeAction

    Move a wall junction. Every wall meeting at it follows.

    View tool JSON
    {
      "name": "move_node",
      "kind": "act",
      "impl": "imperative",
      "description": "Move a wall junction. Every wall meeting at it follows.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "node": {
            "type": "string",
            "description": "Node id, e.g. n3."
          },
          "to": {
            "type": "object",
            "description": "New position in mm.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          }
        },
        "required": [
          "node",
          "to"
        ],
        "additionalProperties": false
      }
    }
    set_wall_thicknessAction

    Change the thickness of one or more walls.

    View tool JSON
    {
      "name": "set_wall_thickness",
      "kind": "act",
      "impl": "imperative",
      "description": "Change the thickness of one or more walls.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "refs": {
            "type": "array",
            "description": "Wall ids.",
            "items": {
              "type": "string",
              "description": "A wall id."
            }
          },
          "thickness": {
            "type": "number",
            "description": "Thickness in mm."
          }
        },
        "required": [
          "refs",
          "thickness"
        ],
        "additionalProperties": false
      }
    }
    add_openingAction

    Add doors or windows. Identify each wall by id, or by a room plus a compass side — 'the south wall of Bedroom 1'. Pass 'openings' with an array to add several at once, which is one call and one undo step instead of a dozen. Position with centre (mm along the wall), or leave it to centre automatically. Check a wall's freeRuns first to see where there is space.

    View tool JSON
    {
      "name": "add_opening",
      "kind": "act",
      "impl": "imperative",
      "description": "Add doors or windows. Identify each wall by id, or by a room plus a compass side — 'the south wall of Bedroom 1'. Pass 'openings' with an array to add several at once, which is one call and one undo step instead of a dozen. Position with centre (mm along the wall), or leave it to centre automatically. Check a wall's freeRuns first to see where there is space.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "wall": {
            "type": "string",
            "description": "Wall id, if you know it."
          },
          "room": {
            "type": "string",
            "description": "Room name, used with 'side' to find the wall."
          },
          "side": {
            "type": "string",
            "description": "Which wall of that room.",
            "enum": [
              "N",
              "E",
              "S",
              "W"
            ]
          },
          "type": {
            "type": "string",
            "description": "Kind of opening.",
            "enum": [
              "door",
              "double-door",
              "window",
              "cased"
            ]
          },
          "width": {
            "type": "number",
            "description": "Width in mm. Defaults to the standard for the type."
          },
          "centre": {
            "type": "number",
            "description": "Distance in mm along the wall to the opening's centre."
          },
          "swing": {
            "type": "string",
            "description": "Which jamb a door is hinged on.",
            "enum": [
              "left",
              "right"
            ]
          },
          "outward": {
            "type": "boolean",
            "description": "Swing away from the room instead of into it."
          },
          "openings": {
            "type": "array",
            "description": "Several openings at once. Each entry takes the same fields as above.",
            "items": {
              "type": "object",
              "properties": {
                "wall": {
                  "type": "string",
                  "description": "Wall id."
                },
                "room": {
                  "type": "string",
                  "description": "Room name, used with 'side'."
                },
                "side": {
                  "type": "string",
                  "description": "Which wall of that room.",
                  "enum": [
                    "N",
                    "E",
                    "S",
                    "W"
                  ]
                },
                "type": {
                  "type": "string",
                  "description": "Kind of opening.",
                  "enum": [
                    "door",
                    "double-door",
                    "window",
                    "cased"
                  ]
                },
                "width": {
                  "type": "number",
                  "description": "Width in mm."
                },
                "centre": {
                  "type": "number",
                  "description": "Distance along the wall to the centre."
                },
                "swing": {
                  "type": "string",
                  "description": "Hinge side.",
                  "enum": [
                    "left",
                    "right"
                  ]
                },
                "outward": {
                  "type": "boolean",
                  "description": "Swing away from the room."
                }
              },
              "required": [
                "type"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    place_furnitureAction

    Place a symbol. Prefer describing intent — a room and a side to sit against — over raw coordinates; the position is then computed from real geometry and clearances. Rejections come back with positions that would work.

    View tool JSON
    {
      "name": "place_furniture",
      "kind": "act",
      "impl": "imperative",
      "description": "Place a symbol. Prefer describing intent — a room and a side to sit against — over raw coordinates; the position is then computed from real geometry and clearances. Rejections come back with positions that would work.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "symbol": {
            "type": "string",
            "description": "Symbol id from list_symbols."
          },
          "room": {
            "type": "string",
            "description": "Room to place it in."
          },
          "against": {
            "type": "string",
            "description": "Put it against this side of the room. The object is turned to face inward automatically — a sofa against the north wall faces south.",
            "enum": [
              "N",
              "E",
              "S",
              "W",
              "any"
            ]
          },
          "clearance": {
            "type": "number",
            "description": "Extra clear space to leave around it, in mm."
          },
          "x": {
            "type": "number",
            "description": "Explicit x in mm. Only when 'room' will not do."
          },
          "y": {
            "type": "number",
            "description": "Explicit y in mm."
          },
          "rotation": {
            "type": "number",
            "description": "Rotation in degrees, snapped to 15. At 0 an object faces north; each 90 turns it clockwise. Usually better to give 'against' and let it be worked out."
          },
          "name": {
            "type": "string",
            "description": "A name for this object."
          }
        },
        "required": [
          "symbol"
        ],
        "additionalProperties": false
      }
    }
    move_elementAction

    Move an element to a point, or by an offset. Doors slide along their wall; walls carry their junctions.

    View tool JSON
    {
      "name": "move_element",
      "kind": "act",
      "impl": "imperative",
      "description": "Move an element to a point, or by an offset. Doors slide along their wall; walls carry their junctions.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "description": "Element id or name."
          },
          "to": {
            "type": "object",
            "description": "Target position in mm.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          },
          "by": {
            "type": "object",
            "description": "Offset in mm.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          }
        },
        "required": [
          "ref"
        ],
        "additionalProperties": false
      }
    }
    rotate_elementAction

    Rotate an element, in degrees, snapped to 15.

    View tool JSON
    {
      "name": "rotate_element",
      "kind": "act",
      "impl": "imperative",
      "description": "Rotate an element, in degrees, snapped to 15.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "description": "Element id or name."
          },
          "degrees": {
            "type": "number",
            "description": "Degrees clockwise."
          }
        },
        "required": [
          "ref",
          "degrees"
        ],
        "additionalProperties": false
      }
    }
    delete_elementsSensitive Action

    Delete elements. Deleting a wall also deletes the doors and windows it hosts.

    View tool JSON
    {
      "name": "delete_elements",
      "kind": "transact",
      "impl": "imperative",
      "description": "Delete elements. Deleting a wall also deletes the doors and windows it hosts.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "refs": {
            "type": "array",
            "description": "Ids or names.",
            "items": {
              "type": "string",
              "description": "An id or name."
            }
          }
        },
        "required": [
          "refs"
        ],
        "additionalProperties": false
      }
    }
    subdivide_roomAction

    THE PRIMARY WAY TO MAKE ROOMS. Cut an existing space into a row of smaller ones — a shell into zones, a zone into offices. The dividing walls tee into the shell properly, so the result is real connected rooms sharing walls, which is what a floor plan is. Call it repeatedly, and on its own results, to build up a plan: shell -> zones -> rooms. Fifteen manager offices means subdividing a zone into fifteen, not drawing one enormous room called 'manager offices'.

    View tool JSON
    {
      "name": "subdivide_room",
      "kind": "act",
      "impl": "imperative",
      "description": "THE PRIMARY WAY TO MAKE ROOMS. Cut an existing space into a row of smaller ones — a shell into zones, a zone into offices. The dividing walls tee into the shell properly, so the result is real connected rooms sharing walls, which is what a floor plan is. Call it repeatedly, and on its own results, to build up a plan: shell -> zones -> rooms. Fifteen manager offices means subdividing a zone into fifteen, not drawing one enormous room called 'manager offices'.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "room": {
            "type": "string",
            "description": "Room name or id to divide."
          },
          "axis": {
            "type": "string",
            "description": "Which way the dividing walls run.",
            "enum": [
              "vertical",
              "horizontal"
            ]
          },
          "count": {
            "type": "number",
            "description": "How many cells to end up with."
          },
          "sizes": {
            "type": "array",
            "description": "Explicit cell sizes in mm, instead of count.",
            "items": {
              "type": "number",
              "description": "A size in mm."
            }
          },
          "names": {
            "type": "array",
            "description": "Names for the resulting cells, in position order along the axis. Safer than naming afterwards, since ids do not run in that order.",
            "items": {
              "type": "string",
              "description": "A room name."
            }
          },
          "doors": {
            "type": "boolean",
            "description": "Put a door in each dividing wall so the cells are reachable."
          },
          "thickness": {
            "type": "number",
            "description": "Wall thickness in mm (default 100)."
          }
        },
        "required": [
          "room",
          "axis"
        ],
        "additionalProperties": false
      }
    }
    arrange_roomAction

    Fill a room with a grid of one symbol — desks, dining tables, seating rows. Each position is checked individually, so anything that would block a door or overlap is skipped, and the response says how many actually fitted. Use this rather than calling place_furniture repeatedly.

    View tool JSON
    {
      "name": "arrange_room",
      "kind": "act",
      "impl": "imperative",
      "description": "Fill a room with a grid of one symbol — desks, dining tables, seating rows. Each position is checked individually, so anything that would block a door or overlap is skipped, and the response says how many actually fitted. Use this rather than calling place_furniture repeatedly.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "room": {
            "type": "string",
            "description": "Room name or id."
          },
          "symbol": {
            "type": "string",
            "description": "Symbol id from list_symbols."
          },
          "count": {
            "type": "number",
            "description": "How many to place. Omit to fill the room."
          },
          "spacing": {
            "type": "number",
            "description": "Gap between items in mm. Defaults to the symbol's own clearance."
          },
          "rotation": {
            "type": "number",
            "description": "Rotation for every item, in degrees."
          },
          "margin": {
            "type": "number",
            "description": "Clear space to leave at the room edge, in mm."
          }
        },
        "required": [
          "room",
          "symbol"
        ],
        "additionalProperties": false
      }
    }
    apply_layoutAction

    Lay out a whole room in one call, describing items by their RELATIONSHIP to each other rather than by coordinates. Name an item with 'as', then refer to it from later items with '$name'. Strongly preferred over repeated place_furniture: it is one undo step, it validates the finished arrangement rather than each half-built stage, and relations like 'around' and 'beside' are computed exactly.

    View tool JSON
    {
      "name": "apply_layout",
      "kind": "act",
      "impl": "imperative",
      "description": "Lay out a whole room in one call, describing items by their RELATIONSHIP to each other rather than by coordinates. Name an item with 'as', then refer to it from later items with '$name'. Strongly preferred over repeated place_furniture: it is one undo step, it validates the finished arrangement rather than each half-built stage, and relations like 'around' and 'beside' are computed exactly.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "room": {
            "type": "string",
            "description": "Room name or id."
          },
          "dry_run": {
            "type": "boolean",
            "description": "Resolve the layout and report where everything would land and what it would clash with, WITHOUT changing the drawing. Use this to check an arrangement before committing it, rather than placing, inspecting and deleting."
          },
          "verbosity": {
            "type": "string",
            "description": "How much to report back.",
            "enum": [
              "quiet",
              "diff",
              "full"
            ]
          },
          "items": {
            "type": "array",
            "description": "Items in order. Each may refer to any earlier one.",
            "items": {
              "type": "object",
              "properties": {
                "symbol": {
                  "type": "string",
                  "description": "Symbol id from list_symbols."
                },
                "as": {
                  "type": "string",
                  "description": "Name this item so later items can refer to it as '$name'."
                },
                "name": {
                  "type": "string",
                  "description": "Label for the placed object."
                },
                "against": {
                  "type": "string",
                  "description": "Put it against this side of the room, facing inward.",
                  "enum": [
                    "N",
                    "E",
                    "S",
                    "W",
                    "any"
                  ]
                },
                "beside": {
                  "type": "string",
                  "description": "Place it beside this item, e.g. '$bed'."
                },
                "side": {
                  "type": "string",
                  "description": "Which side of that item, from that item's own point of view.",
                  "enum": [
                    "left",
                    "right",
                    "front",
                    "back"
                  ]
                },
                "align": {
                  "type": "string",
                  "description": "How to line the two up along the shared edge (default back).",
                  "enum": [
                    "front",
                    "center",
                    "back"
                  ]
                },
                "around": {
                  "type": "string",
                  "description": "Ring this item, e.g. '$table'. Each copy turns to face it."
                },
                "count": {
                  "type": "number",
                  "description": "How many copies, for 'around'."
                },
                "between": {
                  "type": "array",
                  "description": "Midway between two items.",
                  "items": {
                    "type": "string",
                    "description": "An item reference."
                  }
                },
                "group": {
                  "type": "string",
                  "description": "Items sharing a group are treated as one arrangement — no clearance or overlap complaints between them. 'around' groups automatically."
                },
                "facing": {
                  "type": "string",
                  "description": "Turn to face this item, overriding the relation's own rotation."
                },
                "at": {
                  "type": "object",
                  "description": "Explicit position, when no relation fits.",
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ]
                },
                "rotation": {
                  "type": "number",
                  "description": "Explicit rotation in degrees."
                },
                "gap": {
                  "type": "number",
                  "description": "Gap to the related item, in mm."
                }
              },
              "required": [
                "symbol"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "room",
          "items"
        ],
        "additionalProperties": false
      }
    }
    set_sheetAction

    Change the paper size and drawing scale. Do this BEFORE drawing anything large: the sheet decides how much building fits on the page, and a plan drawn far outside it cannot be printed or read. An A2 at 1:50 covers about 620 m²; at 1:200 about 10,000 m².

    View tool JSON
    {
      "name": "set_sheet",
      "kind": "act",
      "impl": "imperative",
      "description": "Change the paper size and drawing scale. Do this BEFORE drawing anything large: the sheet decides how much building fits on the page, and a plan drawn far outside it cannot be printed or read. An A2 at 1:50 covers about 620 m²; at 1:200 about 10,000 m².",
      "inputSchema": {
        "type": "object",
        "properties": {
          "paper": {
            "type": "string",
            "description": "Paper size.",
            "enum": [
              "A4",
              "A3",
              "A2",
              "A1",
              "A0"
            ]
          },
          "scale": {
            "type": "number",
            "description": "Drawing scale denominator, e.g. 100 for 1:100."
          },
          "orientation": {
            "type": "string",
            "description": "Sheet orientation.",
            "enum": [
              "portrait",
              "landscape"
            ]
          },
          "name": {
            "type": "string",
            "description": "Sheet name, e.g. 'A-101 Ground Floor Plan'. Also names the plan if it is still untitled."
          },
          "plan_name": {
            "type": "string",
            "description": "Name of the drawing itself."
          },
          "fit": {
            "type": "boolean",
            "description": "Pick the smallest paper and scale that fits what is drawn. Ignored if you give paper or scale yourself."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    annotateAction

    Add a dimension line between two points, or a text note.

    View tool JSON
    {
      "name": "annotate",
      "kind": "act",
      "impl": "imperative",
      "description": "Add a dimension line between two points, or a text note.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What to add.",
            "enum": [
              "dimension",
              "text"
            ]
          },
          "from": {
            "type": "object",
            "description": "Dimension start.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          },
          "to": {
            "type": "object",
            "description": "Dimension end.",
            "properties": {
              "x": {
                "type": "number"
              },
              "y": {
                "type": "number"
              }
            },
            "required": [
              "x",
              "y"
            ]
          },
          "offset": {
            "type": "number",
            "description": "How far the dimension line stands off, in mm."
          },
          "x": {
            "type": "number",
            "description": "Text position x."
          },
          "y": {
            "type": "number",
            "description": "Text position y."
          },
          "text": {
            "type": "string",
            "description": "Text content."
          }
        },
        "required": [
          "kind"
        ],
        "additionalProperties": false
      }
    }
    set_styleAction

    Recolour elements. Targets ids, or everything in a room.

    View tool JSON
    {
      "name": "set_style",
      "kind": "act",
      "impl": "imperative",
      "description": "Recolour elements. Targets ids, or everything in a room.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "refs": {
            "type": "array",
            "description": "Ids or names.",
            "items": {
              "type": "string",
              "description": "An id or name."
            }
          },
          "room": {
            "type": "string",
            "description": "Recolour everything in this room instead."
          },
          "stroke": {
            "type": "string",
            "description": "Outline colour as hex, or 'default' to clear."
          },
          "fill": {
            "type": "string",
            "description": "Fill colour as hex, or 'default' to clear."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    name_roomAction

    Name a room, so it can be referred to by name afterwards.

    View tool JSON
    {
      "name": "name_room",
      "kind": "act",
      "impl": "imperative",
      "description": "Name a room, so it can be referred to by name afterwards.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "room": {
            "type": "string",
            "description": "Room id, or its current name."
          },
          "name": {
            "type": "string",
            "description": "New name."
          }
        },
        "required": [
          "room",
          "name"
        ],
        "additionalProperties": false
      }
    }
    set_programAction

    Record the design brief BEFORE drawing: the rooms wanted, how many people each is for, minimum areas, which must adjoin which, orientation, and required fixtures. Giving 'occupants' and 'use' is what makes validate_program a real check — it sizes each space against actual area-per-person figures, so an oversized or under-divided room fails.

    View tool JSON
    {
      "name": "set_program",
      "kind": "act",
      "impl": "imperative",
      "description": "Record the design brief BEFORE drawing: the rooms wanted, how many people each is for, minimum areas, which must adjoin which, orientation, and required fixtures. Giving 'occupants' and 'use' is what makes validate_program a real check — it sizes each space against actual area-per-person figures, so an oversized or under-divided room fails.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "entries": {
            "type": "array",
            "description": "One entry per required room.",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "description": "Short identifier, e.g. 'bedroom-1'."
                },
                "name": {
                  "type": "string",
                  "description": "Room name to match against the drawing."
                },
                "min_area_m2": {
                  "type": "number",
                  "description": "Minimum floor area."
                },
                "max_area_m2": {
                  "type": "number",
                  "description": "Maximum floor area."
                },
                "adjacent_to": {
                  "type": "array",
                  "description": "Keys of rooms this must connect to.",
                  "items": {
                    "type": "string",
                    "description": "A key."
                  }
                },
                "facing": {
                  "type": "string",
                  "description": "Which way it should face.",
                  "enum": [
                    "N",
                    "E",
                    "S",
                    "W"
                  ]
                },
                "requires": {
                  "type": "array",
                  "description": "Fixtures that must be present.",
                  "items": {
                    "type": "string",
                    "description": "A symbol id or keyword."
                  }
                },
                "occupants": {
                  "type": "number",
                  "description": "How many people this space is for. Checked against real area-per-person figures."
                },
                "use": {
                  "type": "string",
                  "description": "What kind of space, which sets the area each person needs.",
                  "enum": [
                    "openPlanDesk",
                    "privateOffice",
                    "meetingSeat",
                    "cafeteriaSeat"
                  ]
                }
              },
              "required": [
                "key"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "entries"
        ],
        "additionalProperties": false
      }
    }
    validate_programAction

    Check the drawing against the brief: areas, adjacencies, orientation and required fixtures.

    View tool JSON
    {
      "name": "validate_program",
      "kind": "act",
      "impl": "imperative",
      "description": "Check the drawing against the brief: areas, adjacencies, orientation and required fixtures.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": [],
        "additionalProperties": false
      }
    }
    undoAction

    Undo recent changes, yours or the user's.

    View tool JSON
    {
      "name": "undo",
      "kind": "act",
      "impl": "imperative",
      "description": "Undo recent changes, yours or the user's.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "steps": {
            "type": "number",
            "description": "How many steps (default 1)."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }
    focus_viewAction

    Pan and zoom the user's view to an element or room, so they can see what you changed.

    View tool JSON
    {
      "name": "focus_view",
      "kind": "act",
      "impl": "imperative",
      "description": "Pan and zoom the user's view to an element or room, so they can see what you changed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ref": {
            "type": "string",
            "description": "Element id, room name, or omit to fit everything."
          }
        },
        "required": [],
        "additionalProperties": false
      }
    }