Files
editor/packages/mcp/examples/renovate-from-photos.md
T
Adrian PerezandClaude Opus 4.7 3406dad8f5 docs(mcp): add README, examples, and changelog
- README.md: install/quick start; configs for Claude Desktop, Claude
  Code, and Cursor; programmatic usage; tables covering all 21 tools,
  4 resources, and 3 prompts; limitations; development commands.
- CHANGELOG.md: 0.1.0 entry in Keep a Changelog format.
- examples/generate-apartment.md: prose transcript using from_brief
  to build an 80 m² 2-bed apartment, showing apply_patch, set_zone,
  cut_opening, validate_scene.
- examples/renovate-from-photos.md: prose transcript using the vision
  tools + renovation_from_photos prompt.
- examples/embed-in-agent.ts: compilable TypeScript showing
  programmatic usage via InMemoryTransport.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 17:51:37 +02:00

203 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Renovate an existing flat from photos
This example shows how an agent can combine the `renovation_from_photos`
prompt with the `analyze_floorplan_image` and `analyze_room_photo` vision
tools to propose a renovation plan grounded in real photos.
> **Note:** the vision tools use MCP sampling (`createMessage`), which
> Claude Desktop supports today. Hosts without sampling support will get a
> structured `sampling_unavailable` error; fall back to the text-only
> `from_brief` prompt in that case.
## The brief
The user drops four photos into the chat:
1. A floorplan PDF page (exported as PNG).
2. A photo of the current living room.
3. A photo of the current kitchen.
4. An inspirational photo from a magazine — a minimal Scandinavian loft.
And types:
> **User:** Claude, help me plan a renovation. Here's the current plan and
> two room photos. I want something like this Scandinavian reference —
> open-plan, neutral tones, keep the footprint.
## What the agent does
The host loads the **`renovation_from_photos`** prompt:
```text
currentPhotos: ["data:image/png;base64,...", "data:image/jpeg;base64,..."]
referencePhotos: ["data:image/jpeg;base64,..."]
goals: "Open-plan living/kitchen, neutral tones, keep the footprint."
```
The prompt tells the agent to (1) analyze the floorplan, (2) analyze each
room photo, (3) seed a scene from the floorplan, (4) compare against the
reference, and (5) propose patches.
### 1. Extract the floorplan
```jsonc
// tool: analyze_floorplan_image
{
"name": "analyze_floorplan_image",
"arguments": {
"image": "data:image/png;base64,iVBORw0KGgoAAAANS...",
"scaleHint": "1 m grid, total footprint ~9.5 m × 7 m"
}
}
```
Under the hood, the tool issues an MCP sampling request to the host with
the image and a structured prompt asking for walls, rooms, and
approximate dimensions. The response is validated against the tool's
output schema:
```jsonc
{
"walls": [
{ "start": [0, 0], "end": [9.5, 0], "thickness": 0.25 },
{ "start": [9.5, 0], "end": [9.5, 7], "thickness": 0.25 },
{ "start": [9.5, 7], "end": [0, 7], "thickness": 0.25 },
{ "start": [0, 7], "end": [0, 0], "thickness": 0.25 },
{ "start": [4.5, 0], "end": [4.5, 7], "thickness": 0.15 },
{ "start": [4.5, 3.5], "end": [9.5, 3.5], "thickness": 0.15 }
],
"rooms": [
{ "label": "Living", "polygon": [[0, 0], [4.5, 0], [4.5, 7], [0, 7]] },
{ "label": "Kitchen", "polygon": [[4.5, 0], [9.5, 0], [9.5, 3.5], [4.5, 3.5]] },
{ "label": "Bedroom", "polygon": [[4.5, 3.5], [9.5, 3.5], [9.5, 7], [4.5, 7]] }
],
"approximateDimensions": { "widthMeters": 9.5, "depthMeters": 7, "areaSqMeters": 66.5 },
"confidence": 0.82
}
```
### 2. Analyze the room photos
```jsonc
// tool: analyze_room_photo
{
"name": "analyze_room_photo",
"arguments": { "image": "data:image/jpeg;base64,/9j/4AAQ..." }
}
```
Response:
```jsonc
{
"approximateDimensions": { "widthMeters": 4.4, "depthMeters": 5.8, "heightMeters": 2.5 },
"identifiedFixtures": [
{ "kind": "sofa", "approximatePosition": [2.2, 3.5] },
{ "kind": "coffee-table", "approximatePosition": [2.2, 2.4] },
{ "kind": "tv-unit", "approximatePosition": [0.3, 2.0] }
],
"identifiedWindows": [
{ "wallHint": "south", "approximateWidth": 1.4, "approximateHeight": 1.5 }
]
}
```
The kitchen photo is analyzed the same way.
### 3. Seed the scene
The agent reads `get_scene`, confirms the default empty Site → Building →
Level is present, and then batch-creates walls matching the floorplan:
```jsonc
// tool: apply_patch
{
"name": "apply_patch",
"arguments": {
"patches": [
{ "op": "create", "parentId": "level-1",
"node": { "type": "wall", "start": [0, 0], "end": [9.5, 0],
"thickness": 0.25, "height": 2.5 } },
/* ...remaining perimeter + partition walls from the vision result... */
]
}
}
```
The agent then calls `set_zone` three times to seed the Living / Kitchen /
Bedroom polygons from the floorplan rooms.
### 4. Cut the identified openings
For each window the vision tool reported, the agent calls `cut_opening`
against the corresponding perimeter wall:
```jsonc
{
"name": "cut_opening",
"arguments": {
"wallId": "wall-south",
"type": "window",
"position": 0.5,
"width": 1.4,
"height": 1.5
}
}
```
### 5. Propose the renovation
Guided by the reference photo's analysis (bright neutrals, open plan,
minimal furnishing), the agent proposes a single logical patch:
- Remove the partition wall between Living and Kitchen.
- Relocate the kitchen island further west.
- Delete the bulky TV unit item; leave the sofa and coffee table.
- Re-label the merged zone `"Open-Plan Living / Kitchen"`.
All of that goes into one `apply_patch`:
```jsonc
{
"name": "apply_patch",
"arguments": {
"patches": [
{ "op": "delete", "id": "wall-partition-living-kitchen", "cascade": false },
{ "op": "update", "id": "zone-living", "data": { "label": "Open-Plan Living / Kitchen",
"polygon": [[0, 0], [9.5, 0],
[9.5, 3.5], [0, 3.5]] } },
{ "op": "delete", "id": "zone-kitchen", "cascade": false }
/* + item moves / deletes for the TV unit etc. */
]
}
}
```
The user can walk back with `undo`; `redo` returns them to the proposal.
### 6. Sanity-check
```jsonc
// tool: validate_scene
{ "name": "validate_scene", "arguments": {} }
// → { "valid": true, "errors": [] }
// tool: check_collisions
{ "name": "check_collisions", "arguments": { "levelId": "level-1" } }
// → { "collisions": [] }
```
The agent reports a summary of the changes plus the approximate new
usable area (from the summary resource), and the user opens the scene in
`@pascal-app/viewer` to see the renovated 3D layout.
## Takeaways
- The vision tools only return **data**. They don't mutate the scene —
the agent is explicit about every structural change via `apply_patch`.
- Photos supply priors (approximate dimensions, fixture types) that a
brief-only workflow can't. Combine them with `from_brief`-style
prompts when the user has both a reference and concrete text goals.
- All renovation steps are a single temporal step per patch, so the user
can compare before/after with `undo` / `redo`.