construct-shader-graph-mcp 0.3.0 → 0.4.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.
- package/package.json +1 -1
- package/src/server.mjs +53 -16
package/package.json
CHANGED
package/src/server.mjs
CHANGED
|
@@ -227,7 +227,9 @@ function createToolDefinitions() {
|
|
|
227
227
|
description:
|
|
228
228
|
"Choose which connected shader graph tab future MCP calls should target.",
|
|
229
229
|
inputSchema: {
|
|
230
|
-
sessionId: z
|
|
230
|
+
sessionId: z
|
|
231
|
+
.string()
|
|
232
|
+
.describe("Session id returned by list_projects."),
|
|
231
233
|
},
|
|
232
234
|
outputSchema: {
|
|
233
235
|
sessionId: z.string(),
|
|
@@ -291,7 +293,9 @@ function createToolDefinitions() {
|
|
|
291
293
|
.describe("Optional session id; defaults to the selected project."),
|
|
292
294
|
method: z
|
|
293
295
|
.string()
|
|
294
|
-
.describe(
|
|
296
|
+
.describe(
|
|
297
|
+
"Manifest method path, for example nodes.create or shader.getInfo.",
|
|
298
|
+
),
|
|
295
299
|
args: z
|
|
296
300
|
.array(z.any())
|
|
297
301
|
.optional()
|
|
@@ -397,12 +401,15 @@ function registerPrompts(server) {
|
|
|
397
401
|
"inspect-graph",
|
|
398
402
|
{
|
|
399
403
|
title: "Inspect Graph",
|
|
400
|
-
description:
|
|
404
|
+
description:
|
|
405
|
+
"Prompt for safely inspecting the current graph before any edits.",
|
|
401
406
|
argsSchema: z.object({
|
|
402
407
|
focus: z
|
|
403
408
|
.string()
|
|
404
409
|
.optional()
|
|
405
|
-
.describe(
|
|
410
|
+
.describe(
|
|
411
|
+
"Optional area to inspect, like uniforms, preview, or node types.",
|
|
412
|
+
),
|
|
406
413
|
}),
|
|
407
414
|
},
|
|
408
415
|
({ focus }) => ({
|
|
@@ -447,7 +454,10 @@ function registerPrompts(server) {
|
|
|
447
454
|
description:
|
|
448
455
|
"Prompt for debugging generated code or preview issues in a shader graph project.",
|
|
449
456
|
argsSchema: z.object({
|
|
450
|
-
issue: z
|
|
457
|
+
issue: z
|
|
458
|
+
.string()
|
|
459
|
+
.optional()
|
|
460
|
+
.describe("Optional description of the observed preview issue."),
|
|
451
461
|
}),
|
|
452
462
|
},
|
|
453
463
|
({ issue }) => ({
|
|
@@ -480,7 +490,6 @@ function createLocalServer() {
|
|
|
480
490
|
}
|
|
481
491
|
|
|
482
492
|
async function startPrimaryBackend() {
|
|
483
|
-
isPrimaryInstance = true;
|
|
484
493
|
localServer = createLocalServer();
|
|
485
494
|
|
|
486
495
|
bridge = new WebSocketServer({ noServer: true });
|
|
@@ -541,7 +550,9 @@ async function startPrimaryBackend() {
|
|
|
541
550
|
selectedSessionId = sessionId;
|
|
542
551
|
}
|
|
543
552
|
|
|
544
|
-
log(
|
|
553
|
+
log(
|
|
554
|
+
`registered ${sessionId} (${session.project?.name || "Untitled Shader"})`,
|
|
555
|
+
);
|
|
545
556
|
sendWsJson(socket, {
|
|
546
557
|
type: "registered",
|
|
547
558
|
sessionId,
|
|
@@ -631,9 +642,15 @@ async function startPrimaryBackend() {
|
|
|
631
642
|
return;
|
|
632
643
|
}
|
|
633
644
|
|
|
634
|
-
const tool = createToolDefinitions().find(
|
|
645
|
+
const tool = createToolDefinitions().find(
|
|
646
|
+
(entry) => entry.name === request.tool,
|
|
647
|
+
);
|
|
635
648
|
if (!tool) {
|
|
636
|
-
sendJson(socket, {
|
|
649
|
+
sendJson(socket, {
|
|
650
|
+
id: request.id,
|
|
651
|
+
ok: false,
|
|
652
|
+
error: `Unknown tool '${request.tool}'`,
|
|
653
|
+
});
|
|
637
654
|
return;
|
|
638
655
|
}
|
|
639
656
|
|
|
@@ -650,14 +667,25 @@ async function startPrimaryBackend() {
|
|
|
650
667
|
});
|
|
651
668
|
});
|
|
652
669
|
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
controlServer.
|
|
657
|
-
|
|
670
|
+
try {
|
|
671
|
+
await new Promise((resolve, reject) => {
|
|
672
|
+
controlServer.once("error", reject);
|
|
673
|
+
controlServer.listen(CONTROL_PORT, "127.0.0.1", () => {
|
|
674
|
+
controlServer.off("error", reject);
|
|
675
|
+
resolve();
|
|
676
|
+
});
|
|
658
677
|
});
|
|
659
|
-
})
|
|
678
|
+
} catch (err) {
|
|
679
|
+
httpServer.close();
|
|
680
|
+
bridge.close();
|
|
681
|
+
throw err;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Permanent error handlers to prevent unhandled error crashes
|
|
685
|
+
httpServer.on("error", (err) => log("bridge http error:", err.message));
|
|
686
|
+
controlServer.on("error", (err) => log("control server error:", err.message));
|
|
660
687
|
|
|
688
|
+
isPrimaryInstance = true;
|
|
661
689
|
log(`control listening on tcp://127.0.0.1:${CONTROL_PORT}`);
|
|
662
690
|
}
|
|
663
691
|
|
|
@@ -680,7 +708,10 @@ function createProxyServer() {
|
|
|
680
708
|
|
|
681
709
|
function callPrimaryTool(tool, input) {
|
|
682
710
|
return new Promise((resolve, reject) => {
|
|
683
|
-
const socket = net.createConnection({
|
|
711
|
+
const socket = net.createConnection({
|
|
712
|
+
host: "127.0.0.1",
|
|
713
|
+
port: CONTROL_PORT,
|
|
714
|
+
});
|
|
684
715
|
const requestId = `rpc_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
685
716
|
const rl = readline.createInterface({ input: socket });
|
|
686
717
|
|
|
@@ -728,6 +759,12 @@ async function ensureBackend() {
|
|
|
728
759
|
throw error;
|
|
729
760
|
}
|
|
730
761
|
|
|
762
|
+
// Clean up any partially created resources
|
|
763
|
+
isPrimaryInstance = false;
|
|
764
|
+
localServer = null;
|
|
765
|
+
bridge = null;
|
|
766
|
+
controlServer = null;
|
|
767
|
+
|
|
731
768
|
log(`bridge already running on ${BRIDGE_PORT}; starting follower proxy`);
|
|
732
769
|
}
|
|
733
770
|
}
|