{"ok":true,"site":{"host":"room-designer.ruhanwankhede0.workers.dev","url":"https://room-designer.ruhanwankhede0.workers.dev/","type":"live","desc":"ShuiSpace is a room designer where a person and their agent lay out the same floor plan together, through the same nineteen WebMCP actions.","tools":[{"name":"get_plan","kind":"answer","impl":"imperative","description":"Start here. This page is a room plan you can read and change directly through these tools, which is always better than clicking around the page: they give you exact centimetres, refuse anything that would not fit, and tell you why. Returns the room dimensions, its doors and windows, every placed item with its position and real dimensions in centimetres, what has been spent, and how many layout rules are currently broken.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"query_selection","kind":"answer","impl":"imperative","description":"Read which items the person currently has selected on the workplane. Use this to resolve what they mean by \"this one\" or \"that chair\".","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"budget_summary","kind":"answer","impl":"imperative","description":"Read what the plan costs so far, broken down by category, and how much of the budget is left. Prices are in the smallest currency unit.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"validate_plan","kind":"act","impl":"imperative","description":"Check the plan against every layout rule: walkway width to the door, items sharing the same space, and the clearances each piece of furniture needs around it. Returns one entry per item per broken rule, each with a severity of error or warning.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"find_gap","kind":"answer","impl":"imperative","description":"Find the largest empty rectangles of floor, largest first, each with its dimensions in centimetres and an id you can pass to search_catalog. Rugs do not count as occupied.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"minW":{"type":"number","minimum":0,"maximum":2000,"description":"Least acceptable width in cm"},"minD":{"type":"number","minimum":0,"maximum":2000,"description":"Least acceptable depth in cm"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"measure_clearance","kind":"act","impl":"imperative","description":"Measure how much room an item has on each of its four sides, in centimetres, and name what is in the way. Sides are relative to the item: front, back, left, right.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"itemId":{"type":"string"},"side":{"type":"string","enum":["front","back","left","right"]}},"required":["itemId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"search_catalog","kind":"answer","impl":"imperative","description":"Search the furniture catalog. Filter by category, by maximum footprint, by price, or by a gap id from find_gap to get only what would fit there in some orientation.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"category":{"type":"string","enum":["seating","table","storage","rug","decor"]},"maxW":{"type":"number","minimum":0,"maximum":2000},"maxD":{"type":"number","minimum":0,"maximum":2000},"maxPrice":{"type":"number","minimum":0},"fitsGapId":{"type":"string","description":"A gap id returned by find_gap"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"check_delivery_path","kind":"answer","impl":"imperative","description":"Check whether an item can physically be carried through each door of this room, given the door width and height. Reports the face it would go through and the centimetres to spare. Assumes no diagonal tilting, so it errs on the safe side.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"catalogId":{"type":"string"}},"required":["catalogId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"suggest_placements","kind":"act","impl":"imperative","description":"Ask where an item could go. Returns valid, collision-free positions ranked by how well they work, each with a plain-language reason. Choose among them by what the person actually wants - this tool knows the geometry, not the intent.","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"catalogId":{"type":"string"},"limit":{"type":"integer","minimum":1,"maximum":20},"bounds":{"type":"object","description":"Restrict suggestions to a region of the floor, in cm","properties":{"x0":{"type":"number"},"x1":{"type":"number"},"y0":{"type":"number"},"y1":{"type":"number"}},"required":["x0","x1","y0","y1"]}},"required":["catalogId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"place_item","kind":"act","impl":"imperative","description":"Put a new item from the catalog into the room at a position in centimetres, measured from the north-west corner to the item centre. Refuses if something is already there.","inputSchema":{"type":"object","properties":{"catalogId":{"type":"string"},"x":{"type":"number","minimum":0,"maximum":2000},"y":{"type":"number","minimum":0,"maximum":2000},"rotation":{"type":"integer","minimum":0,"maximum":270,"description":"Quarter turns only: 0, 90, 180 or 270"}},"required":["catalogId","x","y"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_item","kind":"act","impl":"imperative","description":"Move an item to a new position, turn it, or both. Give x and y to move, rotation to turn, or all three. Omitted values are left as they are. Refuses pinned items and refuses to overlap anything.","inputSchema":{"type":"object","properties":{"itemId":{"type":"string"},"x":{"type":"number","minimum":0,"maximum":2000},"y":{"type":"number","minimum":0,"maximum":2000},"rotation":{"type":"integer","minimum":0,"maximum":270,"description":"Quarter turns only: 0, 90, 180 or 270"}},"required":["itemId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"nudge_item","kind":"act","impl":"imperative","description":"Move an item by a distance in a direction, instead of to a coordinate. Use this whenever the person says something like \"a little to the right\", \"push it back\", or \"a bit further north\" — left, right, away and closer are resolved against the view they are looking at, so you never have to work out which way that is. Distance is centimetres: a nudge is about 10, \"a bit\" about 30, \"move it over\" about 60. Movement is always along a room axis, and the result says which compass direction that turned out to be. Refuses pinned items, and if something is in the way it reports how far the item could have gone.","inputSchema":{"type":"object","properties":{"itemId":{"type":"string"},"direction":{"type":"string","enum":["left","right","away","closer","north","south","east","west"],"description":"left, right, away and closer are from where the person is looking; north, south, east and west are fixed to the room, north being the wall at y = 0"},"distance":{"type":"number","minimum":1,"maximum":500,"description":"How far to move it, in centimetres"}},"required":["itemId","direction","distance"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"remove_item","kind":"act","impl":"imperative","description":"Take an item out of the room. Refuses pinned items. Reversible with undo_last.","inputSchema":{"type":"object","properties":{"itemId":{"type":"string"}},"required":["itemId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"swap_item","kind":"act","impl":"imperative","description":"Replace an item with a different one from the catalog, keeping its position and rotation, and report what the change does to the budget. Refuses if the replacement would not fit.","inputSchema":{"type":"object","properties":{"itemId":{"type":"string"},"catalogId":{"type":"string"}},"required":["itemId","catalogId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"pin_item","kind":"act","impl":"imperative","description":"Pin an item so nothing can move, swap or remove it, or unpin one. A pinned item is the person's decision, not a suggestion — never unpin without being asked to.","inputSchema":{"type":"object","properties":{"itemId":{"type":"string"},"pinned":{"type":"boolean"}},"required":["itemId","pinned"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"undo_last","kind":"act","impl":"imperative","description":"Undo the most recent change to the plan, whoever made it. Use this when the person says they preferred it the way it was.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"create_room","kind":"act","impl":"imperative","description":"Start a new room of a given width and depth in centimetres, replacing whatever is there. This clears all furniture and openings, so confirm with the person first. Add doors and windows afterwards with add_aperture.","inputSchema":{"type":"object","properties":{"w":{"type":"number","minimum":100,"maximum":2000,"description":"East-west, in cm"},"d":{"type":"number","minimum":100,"maximum":2000,"description":"North-south, in cm"},"ceilingHeight":{"type":"number","minimum":180,"maximum":500}},"required":["w","d"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_aperture","kind":"act","impl":"imperative","description":"Add a door or a window to one wall. The offset is measured in centimetres along that wall, from its north or west end. Doors default to floor level; windows default to a 90 cm sill.","inputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["door","window"]},"wall":{"type":"string","enum":["N","E","S","W"]},"offset":{"type":"number","minimum":0,"maximum":2000},"width":{"type":"number","minimum":30,"maximum":600},"sill":{"type":"number","minimum":0,"maximum":400},"top":{"type":"number","minimum":30,"maximum":500}},"required":["type","wall","offset","width"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"propose_layout","kind":"act","impl":"imperative","description":"Propose several placements at once as a single change. The person sees them as a translucent preview on the plan with your summary, and this call does not return until they accept or reject. Use it for anything bigger than one piece of furniture.","inputSchema":{"type":"object","properties":{"summary":{"type":"string","description":"One sentence describing the change, shown to the person verbatim"},"placements":{"type":"array","description":"Each placement is {catalogId, x, y, rotation?} in centimetres","items":{"type":"object","properties":{"catalogId":{"type":"string"},"x":{"type":"number"},"y":{"type":"number"},"rotation":{"type":"integer"}},"required":["catalogId","x","y"]}}},"required":["summary","placements"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"favicon":"/favicons/room-designer.ruhanwankhede0.workers.dev.svg","apiSurface":"spec","category":"Productivity & Business","toolCount":19}}