10 parallel research agents (R1-R10) investigated whether MCP can save
scenes as saveable entities that the user later opens in the editor —
rather than injecting via a dev-only window.__pascalScene hook.
Key findings:
- Editor is already backend-agnostic via onLoad/onSave callbacks (R2,R7)
- Current persistence is localStorage-only, single key (R1)
- Zero dynamic routes and no backend code yet — env declared (R4,R5)
- File import exists as "Load Build" but lacks Zod validation (R6)
- MCP-written scenes load cleanly into the editor today (R6, Casa del
Sol test already proved this)
- Best path: filesystem-handoff this week, Supabase in weeks 2-4,
Supabase Realtime for live mode in Q2. Skip Yjs for now. (R8)
- 4-5 weeks to private beta, 10-14 to GA (R9)
- 10 high-value ideas ranked; "photo -> scene" is the unblocker (R10)
SYNTHESIS.md pulls all 10 reports together with the recommended
implementation plan.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds window.__pascalScene = useScene in development builds so that a
running MCP process (which has its own Node-side in-memory store) can
inject a built scene into the browser editor for visual verification:
fetch('/dev/casa-sol.json')
.then(r => r.json())
.then(s => window.__pascalScene.getState().setScene(s.nodes, s.rootNodeIds))
Also ships /public/dev/casa-sol.json as a reference scene — the
artefact exported from the MCP Casa del Sol test build.
Gated behind NODE_ENV !== 'production' so nothing leaks to prod.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Design and live-built a 3-bed 2-bath single-story house with pool and
privacy-screened perimeter ("Casa del Sol") using only @pascal-app/mcp
tools. Exercises every mutation tool in a realistic scenario.
- DESIGN.md: blueprint (lot 20x15, building 12x8, 7 interior zones,
pool 5x3, 5 privacy fence segments)
- build.ts: MCP client orchestrator
- scene.json: full exported scene (26.7 KB)
- BUILD_REPORT.md: per-step status + final totals
Final scene: 39 nodes pre-duplicate (1 site, 1 building, 1 level,
9 walls, 9 zones, 6 doors, 6 windows, 5 fences, 1 slab), 76 nodes
post-duplicate_level, valid=true, errors=0.
Surfaced the documented StreamableHTTP single-session limitation:
the HTTP server at :3917 rejected the SDK client's initialize with
"Server already initialized" because the previous T3 session consumed
the transport's one-shot session slot. Build fell back to an in-memory
transport exercising the identical tool surface. Fix tracked for v0.2.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SceneBridge.applyPatch now threads the Zod-parsed node through to the
apply phase instead of the raw input. Previously, when a caller sent a
create patch without an `id` field, the schema's objectId default ran
during dry-run parsing but only in `res.data`; the apply phase pushed
the unparsed `p.node` (no id) to the store, so subsequent tools that
walked `level.children` crashed on undefined entries (e.g.
duplicate_level -> cloneLevelSubtree -> extractIdPrefix(undefined)).
Also adds test-reports/ artefacts from live end-to-end testing:
- t1-stdio: 21/21 tools pass via stdio (~106ms)
- t2-http: connect/single-session behaviour (HTTP transport quirk
documented)
- t3-scenario: 2-bedroom apartment built end-to-end — 12/12 steps
after this fix (24 final nodes, validate=true, apartment.json
exported)
- t4-errors: 24/24 invalid-input cases rejected with proper MCP errors
- t5-resources-prompts: 4/4 resources, 3/3 prompts, dev server
/api/health 200 OK
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Full PR description summarising the 9-commit series, tool/resource/prompt
inventory, architecture, verification checklist, and follow-ups.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- .github/workflows/mcp-ci.yml: runs on pushes to main and PRs
touching packages/mcp/, packages/core/, or bun.lock. Installs with
Bun 1.3.0, builds core then mcp, runs bun test, and runs biome.
- packages/mcp/CROSS_CUTTING.md: documents the two additive changes
outside the package boundary (core exports map, this CI workflow)
plus observations about SiteNode.children inconsistency.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 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>
- connectStdio(server): wires the MCP server to StdioServerTransport.
- connectHttp(server, port): wires the MCP server to
StreamableHTTPServerTransport over node:http. Returns a handle with
port and close().
- bin/pascal-mcp.ts: CLI entrypoint with --stdio (default), --http,
--port, --scene, --help, --version. Loads node-shims before any
core import. Logs to stderr (stdio transport uses stdout for
JSON-RPC).
- scripts/smoke.ts: end-to-end smoke — spawns the stdio bin, connects
as an MCP Client, exercises get_scene, create_level, validate_scene,
undo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
analyze_floorplan_image and analyze_room_photo defer the vision work
to the host via MCP sampling (server.server.createMessage). Validates
host capability before calling, fetches URL inputs and base64-encodes
them, constrains output to a Zod schema, and returns structured
content. No vision model is bundled.
9 tests, all passing via a mocked sampling-capable client.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resources: pascal://scene/current (JSON), /scene/current/summary
(markdown with per-level counts, floor areas, bbox), /catalog/items
(returns catalog_unavailable in headless mode), and the templated
pascal://constraints/{levelId} which exposes slabs + wall footprints
via @pascal-app/core/wall helpers.
Prompts: from_brief (generate scene from a natural-language brief),
iterate_on_feedback (minimal-diff patch proposals), and
renovation_from_photos (orchestrates the vision tools).
17 tests, all passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SceneBridge class wraps @pascal-app/core's Zustand store for Node,
exposing a clean programmatic API for scene load/mutate/export plus
Zundo undo/redo. Requires a requestAnimationFrame polyfill loaded
before any core import to work around the store's RAF-batched dirty
marking.
- 51 tests, 99.68% line coverage on scene-bridge.ts
- All-or-nothing applyPatch with Zod dry-run validation
- Safeguards against prototype-polluting keys in loadJSON
- Resolves children through the flat nodes dict (handles the
SiteNode.children-as-objects inconsistency)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds packages/mcp/.gitignore, src/index.ts (public API barrel),
src/server.ts (createPascalMcpServer factory), and a smoke test
for the public API.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add packages/mcp/ with package.json, tsconfig, PLAN.md, CROSS_CUTTING.md
- Extend @pascal-app/core exports map with subpaths (./schema, ./store,
./material-library, ./spatial-grid, ./wall) so Node consumers can skip
the graphics-bound systems re-export chain.
- Add scripts/spike.ts that proves useScene + temporal work in Node with
a requestAnimationFrame polyfill. Spike passes end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>