wadi-mcp 0.1.19 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/server.mjs +16 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ repo; this server replaces them for agents that speak MCP.)
|
|
|
20
20
|
| `wadi_examples` | List, or fetch the full source of, a validated example `.wdl` (`minimal` / `two_room` / `two_story` / `coastal` / `complete`). Copy from these. |
|
|
21
21
|
| `wadi_reference` | The authoring docs, embedded: `guide`, `dsl`, `conventions`, `coordinate-system`, `parametric-conventions`, `roof-v2-guide`, `data-model`. |
|
|
22
22
|
| `wadi_view_3d` | Load a `.wdl` into the **running Wadi desktop app's** live 3D view (so you + the user see the same model). Needs the app open. |
|
|
23
|
-
| `wadi_capture_3d` | Render a `.wdl` in the running app and return a **real 3D image** (the textured model). Needs the app open. |
|
|
23
|
+
| `wadi_capture_3d` | Render a `.wdl` in the running app and return a **real 3D image** (the textured model). Choose the shot with `camera` (a named exterior angle: `iso`/`front`/`back`/`left`/`right`/`top`) or `room` (first-person interior); `isolate`/`layers` show-only or toggle layers before the shot (by id or label). The response lists the house's layers so you can refine. Needs the app open. |
|
|
24
24
|
|
|
25
25
|
The last two reach the desktop app over a localhost bridge (`127.0.0.1:8765`, override
|
|
26
26
|
`WADI_APP_PORT`); when the app isn't running they return a "open the Wadi app" message and
|
package/dist/server.mjs
CHANGED
|
@@ -419128,7 +419128,7 @@ async function appCapture(config3, view) {
|
|
|
419128
419128
|
if (!r2.ok) throw new Error(`app /capture returned ${r2.status}`);
|
|
419129
419129
|
const j = await r2.json();
|
|
419130
419130
|
if (!j.ok || !j.png) throw new Error(j.error || "capture failed");
|
|
419131
|
-
return { data: j.png, mime: j.mime || "image/jpeg" };
|
|
419131
|
+
return { data: j.png, mime: j.mime || "image/jpeg", layers: j.layers };
|
|
419132
419132
|
}
|
|
419133
419133
|
var APP_NOT_RUNNING = "The Wadi desktop app isn't running, so live 3D isn't available. Open the Wadi app (it serves the bridge on 127.0.0.1:" + PORT + "), or use `wadi_preview` for headless 2D drawings (plans / elevations / roof).";
|
|
419134
419134
|
|
|
@@ -419234,14 +419234,17 @@ server.registerTool(
|
|
|
419234
419234
|
"wadi_capture_3d",
|
|
419235
419235
|
{
|
|
419236
419236
|
title: "Capture a 3D image of a Wadi design",
|
|
419237
|
-
description: 'Render a Wadi DSL house in the RUNNING Wadi desktop app and return a real 3D PNG \u2014 the actual textured model, not a 2D drawing. Requires the Wadi app to be open
|
|
419237
|
+
description: 'Render a Wadi DSL house in the RUNNING Wadi desktop app and return a real 3D PNG \u2014 the actual textured model, not a 2D drawing. Requires the Wadi app to be open.\nCAMERA: pass `room` (a room name, e.g. "Bedroom") for a first-person INTERIOR look (best for checking furniture placement/orientation), OR `camera` for a named EXTERIOR angle (iso | front | back | left | right | top). Omit both for the current outside orbit.\nLAYERS: pass `isolate` (a list of layer ids/labels) to show ONLY those, or `layers` (a map of id/label \u2192 on/off) to toggle specific ones \u2014 e.g. isolate the structure to shoot the frame, or hide the roof to see the plan of walls. The response lists every available layer (id + label) so you can refine a follow-up shot. Layer changes are restored after the capture.\nThe PNG is BOTH returned inline AND written to a file whose path is in the text. (Headless 2D plans/elevations/roof: wadi_preview.)',
|
|
419238
419238
|
inputSchema: {
|
|
419239
419239
|
wdl: external_exports.string().describe("The full .wdl source text."),
|
|
419240
|
-
room: external_exports.string().optional().describe("A room name (as written in the .wdl) to view from
|
|
419240
|
+
room: external_exports.string().optional().describe("A room name (as written in the .wdl) to view from INSIDE (first-person). Takes precedence over `camera`."),
|
|
419241
|
+
camera: external_exports.enum(["iso", "front", "back", "left", "right", "top"]).optional().describe("A named EXTERIOR camera angle. Ignored if `room` is given. Omit for the current outside orbit."),
|
|
419242
|
+
isolate: external_exports.array(external_exports.string()).optional().describe("Show ONLY these layers (ids or labels, case-insensitive); hide all others. See the returned layer list."),
|
|
419243
|
+
layers: external_exports.record(external_exports.string(), external_exports.boolean()).optional().describe('Toggle specific layers by id or label, e.g. { "Roof": false, "Structure": true }.'),
|
|
419241
419244
|
out_dir: external_exports.string().optional().describe("Absolute directory to save the PNG to. Default: the OS temp dir. The saved path is returned in the text.")
|
|
419242
419245
|
}
|
|
419243
419246
|
},
|
|
419244
|
-
async ({ wdl, room: room3, out_dir }) => {
|
|
419247
|
+
async ({ wdl, room: room3, camera, isolate, layers, out_dir }) => {
|
|
419245
419248
|
let config3;
|
|
419246
419249
|
try {
|
|
419247
419250
|
config3 = compileConfig(wdl);
|
|
@@ -419250,12 +419253,17 @@ server.registerTool(
|
|
|
419250
419253
|
}
|
|
419251
419254
|
if (!await appReachable()) return { content: [{ type: "text", text: APP_NOT_RUNNING }] };
|
|
419252
419255
|
try {
|
|
419253
|
-
const
|
|
419254
|
-
const
|
|
419255
|
-
const
|
|
419256
|
+
const view = { room: room3, camera, isolate, layers };
|
|
419257
|
+
const hasView = room3 || camera || isolate?.length || layers && Object.keys(layers).length;
|
|
419258
|
+
const img = await appCapture(config3, hasView ? view : void 0);
|
|
419259
|
+
const slug = room3 ? `wadi_3d_${room3.replace(/\W+/g, "_")}` : camera ? `wadi_3d_${camera}` : "wadi_3d";
|
|
419260
|
+
const file2 = savePng(Buffer.from(img.data, "base64"), out_dir, `${slug}.png`);
|
|
419261
|
+
const label = room3 ? `3D interior view of "${room3}"` : camera ? `3D exterior view (${camera})` : "3D view (outside orbit)";
|
|
419262
|
+
const shown = isolate?.length ? ` \xB7 showing only: ${isolate.join(", ")}` : "";
|
|
419263
|
+
const layerList = img.layers?.length ? "\nAvailable layers (id \u2014 label): " + img.layers.map((l) => `${l.id} \u2014 ${l.label}`).join(" \xB7 ") + "\nPass `isolate` or `layers` (id or label) to control what's visible." : "";
|
|
419256
419264
|
return {
|
|
419257
419265
|
content: [
|
|
419258
|
-
{ type: "text", text: `\u2014 ${label} \u2014 saved to: ${file2}` },
|
|
419266
|
+
{ type: "text", text: `\u2014 ${label}${shown} (from the live app) \u2014 saved to: ${file2}${layerList}` },
|
|
419259
419267
|
{ type: "image", data: img.data, mimeType: img.mime }
|
|
419260
419268
|
]
|
|
419261
419269
|
};
|