Hello there and thanks for this amazing tool, it has been a real "game changer" (haha!)
While trying to work on some shaders, I ran into some issues. I asked Opus to try to disprove them, and write up a bug report with clean repro scenarios for what it couldn't disprove. I am happy to file these as separate bugs if it's helpful, but I wanted to create this first to see what direction was preferable (and if you can repro and agree these are bugs). Below is the bug report generated by Opus 4.8:
Environment
com.anklebreaker.unity-mcp v2.32.0 (Git)
- Unity 6000.3.15f1,
com.unity.shadergraph (bundled)
- Windows 11
Four independent bugs in the unity_shadergraph_* advanced tools. All reproduce on a freshly created graph.
Bug 1 — unity_shadergraph_create ignores the template and writes an empty, invalid graph
Every template (urp_lit, urp_unlit, blank) writes the identical 809-byte file: no UniversalTarget, no SubTarget, no BlockNodes, m_Properties: [], and an m_OutputNode referencing an id (da732cfa…) that does not exist in m_Nodes.
Reproduce
All three files are byte-identical (809 chars). Compare against a real authored URP Lit graph (17 KB+, with UniversalTarget + UniversalLitSubTarget + 9 surface/vertex BlockNodes).
The full produced file:
{
"m_SGVersion": 3,
"m_Type": "UnityEditor.ShaderGraph.GraphData",
"m_ObjectId": "c5db29678c40486dae73be5271e8cf74",
"m_Properties": [],
"m_Keywords": [],
"m_Dropdowns": [],
"m_CategoryData": [],
"m_Nodes": [],
"m_GroupDatas": [],
"m_StickyNoteDatas": [],
"m_Edges": [],
"m_VertexContext": { "m_Position": { "x": 0.0, "y": 0.0 }, "m_Blocks": [] },
"m_FragmentContext": { "m_Position": { "x": 200.0, "y": 0.0 }, "m_Blocks": [] },
"m_PreviewData": { "serializedMesh": { "m_SerializedMesh": "", "m_Guid": "" } },
"m_Path": "Shader Graphs",
"m_GraphPrecision": 1,
"m_PreviewMode": 2,
"m_OutputNode": { "m_Id": "da732cfa5b4444a59a244468f6f3ad02" }
}
- Expected:
urp_lit produces a graph with a UniversalTarget / UniversalLitSubTarget and the standard surface + vertex block nodes; the templates differ from one another.
- Actual: all templates yield the same empty graph with a dangling
m_OutputNode; unusable as a starting point.
Bug 2 — unity_shadergraph_disconnect deletes the wrong edges and corrupts survivors
Two distinct failures.
2a. Matches by output slot only
Disconnect removes every edge fanning out of the named output node + slot, ignoring the input node/slot.
Returns {"removedEdges":1,"remainingEdges":0}; file m_Edges is now []. The M.Out → A.B edge (input slot 1) was destroyed too. Edges from a different output slot are correctly preserved, confirming the match ignores the input.
2b. Corrupts surviving multi-line edges
When a surviving edge is in standard multi-line format (as the Shader Graph editor and hand/JSON authoring write it), disconnect re-emits it with blanked node ids and zeroed slots:
"m_Edges": [{"m_OutputSlot":{"m_Node":{"m_Id":""},"m_SlotId":0},"m_InputSlot":{"m_Node":{"m_Id":""},"m_SlotId":0}}]
Original ids/slots were M(118b…)/2 → A(37b2…)/0 etc. The reported remainingEdges count is also wrong.
- Expected: remove exactly the one edge matching all four of
{outputNode, outputSlot, inputNode, inputSlot}; leave every other edge byte-faithful.
- Actual: removes all edges sharing the output slot, and blanks/zeros any surviving multi-line edge.
Note: unity_shadergraph_remove_node handles the same array correctly (removes connected edges, re-emits survivors with full ids and slots), so the regression is specific to disconnect's edge-matching / rewriting path.
Bug 3 — unity_shadergraph_add_node cannot bind a PropertyNode, producing an asset that fails import
Creating a PropertyNode and passing the blackboard property id is ignored; the node is written with "m_Property":{"m_Id":""} and empty m_Slots.
Result node:
{ "m_Type":"UnityEditor.ShaderGraph.PropertyNode", "m_Slots":[], "m_Property":{"m_Id":""} }
On the next import this throws and fails the whole asset:
NullReferenceException: Object reference not set to an instance of an object
at UnityEditor.ShaderGraph.PropertyNode.AddOutputSlot () (PropertyNode.cs:86)
at UnityEditor.ShaderGraph.PropertyNode.OnEnable () (PropertyNode.cs:74)
at UnityEditor.ShaderGraph.GraphData.OnEnable () (GraphData.cs:2929)
at UnityEditor.ShaderGraph.ShaderGraphImporter.OnImportAsset (...) (ShaderGraphImporter.cs:240)
at UnityMCP.Editor.MCPShaderGraphCommands:AddGraphNode (MCPShaderGraphCommands.cs:877)
Asset import failed, "Assets/.../X.shadergraph" > NullReferenceException ...
- Expected: either bind the PropertyNode to the given property (so the importer creates output slot 0 from the property type), or reject the call. Don't leave an unbindable node that breaks import.
- Actual: unbound PropertyNode written; every subsequent import throws and the asset fails to compile.
Bug 4 — unity_shadergraph_add_node ignores the x / y position
Returns "position":{"x":0,"y":0} and writes m_DrawState.m_Position as (0,0). Every scripted node stacks at the origin.
- Expected: the passed
x / y land in m_DrawState.m_Position.
- Actual: always
(0,0); the supplied coordinates are dropped.
Hello there and thanks for this amazing tool, it has been a real "game changer" (haha!)
While trying to work on some shaders, I ran into some issues. I asked Opus to try to disprove them, and write up a bug report with clean repro scenarios for what it couldn't disprove. I am happy to file these as separate bugs if it's helpful, but I wanted to create this first to see what direction was preferable (and if you can repro and agree these are bugs). Below is the bug report generated by Opus 4.8:
Environment
com.anklebreaker.unity-mcpv2.32.0 (Git)com.unity.shadergraph(bundled)Four independent bugs in the
unity_shadergraph_*advanced tools. All reproduce on a freshly created graph.Bug 1 —
unity_shadergraph_createignores thetemplateand writes an empty, invalid graphEvery template (
urp_lit,urp_unlit,blank) writes the identical 809-byte file: noUniversalTarget, no SubTarget, noBlockNodes,m_Properties: [], and anm_OutputNodereferencing an id (da732cfa…) that does not exist inm_Nodes.Reproduce
unity_advanced_tool unity_shadergraph_create {"path":"Assets/T/A.shadergraph","template":"urp_lit"} unity_advanced_tool unity_shadergraph_create {"path":"Assets/T/B.shadergraph","template":"urp_unlit"} unity_advanced_tool unity_shadergraph_create {"path":"Assets/T/C.shadergraph","template":"blank"}All three files are byte-identical (809 chars). Compare against a real authored URP Lit graph (17 KB+, with
UniversalTarget+UniversalLitSubTarget+ 9 surface/vertexBlockNodes).The full produced file:
{ "m_SGVersion": 3, "m_Type": "UnityEditor.ShaderGraph.GraphData", "m_ObjectId": "c5db29678c40486dae73be5271e8cf74", "m_Properties": [], "m_Keywords": [], "m_Dropdowns": [], "m_CategoryData": [], "m_Nodes": [], "m_GroupDatas": [], "m_StickyNoteDatas": [], "m_Edges": [], "m_VertexContext": { "m_Position": { "x": 0.0, "y": 0.0 }, "m_Blocks": [] }, "m_FragmentContext": { "m_Position": { "x": 200.0, "y": 0.0 }, "m_Blocks": [] }, "m_PreviewData": { "serializedMesh": { "m_SerializedMesh": "", "m_Guid": "" } }, "m_Path": "Shader Graphs", "m_GraphPrecision": 1, "m_PreviewMode": 2, "m_OutputNode": { "m_Id": "da732cfa5b4444a59a244468f6f3ad02" } }urp_litproduces a graph with aUniversalTarget/UniversalLitSubTargetand the standard surface + vertex block nodes; the templates differ from one another.m_OutputNode; unusable as a starting point.Bug 2 —
unity_shadergraph_disconnectdeletes the wrong edges and corrupts survivorsTwo distinct failures.
2a. Matches by output slot only
Disconnect removes every edge fanning out of the named output node + slot, ignoring the input node/slot.
Returns
{"removedEdges":1,"remainingEdges":0}; filem_Edgesis now[]. TheM.Out → A.Bedge (input slot 1) was destroyed too. Edges from a different output slot are correctly preserved, confirming the match ignores the input.2b. Corrupts surviving multi-line edges
When a surviving edge is in standard multi-line format (as the Shader Graph editor and hand/JSON authoring write it),
disconnectre-emits it with blanked node ids and zeroed slots:Original ids/slots were
M(118b…)/2 → A(37b2…)/0etc. The reportedremainingEdgescount is also wrong.{outputNode, outputSlot, inputNode, inputSlot}; leave every other edge byte-faithful.Bug 3 —
unity_shadergraph_add_nodecannot bind a PropertyNode, producing an asset that fails importCreating a PropertyNode and passing the blackboard property id is ignored; the node is written with
"m_Property":{"m_Id":""}and emptym_Slots.unity_shadergraph_add_node {"path":P,"nodeType":"Property","property":<id>,"propertyId":<id>,"propertyName":"TestColor"}Result node:
{ "m_Type":"UnityEditor.ShaderGraph.PropertyNode", "m_Slots":[], "m_Property":{"m_Id":""} }On the next import this throws and fails the whole asset:
Bug 4 —
unity_shadergraph_add_nodeignores thex/ypositionunity_shadergraph_add_node {"path":P,"nodeType":"Multiply","x":150,"y":250}Returns
"position":{"x":0,"y":0}and writesm_DrawState.m_Positionas(0,0). Every scripted node stacks at the origin.x/yland inm_DrawState.m_Position.(0,0); the supplied coordinates are dropped.