sceneview-mcp 3.3.0 → 3.4.1
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/dist/index.js +99 -0
- package/dist/samples.js +84 -0
- package/dist/validator.js +75 -0
- package/llms.txt +106 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -195,6 +195,14 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
|
195
195
|
required: ["type"],
|
|
196
196
|
},
|
|
197
197
|
},
|
|
198
|
+
{
|
|
199
|
+
name: "get_web_setup",
|
|
200
|
+
description: "Returns the complete Web setup guide for SceneView Web — npm install, Kotlin/JS Gradle config, HTML canvas setup, and basic Filament.js integration code. SceneView Web uses the same Filament rendering engine as Android, compiled to WebAssembly. Use this when a user wants to set up SceneView for browsers.",
|
|
201
|
+
inputSchema: {
|
|
202
|
+
type: "object",
|
|
203
|
+
properties: {},
|
|
204
|
+
},
|
|
205
|
+
},
|
|
198
206
|
],
|
|
199
207
|
}));
|
|
200
208
|
// ─── Tool handlers ────────────────────────────────────────────────────────────
|
|
@@ -594,6 +602,97 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
594
602
|
isError: true,
|
|
595
603
|
};
|
|
596
604
|
}
|
|
605
|
+
// ── get_web_setup ────────────────────────────────────────────────────────
|
|
606
|
+
case "get_web_setup": {
|
|
607
|
+
return {
|
|
608
|
+
content: [
|
|
609
|
+
{
|
|
610
|
+
type: "text",
|
|
611
|
+
text: [
|
|
612
|
+
`## SceneView Web — Browser 3D Setup`,
|
|
613
|
+
``,
|
|
614
|
+
`SceneView Web uses **Filament.js** — the same rendering engine as Android, compiled to WebAssembly (WebGL2).`,
|
|
615
|
+
``,
|
|
616
|
+
`### 1. Install`,
|
|
617
|
+
``,
|
|
618
|
+
`\`\`\`bash`,
|
|
619
|
+
`npm install @sceneview/sceneview-web`,
|
|
620
|
+
`\`\`\``,
|
|
621
|
+
``,
|
|
622
|
+
`Or in a Kotlin/JS Gradle project:`,
|
|
623
|
+
`\`\`\`kotlin`,
|
|
624
|
+
`// build.gradle.kts`,
|
|
625
|
+
`kotlin {`,
|
|
626
|
+
` js(IR) { browser(); binaries.executable() }`,
|
|
627
|
+
` sourceSets {`,
|
|
628
|
+
` jsMain.dependencies {`,
|
|
629
|
+
` implementation("@sceneview/sceneview-web")`,
|
|
630
|
+
` // or: implementation(project(":sceneview-web"))`,
|
|
631
|
+
` }`,
|
|
632
|
+
` }`,
|
|
633
|
+
`}`,
|
|
634
|
+
`\`\`\``,
|
|
635
|
+
``,
|
|
636
|
+
`### 2. HTML`,
|
|
637
|
+
``,
|
|
638
|
+
`\`\`\`html`,
|
|
639
|
+
`<canvas id="scene-canvas" style="width:100%;height:100vh"></canvas>`,
|
|
640
|
+
`<script src="your-app.js"></script>`,
|
|
641
|
+
`\`\`\``,
|
|
642
|
+
``,
|
|
643
|
+
`### 3. Kotlin/JS Code`,
|
|
644
|
+
``,
|
|
645
|
+
`\`\`\`kotlin`,
|
|
646
|
+
`import io.github.sceneview.web.SceneView`,
|
|
647
|
+
`import kotlinx.browser.document`,
|
|
648
|
+
`import org.w3c.dom.HTMLCanvasElement`,
|
|
649
|
+
``,
|
|
650
|
+
`fun main() {`,
|
|
651
|
+
` val canvas = document.getElementById("scene-canvas") as HTMLCanvasElement`,
|
|
652
|
+
` canvas.width = canvas.clientWidth`,
|
|
653
|
+
` canvas.height = canvas.clientHeight`,
|
|
654
|
+
``,
|
|
655
|
+
` SceneView.create(`,
|
|
656
|
+
` canvas = canvas,`,
|
|
657
|
+
` configure = {`,
|
|
658
|
+
` camera {`,
|
|
659
|
+
` eye(0.0, 1.5, 5.0)`,
|
|
660
|
+
` target(0.0, 0.0, 0.0)`,
|
|
661
|
+
` fov(45.0)`,
|
|
662
|
+
` }`,
|
|
663
|
+
` light {`,
|
|
664
|
+
` directional()`,
|
|
665
|
+
` intensity(100_000.0)`,
|
|
666
|
+
` }`,
|
|
667
|
+
` model("models/DamagedHelmet.glb")`,
|
|
668
|
+
` autoRotate()`,
|
|
669
|
+
` },`,
|
|
670
|
+
` onReady = { sceneView ->`,
|
|
671
|
+
` sceneView.startRendering()`,
|
|
672
|
+
` }`,
|
|
673
|
+
` )`,
|
|
674
|
+
`}`,
|
|
675
|
+
`\`\`\``,
|
|
676
|
+
``,
|
|
677
|
+
`### 4. Features`,
|
|
678
|
+
``,
|
|
679
|
+
`- Same Filament PBR renderer as Android (WASM)`,
|
|
680
|
+
`- glTF 2.0 / GLB model loading`,
|
|
681
|
+
`- IBL environment lighting (KTX)`,
|
|
682
|
+
`- Orbit camera with mouse/touch/pinch controls`,
|
|
683
|
+
`- Auto-rotation`,
|
|
684
|
+
`- Directional, point, and spot lights`,
|
|
685
|
+
``,
|
|
686
|
+
`### 5. Limitations`,
|
|
687
|
+
``,
|
|
688
|
+
`- No AR (requires native sensors)`,
|
|
689
|
+
`- WebGL2 required (~95% of browsers)`,
|
|
690
|
+
`- glTF/GLB format only (same as Android)`,
|
|
691
|
+
].join("\n"),
|
|
692
|
+
},
|
|
693
|
+
],
|
|
694
|
+
};
|
|
695
|
+
}
|
|
597
696
|
default:
|
|
598
697
|
return {
|
|
599
698
|
content: [{ type: "text", text: `Unknown tool: ${request.params.name}` }],
|
package/dist/samples.js
CHANGED
|
@@ -884,6 +884,90 @@ struct VideoPlayerScreen: View {
|
|
|
884
884
|
}
|
|
885
885
|
}
|
|
886
886
|
}
|
|
887
|
+
}`,
|
|
888
|
+
},
|
|
889
|
+
// ── Web Samples (Kotlin/JS + Filament.js) ──────────────────────────────
|
|
890
|
+
"web-model-viewer": {
|
|
891
|
+
id: "web-model-viewer",
|
|
892
|
+
title: "Web 3D Model Viewer",
|
|
893
|
+
description: "Browser-based 3D model viewer using Filament.js (WebGL2/WASM) — same engine as SceneView Android",
|
|
894
|
+
tags: ["3d", "model", "web", "filament-js"],
|
|
895
|
+
dependency: "@sceneview/sceneview-web",
|
|
896
|
+
language: "kotlin-js",
|
|
897
|
+
prompt: "Create a browser-based 3D model viewer using SceneView Web (Kotlin/JS + Filament.js). Load a GLB model with camera and lighting.",
|
|
898
|
+
code: `import io.github.sceneview.web.SceneView
|
|
899
|
+
import kotlinx.browser.document
|
|
900
|
+
import kotlinx.browser.window
|
|
901
|
+
import org.w3c.dom.HTMLCanvasElement
|
|
902
|
+
|
|
903
|
+
fun main() {
|
|
904
|
+
val canvas = document.getElementById("scene-canvas") as HTMLCanvasElement
|
|
905
|
+
canvas.width = canvas.clientWidth
|
|
906
|
+
canvas.height = canvas.clientHeight
|
|
907
|
+
|
|
908
|
+
SceneView.create(
|
|
909
|
+
canvas = canvas,
|
|
910
|
+
configure = {
|
|
911
|
+
camera {
|
|
912
|
+
eye(0.0, 1.5, 5.0)
|
|
913
|
+
target(0.0, 0.0, 0.0)
|
|
914
|
+
fov(45.0)
|
|
915
|
+
}
|
|
916
|
+
light {
|
|
917
|
+
directional()
|
|
918
|
+
intensity(100_000.0)
|
|
919
|
+
direction(0.0f, -1.0f, -0.5f)
|
|
920
|
+
}
|
|
921
|
+
model("models/DamagedHelmet.glb")
|
|
922
|
+
},
|
|
923
|
+
onReady = { sceneView ->
|
|
924
|
+
sceneView.startRendering()
|
|
925
|
+
|
|
926
|
+
window.addEventListener("resize", {
|
|
927
|
+
canvas.width = canvas.clientWidth
|
|
928
|
+
canvas.height = canvas.clientHeight
|
|
929
|
+
})
|
|
930
|
+
}
|
|
931
|
+
)
|
|
932
|
+
}`,
|
|
933
|
+
},
|
|
934
|
+
"web-environment": {
|
|
935
|
+
id: "web-environment",
|
|
936
|
+
title: "Web Environment Lighting",
|
|
937
|
+
description: "Browser 3D scene with IBL environment lighting and skybox from KTX files",
|
|
938
|
+
tags: ["3d", "environment", "web", "filament-js", "lighting"],
|
|
939
|
+
dependency: "@sceneview/sceneview-web",
|
|
940
|
+
language: "kotlin-js",
|
|
941
|
+
prompt: "Create a browser 3D viewer with HDR environment lighting (IBL + skybox) using SceneView Web and Filament.js.",
|
|
942
|
+
code: `import io.github.sceneview.web.SceneView
|
|
943
|
+
import kotlinx.browser.document
|
|
944
|
+
import org.w3c.dom.HTMLCanvasElement
|
|
945
|
+
|
|
946
|
+
fun main() {
|
|
947
|
+
val canvas = document.getElementById("scene-canvas") as HTMLCanvasElement
|
|
948
|
+
canvas.width = canvas.clientWidth
|
|
949
|
+
canvas.height = canvas.clientHeight
|
|
950
|
+
|
|
951
|
+
SceneView.create(
|
|
952
|
+
canvas = canvas,
|
|
953
|
+
configure = {
|
|
954
|
+
camera {
|
|
955
|
+
eye(0.0, 1.0, 4.0)
|
|
956
|
+
target(0.0, 0.0, 0.0)
|
|
957
|
+
fov(50.0)
|
|
958
|
+
exposure(16.0, 1.0 / 125.0, 100.0)
|
|
959
|
+
}
|
|
960
|
+
// Environment from KTX IBL + skybox files
|
|
961
|
+
environment(
|
|
962
|
+
iblUrl = "environments/pillars_2k_ibl.ktx",
|
|
963
|
+
skyboxUrl = "environments/pillars_2k_skybox.ktx"
|
|
964
|
+
)
|
|
965
|
+
model("models/DamagedHelmet.glb")
|
|
966
|
+
},
|
|
967
|
+
onReady = { sceneView ->
|
|
968
|
+
sceneView.startRendering()
|
|
969
|
+
}
|
|
970
|
+
)
|
|
887
971
|
}`,
|
|
888
972
|
},
|
|
889
973
|
};
|
package/dist/validator.js
CHANGED
|
@@ -489,6 +489,13 @@ const SWIFT_RULES = [
|
|
|
489
489
|
},
|
|
490
490
|
];
|
|
491
491
|
function detectLanguage(code) {
|
|
492
|
+
// Heuristic: detect web/Kotlin-JS code
|
|
493
|
+
if (code.includes("io.github.sceneview.web") ||
|
|
494
|
+
code.includes("kotlinx.browser") ||
|
|
495
|
+
code.includes("HTMLCanvasElement") ||
|
|
496
|
+
code.includes("SceneView.create(")) {
|
|
497
|
+
return "kotlin-js";
|
|
498
|
+
}
|
|
492
499
|
// Heuristic: if the code has Swift markers, validate as Swift
|
|
493
500
|
if (code.includes("import SwiftUI") ||
|
|
494
501
|
code.includes("import RealityKit") ||
|
|
@@ -500,12 +507,80 @@ function detectLanguage(code) {
|
|
|
500
507
|
}
|
|
501
508
|
return "kotlin";
|
|
502
509
|
}
|
|
510
|
+
// ─── Web (Kotlin/JS) validation rules ────────────────────────────────────────
|
|
511
|
+
const WEB_RULES = [
|
|
512
|
+
{
|
|
513
|
+
id: "web/missing-canvas-null-check",
|
|
514
|
+
severity: "warning",
|
|
515
|
+
check(code, lines) {
|
|
516
|
+
const issues = [];
|
|
517
|
+
if (code.includes("getElementById") && !code.includes("as?") && !code.includes("?: ") && !code.includes("== null")) {
|
|
518
|
+
findLines(lines, /getElementById/).forEach((line) => issues.push({
|
|
519
|
+
severity: "warning",
|
|
520
|
+
rule: "web/missing-canvas-null-check",
|
|
521
|
+
message: "Canvas element lookup should include a null check. Use `as? HTMLCanvasElement` with a null guard.",
|
|
522
|
+
line,
|
|
523
|
+
}));
|
|
524
|
+
}
|
|
525
|
+
return issues;
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
id: "web/missing-canvas-resize",
|
|
530
|
+
severity: "info",
|
|
531
|
+
check(code, lines) {
|
|
532
|
+
const issues = [];
|
|
533
|
+
if (code.includes("SceneView.create(") && !code.includes("clientWidth") && !code.includes("resize")) {
|
|
534
|
+
issues.push({
|
|
535
|
+
severity: "info",
|
|
536
|
+
rule: "web/missing-canvas-resize",
|
|
537
|
+
message: "Canvas should be sized before creating SceneView. Set `canvas.width = canvas.clientWidth` and `canvas.height = canvas.clientHeight` before `SceneView.create()`. Or enable `autoResize` (on by default).",
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
return issues;
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
id: "web/ar-not-supported",
|
|
545
|
+
severity: "error",
|
|
546
|
+
check(code, lines) {
|
|
547
|
+
const issues = [];
|
|
548
|
+
if (code.includes("ARScene") || code.includes("ARSceneView")) {
|
|
549
|
+
findLines(lines, /ARScene|ARSceneView/).forEach((line) => issues.push({
|
|
550
|
+
severity: "error",
|
|
551
|
+
rule: "web/ar-not-supported",
|
|
552
|
+
message: "AR is not supported on the web platform. SceneView Web only supports 3D scenes (no camera/sensor access in browsers). Use `SceneView.create()` for 3D-only web rendering.",
|
|
553
|
+
line,
|
|
554
|
+
}));
|
|
555
|
+
}
|
|
556
|
+
return issues;
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
id: "web/missing-start-rendering",
|
|
561
|
+
severity: "warning",
|
|
562
|
+
check(code, lines) {
|
|
563
|
+
const issues = [];
|
|
564
|
+
if (code.includes("SceneView.create(") && !code.includes("startRendering")) {
|
|
565
|
+
issues.push({
|
|
566
|
+
severity: "warning",
|
|
567
|
+
rule: "web/missing-start-rendering",
|
|
568
|
+
message: "Don't forget to call `sceneView.startRendering()` in the `onReady` callback to start the render loop.",
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
return issues;
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
];
|
|
503
575
|
export function validateCode(code) {
|
|
504
576
|
const lines = code.split("\n");
|
|
505
577
|
const lang = detectLanguage(code);
|
|
506
578
|
if (lang === "swift") {
|
|
507
579
|
return SWIFT_RULES.flatMap((rule) => rule.check(code, lines));
|
|
508
580
|
}
|
|
581
|
+
if (lang === "kotlin-js") {
|
|
582
|
+
return WEB_RULES.flatMap((rule) => rule.check(code, lines));
|
|
583
|
+
}
|
|
509
584
|
return RULES.flatMap((rule) => rule.check(code, lines));
|
|
510
585
|
}
|
|
511
586
|
export function formatValidationReport(issues) {
|
package/llms.txt
CHANGED
|
@@ -2154,3 +2154,109 @@ Pure Kotlin logic shared between Android and Apple platforms:
|
|
|
2154
2154
|
- **Animation**: Easing, lerp/slerp, spring, smooth transform interpolation
|
|
2155
2155
|
- **Physics**: Euler integration, floor bounce, restitution, sleep detection
|
|
2156
2156
|
- **Triangulation**: Earcut (polygon), Delaunator (Delaunay)
|
|
2157
|
+
|
|
2158
|
+
---
|
|
2159
|
+
|
|
2160
|
+
## Web Platform (Alpha)
|
|
2161
|
+
|
|
2162
|
+
SceneView for Web uses **Filament.js** — the same Filament rendering engine as Android, compiled to WebAssembly for browsers (WebGL2).
|
|
2163
|
+
|
|
2164
|
+
### npm package
|
|
2165
|
+
```
|
|
2166
|
+
npm install @sceneview/sceneview-web
|
|
2167
|
+
```
|
|
2168
|
+
|
|
2169
|
+
### Kotlin/JS API
|
|
2170
|
+
```kotlin
|
|
2171
|
+
import io.github.sceneview.web.SceneView
|
|
2172
|
+
import kotlinx.browser.document
|
|
2173
|
+
import org.w3c.dom.HTMLCanvasElement
|
|
2174
|
+
|
|
2175
|
+
fun main() {
|
|
2176
|
+
val canvas = document.getElementById("scene-canvas") as HTMLCanvasElement
|
|
2177
|
+
|
|
2178
|
+
SceneView.create(
|
|
2179
|
+
canvas = canvas,
|
|
2180
|
+
configure = {
|
|
2181
|
+
camera {
|
|
2182
|
+
eye(0.0, 1.5, 5.0)
|
|
2183
|
+
target(0.0, 0.0, 0.0)
|
|
2184
|
+
fov(45.0)
|
|
2185
|
+
}
|
|
2186
|
+
model("models/DamagedHelmet.glb")
|
|
2187
|
+
environment("environments/sky_ibl.ktx", "environments/sky_skybox.ktx")
|
|
2188
|
+
},
|
|
2189
|
+
onReady = { sceneView ->
|
|
2190
|
+
sceneView.startRendering()
|
|
2191
|
+
}
|
|
2192
|
+
)
|
|
2193
|
+
}
|
|
2194
|
+
```
|
|
2195
|
+
|
|
2196
|
+
### HTML
|
|
2197
|
+
```html
|
|
2198
|
+
<canvas id="scene-canvas"></canvas>
|
|
2199
|
+
<script src="sceneview-web.js"></script>
|
|
2200
|
+
```
|
|
2201
|
+
|
|
2202
|
+
### SceneView Web API
|
|
2203
|
+
|
|
2204
|
+
| Class | Purpose |
|
|
2205
|
+
|---|---|
|
|
2206
|
+
| `SceneView` | Main entry — `create(canvas, configure, onReady)` |
|
|
2207
|
+
| `SceneViewBuilder` | DSL: `camera {}`, `light {}`, `model()`, `environment()` |
|
|
2208
|
+
| `CameraConfig` | `eye()`, `target()`, `up()`, `fov()`, `near()`, `far()`, `exposure()` |
|
|
2209
|
+
| `LightConfig` | `directional()`, `point()`, `spot()`, `intensity()`, `color()`, `direction()` |
|
|
2210
|
+
| `ModelConfig` | `url`, `scale()`, `autoAnimate()`, `onLoaded {}` |
|
|
2211
|
+
|
|
2212
|
+
### SceneView instance methods
|
|
2213
|
+
|
|
2214
|
+
| Method | Description |
|
|
2215
|
+
|---|---|
|
|
2216
|
+
| `startRendering()` | Begin render loop (requestAnimationFrame) |
|
|
2217
|
+
| `stopRendering()` | Stop render loop |
|
|
2218
|
+
| `loadModel(url, onLoaded?)` | Load glTF/GLB from URL |
|
|
2219
|
+
| `loadEnvironment(iblUrl, skyboxUrl?)` | Load IBL + skybox KTX files |
|
|
2220
|
+
| `destroy()` | Clean up all Filament resources |
|
|
2221
|
+
|
|
2222
|
+
### Web AR (WebXR)
|
|
2223
|
+
|
|
2224
|
+
SceneView Web supports augmented reality via the **WebXR Device API** on supported browsers:
|
|
2225
|
+
|
|
2226
|
+
```kotlin
|
|
2227
|
+
ARSceneView.checkSupport { supported ->
|
|
2228
|
+
if (supported) {
|
|
2229
|
+
ARSceneView.create(canvas) { arView ->
|
|
2230
|
+
arView.onHitTest = { pose ->
|
|
2231
|
+
// Place model at hit position
|
|
2232
|
+
}
|
|
2233
|
+
arView.start()
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
```
|
|
2238
|
+
|
|
2239
|
+
**Supported browsers:** Chrome Android 79+, Safari iOS 18+, Quest Browser, Edge
|
|
2240
|
+
**Features:** Hit-test (tap-to-place), light estimation, DOM overlay
|
|
2241
|
+
|
|
2242
|
+
### Web constraints
|
|
2243
|
+
- AR requires WebXR-capable browser (not all browsers — check with `ARSceneView.checkSupport`)
|
|
2244
|
+
- WebGL2 required for 3D (~95% of browsers)
|
|
2245
|
+
- glTF 2.0 / GLB format only (same as Android)
|
|
2246
|
+
- Cross-origin asset loading requires CORS headers
|
|
2247
|
+
|
|
2248
|
+
---
|
|
2249
|
+
|
|
2250
|
+
## Platform Coverage Summary
|
|
2251
|
+
|
|
2252
|
+
| Platform | Renderer | Framework | Sample | Status |
|
|
2253
|
+
|---|---|---|---|---|
|
|
2254
|
+
| Android | Filament | Jetpack Compose | `samples/android-demo` | Stable |
|
|
2255
|
+
| Android TV | Filament | Compose TV | `samples/android-tv-demo` | Alpha |
|
|
2256
|
+
| iOS | RealityKit | SwiftUI | `samples/ios-demo` | Alpha |
|
|
2257
|
+
| macOS | RealityKit | SwiftUI | via SceneViewSwift | Alpha |
|
|
2258
|
+
| visionOS | RealityKit | SwiftUI | via SceneViewSwift | Alpha |
|
|
2259
|
+
| Web | Filament.js + WebXR | Kotlin/JS | `samples/web-demo` | Alpha |
|
|
2260
|
+
| Desktop | Software renderer | Compose Desktop | `samples/desktop-demo` | Alpha |
|
|
2261
|
+
| Flutter | Filament/RealityKit | PlatformView | `samples/flutter-demo` | Alpha |
|
|
2262
|
+
| React Native | Filament/RealityKit | Fabric | `samples/react-native-demo` | Alpha |
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sceneview-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.1",
|
|
4
|
+
"mcpName": "io.github.sceneview/mcp",
|
|
4
5
|
"description": "MCP server for SceneView — cross-platform 3D & AR SDK for Android and iOS. Give Claude the full SceneView SDK so it writes correct, compilable code.",
|
|
5
6
|
"keywords": [
|
|
6
7
|
"mcp",
|