Tool tree
gradeNot graded
get_roomAnswer
Call this first. The whole room: size, doors, windows, outlets, every item in cm (x,y = top-left of footprint, rot clockwise, rot 0 faces south), the rules in force, the violations and the score out of 100. Also humanChanges — what the human did since your last call, as events {action, item, from, to, text}. Every tool returns those, so you always see their side. Workflow: get_room → brief → sense_room → set_profile → find_space per item → move_items → say.
View tool JSON
{
"name": "get_room",
"kind": "answer",
"impl": "imperative",
"description": "Call this first. The whole room: size, doors, windows, outlets, every item in cm (x,y = top-left of footprint, rot clockwise, rot 0 faces south), the rules in force, the violations and the score out of 100. Also humanChanges — what the human did since your last call, as events {action, item, from, to, text}. Every tool returns those, so you always see their side. Workflow: get_room → brief → sense_room → set_profile → find_space per item → move_items → say.",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
}
}sense_roomAction
Whether this reads as a room someone lives in — the judgement collision rules cannot make. Returns a verdict and ranked composition problems (no focal point, one-sided balance, seats that form no group, dead corners, a bed or wardrobe stranded off its wall), plus how full it is, its focal point, daylight per window through the day, and each light fixture with its layer, colour temperature and reach. Read it BEFORE arranging and quote it back in say() — it makes advice sound like a person.
View tool JSON
{
"name": "sense_room",
"kind": "act",
"impl": "imperative",
"description": "Whether this reads as a room someone lives in — the judgement collision rules cannot make. Returns a verdict and ranked composition problems (no focal point, one-sided balance, seats that form no group, dead corners, a bed or wardrobe stranded off its wall), plus how full it is, its focal point, daylight per window through the day, and each light fixture with its layer, colour temperature and reach. Read it BEFORE arranging and quote it back in say() — it makes advice sound like a person.",
"inputSchema": {
"type": "object",
"properties": {},
"required": []
}
}find_spaceAnswer
Where a footprint fits: up to 5 positions {x,y,rot} that break no rule. NEVER invent coordinates — the page owns the geometry. Pass `id` to re-place something already here, `type` for something new, or raw `w`/`h`. Every call is judged against the room AS IT IS NOW, so placing several pieces needs `ignore` (ids you will move anyway) and `plan` (spots already chosen), or they will overlap. `caveat` = the free spots cut a walkway. `least_bad` = nothing legal exists; set something aside.
View tool JSON
{
"name": "find_space",
"kind": "answer",
"impl": "imperative",
"description": "Where a footprint fits: up to 5 positions {x,y,rot} that break no rule. NEVER invent coordinates — the page owns the geometry. Pass `id` to re-place something already here, `type` for something new, or raw `w`/`h`.\n\nEvery call is judged against the room AS IT IS NOW, so placing several pieces needs `ignore` (ids you will move anyway) and `plan` (spots already chosen), or they will overlap.\n\n`caveat` = the free spots cut a walkway. `least_bad` = nothing legal exists; set something aside.",
"inputSchema": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"sofa",
"armchair",
"tv_unit",
"coffee_table",
"dining_table",
"chair",
"desk",
"bed_double",
"bed_single",
"wardrobe",
"bookshelf",
"plant",
"lamp",
"rug",
"counter",
"toilet",
"basin",
"shower",
"bathtub",
"sink",
"hob",
"fridge",
"blind",
"ceiling_light",
"pendant",
"spotlight_bar",
"chandelier",
"downlights",
"cove_strip",
"wall_sconce",
"track_light"
]
},
"w": {
"type": "number"
},
"h": {
"type": "number"
},
"prefer": {
"type": "string",
"enum": [
"wall",
"corner",
"center",
"near_window",
"near_outlet",
"any"
]
},
"near": {
"type": "string",
"description": "item id to stay close to"
},
"facing": {
"type": "string",
"description": "item id the front should face (e.g. sofa facing tv)"
},
"id": {
"type": "string",
"description": "an existing item you want to RE-place — its size and type are taken from it and its current position is ignored"
},
"ignore": {
"type": "array",
"items": {
"type": "string"
},
"description": "item ids to treat as not in the room, because you are about to move them too"
},
"plan": {
"type": "array",
"description": "placements you have already decided but not applied yet — pass them and the page will not hand you a spot that sits on top of one",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"sofa",
"armchair",
"tv_unit",
"coffee_table",
"dining_table",
"chair",
"desk",
"bed_double",
"bed_single",
"wardrobe",
"bookshelf",
"plant",
"lamp",
"rug",
"counter",
"toilet",
"basin",
"shower",
"bathtub",
"sink",
"hob",
"fridge",
"blind",
"ceiling_light",
"pendant",
"spotlight_bar",
"chandelier",
"downlights",
"cove_strip",
"wall_sconce",
"track_light"
]
},
"w": {
"type": "number"
},
"h": {
"type": "number"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"rot": {
"type": "number",
"enum": [
0,
90,
180,
270
]
}
},
"required": [
"x",
"y"
]
}
}
},
"required": []
}
}add_itemAction
Add a piece of furniture or a light fixture from the catalogue. Give x,y from find_space if you have somewhere in mind — or leave them out and the page picks a spot that breaks no rule, which is what you want most of the time. Returns the new item id. sense_room lists what each light fixture is for.
View tool JSON
{
"name": "add_item",
"kind": "act",
"impl": "imperative",
"description": "Add a piece of furniture or a light fixture from the catalogue. Give x,y from find_space if you have somewhere in mind — or leave them out and the page picks a spot that breaks no rule, which is what you want most of the time. Returns the new item id. sense_room lists what each light fixture is for.",
"inputSchema": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"sofa",
"armchair",
"tv_unit",
"coffee_table",
"dining_table",
"chair",
"desk",
"bed_double",
"bed_single",
"wardrobe",
"bookshelf",
"plant",
"lamp",
"rug",
"counter",
"toilet",
"basin",
"shower",
"bathtub",
"sink",
"hob",
"fridge",
"blind",
"ceiling_light",
"pendant",
"spotlight_bar",
"chandelier",
"downlights",
"cove_strip",
"wall_sconce",
"track_light"
]
},
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"rot": {
"type": "number",
"enum": [
0,
90,
180,
270
]
},
"prefer": {
"type": "string",
"enum": [
"wall",
"corner",
"center",
"near_window",
"near_outlet",
"any"
],
"description": "where it should look, when the page is choosing the spot"
}
},
"required": [
"type"
]
}
}sayAction
Speak to the human ON the plan: a bubble on an item, pinned at a point (`x,y`), or a banner. Use it after every change, one sentence under 90 chars. kind: say, ok, warn, idea. `options` makes it a question with up to 3 clickable answers; their choice arrives in humanChanges. If your sentence states a measurement, pass it as `claim` — the page checks it against its own geometry and either ticks it or corrects you in public. A claim you can prove beats confident prose.
View tool JSON
{
"name": "say",
"kind": "act",
"impl": "imperative",
"description": "Speak to the human ON the plan: a bubble on an item, pinned at a point (`x,y`), or a banner. Use it after every change, one sentence under 90 chars. kind: say, ok, warn, idea. `options` makes it a question with up to 3 clickable answers; their choice arrives in humanChanges. If your sentence states a measurement, pass it as `claim` — the page checks it against its own geometry and either ticks it or corrects you in public. A claim you can prove beats confident prose.",
"inputSchema": {
"type": "object",
"properties": {
"text": {
"type": "string"
},
"item": {
"type": "string",
"description": "item id to attach the bubble to"
},
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"kind": {
"type": "string",
"enum": [
"say",
"ok",
"warn",
"idea"
]
},
"options": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 2,
"maxItems": 3,
"description": "turns the bubble into a question with clickable answers"
},
"clear": {
"type": "boolean",
"description": "remove all existing bubbles first"
},
"claim": {
"type": "object",
"description": "OPTIONAL measurable claim in your sentence, which the page checks against its own geometry and marks true or corrects in front of the human",
"properties": {
"kind": {
"type": "string",
"enum": [
"distance",
"gap",
"angle",
"clear"
],
"description": "distance: centre to centre. gap: clear space between two pieces. clear: to the nearest WALL, not to a door. angle: how far b sits off a's facing."
},
"a": {
"type": "string",
"description": "the item the measurement is about"
},
"b": {
"type": "string",
"description": "the second item; distance, gap and angle need one"
},
"value": {
"type": "number",
"description": "the number you said out loud"
},
"unit": {
"type": "string"
}
},
"required": [
"kind",
"a",
"value"
]
}
},
"required": [
"text"
]
}
}showAction
Direct the human's attention. `highlight`: dim all but these ids while you explain a problem. `route_to`: draw and measure the walk from the door to an item. `view`: 2D for precise work, 3D for a finished layout or the lighting after dark. `eye`: SIT THEM INSIDE THE ROOM, at that seat's eye height facing the way it faces — the argument a plan cannot make. Put them in the wheelchair by the door and let them see the sofa blocking it, then show({eye:'off'}).
View tool JSON
{
"name": "show",
"kind": "act",
"impl": "imperative",
"description": "Direct the human's attention. `highlight`: dim all but these ids while you explain a problem. `route_to`: draw and measure the walk from the door to an item. `view`: 2D for precise work, 3D for a finished layout or the lighting after dark. `eye`: SIT THEM INSIDE THE ROOM, at that seat's eye height facing the way it faces — the argument a plan cannot make. Put them in the wheelchair by the door and let them see the sofa blocking it, then show({eye:'off'}).",
"inputSchema": {
"type": "object",
"properties": {
"highlight": {
"type": "array",
"items": {
"type": "string"
}
},
"route_to": {
"type": "string"
},
"panel": {
"type": "string",
"enum": [
"hide",
"show"
],
"description": "fold the side panel away to give the plan the whole screen, or bring it back"
},
"width": {
"type": "number",
"description": "route corridor width in cm; defaults to the profile (60, or 90 for accessibility)"
},
"view": {
"type": "string",
"enum": [
"2d",
"3d"
]
},
"eye": {
"type": "string",
"description": "item id to SIT INSIDE and look out from; switches to 3D on its own. 'off' stands back up."
},
"eye_height": {
"type": "number",
"description": "cm above the floor: 120 seated in a chair, 115 in a wheelchair, 160 standing. Defaults from the piece."
}
},
"required": []
}
}briefAction
Record WHO uses the room and WHAT they do in it — the half of the problem geometry cannot see. A desk for one and a desk for five look identical to a collision check. Once set, the page counts places, chairs and desks against real people and catches a layout that works on paper but not in life: five desks welded into a slab is a conference table, not five places to work. ASK the human, do not assume. Call it before arranging anything. No arguments reads the current brief back.
View tool JSON
{
"name": "brief",
"kind": "act",
"impl": "imperative",
"description": "Record WHO uses the room and WHAT they do in it — the half of the problem geometry cannot see. A desk for one and a desk for five look identical to a collision check. Once set, the page counts places, chairs and desks against real people and catches a layout that works on paper but not in life: five desks welded into a slab is a conference table, not five places to work. ASK the human, do not assume. Call it before arranging anything. No arguments reads the current brief back.",
"inputSchema": {
"type": "object",
"properties": {
"people": {
"type": "number",
"description": "how many people use the room at once"
},
"activity": {
"type": "string",
"enum": [
"study",
"work",
"dine",
"watch",
"sleep",
"talk"
]
},
"who": {
"type": "string",
"description": "what to call them in plain words — \"kids\", \"guests\", \"my dad\" — used in the messages the human reads"
}
},
"required": []
}
}set_profileAction
Set the design goal; this switches which rules apply, and the page may give you NEW TOOLS as a result — accessibility adds a wheelchair audit tool, 90cm corridors, 150cm turning circles and socket-reach checks; theater adds viewing distance, angle and glare; bedroom adds bed clearance; office adds glare and back-to-door. Returns the new rule list and violations. Re-read your tool list after calling this.
View tool JSON
{
"name": "set_profile",
"kind": "act",
"impl": "imperative",
"description": "Set the design goal; this switches which rules apply, and the page may give you NEW TOOLS as a result — accessibility adds a wheelchair audit tool, 90cm corridors, 150cm turning circles and socket-reach checks; theater adds viewing distance, angle and glare; bedroom adds bed clearance; office adds glare and back-to-door. Returns the new rule list and violations. Re-read your tool list after calling this.",
"inputSchema": {
"type": "object",
"properties": {
"profile": {
"type": "string",
"enum": [
"general",
"theater",
"office",
"bedroom",
"accessibility"
]
}
},
"required": [
"profile"
]
}
}sunAction
Read or set the sun. `hour` 0–23 is the time of day; `north` is the compass bearing of the wall at the top of the plan (0 = it faces north); `season` changes the sun's height and the day length. No arguments just reads. Always returns where the sun is now, which windows it enters and how strongly, how far the beam reaches across the floor, and for every screen the hours a window will shine on it. Ask "which way do your windows face?" rather than guessing.
View tool JSON
{
"name": "sun",
"kind": "act",
"impl": "imperative",
"description": "Read or set the sun. `hour` 0–23 is the time of day; `north` is the compass bearing of the wall at the top of the plan (0 = it faces north); `season` changes the sun's height and the day length. No arguments just reads. Always returns where the sun is now, which windows it enters and how strongly, how far the beam reaches across the floor, and for every screen the hours a window will shine on it. Ask \"which way do your windows face?\" rather than guessing.",
"inputSchema": {
"type": "object",
"properties": {
"hour": {
"type": "number",
"minimum": 0,
"maximum": 23
},
"north": {
"type": "number",
"description": "0-359; bearing of the top wall"
},
"season": {
"type": "string",
"enum": [
"summer",
"spring",
"winter"
]
}
},
"required": []
}
}set_roomAction
Size in cm unless you pass `units`. w and h alone RESIZE the room, keeping doors, windows, outlets and furniture (anything the smaller room cannot hold is set aside, not deleted) — use it when the human gives you their real measurements. Add doors/windows/outlets to build a NEW EMPTY room instead. `pos` is the offset along the wall from its top/left end. Openings are ALWAYS in cm whatever `units` says, so leave them out and add them after.
View tool JSON
{
"name": "set_room",
"kind": "act",
"impl": "imperative",
"description": "Size in cm unless you pass `units`. w and h alone RESIZE the room, keeping doors, windows, outlets and furniture (anything the smaller room cannot hold is set aside, not deleted) — use it when the human gives you their real measurements. Add doors/windows/outlets to build a NEW EMPTY room instead. `pos` is the offset along the wall from its top/left end. Openings are ALWAYS in cm whatever `units` says, so leave them out and add them after.",
"inputSchema": {
"type": "object",
"properties": {
"w": {
"type": "number"
},
"h": {
"type": "number"
},
"units": {
"type": "string",
"enum": [
"cm",
"m",
"in",
"ft"
],
"description": "unit for w and h; default cm. If they said \"12 by 14 feet\" pass ft and 12/14 — never convert in your head."
},
"doors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"wall": {
"type": "string",
"enum": [
"N",
"S",
"E",
"W"
]
},
"pos": {
"type": "number"
},
"width": {
"type": "number"
}
},
"required": [
"wall",
"pos"
]
}
},
"windows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"wall": {
"type": "string",
"enum": [
"N",
"S",
"E",
"W"
]
},
"pos": {
"type": "number"
},
"width": {
"type": "number"
}
},
"required": [
"wall",
"pos"
]
}
},
"outlets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
},
"required": [
"x",
"y"
]
}
}
},
"required": [
"w",
"h"
]
}
}define_flatAction
Set up a home of several rooms — "2BHK for four of us" — instead of one room in isolation. Give the number of bedrooms and how many people live there; the page builds a hall, that many bedrooms, a kitchen and a bathroom at ordinary sizes, works out who sleeps where, and sets each room the goal it should be judged against. Rooms start empty for you to furnish. Add a study or a balcony with `extras`. Ask the human how many bedrooms and how many people before you call this.
View tool JSON
{
"name": "define_flat",
"kind": "act",
"impl": "imperative",
"description": "Set up a home of several rooms — \"2BHK for four of us\" — instead of one room in isolation. Give the number of bedrooms and how many people live there; the page builds a hall, that many bedrooms, a kitchen and a bathroom at ordinary sizes, works out who sleeps where, and sets each room the goal it should be judged against. Rooms start empty for you to furnish. Add a study or a balcony with `extras`. Ask the human how many bedrooms and how many people before you call this.",
"inputSchema": {
"type": "object",
"properties": {
"bedrooms": {
"type": "number",
"description": "1 to 4 — the B in 2BHK"
},
"people": {
"type": "number",
"description": "how many live here in total"
},
"extras": {
"type": "array",
"items": {
"type": "string",
"enum": [
"study",
"balcony"
]
}
}
},
"required": [
"bedrooms",
"people"
]
}
}savesAction
Named rooms kept in this browser only — nothing is uploaded. No action lists them. `save` stores the room as it stands right now under `name` (up to 12; saving over a name replaces it). `load` reopens one, replacing the current room. `delete` removes one for good. Offer to save before you rearrange anything the human might want back, and tell them the name you used.
View tool JSON
{
"name": "saves",
"kind": "act",
"impl": "imperative",
"description": "Named rooms kept in this browser only — nothing is uploaded. No action lists them. `save` stores the room as it stands right now under `name` (up to 12; saving over a name replaces it). `load` reopens one, replacing the current room. `delete` removes one for good. Offer to save before you rearrange anything the human might want back, and tell them the name you used.",
"inputSchema": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"list",
"save",
"load",
"delete"
]
},
"name": {
"type": "string",
"description": "what to call it, up to 24 characters"
}
},
"required": []
}
}presetAction
With no id, lists the ready-made scenes (id, title, the problem each one poses) so you can offer the human a different room. With an id, loads it, replacing the current room.
View tool JSON
{
"name": "preset",
"kind": "act",
"impl": "imperative",
"description": "With no id, lists the ready-made scenes (id, title, the problem each one poses) so you can offer the human a different room. With an id, loads it, replacing the current room.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"enum": [
"living-pile",
"studio-tight",
"office-glare",
"dad-visits",
"open-plan",
"blank"
]
}
},
"required": []
}
}