Fluorite
MCP server

Building shaders

How an agent finds nodes, builds a shader, checks it and publishes it.

An agent works in a loop: find what it needs, create a shader, edit it, look at the result, and publish when it looks right. You can ask it in plain words, like "make a ring I can resize from my site".

The loop

  1. Discover. nodes_list searches the built-in nodes and presets, and nodes_get shows one in full, with its ports and an example. A preset is a whole effect, so it's usually quicker than rebuilding one from nodes. shaders_search and shaders_read show what others have published.
  2. Create. shaders_create starts a private draft with a UV node connected to the output. shaders_fork starts from a public shader instead.
  3. Edit. shaders_edit applies a list of changes. If any change fails, none are applied, and the error says which one. Every edit returns problems found in the graph, so the agent can fix them.
  4. Look. render shows the draft as an image. times: [0, 0.5, 1, 2] puts four moments side by side to show motion.
  5. Publish. shaders_publish saves a new version. shaders_update with visibility: "public" lists it in the community.

An example

Create a draft:

shaders_create
{ "name": "Ring" }

It answers with the shader id and revision: 0. The draft already has a node with id uv wired to the output, whose id is __output__.

Add the Ring preset, feed it the UV, give it a size input your site can set, and send it to the output:

shaders_edit
{
  "id": "<shader id>",
  "expectedRevision": 0,
  "ops": [
    {
      "op": "add_preset",
      "presetId": "official:ring",
      "id": "ring",
      "inputs": { "thickness": 0.02 }
    },
    { "op": "connect", "source": "uv", "target": "ring", "targetHandle": "uv" },
    {
      "op": "add_input",
      "kind": "float",
      "value": 0.3,
      "exposed": true,
      "inputName": "size",
      "id": "size"
    },
    {
      "op": "connect",
      "source": "size",
      "target": "ring",
      "targetHandle": "radius"
    },
    {
      "op": "connect",
      "source": "ring",
      "target": "__output__",
      "targetHandle": "color"
    }
  ]
}

The answer has revision: 1, no problems, and size listed as an input. Look at it:

render
{ "shaderId": "<shader id>", "draft": true }

Then publish it and make it public:

shaders_publish
{ "id": "<shader id>", "bump": "major" }
shaders_update
{ "id": "<shader id>", "visibility": "public" }

Good to know

  • Revisions. Each edit passes the revision it last saw. If the shader changed since, for example in the editor, nothing is written and the agent reads it again with shaders_read and draft: true.
  • Using someone else's shader. shaders_fork copies it into a new draft. The import_shader op adds it to your shader as a single node instead, frozen at the version you picked.
  • Textures. The agent can use a texture you've already uploaded, by its path, but it can't upload one.

Every tool and its arguments are on the Tools page.

On this page