{"ok":true,"site":{"host":"ventouris.github.io","url":"https://ventouris.github.io/Room-planner-with-WebMCP/","type":"live","desc":"A 2D room layout planner. Place furniture, check clearances, and let an AI agent read and edit the exact same geometry through WebMCP.","tools":[{"name":"get_room","kind":"answer","impl":"imperative","description":"Get the room dimensions in centimetres. Coordinates start at the top-left corner of the room.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"get_openings","kind":"answer","impl":"imperative","description":"List the doors and windows, with the wall each sits on, its offset along that wall, and its width in centimetres.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"get_objects","kind":"answer","impl":"imperative","description":"List every furniture object with its position, footprint, rotation and locked flag.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"get_object","kind":"answer","impl":"imperative","description":"Get one furniture object by id.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."}},"required":["objectId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"get_constraints","kind":"answer","impl":"imperative","description":"List the layout constraints, each with a human-readable description and whether it is currently satisfied.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"get_collisions","kind":"answer","impl":"imperative","description":"List overlapping furniture, objects outside the room bounds, and objects blocking a door clearance zone.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"get_distances","kind":"answer","impl":"imperative","description":"Distances for one object: to each wall, to every other object (nearest first), to each opening, and to the nearest window.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."}},"required":["objectId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"validate_layout","kind":"act","impl":"imperative","description":"Check the whole layout: returns valid plus the current collisions and constraint violations.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"set_room_dimensions","kind":"act","impl":"imperative","description":"Resize the room. Furniture keeps its coordinates, so shrinking a room can push objects out of bounds.","inputSchema":{"type":"object","properties":{"widthCm":{"type":"number"},"heightCm":{"type":"number"}},"required":["widthCm","heightCm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"add_object","kind":"act","impl":"imperative","description":"Add a piece of furniture. Known types (bed, desk, chair, sofa, table, wardrobe, bookshelf, nightstand) fill in default dimensions when width and depth are omitted. Position defaults to a free-ish spot near the top-left.","inputSchema":{"type":"object","properties":{"type":{"type":"string","description":"bed | desk | chair | sofa | table | wardrobe | bookshelf | nightstand | custom"},"label":{"type":"string"},"xCm":{"type":"number"},"yCm":{"type":"number"},"widthCm":{"type":"number"},"heightCm":{"type":"number","description":"Depth in centimetres."},"rotation":{"type":"number","enum":[0,90,180,270],"description":"Rotation in degrees."}},"required":["type"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"move_object","kind":"act","impl":"imperative","description":"Move an object to an absolute position (top-left corner, in centimetres) and re-validate the layout.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."},"xCm":{"type":"number"},"yCm":{"type":"number"}},"required":["objectId","xCm","yCm"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"rotate_object","kind":"act","impl":"imperative","description":"Rotate an object to 0, 90, 180 or 270 degrees. At 90 and 270 its width and depth swap.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."},"rotation":{"type":"number","enum":[0,90,180,270],"description":"Rotation in degrees."}},"required":["objectId","rotation"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"resize_object","kind":"act","impl":"imperative","description":"Change an object width and/or depth in centimetres.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."},"widthCm":{"type":"number"},"heightCm":{"type":"number"}},"required":["objectId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"rename_object","kind":"act","impl":"imperative","description":"Rename an object. The label is what the person sees on the canvas.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."},"label":{"type":"string"}},"required":["objectId","label"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"remove_object","kind":"act","impl":"imperative","description":"Remove an object from the room. Constraints that referenced it are removed too.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."}},"required":["objectId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"duplicate_object","kind":"act","impl":"imperative","description":"Duplicate an object, offset 20 cm down and right, and return the copy.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."}},"required":["objectId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"lock_object","kind":"act","impl":"imperative","description":"Lock or unlock an object. A locked object cannot be moved, rotated or resized — by the agent or by dragging.","inputSchema":{"type":"object","properties":{"objectId":{"type":"string","description":"Id of a furniture object, e.g. \"desk-1\"."},"locked":{"type":"boolean"}},"required":["objectId","locked"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"add_opening","kind":"act","impl":"imperative","description":"Add a door or a window to one of the four walls. offsetCm is measured from the top or left end of that wall.","inputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["door","window"]},"wall":{"type":"string","enum":["top","right","bottom","left"]},"offsetCm":{"type":"number"},"widthCm":{"type":"number"}},"required":["type","wall"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"update_opening","kind":"act","impl":"imperative","description":"Move or resize a door or window.","inputSchema":{"type":"object","properties":{"openingId":{"type":"string"},"wall":{"type":"string","enum":["top","right","bottom","left"]},"offsetCm":{"type":"number"},"widthCm":{"type":"number"}},"required":["openingId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"remove_opening","kind":"act","impl":"imperative","description":"Remove a door or window, along with any keep-clear constraint attached to it.","inputSchema":{"type":"object","properties":{"openingId":{"type":"string"}},"required":["openingId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"add_constraint","kind":"act","impl":"imperative","description":"Add a layout rule. min_distance needs objectAId, objectBId and distanceCm; near_window needs objectId and maxDistanceCm; against_wall needs objectId; keep_clear needs openingId and clearanceCm; clearance_zone needs objectId, side and clearanceCm — a functional clearance on one side of a piece of furniture (wardrobe door swing, desk chair pull-out, drawer access) rather than a door; max_distance needs objectAId, objectBId and maxDistanceCm — keeps two objects near each other, e.g. a nightstand near a bed; facing needs objectAId and objectBId — objectA's front (derived from its rotation: 0°=bottom, 90°=left, 180°=top, 270°=right) must point toward objectB, e.g. a chair facing a desk; centered_on_wall needs objectId, wall and toleranceCm — the object must touch that wall and sit centred along it.","inputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["min_distance","near_window","against_wall","keep_clear","clearance_zone","max_distance","facing","centered_on_wall"]},"objectAId":{"type":"string"},"objectBId":{"type":"string"},"objectId":{"type":"string"},"openingId":{"type":"string"},"side":{"type":"string","enum":["top","right","bottom","left"],"description":"Which side of the object the clearance_zone extends from."},"wall":{"type":"string","enum":["top","right","bottom","left"],"description":"Which wall the object should be centered on."},"distanceCm":{"type":"number"},"maxDistanceCm":{"type":"number"},"clearanceCm":{"type":"number"},"toleranceCm":{"type":"number","description":"Allowed off-centre slack for centered_on_wall, in centimetres."}},"required":["type"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"update_constraint","kind":"act","impl":"imperative","description":"Change the values on an existing constraint.","inputSchema":{"type":"object","properties":{"constraintId":{"type":"string"},"distanceCm":{"type":"number"},"maxDistanceCm":{"type":"number"},"clearanceCm":{"type":"number"},"toleranceCm":{"type":"number"},"objectAId":{"type":"string"},"objectBId":{"type":"string"},"objectId":{"type":"string"},"openingId":{"type":"string"},"side":{"type":"string","enum":["top","right","bottom","left"]},"wall":{"type":"string","enum":["top","right","bottom","left"]}},"required":["constraintId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"remove_constraint","kind":"act","impl":"imperative","description":"Remove a layout constraint.","inputSchema":{"type":"object","properties":{"constraintId":{"type":"string"}},"required":["constraintId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"highlight_objects","kind":"act","impl":"imperative","description":"Draw attention to objects or openings on the canvas and show the person a short message explaining why.","inputSchema":{"type":"object","properties":{"objectIds":{"type":"array","items":{"type":"string"},"description":"Object or opening ids."},"message":{"type":"string","description":"Shown above the room, e.g. \"These three items drive the layout.\""}},"required":["objectIds"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"clear_highlights","kind":"act","impl":"imperative","description":"Clear the highlight banner and outlines.","inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"},{"name":"capture_floorplan","kind":"act","impl":"imperative","description":"Render the floor plan on its own — no app chrome — as a PNG or a standalone SVG, and return it as a data URL the caller can save to a file. Pass download:true to have the browser save it instead, which keeps the (large) data URL out of the reply.","inputSchema":{"type":"object","properties":{"format":{"type":"string","enum":["png","svg"],"description":"Default png."},"scale":{"type":"number","description":"PNG pixel density, 0.25–4. Default 2."},"background":{"type":"string","enum":["paper","transparent"],"description":"Default paper."},"download":{"type":"boolean","description":"Save via the browser instead of returning the image data."},"filename":{"type":"string"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute","page":"/Room-planner-with-WebMCP/"}],"favicon":"/favicons/ventouris.github.io.svg","apiSurface":"spec","category":"Productivity & Business","toolCount":26}}