construct-shader-graph-mcp 0.8.0 → 0.9.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.mjs +57 -107
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "construct-shader-graph-mcp",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Standalone MCP server for Construct Shader Graph",
5
5
  "type": "module",
6
6
  "files": [
package/src/server.mjs CHANGED
@@ -33,7 +33,60 @@ function nowIso() {
33
33
  }
34
34
 
35
35
  function loadSkillText() {
36
- return fs.readFileSync(SKILL_PATH, "utf8");
36
+ try {
37
+ return fs.readFileSync(SKILL_PATH, "utf8");
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+
43
+ async function fetchGuidanceFromApp() {
44
+ if (!selectedSessionId) {
45
+ return null;
46
+ }
47
+
48
+ const session = sessions.get(selectedSessionId);
49
+ if (!session) {
50
+ return null;
51
+ }
52
+
53
+ try {
54
+ const result = await invokeSession(session, "getGuidance", []);
55
+ if (result?.ok && result.result) {
56
+ return result.result;
57
+ }
58
+ } catch {
59
+ // Fall back to local file.
60
+ }
61
+
62
+ return null;
63
+ }
64
+
65
+ async function getSkillText() {
66
+ const appGuidance = await fetchGuidanceFromApp();
67
+ if (appGuidance?.skill) {
68
+ return appGuidance.skill;
69
+ }
70
+
71
+ return loadSkillText() || "No guidance available.";
72
+ }
73
+
74
+ async function getQuickstartText() {
75
+ const appGuidance = await fetchGuidanceFromApp();
76
+ if (appGuidance?.quickstart) {
77
+ return appGuidance.quickstart;
78
+ }
79
+
80
+ return loadQuickstartText();
81
+ }
82
+
83
+ async function getPromptPreambleText() {
84
+ const appGuidance = await fetchGuidanceFromApp();
85
+ if (appGuidance?.preamble) {
86
+ return appGuidance.preamble;
87
+ }
88
+
89
+ return getPromptPreamble();
37
90
  }
38
91
 
39
92
  function loadQuickstartText() {
@@ -170,7 +223,7 @@ function createToolDefinitions() {
170
223
  handler: async () => {
171
224
  const result = {
172
225
  title: "Construct Shader Graph MCP Guidance",
173
- content: loadSkillText(),
226
+ content: await getSkillText(),
174
227
  };
175
228
  return {
176
229
  content: [{ type: "text", text: result.content }],
@@ -339,7 +392,7 @@ function registerResources(server) {
339
392
  {
340
393
  uri: uri.href,
341
394
  mimeType: "text/markdown",
342
- text: loadSkillText(),
395
+ text: await getSkillText(),
343
396
  },
344
397
  ],
345
398
  }),
@@ -358,108 +411,7 @@ function registerResources(server) {
358
411
  {
359
412
  uri: uri.href,
360
413
  mimeType: "text/markdown",
361
- text: loadQuickstartText(),
362
- },
363
- ],
364
- }),
365
- );
366
- }
367
-
368
- function registerPrompts(server) {
369
- server.registerPrompt(
370
- "work-with-shader-graph",
371
- {
372
- title: "Work With Shader Graph",
373
- description:
374
- "General prompt for safely inspecting and editing a Construct Shader Graph project.",
375
- argsSchema: z.object({
376
- task: z.string().optional().describe("The user task to accomplish."),
377
- }),
378
- },
379
- ({ task }) => ({
380
- messages: [
381
- {
382
- role: "user",
383
- content: {
384
- type: "text",
385
- text: `${getPromptPreamble()}\n\nFollow the full guidance resource if more detail is needed.\n\nTask: ${task || "Inspect the current project, understand its graph state, and proceed safely."}`,
386
- },
387
- },
388
- ],
389
- }),
390
- );
391
-
392
- server.registerPrompt(
393
- "inspect-graph",
394
- {
395
- title: "Inspect Graph",
396
- description:
397
- "Prompt for safely inspecting the current graph before any edits.",
398
- argsSchema: z.object({
399
- focus: z
400
- .string()
401
- .optional()
402
- .describe(
403
- "Optional area to inspect, like uniforms, preview, or node types.",
404
- ),
405
- }),
406
- },
407
- ({ focus }) => ({
408
- messages: [
409
- {
410
- role: "user",
411
- content: {
412
- type: "text",
413
- text: `${getPromptPreamble()}\n\nInspect the current graph without mutating it. Read nodes, wires, uniforms, shader info, and any relevant settings first. ${focus ? `Focus on: ${focus}.` : ""}`,
414
- },
415
- },
416
- ],
417
- }),
418
- );
419
-
420
- server.registerPrompt(
421
- "edit-graph-safely",
422
- {
423
- title: "Edit Graph Safely",
424
- description: "Prompt for making a small validated graph edit with MCP.",
425
- argsSchema: z.object({
426
- task: z.string().describe("The graph edit to perform."),
427
- }),
428
- },
429
- ({ task }) => ({
430
- messages: [
431
- {
432
- role: "user",
433
- content: {
434
- type: "text",
435
- text: `${getPromptPreamble()}\n\nMake the smallest valid change that satisfies this task: ${task}\n\nBefore wiring, inspect ports. Before choosing a node type, use nodeTypes.search or nodeTypes.list. After each structural edit, re-read affected nodes or ports and validate preview/code if relevant.`,
436
- },
437
- },
438
- ],
439
- }),
440
- );
441
-
442
- server.registerPrompt(
443
- "debug-preview-errors",
444
- {
445
- title: "Debug Preview Errors",
446
- description:
447
- "Prompt for debugging generated code or preview issues in a shader graph project.",
448
- argsSchema: z.object({
449
- issue: z
450
- .string()
451
- .optional()
452
- .describe("Optional description of the observed preview issue."),
453
- }),
454
- },
455
- ({ issue }) => ({
456
- messages: [
457
- {
458
- role: "user",
459
- content: {
460
- type: "text",
461
- text: `${getPromptPreamble()}\n\nDebug the current shader graph by inspecting shader.getGeneratedCode, preview.getErrors, preview settings, node preview, and ai.runDebugCheck. ${issue ? `Observed issue: ${issue}` : ""}`,
462
- },
414
+ text: await getQuickstartText(),
463
415
  },
464
416
  ],
465
417
  }),
@@ -473,7 +425,6 @@ function createLocalServer() {
473
425
  });
474
426
 
475
427
  registerResources(server);
476
- registerPrompts(server);
477
428
  createToolDefinitions().forEach((tool) => {
478
429
  server.registerTool(tool.name, tool.config, tool.handler);
479
430
  });
@@ -688,7 +639,6 @@ function createProxyServer() {
688
639
  });
689
640
 
690
641
  registerResources(server);
691
- registerPrompts(server);
692
642
  createToolDefinitions().forEach((tool) => {
693
643
  server.registerTool(tool.name, tool.config, async (input = {}) => {
694
644
  return callPrimaryTool(tool.name, input);