@instruktlabs/kiln 1.0.0 → 1.2.0

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.
Files changed (92) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/CHANGELOG.md +60 -3
  5. package/CONTRIBUTING.md +16 -7
  6. package/README.md +95 -381
  7. package/dist/agent-run.mjs +220 -150
  8. package/dist/build.json +40 -28
  9. package/dist/cli.mjs +242 -163
  10. package/dist/mcp-engine.mjs +412 -154
  11. package/dist/mcp-server.mjs +1 -1
  12. package/docs/architecture.md +6 -3
  13. package/docs/chatgpt.md +20 -5
  14. package/docs/examples.md +40 -170
  15. package/docs/install.md +100 -35
  16. package/docs/migration.md +20 -0
  17. package/docs/sdk.md +49 -5
  18. package/docs/tools-operations.md +1529 -0
  19. package/lib/asset-widget-uri.d.ts +9 -0
  20. package/lib/asset-widget-uri.js +9 -0
  21. package/lib/cli-render-mode.js +10 -3
  22. package/lib/discovery/index.d.ts +1 -1
  23. package/lib/discovery/index.js +2 -2
  24. package/lib/discovery/portable.d.ts +9 -0
  25. package/lib/discovery/portable.js +6 -0
  26. package/lib/discovery/service.d.ts +3 -1
  27. package/lib/discovery/service.js +4 -2
  28. package/lib/engine-identity.d.ts +1 -1
  29. package/lib/engine-identity.js +1 -1
  30. package/lib/evaluator/isolation.js +19 -5
  31. package/lib/evaluator/probe-invariants.d.ts +11 -0
  32. package/lib/evaluator/probe-invariants.js +36 -0
  33. package/lib/evaluator/probe-worker.js +16 -4
  34. package/lib/loopback.d.ts +6 -0
  35. package/lib/loopback.js +6 -0
  36. package/lib/mcp-core.d.ts +210 -0
  37. package/lib/mcp-core.js +279 -0
  38. package/lib/mcp-engine.d.ts +59 -0
  39. package/lib/mcp-engine.js +289 -0
  40. package/lib/mcp-manifest.d.ts +15 -0
  41. package/lib/mcp-manifest.js +65 -0
  42. package/lib/mcp.d.ts +5 -0
  43. package/lib/mcp.js +2 -0
  44. package/lib/render-service-host.js +1 -1
  45. package/lib/tools/discovery.d.ts +1 -1
  46. package/lib/tools/discovery.js +11 -9
  47. package/lib/tools/materials.d.ts +1 -1
  48. package/lib/tools/materials.js +44 -14
  49. package/lib/tools/operation-contract.d.ts +8 -0
  50. package/lib/tools/operation-contract.js +37 -0
  51. package/lib/tools/operations.d.ts +3 -0
  52. package/lib/tools/operations.js +154 -0
  53. package/lib/tools/registry.d.ts +6 -2
  54. package/lib/tools/registry.js +71 -23
  55. package/package.json +23 -1
  56. package/plugin.json +1 -1
  57. package/plugins/kiln-engine/.claude-plugin/icon.png +0 -0
  58. package/plugins/kiln-engine/.claude-plugin/plugin.json +9 -3
  59. package/plugins/kiln-engine/PRIVACY.md +100 -0
  60. package/plugins/kiln-engine/README.md +103 -18
  61. package/plugins/kiln-engine/{scripts/setup-workspace.mjs → bin/kiln-setup-workspace.mjs} +37 -9
  62. package/plugins/kiln-engine/package-provenance.json +15 -8
  63. package/plugins/kiln-engine/plugin.json +10 -4
  64. package/plugins/kiln-engine/runtime.json +10 -1
  65. package/plugins/kiln-engine/skills/kiln-setup-workspace/SKILL.md +17 -18
  66. package/plugins/kiln-engine/skills/kiln-setup-workspace/references/plugin-install.md +28 -8
  67. package/plugins/kiln-engine/skills/kiln-setup-workspace/references/renderer-setup.md +11 -0
  68. package/scripts/create-workspace.mjs +71 -13
  69. package/scripts/workspace-config.mjs +239 -0
  70. package/scripts/workspace-project.mjs +384 -0
  71. package/scripts/workspace-transaction.mjs +504 -0
  72. package/skills/kiln-setup-workspace/SKILL.md +17 -18
  73. package/skills/kiln-setup-workspace/references/plugin-install.md +28 -8
  74. package/skills/kiln-setup-workspace/references/renderer-setup.md +11 -0
  75. package/src/cli-render-mode.ts +9 -9
  76. package/src/cli.ts +3 -3
  77. package/src/discovery/index.ts +2 -0
  78. package/src/discovery/portable.ts +9 -0
  79. package/src/discovery/service.ts +3 -1
  80. package/src/engine-identity.ts +1 -1
  81. package/src/evaluator/isolation.ts +27 -6
  82. package/src/evaluator/probe-invariants.ts +50 -0
  83. package/src/evaluator/probe-worker.ts +22 -4
  84. package/src/mcp-core.ts +3 -0
  85. package/src/mcp-engine.ts +11 -1
  86. package/src/mcp.ts +5 -0
  87. package/src/render-service-host.ts +1 -1
  88. package/src/tools/discovery.ts +20 -10
  89. package/src/tools/materials.ts +59 -15
  90. package/src/tools/operation-contract.ts +51 -0
  91. package/src/tools/operations.ts +177 -0
  92. package/src/tools/registry.ts +100 -20
