{"ok":true,"site":{"host":"floor-plan-pink.vercel.app","url":"https://floor-plan-pink.vercel.app/","type":"live","desc":"A shared conceptual floor-planning workspace where humans draw directly on the canvas and agents work the same plans through semantic WebMCP tools.","tools":[{"name":"get_project_state","kind":"answer","impl":"imperative","description":"List every floor plan in the shared FloorPlan workspace with its id, author (human or agent), version, site and indoor areas, room counts and design scores. Call this first to discover what already exists and which plan is active, before creating or modifying anything. Read-only.","annotations":{"title":"Read the floor-plan project","readOnlyHint":true,"idempotentHint":true,"openWorldHint":false},"inputSchema":{"type":"object","properties":{}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_floorplan_state","kind":"answer","impl":"imperative","description":"Get the full geometry of one floor plan: every room with its position, size and area in feet, which walls are exterior, all doors, windows and stairs, furniture with its host room, garden and parking allocations, room-to-room adjacency, the design-score breakdown, and which stated requirements are actually satisfied. Use this before modifying a plan, and after a human edit to see what changed. Read-only.","annotations":{"title":"Read one floor plan in detail","readOnlyHint":true,"idempotentHint":true,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"create_floorplan_from_requirements","kind":"act","impl":"imperative","description":"Design a complete conceptual floor plan from a site area and a list of room requirements, and render it immediately in the shared workspace. Use this when the user wants a NEW layout designed (\"I have 1,800 sq ft, I need 3 bedrooms, a maid room, storage, laundry, a closed kitchen, garden and parking\") rather than a change to an existing plan. The engine zones the plot into public, private, service and outdoor areas, sizes rooms against design heuristics, adds internal doors and exterior windows, furnishes each room, and scores the result. With outputMode \"append\" (the default) the new plan appears below the existing plans so the human can compare, and their own plan is left untouched. Returns the plan id, room-by-room areas, requirement checklist and design rationale. Plans are conceptual, not construction documentation.","annotations":{"title":"Design a new floor plan","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"totalAreaSqFt":{"type":"number","minimum":250,"description":"Total plot area in square feet, including garden and parking. Supply this when the user only knows their total area — the engine picks a sensible rectangular footprint (1,800 sq ft becomes roughly 45 x 40 ft)."},"lotWidthFt":{"type":"number","minimum":12,"description":"Plot width in feet, if known. Use with lotDepthFt for a specific plot shape."},"lotDepthFt":{"type":"number","minimum":12,"description":"Plot depth in feet, if known."},"requirements":{"type":"object","description":"The rooms and features the dwelling must contain.","properties":{"bedrooms":{"type":"integer","minimum":0,"maximum":6,"description":"Number of bedrooms. The first is treated as the master and sized larger."},"bathrooms":{"type":"integer","minimum":0,"maximum":4,"description":"Number of bathrooms. Defaults to 2 when three or more bedrooms are requested."},"maidRoom":{"type":"boolean","description":"Include a maid / staff room in the service zone."},"storageRoom":{"type":"boolean","description":"Include a dedicated store room."},"laundryRoom":{"type":"boolean","description":"Include a laundry / utility room, placed next to the kitchen."},"kitchenType":{"type":"string","enum":["closed","open"],"description":"\"closed\" gives the kitchen its own door; \"open\" leaves it open to the living/dining space."},"diningRoom":{"type":"boolean","default":true,"description":"Include a distinct dining area."},"garden":{"type":"boolean","description":"Allocate garden area on the plot outside the building envelope."},"parkingSpaces":{"type":"integer","minimum":0,"maximum":4,"description":"Number of car parking spaces to allocate on the plot."},"stairs":{"type":"boolean","description":"Place a stair core (for a future upper floor)."}}},"priorities":{"type":"array","items":{"type":"string"},"description":"Ranked design priorities in the user's own words, e.g. [\"space efficiency\", \"bedroom privacy\", \"natural daylight\", \"practical room adjacency\"]. The layout engine maps these onto zoning, corridor width and area weighting, and reports back which ones it recognised."},"strategy":{"type":"string","enum":["balanced","living-first","privacy-first","outdoor-first","storage-first"],"description":"Optional explicit layout strategy. Leave this out to let the engine choose from the stated priorities. Each strategy produces a genuinely different site organisation and interior zoning, not just a different label."},"name":{"type":"string","description":"Optional plan name. Defaults to the next label in the series (\"AI Option A\", \"AI Option B\", ...)."},"outputMode":{"type":"string","enum":["append","replace"],"default":"append","description":"\"append\" adds a new plan below the existing ones so the human can compare before and after — this is the recommended default. \"replace\" overwrites the target plan in place and increments its version."},"planId":{"type":"string","description":"Only used when outputMode is \"replace\": the plan to overwrite."}},"required":["requirements"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"optimize_floorplan","kind":"act","impl":"imperative","description":"Improve an existing floor plan against explicit goals such as \"larger living room\", \"less circulation waste\", \"more natural light\", \"more storage\", \"better bedroom privacy\", \"improve accessibility\" or \"preserve garden space\", while honouring constraints such as \"keep 2 bedrooms\" or \"keep 1 bathroom\". Works on a plan the human drew by hand as well as on a generated one — the room program is read back out of the plan's own geometry, so no stored brief is needed. Returns before and after scores plus a change list derived by comparing the two geometries. Default outputMode \"append\" places the optimised layout below the original so the before/after comparison is visible; use \"replace\" to improve the plan in place.","annotations":{"title":"Optimise an existing floor plan","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."},"goals":{"type":"array","minItems":1,"items":{"type":"string"},"description":"What to improve, in the user's words. Recognised themes: larger living area, bedroom privacy, more daylight, less circulation waste, more storage, better room adjacency, improved accessibility, preserve garden space, space efficiency."},"constraints":{"type":"array","items":{"type":"string"},"description":"What must not change, e.g. [\"keep 2 bedrooms\", \"keep 1 bathroom\", \"keep the garden\"]. Room counts and features are parsed out and held fixed."},"outputMode":{"type":"string","enum":["append","replace"],"default":"append","description":"\"append\" adds a new plan below the existing ones so the human can compare before and after — this is the recommended default. \"replace\" overwrites the target plan in place and increments its version."}},"required":["goals"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"generate_floorplan_variations","kind":"act","impl":"imperative","description":"Produce one to three genuinely different alternative layouts from a base plan, each solved with a different zoning strategy (living-first, privacy-first, outdoor-first, storage-first or balanced) and steered by the given priorities. The geometry really differs — building footprint, garden position, room sizes and circulation all change — so the variations are worth comparing rather than being relabelled copies. Use this when the user asks for \"another option\" or \"a variation with a bigger living room and more bedroom privacy\". Variations are appended below the existing plans by default.","annotations":{"title":"Generate alternative layouts","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"basePlanId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."},"count":{"type":"integer","minimum":1,"maximum":3,"default":1,"description":"How many variations to generate (1-3)."},"priorities":{"type":"array","items":{"type":"string"},"description":"Ranked design priorities in the user's own words, e.g. [\"space efficiency\", \"bedroom privacy\", \"natural daylight\", \"practical room adjacency\"]. The layout engine maps these onto zoning, corridor width and area weighting, and reports back which ones it recognised."},"outputMode":{"type":"string","enum":["append","replace"],"default":"append","description":"\"append\" adds a new plan below the existing ones so the human can compare before and after — this is the recommended default. \"replace\" overwrites the target plan in place and increments its version."}},"required":["basePlanId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"replace_floorplan","kind":"act","impl":"imperative","description":"Redesign one specific plan from scratch, keeping its identity and position in the workspace but incrementing its version. Use this when the user rejects an option outright — \"I don't like Option B, replace it with something that has less corridor and a bigger living room\". The room program carries over from the plan being replaced unless new requirements are supplied, and the engine deliberately picks a different strategy so the geometry visibly changes. Returns the previous and new scores plus the concrete changes.","annotations":{"title":"Replace a plan with a new design","readOnlyHint":false,"destructiveHint":true,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."},"requirements":{"type":"object","description":"The rooms and features the dwelling must contain.","properties":{"bedrooms":{"type":"integer","minimum":0,"maximum":6,"description":"Number of bedrooms. The first is treated as the master and sized larger."},"bathrooms":{"type":"integer","minimum":0,"maximum":4,"description":"Number of bathrooms. Defaults to 2 when three or more bedrooms are requested."},"maidRoom":{"type":"boolean","description":"Include a maid / staff room in the service zone."},"storageRoom":{"type":"boolean","description":"Include a dedicated store room."},"laundryRoom":{"type":"boolean","description":"Include a laundry / utility room, placed next to the kitchen."},"kitchenType":{"type":"string","enum":["closed","open"],"description":"\"closed\" gives the kitchen its own door; \"open\" leaves it open to the living/dining space."},"diningRoom":{"type":"boolean","default":true,"description":"Include a distinct dining area."},"garden":{"type":"boolean","description":"Allocate garden area on the plot outside the building envelope."},"parkingSpaces":{"type":"integer","minimum":0,"maximum":4,"description":"Number of car parking spaces to allocate on the plot."},"stairs":{"type":"boolean","description":"Place a stair core (for a future upper floor)."}}},"priorities":{"type":"array","items":{"type":"string"},"description":"Ranked design priorities in the user's own words, e.g. [\"space efficiency\", \"bedroom privacy\", \"natural daylight\", \"practical room adjacency\"]. The layout engine maps these onto zoning, corridor width and area weighting, and reports back which ones it recognised."},"strategy":{"type":"string","enum":["balanced","living-first","privacy-first","outdoor-first","storage-first"],"description":"Optional explicit layout strategy. Leave this out to let the engine choose from the stated priorities. Each strategy produces a genuinely different site organisation and interior zoning, not just a different label."}},"required":["planId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"apply_floorplan_variation","kind":"act","impl":"imperative","description":"Promote a generated variation to be the active working plan, so subsequent human and agent edits land on it. By default this only changes which plan is active and leaves every plan intact. Pass mode \"overwrite-source\" together with sourcePlanId to copy the variation's geometry over another plan (for example, to accept an AI option into the human plan) — that increments the target's version and keeps its name.","annotations":{"title":"Adopt a variation as the working plan","readOnlyHint":false,"destructiveHint":false,"idempotentHint":true,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"variationPlanId":{"type":"string","description":"The variation to adopt, by id or name."},"sourcePlanId":{"type":"string","description":"Only for mode \"overwrite-source\": the plan whose geometry gets replaced."},"mode":{"type":"string","enum":["activate","overwrite-source"],"default":"activate","description":"\"activate\" just makes the variation the working plan. \"overwrite-source\" also copies its geometry onto sourcePlanId."}},"required":["variationPlanId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"modify_room","kind":"act","impl":"imperative","description":"Change one room in a plan: rename it, change its type, move it, resize it, or scale it towards a target area. Rooms can be named semantically (\"Master Bedroom\", \"kitchen\", \"master\") rather than by id. All measurements are in feet, matching the plan's own coordinate system — never screen pixels. Note that this edits a single room without reflowing its neighbours, so prefer optimize_floorplan for whole-layout changes.","annotations":{"title":"Modify a room","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."},"roomId":{"type":"string","description":"Room id, or a name such as \"Master Bedroom\", \"kitchen\" or \"master\"."},"changes":{"type":"object","description":"The changes to apply. Supply at least one.","properties":{"name":{"type":"string","description":"New room name."},"type":{"type":"string","enum":["living","dining","kitchen","bedroom","maid","bathroom","storage","laundry","corridor","entry"],"description":"New room type. Changes how the room is coloured, sized and scored."},"position":{"type":"object","description":"New top-left position in feet, measured from the plot origin.","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"width":{"type":"number","minimum":3,"description":"New width in feet."},"height":{"type":"number","minimum":3,"description":"New depth in feet."},"targetAreaSqFt":{"type":"number","minimum":12,"description":"Scale the room towards this area, keeping its proportions. Ignored if width or height is given."}}}},"required":["roomId","changes"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_architectural_element","kind":"act","impl":"imperative","description":"Add a door, window, stair core or freestanding wall to a plan using semantic placement. Name the room and, optionally, the wall — \"add another exterior window to the master bedroom\", or wall \"exterior-south\" — and the engine resolves the actual wall, picks a spot that does not collide with existing openings, and sizes the opening to the wall. Windows are only placed on exterior walls; doors prefer a wall shared with the hallway. Returns which wall was chosen and the plan's updated daylight reading. No pixel coordinates are needed, though an explicit position in feet is accepted as a fallback.","annotations":{"title":"Add a door, window, stairs or wall","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."},"type":{"type":"string","enum":["door","window","stairs","wall"],"description":"What to add."},"roomId":{"type":"string","description":"The room the element belongs to, by id or name (\"Master Bedroom\", \"kitchen\"). Required for doors and windows unless an explicit position is given."},"wall":{"type":"string","description":"Semantic wall reference: \"north\", \"south\", \"east\", \"west\", or \"exterior-south\". Omit to let the engine pick the best available wall."},"offsetAlongWall":{"type":"number","minimum":0,"maximum":1,"description":"Where along the wall to place the opening, 0 = start, 1 = end. Omit to auto-place clear of existing openings."},"widthFt":{"type":"number","minimum":1.5,"description":"Clear opening width in feet. Omit for a sensible default."},"position":{"type":"object","description":"Fallback absolute position in feet, used only when no room is named.","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"rotation":{"type":"number","description":"Rotation in degrees, for stairs and freestanding walls."}},"required":["type"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_furniture","kind":"act","impl":"imperative","description":"Reposition a piece of furniture using intent rather than coordinates. Name the item (\"dining table\", \"sofa\", \"bed\") and either a target room, or an anchor to position against — for example relativeTo { elementId: \"Kitchen\", relationship: \"near\" } for \"move the dining table closer to the kitchen\". The engine keeps the item inside its room and can rotate it. An explicit position in feet is accepted but rarely needed.","annotations":{"title":"Move a furniture item","readOnlyHint":false,"destructiveHint":false,"idempotentHint":false,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planId":{"type":"string","description":"Id of the target plan, from get_project_state. Also accepts a plan name (\"AI Option B\"), or \"active\" for the current working plan. Omit to use the active plan."},"furnitureId":{"type":"string","description":"Furniture id, or a name/type such as \"dining table\", \"sofa\", \"bed\"."},"targetRoomId":{"type":"string","description":"Move the item into this room, by id or name. Centres it if no anchor is given."},"relativeTo":{"type":"object","description":"Position the item against a room or another item.","properties":{"elementId":{"type":"string","description":"Anchor room or furniture item, by id or name (e.g. \"Kitchen\", \"sofa\")."},"relationship":{"type":"string","enum":["near","against-wall","centre","left-of","right-of"],"default":"near","description":"How to position relative to the anchor."}},"required":["elementId"]},"position":{"type":"object","description":"Explicit top-left position in feet. Prefer targetRoomId or relativeTo.","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"rotation":{"type":"number","description":"Rotation in degrees (0 or 90 for most items)."}},"required":["furnitureId"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"compare_floorplans","kind":"act","impl":"imperative","description":"Compare two or more plans side by side on efficiency, circulation, daylight, privacy, requirement fit and overall score, and open the comparison view in the workspace so the human sees the same table. Useful for answering \"which of these is better and why\". Returns the score table, the best plan per metric and, for two plans, a list of the concrete geometric differences.","annotations":{"title":"Compare floor plans","readOnlyHint":false,"idempotentHint":true,"openWorldHint":false},"inputSchema":{"type":"object","properties":{"planIds":{"type":"array","minItems":2,"items":{"type":"string"},"description":"Plan ids or names to compare. Defaults to the first two plans in the project."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"AI & Agents","favicon":"/favicons/floor-plan-pink.vercel.app.svg","apiSurface":"spec","toolCount":11}}