Inspiration

I've moved apartments four times and every time the same thing happens. I open a chat, describe the room, get a nice paragraph about "creating a cozy reading nook by the window", and then I stand in the room with a tape measure and none of it fits. The bed blocks the door. The desk is in the dark corner. Meanwhile the planner apps that can actually draw a room have no idea what I asked for.

So the idea was pretty simple: put the drawing and the agent in the same place. Not a chat with a picture attached. A real plan that an AI agent can read and change, next to me, while I drag things around too.

What it does

Floorplay is a room designer where you and an AI agent work on the same floor plan.

On the left there's a plan that looks like something an architect would hand you: grid, thick wall bands with the doors and windows cut out, swing arcs, dimensions. On the right the same room in 3D, and you can walk through it at eye height. Eight rooms come already furnished because staring at an empty rectangle is the worst part of any planner. There's a catalog of 139 pieces with real sizes and prices.

The whole room is exposed to the agent as WebMCP tools. Sixty of them, plus four that show up only while you have something selected. It can read the plan, ask where a bed would fit, place and move things, paint a wall, resize the room, cut a window, move the camera, or lay out a whole option. When it proposes a layout you see it as ghosts on the drawing with a little card. Hover to preview, accept or reject. Everything else it does lands straight on the plan, goes into a ledger next to your own edits, and any step can be reverted.

Late in the week I added homes. You can put rooms next to each other on one sheet, they snap edge to edge and refuse to overlap, and if you cut a doorway through a shared wall it opens in both rooms. Then you can walk from the living room into the bedroom in 3D.

The part I like most is small. Ask the agent "what do I see from the door?" and the camera actually walks to the door and the answer comes from what is in that view. No guessing.

How we built it

It's a Vite + React + TypeScript app, no backend, three.js for the 3D through react-three-fiber. I built it in three days with an AI coding agent doing most of the typing and me doing most of the complaining.

Underneath there's a plain TypeScript engine that doesn't know the UI exists. It computes footprints and overlaps, whether a door can swing, whether you can reach everything, walkway width on a 10 cm grid, a rough daylight model, budget, and it can invert every operation so undo is exact. Homes sit on top of that: snapping, overlap checks, and a doorway stored as one record that owns an opening in two rooms.

The WebMCP part registers every tool on document.modelContext with a schema and a readOnlyHint where it applies. The selection tools live in their own group behind an AbortController, so when you click a different chair the old group is torn down and a new one registered. All the editing tools share one write path, which means they all answer the same way: what happened, what's now broken, the new numbers. That turned out to matter more than anything else I did.

Since most browsers don't have document.modelContext yet, the app has a fake one built in and a dev panel (Cmd+Shift+D) where you can call any tool by hand. Honestly that's where I spent most of the time. There are 309 tests and a Playwright script that runs the real app through 44 screenshots.

Challenges we ran into

The first time I opened the DevTools WebMCP panel it was empty. Every tool registered without an error, and Chrome just didn't list any. It took most of an afternoon to learn the page needs to be origin isolated, which is two headers (Origin-Agent-Cluster: ?1 and Permissions-Policy: tools=(self)). Two lines in the Vercel config.

At the start the agent placed furniture by guessing coordinates and it was awful. I tried writing better tool descriptions and it barely helped. What helped was giving it real answers: a suggest_positions tool that returns ranked spots with a reason for each, and every edit reporting the violations it caused. Once it could see that the bed now blocks the door, it fixed it on its own.

When I added homes, the walls between rooms poked into each other's floors, because each room draws its walls just outside its own rectangle. Fine alone, wrong the moment two rooms touch. Now a shared wall is drawn as two halves, one on each side of the line.

I also built a "Propose first" switch that turned every agent edit into a card you had to approve. It sounded responsible. In practice it just made the agent feel slow, and undo already covers the risk, so I took it out again the same day.

And on the last day I noticed you couldn't move a window at all. Not by dragging, not from the editor, not from a tool. Nobody had ever needed to during testing. That's fixed now.

Accomplishments that we're proud of

The agent can do anything I can do in the app. It never has to say "please click this for me".

The plan looks like a drawing, not a toy. Early versions looked like they were built for kids and that bothered me more than any bug.

Homes with doorways. Cutting one door and seeing it appear in both rooms, then walking through it in 3D, was the moment the project felt done.

What we learned

The number of tools is a vanity metric. What the tools return is what changes the agent's behaviour. Give it computed facts in every answer and it stops needing instructions.

Selection-scoped tools are worth the setup. "Move the thing the user just clicked" removes a whole class of wrong-id mistakes.

And an agent dropped into a page needs the same thing a new colleague does: a short tour. There's a get_guide tool for exactly that.

What's next for Floorplay

The Buy tab already lets the agent find where to buy each piece you don't own. Real store listings and price tracking would make that useful for real. After that: more home templates, more than one floor, and a share link so two people and one agent can work on the same flat.

Built With

Share this project:

Updates

Submission history