@@ -0,0 +1,1529 @@
1
+ # Named operation reference
2
+
3
+ Available in package version 1.2.0 and later. Generated with `bun run docs:tools` from the same engine registry as the default [local tools](tools.md). This profile supplies asset and material storage without project/review or renderer-control callbacks. Other host capabilities can change the tool list; connected tools/list is authoritative. See the [embedding contract](sdk.md#named-operation-presentation).
4
+
5
+ Select this presentation explicitly with `createKilnMcpServer(context, { toolPresentation: "operations" })`. Existing local tool names and actions remain the default. Host authentication, request quotas, isolation and persistence policy are outside this engine reference.
6
+
7
+ Use kiln_discover for helper contracts and complete shape: records; kiln_capabilities reports configuration, not proof of successful rendering. Material creation requires a typed definition. Search results preserve collection, asset/material and revision identity. Saving remains an explicit decision.
8
+
9
+ ## kiln_discover
10
+
11
+ Discover geometry helpers, assemblies, recipes and complete input shapes. Search with modeling language or fetch up to six exact IDs. Use kiln_capabilities for current host facts.
12
+
13
+ <details>
14
+ <summary>Input JSON Schema</summary>
15
+
16
+
17
+ ```json
18
+ {
19
+ "type": "object",
20
+ "properties": {
21
+ "query": {
22
+ "type": "string",
23
+ "minLength": 1,
24
+ "maxLength": 500
25
+ },
26
+ "ids": {
27
+ "minItems": 1,
28
+ "maxItems": 6,
29
+ "type": "array",
30
+ "items": {
31
+ "type": "string",
32
+ "minLength": 1,
33
+ "maxLength": 120
34
+ }
35
+ },
36
+ "overview": {
37
+ "type": "boolean",
38
+ "const": true
39
+ },
40
+ "family": {
41
+ "type": "string",
42
+ "minLength": 1,
43
+ "maxLength": 120
44
+ },
45
+ "kind": {
46
+ "type": "string",
47
+ "enum": [
48
+ "operation",
49
+ "assembly",
50
+ "recipe",
51
+ "shape"
52
+ ]
53
+ },
54
+ "tags": {
55
+ "minItems": 1,
56
+ "maxItems": 8,
57
+ "type": "array",
58
+ "items": {
59
+ "type": "string",
60
+ "minLength": 1,
61
+ "maxLength": 120
62
+ }
63
+ },
64
+ "offset": {
65
+ "type": "integer",
66
+ "minimum": 0,
67
+ "maximum": 10000
68
+ },
69
+ "limit": {
70
+ "type": "integer",
71
+ "minimum": 1,
72
+ "maximum": 12
73
+ }
74
+ },
75
+ "additionalProperties": false
76
+ }
77
+ ```
78
+
79
+ </details>
80
+
81
+ ## kiln_capabilities
82
+
83
+ Inspect declared host capabilities, execution limits and available storage. Observed rendering fidelity is returned by each render.
84
+
85
+ <details>
86
+ <summary>Input JSON Schema</summary>
87
+
88
+
89
+ ```json
90
+ {
91
+ "type": "object",
92
+ "properties": {},
93
+ "additionalProperties": false
94
+ }
95
+ ```
96
+
97
+ </details>
98
+
99
+ ## kiln_validate
100
+
101
+ Check program syntax, sandbox rules and retired globals before building. Returns findings with codes, lines and repair hints where available; use kiln_render to evaluate geometry and see the asset. Supply code OR programRef (kept in this process until it ends). Invalid drafts keep a ref.
102
+
103
+ <details>
104
+ <summary>Input JSON Schema</summary>
105
+
106
+
107
+ ```json
108
+ {
109
+ "type": "object",
110
+ "properties": {
111
+ "code": {
112
+ "description": "New source.",
113
+ "type": "string"
114
+ },
115
+ "programRef": {
116
+ "type": "string",
117
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
118
+ "description": "Returned p_ handle or full sha256 ref."
119
+ }
120
+ }
121
+ }
122
+ ```
123
+
124
+ </details>
125
+
126
+ ## kiln_render
127
+
128
+ Build and return metrics, part paths and images. If partsTruncated, use kiln_inspect listParts. Omit capture for six views, preset/cells for orbit grids, or kiln.capture.v1/v2 shots for exact orthographic/perspective cameras; v2 adds hide. Check viewFidelity before judging materials. Failed builds return errors without images. Supply code OR programRef (kept in this process until it ends). Invalid drafts keep a ref.
129
+
130
+ <details>
131
+ <summary>Input JSON Schema</summary>
132
+
133
+
134
+ ```json
135
+ {
136
+ "type": "object",
137
+ "properties": {
138
+ "code": {
139
+ "description": "New source.",
140
+ "type": "string"
141
+ },
142
+ "capture": {
143
+ "description": "Omit for six views; preset/cells for orbit sheets. Use kiln.capture.v1 or v2 with 1..9 shots for exact cameras. v2 adds hide: exact paths or unique names. Framing retains subject bounds.",
144
+ "anyOf": [
145
+ {
146
+ "type": "object",
147
+ "properties": {
148
+ "version": {
149
+ "type": "string",
150
+ "enum": [
151
+ "kiln.capture.v1",
152
+ "kiln.capture.v2"
153
+ ]
154
+ },
155
+ "shots": {
156
+ "minItems": 1,
157
+ "maxItems": 9,
158
+ "type": "array",
159
+ "items": {
160
+ "type": "object",
161
+ "properties": {
162
+ "name": {
163
+ "type": "string"
164
+ },
165
+ "subject": {
166
+ "type": "object",
167
+ "properties": {
168
+ "path": {
169
+ "type": "string"
170
+ },
171
+ "name": {
172
+ "type": "string"
173
+ }
174
+ },
175
+ "additionalProperties": false
176
+ },
177
+ "visibility": {
178
+ "type": "string",
179
+ "enum": [
180
+ "context",
181
+ "isolate"
182
+ ]
183
+ },
184
+ "hide": {
185
+ "maxItems": 64,
186
+ "type": "array",
187
+ "items": {
188
+ "type": "string",
189
+ "minLength": 1,
190
+ "maxLength": 1024
191
+ }
192
+ },
193
+ "camera": {
194
+ "oneOf": [
195
+ {
196
+ "type": "object",
197
+ "properties": {
198
+ "type": {
199
+ "type": "string",
200
+ "const": "orbit"
201
+ },
202
+ "azimuthDeg": {
203
+ "type": "number"
204
+ },
205
+ "elevationDeg": {
206
+ "type": "number"
207
+ },
208
+ "relativeTo": {
209
+ "type": "string",
210
+ "enum": [
211
+ "world",
212
+ "asset",
213
+ "part"
214
+ ]
215
+ },
216
+ "padding": {
217
+ "type": "number",
218
+ "exclusiveMinimum": 0,
219
+ "maximum": 100
220
+ }
221
+ },
222
+ "required": [
223
+ "type"
224
+ ],
225
+ "additionalProperties": false
226
+ },
227
+ {
228
+ "type": "object",
229
+ "properties": {
230
+ "type": {
231
+ "type": "string",
232
+ "const": "explicit"
233
+ },
234
+ "projection": {
235
+ "type": "string",
236
+ "enum": [
237
+ "orthographic",
238
+ "perspective"
239
+ ]
240
+ },
241
+ "position": {
242
+ "minItems": 3,
243
+ "maxItems": 3,
244
+ "type": "array",
245
+ "items": {
246
+ "type": "number"
247
+ }
248
+ },
249
+ "target": {
250
+ "minItems": 3,
251
+ "maxItems": 3,
252
+ "type": "array",
253
+ "items": {
254
+ "type": "number"
255
+ }
256
+ },
257
+ "relativeTo": {
258
+ "type": "string",
259
+ "enum": [
260
+ "world",
261
+ "asset",
262
+ "part",
263
+ "local"
264
+ ]
265
+ },
266
+ "frame": {
267
+ "type": "object",
268
+ "properties": {
269
+ "origin": {
270
+ "minItems": 3,
271
+ "maxItems": 3,
272
+ "type": "array",
273
+ "items": {
274
+ "type": "number"
275
+ }
276
+ },
277
+ "rotation": {
278
+ "minItems": 3,
279
+ "maxItems": 3,
280
+ "type": "array",
281
+ "items": {
282
+ "type": "number"
283
+ }
284
+ }
285
+ },
286
+ "additionalProperties": false
287
+ },
288
+ "framing": {
289
+ "type": "string",
290
+ "enum": [
291
+ "explicit",
292
+ "bounds"
293
+ ]
294
+ },
295
+ "padding": {
296
+ "type": "number",
297
+ "exclusiveMinimum": 0,
298
+ "maximum": 100
299
+ },
300
+ "targetOffset": {
301
+ "minItems": 3,
302
+ "maxItems": 3,
303
+ "type": "array",
304
+ "items": {
305
+ "type": "number"
306
+ }
307
+ },
308
+ "up": {
309
+ "minItems": 3,
310
+ "maxItems": 3,
311
+ "type": "array",
312
+ "items": {
313
+ "type": "number"
314
+ }
315
+ },
316
+ "halfHeight": {
317
+ "type": "number",
318
+ "exclusiveMinimum": 0
319
+ },
320
+ "fovDeg": {
321
+ "type": "number",
322
+ "exclusiveMinimum": 0,
323
+ "exclusiveMaximum": 180
324
+ },
325
+ "near": {
326
+ "type": "number",
327
+ "exclusiveMinimum": 0
328
+ },
329
+ "far": {
330
+ "type": "number",
331
+ "exclusiveMinimum": 0
332
+ }
333
+ },
334
+ "required": [
335
+ "type",
336
+ "projection",
337
+ "position"
338
+ ],
339
+ "additionalProperties": false
340
+ }
341
+ ]
342
+ }
343
+ },
344
+ "additionalProperties": false
345
+ }
346
+ },
347
+ "cols": {
348
+ "type": "integer",
349
+ "minimum": 1,
350
+ "maximum": 3
351
+ },
352
+ "size": {
353
+ "type": "integer",
354
+ "minimum": 128,
355
+ "maximum": 2048
356
+ },
357
+ "output": {
358
+ "type": "string",
359
+ "enum": [
360
+ "grid",
361
+ "separate"
362
+ ]
363
+ },
364
+ "backdrop": {
365
+ "description": "neutral (default); light for dark parts, dark for light parts.",
366
+ "type": "string",
367
+ "enum": [
368
+ "neutral",
369
+ "dark",
370
+ "light"
371
+ ]
372
+ }
373
+ },
374
+ "required": [
375
+ "version",
376
+ "shots"
377
+ ],
378
+ "additionalProperties": false
379
+ },
380
+ {
381
+ "type": "object",
382
+ "properties": {
383
+ "preset": {
384
+ "description": "COLSxROWS; default 3x2. Fewer views for simple shapes, up to 3x3.",
385
+ "type": "string",
386
+ "enum": [
387
+ "1x1",
388
+ "1x2",
389
+ "2x1",
390
+ "3x1",
391
+ "2x2",
392
+ "3x2",
393
+ "3x3"
394
+ ]
395
+ },
396
+ "cells": {
397
+ "description": "Row-major cameras; omit for preset defaults. Count cannot exceed preset capacity (max 9).",
398
+ "type": "array",
399
+ "items": {
400
+ "type": "object",
401
+ "properties": {
402
+ "azimuthDeg": {
403
+ "type": "number",
404
+ "description": "0 = front, 90 = right, 180 = back, 270 = left. Wraps."
405
+ },
406
+ "elevationDeg": {
407
+ "type": "number",
408
+ "description": "0 eye level; positive above, negative below. Clamped -89..89."
409
+ },
410
+ "zoom": {
411
+ "description": "Bounds padding: below 1 crops, above 1 pulls back; omit for auto-framing.",
412
+ "type": "number"
413
+ },
414
+ "name": {
415
+ "description": "Label; defaults to angles.",
416
+ "type": "string"
417
+ }
418
+ },
419
+ "required": [
420
+ "azimuthDeg",
421
+ "elevationDeg"
422
+ ]
423
+ }
424
+ },
425
+ "backdrop": {
426
+ "description": "neutral (default); light for dark parts, dark for light parts.",
427
+ "type": "string",
428
+ "enum": [
429
+ "neutral",
430
+ "dark",
431
+ "light"
432
+ ]
433
+ }
434
+ },
435
+ "additionalProperties": false
436
+ }
437
+ ]
438
+ },
439
+ "detail": {
440
+ "description": "compact (default) groups findings by code; lean: verdict, blockers, metrics only; full: every finding, rule and part plus the retained report path",
441
+ "type": "string",
442
+ "enum": [
443
+ "lean",
444
+ "compact",
445
+ "full"
446
+ ]
447
+ },
448
+ "programRef": {
449
+ "type": "string",
450
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
451
+ "description": "Returned p_ handle or full sha256 ref."
452
+ }
453
+ }
454
+ }
455
+ ```
456
+
457
+ </details>
458
+
459
+ ## kiln_screenshot_animation
460
+
461
+ Review animation images, poseBounds and loopClosure endpoint evidence. loopIntent is createClip({loop}); open is valid for one-shots; closed endpoints do not prove smooth velocity. Check motion, attachments and requested clearance; sampled bounds do not certify continuous contact or collision safety. Use shot for camera/subject, frameTimes for phases, and framing locked (default) or follow. Add phases when symmetry hides motion. The program must define animate(). Check viewFidelity before judging materials. Supply code OR programRef (kept in this process until it ends). Invalid drafts keep a ref.
462
+
463
+ <details>
464
+ <summary>Input JSON Schema</summary>
465
+
466
+
467
+ ```json
468
+ {
469
+ "type": "object",
470
+ "properties": {
471
+ "shot": {
472
+ "description": "One exact camera shot. Shape: kiln_discover ids [\"shape:camera-shot\"].",
473
+ "type": "object",
474
+ "propertyNames": {
475
+ "type": "string"
476
+ },
477
+ "additionalProperties": {}
478
+ },
479
+ "measureParts": {
480
+ "description": "Exact names or paths of subtrees measured together at each phase, independent of camera selection.",
481
+ "minItems": 1,
482
+ "maxItems": 16,
483
+ "type": "array",
484
+ "items": {
485
+ "type": "object",
486
+ "properties": {
487
+ "path": {
488
+ "type": "string"
489
+ },
490
+ "name": {
491
+ "type": "string"
492
+ }
493
+ },
494
+ "additionalProperties": false
495
+ }
496
+ },
497
+ "frames": {
498
+ "type": "integer",
499
+ "minimum": 2,
500
+ "maximum": 6
501
+ },
502
+ "frameTimes": {
503
+ "description": "Ordered phase fractions 0..1; mutually exclusive with frames.",
504
+ "minItems": 1,
505
+ "maxItems": 9,
506
+ "type": "array",
507
+ "items": {
508
+ "type": "number",
509
+ "minimum": 0,
510
+ "maximum": 1
511
+ }
512
+ },
513
+ "framing": {
514
+ "type": "string",
515
+ "enum": [
516
+ "locked",
517
+ "follow"
518
+ ]
519
+ },
520
+ "size": {
521
+ "description": "Frame size in px; default 256.",
522
+ "type": "integer",
523
+ "minimum": 128,
524
+ "maximum": 1024
525
+ },
526
+ "detail": {
527
+ "description": "compact (default) groups findings by code; lean: verdict, blockers, metrics only; full: every finding, rule and part plus the retained report path",
528
+ "type": "string",
529
+ "enum": [
530
+ "lean",
531
+ "compact",
532
+ "full"
533
+ ]
534
+ },
535
+ "code": {
536
+ "description": "New source.",
537
+ "type": "string"
538
+ },
539
+ "clip": {
540
+ "type": "string",
541
+ "description": "The animation clip to view, by name (e.g. \"walk\", \"attack\"). Must be one your animate() returns."
542
+ },
543
+ "camera": {
544
+ "description": "Camera angle: right (default — side profile, best for leg swing + knee bend direction), front (reveals sideways/lateral motion), back, left, top, or three-quarter.",
545
+ "type": "string"
546
+ },
547
+ "perFrame": {
548
+ "description": "Return the frames as separate high-res images instead of one composite grid. Default false.",
549
+ "type": "boolean"
550
+ },
551
+ "programRef": {
552
+ "type": "string",
553
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
554
+ "description": "Returned p_ handle or full sha256 ref."
555
+ }
556
+ },
557
+ "required": [
558
+ "clip"
559
+ ]
560
+ }
561
+ ```
562
+
563
+ </details>
564
+
565
+ ## kiln_view_interior
566
+
567
+ Render roof-off floor-plan, dollhouse, and eye-level cutaway views. Optional versioned capture selects custom roof-off shots. Select a roof by nodeName or let Kiln resolve its role/name. Review roofsHidden and warnings for unresolved occlusion. Supply code OR programRef (kept in this process until it ends). Invalid drafts keep a ref.
568
+
569
+ <details>
570
+ <summary>Input JSON Schema</summary>
571
+
572
+
573
+ ```json
574
+ {
575
+ "type": "object",
576
+ "properties": {
577
+ "capture": {
578
+ "description": "Cameras, as kiln_render capture takes them. Shape: kiln_discover ids [\"shape:capture\"].",
579
+ "type": "object",
580
+ "propertyNames": {
581
+ "type": "string"
582
+ },
583
+ "additionalProperties": {}
584
+ },
585
+ "code": {
586
+ "description": "New source.",
587
+ "type": "string"
588
+ },
589
+ "nodeName": {
590
+ "description": "Override: lift the roof by exact node name instead of by role. Matches that node and its children. Normally OMIT it — Kiln finds the roof from its semantic role (anything built with createRoofPlanes/createGableRoof), falling back to historical \"Roof\" naming.",
591
+ "type": "string"
592
+ },
593
+ "programRef": {
594
+ "type": "string",
595
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
596
+ "description": "Returned p_ handle or full sha256 ref."
597
+ }
598
+ }
599
+ }
600
+ ```
601
+
602
+ </details>
603
+
604
+ ## kiln_inspect
605
+
606
+ List part paths and inspect joints, clearances and edit preservation. listParts filters names/paths with query; follow partListing.nextOffset on the same programRef/query. measure/surfacePairs return distances, not fit certificates. compare reports static changes and separate animation channel changes; paths adds complete static subtree summaries. image:false skips rendering. Otherwise use part/orbit or exact shot; check viewFidelity for materials. Supply code OR programRef (kept in this process until it ends). Invalid drafts keep a ref.
607
+
608
+ <details>
609
+ <summary>Input JSON Schema</summary>
610
+
611
+
612
+ ```json
613
+ {
614
+ "type": "object",
615
+ "properties": {
616
+ "image": {
617
+ "description": "False: requires listParts/measure/surfacePairs/compare; no image or camera controls. Default true.",
618
+ "type": "boolean"
619
+ },
620
+ "detail": {
621
+ "description": "compact (default) groups findings by code; lean: verdict, blockers, metrics only; full: every finding, rule and part plus the retained report path",
622
+ "type": "string",
623
+ "enum": [
624
+ "lean",
625
+ "compact",
626
+ "full"
627
+ ]
628
+ },
629
+ "listParts": {
630
+ "description": "List exported-scene paths, including nested parts. Default 80, max 100 per page. Follow partListing.nextOffset with the same programRef/query. image:false avoids rendering.",
631
+ "type": "object",
632
+ "properties": {
633
+ "query": {
634
+ "description": "Case-insensitive substring of name or exact encoded path; not a regex.",
635
+ "type": "string",
636
+ "maxLength": 4096
637
+ },
638
+ "offset": {
639
+ "type": "integer",
640
+ "minimum": 0,
641
+ "maximum": 9007199254740991
642
+ },
643
+ "limit": {
644
+ "type": "integer",
645
+ "minimum": 1,
646
+ "maximum": 100
647
+ },
648
+ "placement": {
649
+ "description": "Add world position, rotation, scale, mirroring and bounds per part; pages of 50.",
650
+ "type": "boolean"
651
+ }
652
+ },
653
+ "additionalProperties": false
654
+ },
655
+ "surfacePairs": {
656
+ "description": "[from,to] pairs of exact listParts paths or unambiguous node names; check surfaceMeasurements.status and each result.",
657
+ "minItems": 1,
658
+ "maxItems": 12,
659
+ "type": "array",
660
+ "items": {
661
+ "minItems": 2,
662
+ "maxItems": 2,
663
+ "type": "array",
664
+ "items": {
665
+ "type": "string",
666
+ "maxLength": 4096
667
+ }
668
+ }
669
+ },
670
+ "compare": {
671
+ "description": "Static geometry/material/transform/bounds under current host settings. Follow nextOffset; paths adds complete subtrees.",
672
+ "type": "object",
673
+ "properties": {
674
+ "programRef": {
675
+ "type": "string",
676
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])"
677
+ },
678
+ "offset": {
679
+ "type": "integer",
680
+ "minimum": 0,
681
+ "maximum": 9007199254740991
682
+ },
683
+ "limit": {
684
+ "type": "integer",
685
+ "minimum": 1,
686
+ "maximum": 100
687
+ },
688
+ "paths": {
689
+ "description": "Exact baseline node paths, scene-prefixed without primitive children. Complete subtree summaries.",
690
+ "minItems": 1,
691
+ "maxItems": 12,
692
+ "type": "array",
693
+ "items": {
694
+ "type": "string",
695
+ "maxLength": 4096
696
+ }
697
+ }
698
+ },
699
+ "required": [
700
+ "programRef"
701
+ ],
702
+ "additionalProperties": false
703
+ },
704
+ "measure": {
705
+ "description": "Default anchors: origin/local-point distance. Surface: disjoint mesh triangles, omit points. Rest pose, asset units. Check status/bounds; no solid clearance/attachment proof.",
706
+ "type": "object",
707
+ "properties": {
708
+ "mode": {
709
+ "type": "string",
710
+ "enum": [
711
+ "anchors",
712
+ "surface"
713
+ ]
714
+ },
715
+ "from": {
716
+ "type": "object",
717
+ "properties": {
718
+ "subject": {
719
+ "type": "object",
720
+ "properties": {
721
+ "path": {
722
+ "type": "string"
723
+ },
724
+ "name": {
725
+ "type": "string"
726
+ }
727
+ },
728
+ "additionalProperties": false
729
+ },
730
+ "point": {
731
+ "minItems": 3,
732
+ "maxItems": 3,
733
+ "type": "array",
734
+ "items": {
735
+ "type": "number"
736
+ }
737
+ }
738
+ },
739
+ "required": [
740
+ "subject"
741
+ ],
742
+ "additionalProperties": false
743
+ },
744
+ "to": {
745
+ "type": "object",
746
+ "properties": {
747
+ "subject": {
748
+ "type": "object",
749
+ "properties": {
750
+ "path": {
751
+ "type": "string"
752
+ },
753
+ "name": {
754
+ "type": "string"
755
+ }
756
+ },
757
+ "additionalProperties": false
758
+ },
759
+ "point": {
760
+ "minItems": 3,
761
+ "maxItems": 3,
762
+ "type": "array",
763
+ "items": {
764
+ "type": "number"
765
+ }
766
+ }
767
+ },
768
+ "required": [
769
+ "subject"
770
+ ],
771
+ "additionalProperties": false
772
+ }
773
+ },
774
+ "required": [
775
+ "from",
776
+ "to"
777
+ ],
778
+ "additionalProperties": false
779
+ },
780
+ "shot": {
781
+ "description": "One exact camera shot. Shape: kiln_discover ids [\"shape:camera-shot\"].",
782
+ "type": "object",
783
+ "propertyNames": {
784
+ "type": "string"
785
+ },
786
+ "additionalProperties": {}
787
+ },
788
+ "code": {
789
+ "description": "New source.",
790
+ "type": "string"
791
+ },
792
+ "part": {
793
+ "description": "Frame named part and descendants (case-insensitive, substring fallback). Omit for whole asset.",
794
+ "type": "string"
795
+ },
796
+ "view": {
797
+ "description": "front/right/back/left/top/three-quarter (default). Orbit angles override.",
798
+ "type": "string"
799
+ },
800
+ "azimuthDeg": {
801
+ "description": "Orbit degrees: 0 front, 90 right, 180 back, 270 left. Wraps.",
802
+ "type": "number"
803
+ },
804
+ "elevationDeg": {
805
+ "description": "Elevation degrees: 0 eye level, positive above. Clamped -89..89.",
806
+ "type": "number"
807
+ },
808
+ "zoom": {
809
+ "description": "Bounds padding 1..4; default 1.2. Larger = more context.",
810
+ "type": "number"
811
+ },
812
+ "isolate": {
813
+ "description": "Hide surrounding geometry. Requires part; default false.",
814
+ "type": "boolean"
815
+ },
816
+ "programRef": {
817
+ "type": "string",
818
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
819
+ "description": "Returned p_ handle or full sha256 ref."
820
+ }
821
+ }
822
+ }
823
+ ```
824
+
825
+ </details>
826
+
827
+ ## kiln_edit
828
+
829
+ Atomically apply ordered exact-string replacements and render. Copy anchors from kiln_source. Supply code OR programRef. Returns programRef (kept in this process until it ends), parentRef, diff and preservation comparing static data and animation channels. Review changes; use kiln_inspect compare for more pages or protected subtrees. Failed comparison preserves the repair; render:false leaves preservation not_assessed. capture selects cameras; includeCode adds the patched source, bounded.
830
+
831
+ <details>
832
+ <summary>Input JSON Schema</summary>
833
+
834
+
835
+ ```json
836
+ {
837
+ "type": "object",
838
+ "properties": {
839
+ "code": {
840
+ "description": "New source.",
841
+ "type": "string"
842
+ },
843
+ "edits": {
844
+ "minItems": 1,
845
+ "maxItems": 20,
846
+ "type": "array",
847
+ "items": {
848
+ "type": "object",
849
+ "properties": {
850
+ "oldString": {
851
+ "type": "string",
852
+ "description": "The exact text to replace, copied verbatim from the program (including whitespace and indentation, and with no line-number prefixes). Must be unique unless replaceAll is true."
853
+ },
854
+ "newString": {
855
+ "type": "string",
856
+ "description": "The replacement text. Use an empty string to delete."
857
+ },
858
+ "replaceAll": {
859
+ "description": "Replace every occurrence instead of failing when oldString matches more than once.",
860
+ "type": "boolean"
861
+ }
862
+ },
863
+ "required": [
864
+ "oldString",
865
+ "newString"
866
+ ]
867
+ },
868
+ "description": "Edits applied in order against the program. If any one fails to match, none are applied and the reply says which. Batch related changes into a single call."
869
+ },
870
+ "render": {
871
+ "description": "Render the patched program and return the views (default true). false = patch only.",
872
+ "type": "boolean"
873
+ },
874
+ "capture": {
875
+ "description": "Cameras, as kiln_render capture takes them. Shape: kiln_discover ids [\"shape:capture\"].",
876
+ "type": "object",
877
+ "propertyNames": {
878
+ "type": "string"
879
+ },
880
+ "additionalProperties": {}
881
+ },
882
+ "detail": {
883
+ "description": "compact (default) groups findings by code; lean: verdict, blockers, metrics only; full: every finding, rule and part plus the retained report path",
884
+ "type": "string",
885
+ "enum": [
886
+ "lean",
887
+ "compact",
888
+ "full"
889
+ ]
890
+ },
891
+ "programRef": {
892
+ "type": "string",
893
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
894
+ "description": "Returned p_ handle or full sha256 ref."
895
+ },
896
+ "includeCode": {
897
+ "description": "Also return the patched source, bounded with the result; kiln_source pages it. Default false.",
898
+ "type": "boolean"
899
+ }
900
+ },
901
+ "required": [
902
+ "edits"
903
+ ]
904
+ }
905
+ ```
906
+
907
+ </details>
908
+
909
+ ## kiln_source
910
+
911
+ Read a saved program revision without changing it. Returns exact source text in bounded pages, or searches for literal text with surrounding context. Copy edit anchors from code. Follow nextOffset for more; use matchOffset + 1 to find the next match. Offsets count UTF-16 characters, not bytes.
912
+
913
+ <details>
914
+ <summary>Input JSON Schema</summary>
915
+
916
+
917
+ ```json
918
+ {
919
+ "type": "object",
920
+ "properties": {
921
+ "programRef": {
922
+ "type": "string",
923
+ "pattern": "^(?:sha256:[a-f0-9]{64}|p_[a-f0-9]{12}(?:[a-f0-9]{4}){0,13})(?![\\s\\S])",
924
+ "description": "Returned p_ handle or full sha256 ref."
925
+ },
926
+ "offset": {
927
+ "default": 0,
928
+ "description": "UTF-16 character offset; use nextOffset to continue.",
929
+ "type": "integer",
930
+ "minimum": 0,
931
+ "maximum": 9007199254740991
932
+ },
933
+ "limit": {
934
+ "default": 8000,
935
+ "description": "Maximum characters returned.",
936
+ "type": "integer",
937
+ "minimum": 1,
938
+ "maximum": 16000
939
+ },
940
+ "query": {
941
+ "description": "Find literal text at or after offset; return bounded surrounding source.",
942
+ "type": "string",
943
+ "minLength": 1,
944
+ "maxLength": 1000
945
+ }
946
+ },
947
+ "required": [
948
+ "programRef"
949
+ ]
950
+ }
951
+ ```
952
+
953
+ </details>
954
+
955
+ ## kiln_material_search
956
+
957
+ Browse shipped material recipes and saved material revisions, optionally filtered by exact tag. Recipe IDs and saved material IDs are distinct. Use scope to select presets, saved or both.
958
+
959
+ <details>
960
+ <summary>Input JSON Schema</summary>
961
+
962
+
963
+ ```json
964
+ {
965
+ "type": "object",
966
+ "properties": {
967
+ "tag": {
968
+ "description": "presets, list: keep one tag.",
969
+ "type": "string",
970
+ "minLength": 1,
971
+ "maxLength": 80
972
+ },
973
+ "scope": {
974
+ "default": "all",
975
+ "type": "string",
976
+ "enum": [
977
+ "all",
978
+ "presets",
979
+ "saved"
980
+ ]
981
+ }
982
+ },
983
+ "additionalProperties": false
984
+ }
985
+ ```
986
+
987
+ </details>
988
+
989
+ ## kiln_material_get
990
+
991
+ Read a material revision, provenance and portable specification. Omit revisionId only when exactly one revision exists.
992
+
993
+ <details>
994
+ <summary>Input JSON Schema</summary>
995
+
996
+
997
+ ```json
998
+ {
999
+ "type": "object",
1000
+ "properties": {
1001
+ "materialId": {
1002
+ "description": "get: the id a project palette lists as resourceId; create-preset: optional id.",
1003
+ "type": "string",
1004
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1005
+ },
1006
+ "revisionId": {
1007
+ "description": "get: the immutable revision; omitted, the material's only revision.",
1008
+ "type": "string",
1009
+ "pattern": "^sha256:[a-f0-9]{64}$"
1010
+ }
1011
+ },
1012
+ "required": [
1013
+ "materialId"
1014
+ ],
1015
+ "additionalProperties": false
1016
+ }
1017
+ ```
1018
+
1019
+ </details>
1020
+
1021
+ ## kiln_material_create
1022
+
1023
+ Create and retain one immutable material from a preset or procedural definition. Presets require explicit seed, creator and license. Pin the returned materialId/revisionId for rendering. Does not fetch URLs or execute source.
1024
+
1025
+ <details>
1026
+ <summary>Input JSON Schema</summary>
1027
+
1028
+
1029
+ ```json
1030
+ {
1031
+ "type": "object",
1032
+ "properties": {
1033
+ "definition": {
1034
+ "oneOf": [
1035
+ {
1036
+ "type": "object",
1037
+ "properties": {
1038
+ "presetId": {
1039
+ "description": "create-preset: an id from presets.",
1040
+ "type": "string",
1041
+ "minLength": 1,
1042
+ "maxLength": 80
1043
+ },
1044
+ "seed": {
1045
+ "description": "create-preset.",
1046
+ "type": "integer",
1047
+ "minimum": -2147483648,
1048
+ "maximum": 2147483647
1049
+ },
1050
+ "creator": {
1051
+ "description": "create-preset.",
1052
+ "type": "string",
1053
+ "minLength": 1,
1054
+ "maxLength": 1000
1055
+ },
1056
+ "license": {
1057
+ "description": "create-preset: spdx, url and attribution.",
1058
+ "type": "object",
1059
+ "properties": {
1060
+ "spdx": {
1061
+ "type": "string",
1062
+ "minLength": 1,
1063
+ "maxLength": 1000
1064
+ },
1065
+ "url": {
1066
+ "type": "string",
1067
+ "maxLength": 2000,
1068
+ "format": "uri"
1069
+ },
1070
+ "attribution": {
1071
+ "type": "string",
1072
+ "maxLength": 4000
1073
+ }
1074
+ },
1075
+ "required": [
1076
+ "spdx",
1077
+ "url",
1078
+ "attribution"
1079
+ ],
1080
+ "additionalProperties": false
1081
+ },
1082
+ "size": {
1083
+ "description": "create-preset: map edge in pixels; default 256.",
1084
+ "anyOf": [
1085
+ {
1086
+ "type": "number",
1087
+ "const": 64
1088
+ },
1089
+ {
1090
+ "type": "number",
1091
+ "const": 128
1092
+ },
1093
+ {
1094
+ "type": "number",
1095
+ "const": 256
1096
+ },
1097
+ {
1098
+ "type": "number",
1099
+ "const": 512
1100
+ }
1101
+ ]
1102
+ },
1103
+ "materialId": {
1104
+ "description": "get: the id a project palette lists as resourceId; create-preset: optional id.",
1105
+ "type": "string",
1106
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1107
+ },
1108
+ "kind": {
1109
+ "type": "string",
1110
+ "const": "preset"
1111
+ }
1112
+ },
1113
+ "required": [
1114
+ "presetId",
1115
+ "seed",
1116
+ "creator",
1117
+ "license",
1118
+ "kind"
1119
+ ],
1120
+ "additionalProperties": false
1121
+ },
1122
+ {
1123
+ "type": "object",
1124
+ "properties": {
1125
+ "draft": {
1126
+ "description": "create-procedural: materialId, name, tileable, sources, maps with layered procedural specs; optional tags, physicalSizeMeters, parameters. Shape: kiln_discover({ ids: ['shape:material-draft'] }).",
1127
+ "type": "object",
1128
+ "propertyNames": {
1129
+ "type": "string"
1130
+ },
1131
+ "additionalProperties": {}
1132
+ },
1133
+ "kind": {
1134
+ "type": "string",
1135
+ "const": "procedural"
1136
+ }
1137
+ },
1138
+ "required": [
1139
+ "draft",
1140
+ "kind"
1141
+ ],
1142
+ "additionalProperties": false
1143
+ }
1144
+ ]
1145
+ }
1146
+ },
1147
+ "required": [
1148
+ "definition"
1149
+ ],
1150
+ "additionalProperties": false
1151
+ }
1152
+ ```
1153
+
1154
+ </details>
1155
+
1156
+ ## kiln_material_import
1157
+
1158
+ Import complete normalized material records and embedded PNGs. Does not fetch URLs or execute source.
1159
+
1160
+ <details>
1161
+ <summary>Input JSON Schema</summary>
1162
+
1163
+
1164
+ ```json
1165
+ {
1166
+ "type": "object",
1167
+ "properties": {
1168
+ "payload": {
1169
+ "description": "import: schemaVersion 1 and complete normalized records with embedded PNG bytes. Shape: kiln_discover({ ids: ['shape:material-import'] }).",
1170
+ "type": "object",
1171
+ "propertyNames": {
1172
+ "type": "string"
1173
+ },
1174
+ "additionalProperties": {}
1175
+ }
1176
+ },
1177
+ "required": [
1178
+ "payload"
1179
+ ],
1180
+ "additionalProperties": false
1181
+ }
1182
+ ```
1183
+
1184
+ </details>
1185
+
1186
+ ## kiln_save
1187
+
1188
+ Save a completed source revision into the user-requested collection, or project when none was requested. Persists exact GLB, source, preview and build record. Use programRef returned by render/edit. To revise an asset, pass assetId and parentRevision; earlier revisions stay intact. Returns downloadable resources; draft renders never populate collections.
1189
+
1190
+ <details>
1191
+ <summary>Input JSON Schema</summary>
1192
+
1193
+
1194
+ ```json
1195
+ {
1196
+ "type": "object",
1197
+ "properties": {
1198
+ "collection": {
1199
+ "default": "project",
1200
+ "description": "Collection ID from kiln_assets_collections; default project.",
1201
+ "type": "string",
1202
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1203
+ },
1204
+ "programRef": {
1205
+ "type": "string"
1206
+ },
1207
+ "name": {
1208
+ "type": "string",
1209
+ "minLength": 1,
1210
+ "maxLength": 200
1211
+ },
1212
+ "assetId": {
1213
+ "type": "string",
1214
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1215
+ },
1216
+ "parentRevision": {
1217
+ "type": "string",
1218
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1219
+ },
1220
+ "tags": {
1221
+ "maxItems": 30,
1222
+ "type": "array",
1223
+ "items": {
1224
+ "type": "string",
1225
+ "maxLength": 80
1226
+ }
1227
+ },
1228
+ "brief": {
1229
+ "type": "string",
1230
+ "maxLength": 8000
1231
+ },
1232
+ "description": {
1233
+ "type": "string",
1234
+ "maxLength": 4000
1235
+ },
1236
+ "attribution": {
1237
+ "type": "object",
1238
+ "properties": {
1239
+ "model": {
1240
+ "type": "string",
1241
+ "maxLength": 200
1242
+ },
1243
+ "harness": {
1244
+ "type": "string",
1245
+ "maxLength": 200
1246
+ },
1247
+ "author": {
1248
+ "type": "string",
1249
+ "maxLength": 200
1250
+ }
1251
+ }
1252
+ },
1253
+ "backdrop": {
1254
+ "description": "Preview backdrop: the one the reviewed sheet used.",
1255
+ "type": "string",
1256
+ "enum": [
1257
+ "neutral",
1258
+ "dark",
1259
+ "light"
1260
+ ]
1261
+ }
1262
+ },
1263
+ "required": [
1264
+ "programRef",
1265
+ "name"
1266
+ ]
1267
+ }
1268
+ ```
1269
+
1270
+ </details>
1271
+
1272
+ ## kiln_assets_collections
1273
+
1274
+ List configured asset storage collections. Collection is not project membership.
1275
+
1276
+ <details>
1277
+ <summary>Input JSON Schema</summary>
1278
+
1279
+
1280
+ ```json
1281
+ {
1282
+ "type": "object",
1283
+ "properties": {},
1284
+ "additionalProperties": false
1285
+ }
1286
+ ```
1287
+
1288
+ </details>
1289
+
1290
+ ## kiln_assets_search
1291
+
1292
+ Search saved assets with pagination. Omit collection for all configured collections, or select one explicitly. Results identify exact collection, asset and revision; partial read failures are reported.
1293
+
1294
+ <details>
1295
+ <summary>Input JSON Schema</summary>
1296
+
1297
+
1298
+ ```json
1299
+ {
1300
+ "type": "object",
1301
+ "properties": {
1302
+ "collection": {
1303
+ "description": "Collection ID from kiln_assets_collections; omitted searches all configured collections.",
1304
+ "type": "string",
1305
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1306
+ },
1307
+ "assetId": {
1308
+ "type": "string",
1309
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1310
+ },
1311
+ "query": {
1312
+ "type": "string",
1313
+ "maxLength": 200
1314
+ },
1315
+ "offset": {
1316
+ "default": 0,
1317
+ "type": "integer",
1318
+ "minimum": 0,
1319
+ "maximum": 9007199254740991
1320
+ },
1321
+ "limit": {
1322
+ "default": 20,
1323
+ "type": "integer",
1324
+ "minimum": 1,
1325
+ "maximum": 50
1326
+ }
1327
+ },
1328
+ "additionalProperties": false
1329
+ }
1330
+ ```
1331
+
1332
+ </details>
1333
+
1334
+ ## kiln_assets_get
1335
+
1336
+ Read a saved revision and its download descriptors. Omit revisionId for the newest revision.
1337
+
1338
+ <details>
1339
+ <summary>Input JSON Schema</summary>
1340
+
1341
+
1342
+ ```json
1343
+ {
1344
+ "type": "object",
1345
+ "properties": {
1346
+ "collection": {
1347
+ "default": "project",
1348
+ "description": "Collection ID from kiln_assets_collections; default project.",
1349
+ "type": "string",
1350
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1351
+ },
1352
+ "assetId": {
1353
+ "type": "string",
1354
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1355
+ },
1356
+ "revisionId": {
1357
+ "description": "get, restore: the saved revision; omitted, the newest.",
1358
+ "type": "string",
1359
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1360
+ }
1361
+ },
1362
+ "required": [
1363
+ "assetId"
1364
+ ],
1365
+ "additionalProperties": false
1366
+ }
1367
+ ```
1368
+
1369
+ </details>
1370
+
1371
+ ## kiln_assets_restore
1372
+
1373
+ Restore exact saved source as programRef for editing or rendering. Omit revisionId for the newest revision. Does not overwrite the saved revision. Binary-only assets have no source.
1374
+
1375
+ <details>
1376
+ <summary>Input JSON Schema</summary>
1377
+
1378
+
1379
+ ```json
1380
+ {
1381
+ "type": "object",
1382
+ "properties": {
1383
+ "collection": {
1384
+ "default": "project",
1385
+ "description": "Collection ID from kiln_assets_collections; default project.",
1386
+ "type": "string",
1387
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1388
+ },
1389
+ "assetId": {
1390
+ "type": "string",
1391
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1392
+ },
1393
+ "revisionId": {
1394
+ "description": "get, restore: the saved revision; omitted, the newest.",
1395
+ "type": "string",
1396
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1397
+ }
1398
+ },
1399
+ "required": [
1400
+ "assetId"
1401
+ ],
1402
+ "additionalProperties": false
1403
+ }
1404
+ ```
1405
+
1406
+ </details>
1407
+
1408
+ ## kiln_present
1409
+
1410
+ Present one exact saved revision. Supporting MCP App clients show an interactive 3D card with GLB, editable ZIP, and source downloads. Every host receives exact artifact descriptors with resource URIs in the JSON result; verified hosts may also receive core MCP resource-link blocks. This tool does not launch a local browser in coding harnesses. Call after saving or when the user wants to see or download an asset.
1411
+
1412
+ <details>
1413
+ <summary>Input JSON Schema</summary>
1414
+
1415
+
1416
+ ```json
1417
+ {
1418
+ "type": "object",
1419
+ "properties": {
1420
+ "collection": {
1421
+ "default": "project",
1422
+ "description": "Collection ID from kiln_assets_collections; default project.",
1423
+ "type": "string",
1424
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1425
+ },
1426
+ "assetId": {
1427
+ "type": "string",
1428
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1429
+ },
1430
+ "revisionId": {
1431
+ "type": "string",
1432
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1433
+ }
1434
+ },
1435
+ "required": [
1436
+ "assetId",
1437
+ "revisionId"
1438
+ ]
1439
+ }
1440
+ ```
1441
+
1442
+ </details>
1443
+
1444
+ ## kiln_export
1445
+
1446
+ Export one saved revision. Default editable returns exact GLB, source, preview, and manifest descriptors; configured hosts may include portable editable ZIP download URLs. Opt-in runtime returns a standalone GLB plus a versioned metadata sidecar, moving only Kiln review clips out of GLB extras while preserving native animation and application metadata. Resource URIs remain readable through resources/read. Canonical revisions never change; no binary bytes are placed in tool text.
1447
+
1448
+ <details>
1449
+ <summary>Input JSON Schema</summary>
1450
+
1451
+
1452
+ ```json
1453
+ {
1454
+ "type": "object",
1455
+ "properties": {
1456
+ "collection": {
1457
+ "default": "project",
1458
+ "description": "Collection ID from kiln_assets_collections; default project.",
1459
+ "type": "string",
1460
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1461
+ },
1462
+ "assetId": {
1463
+ "type": "string",
1464
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1465
+ },
1466
+ "revisionId": {
1467
+ "type": "string",
1468
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1469
+ },
1470
+ "profile": {
1471
+ "default": "editable",
1472
+ "description": "editable preserves canonical source/GLB/build resources. runtime returns a standalone GLB and versioned review-metadata sidecar; no source bundle or geometry optimization.",
1473
+ "type": "string",
1474
+ "enum": [
1475
+ "editable",
1476
+ "runtime"
1477
+ ]
1478
+ }
1479
+ },
1480
+ "required": [
1481
+ "assetId",
1482
+ "revisionId"
1483
+ ]
1484
+ }
1485
+ ```
1486
+
1487
+ </details>
1488
+
1489
+ ## kiln_import
1490
+
1491
+ Copy a pinned asset revision between configured collections, preserving identity and provenance. Copies never track later edits automatically. For a GLB or downloaded ZIP on disk, use kiln import <file> --collection <name> in the CLI.
1492
+
1493
+ <details>
1494
+ <summary>Input JSON Schema</summary>
1495
+
1496
+
1497
+ ```json
1498
+ {
1499
+ "type": "object",
1500
+ "properties": {
1501
+ "collection": {
1502
+ "default": "project",
1503
+ "description": "Collection ID from kiln_assets_collections; default project.",
1504
+ "type": "string",
1505
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1506
+ },
1507
+ "assetId": {
1508
+ "type": "string",
1509
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1510
+ },
1511
+ "revisionId": {
1512
+ "type": "string",
1513
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1514
+ },
1515
+ "sourceCollection": {
1516
+ "default": "project",
1517
+ "description": "Collection ID from kiln_assets_collections; default project.",
1518
+ "type": "string",
1519
+ "pattern": "^[a-z][a-z0-9_-]{0,79}$"
1520
+ }
1521
+ },
1522
+ "required": [
1523
+ "assetId",
1524
+ "revisionId"
1525
+ ]
1526
+ }
1527
+ ```
1528
+
1529
+ </details>