Skip to main content
Glama

Draft recipe from operator chain

draft_recipe_from_operator_chain
Read-only

Convert an ordered TouchDesigner operator chain into a RecipeSchema draft. Define operators, tags, and constraints without writing files or touching the TD bridge.

Instructions

Read-only: convert an ordered TouchDesigner operator chain into a RecipeSchema draft without writing files or touching the TD bridge.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idNoOptional recipe id. Generated when omitted.
nameNoOptional recipe display name. Generated when omitted.
tagsNoOptional recipe tags.
chainYesOrdered TouchDesigner operator names, display names, slugs, or optypes, e.g. ['Noise TOP', 'Level TOP', 'Null TOP'].
familyNoOptional operator family/category constraint, e.g. TOP, CHOP, SOP, DAT.
strictNoWhen true, unresolved operators or family mismatches return an isError result.
difficultyNointermediate
descriptionNoOptional recipe description. A chain summary is generated when omitted.
td_version_minNo2023

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
validYes
recipeYes
validationYes
chainReportYes
nextToolHintsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.12.1
    • changedOutput schema / properties / recipe / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "connections": {
      -        "default": [],
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "from": {
      -              "description": "Source node name.",
      -              "type": "string"
      -            },
      -            "from_output": {
      -              "default": 0,
      -              "maximum": 9007199254740991,
      -              "minimum": 0,
      -              "type": "integer"
      -            },
      -            "to": {
      -              "description": "Target node name.",
      -              "type": "string"
      -            },
      -            "to_input": {
      -              "default": 0,
      -              "maximum": 9007199254740991,
      -              "minimum": 0,
      -              "type": "integer"
      -            }
      -          },
      -          "required": [
      -            "from",
      -            "to",
      -            "from_output",
      -            "to_input"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "controls": {
      -        "default": [],
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "bind_to": {
      -              "description": "Parameters this control should drive, each written as 'nodePath.parName' (e.g. '/project1/sys/blur1.size'). Each target is switched to expression mode so moving the control moves the parameter live. Not supported for 'rgb'/'pulse'.",
      -              "items": {
      -                "type": "string"
      -              },
      -              "type": "array"
      -            },
      -            "default": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "type": "boolean"
      -                },
      -                {
      -                  "type": "string"
      -                }
      -              ],
      -              "description": "Initial value."
      -            },
      -            "label": {
      -              "description": "Display label (defaults to `name`).",
      -              "type": "string"
      -            },
      -            "max": {
      -              "description": "Slider upper bound (float/int) — also hard-clamped.",
      -              "type": "number"
      -            },
      -            "menu_items": {
      -              "description": "Options for a 'menu' control.",
      -              "items": {
      -                "type": "string"
      -              },
      -              "type": "array"
      -            },
      -            "min": {
      -              "description": "Slider lower bound (float/int) — also hard-clamped.",
      -              "type": "number"
      -            },
      -            "name": {
      -              "description": "Control label; also sanitized into a valid TD custom-parameter name (e.g. 'blur amount' → 'Bluramount').",
      -              "type": "string"
      -            },
      -            "type": {
      -              "default": "float",
      -              "description": "Widget kind: float/int sliders, a toggle, a dropdown menu, an RGB swatch, a momentary pulse, or a text field.",
      -              "enum": [
      -                "float",
      -                "int",
      -                "toggle",
      -                "menu",
      -                "rgb",
      -                "pulse",
      -                "string"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "type"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "difficulty": {
      -        "default": "intermediate",
      -        "enum": [
      -          "beginner",
      -          "intermediate",
      -          "advanced"
      -        ],
      -        "type": "string"
      -      },
      -      "glsl_code": {
      -        "additionalProperties": {
      -          "type": "string"
      -        },
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "glsl_uniforms": {
      -        "default": [],
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "description": {
      -              "type": "string"
      -            },
      -            "kind": {
      -              "default": "float",
      -              "description": "Uniform kind: float (uniform float), vec (uniform vec2/3/4), color (rgba). float/vec use the Vectors page; color uses the Colors page.",
      -              "enum": [
      -                "float",
      -                "vec",
      -                "color"
      -              ],
      -              "type": "string"
      -            },
      -            "label": {
      -              "type": "string"
      -            },
      -            "max": {
      -              "type": "number"
      -            },
      -            "min": {
      -              "type": "number"
      -            },
      -            "name": {
      -              "description": "Uniform name as referenced in the shader, e.g. 'uFeed'.",
      -              "type": "string"
      -            },
      -            "node": {
      -              "description": "Recipe node name of the GLSL TOP that declares the uniform.",
      -              "type": "string"
      -            },
      -            "value": {
      -              "anyOf": [
      -                {
      -                  "type": "number"
      -                },
      -                {
      -                  "items": {
      -                    "type": "number"
      -                  },
      -                  "type": "array"
      -                }
      -              ],
      -              "description": "Initial value: a number for float, or an array of components for vec/color."
      -            }
      -          },
      -          "required": [
      -            "node",
      -            "name",
      -            "kind"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "id": {
      -        "type": "string"
      -      },
      -      "name": {
      -        "type": "string"
      -      },
      -      "nodes": {
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "comment": {
      -              "type": "string"
      -            },
      -            "name": {
      -              "description": "Unique node name within the recipe (used for wiring).",
      -              "type": "string"
      -            },
      -            "parameters": {
      -              "additionalProperties": {},
      -              "default": {},
      -              "propertyNames": {
      -                "type": "string"
      -              },
      -              "type": "object"
      -            },
      -            "parent": {
      -              "description": "Name of another recipe node (a COMP, e.g. a geometryCOMP) to nest this node inside of. The parent must appear earlier in `nodes`. Used to place SOPs inside a Geometry COMP.",
      -              "type": "string"
      -            },
      -            "render": {
      -              "description": "For a SOP nested in a geometryCOMP: make this the rendered geometry. Sets the render/display flags on it and clears its siblings, so the COMP renders this instead of its default torus.",
      -              "type": "boolean"
      -            },
      -            "type": {
      -              "description": "Operator type, e.g. 'noiseTOP'.",
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "name",
      -            "type",
      -            "parameters"
      -          ],
      -          "type": "object"
      -        },
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "parameters": {
      -        "default": [],
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "description": {
      -              "type": "string"
      -            },
      -            "label": {
      -              "type": "string"
      -            },
      -            "max": {
      -              "type": "number"
      -            },
      -            "min": {
      -              "type": "number"
      -            },
      -            "name": {
      -              "description": "Friendly name of the exposed control.",
      -              "type": "string"
      -            },
      -            "node": {
      -              "description": "Recipe node name the parameter belongs to.",
      -              "type": "string"
      -            },
      -            "param": {
      -              "description": "TD parameter name on that node.",
      -              "type": "string"
      -            },
      -            "value": {}
      -          },
      -          "required": [
      -            "name",
      -            "node",
      -            "param"
      -          ],
      -          "type": "object"
      -        },
      -        "type": "array"
      -      },
      -      "preview_description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "python_code": {
      -        "additionalProperties": {
      -          "type": "string"
      -        },
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "tags": {
      -        "default": [],
      -        "items": {
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "td_version_min": {
      -        "default": "2023",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "id",
      -      "name",
      -      "description",
      -      "tags",
      -      "difficulty",
      -      "td_version_min",
      -      "nodes",
      -      "connections",
      -      "parameters",
      -      "glsl_uniforms",
      -      "controls",
      -      "preview_description"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "connections": {
      +        "default": [],
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "from": {
      +              "description": "Source node name.",
      +              "type": "string"
      +            },
      +            "from_output": {
      +              "default": 0,
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            },
      +            "to": {
      +              "description": "Target node name.",
      +              "type": "string"
      +            },
      +            "to_input": {
      +              "default": 0,
      +              "maximum": 9007199254740991,
      +              "minimum": 0,
      +              "type": "integer"
      +            }
      +          },
      +          "required": [
      +            "from",
      +            "to",
      +            "from_output",
      +            "to_input"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "controls": {
      +        "default": [],
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "bind_to": {
      +              "description": "Parameters this control should drive, each written as 'nodePath.parName' (e.g. '/project1/sys/blur1.size'). Each target is switched to expression mode so moving the control moves the parameter live. Not supported for 'rgb'/'pulse'.",
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            },
      +            "default": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "type": "boolean"
      +                },
      +                {
      +                  "type": "string"
      +                }
      +              ],
      +              "description": "Initial value."
      +            },
      +            "label": {
      +              "description": "Display label (defaults to `name`).",
      +              "type": "string"
      +            },
      +            "max": {
      +              "description": "Slider upper bound (float/int) — also hard-clamped.",
      +              "type": "number"
      +            },
      +            "menu_items": {
      +              "description": "Options for a 'menu' control.",
      +              "items": {
      +                "type": "string"
      +              },
      +              "type": "array"
      +            },
      +            "min": {
      +              "description": "Slider lower bound (float/int) — also hard-clamped.",
      +              "type": "number"
      +            },
      +            "name": {
      +              "description": "Control label; also sanitized into a valid TD custom-parameter name (e.g. 'blur amount' → 'Bluramount').",
      +              "type": "string"
      +            },
      +            "type": {
      +              "default": "float",
      +              "description": "Widget kind: float/int sliders, a toggle, a dropdown menu, an RGB swatch, a momentary pulse, or a text field.",
      +              "enum": [
      +                "float",
      +                "int",
      +                "toggle",
      +                "menu",
      +                "rgb",
      +                "pulse",
      +                "string"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "type"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "difficulty": {
      +        "default": "intermediate",
      +        "enum": [
      +          "beginner",
      +          "intermediate",
      +          "advanced"
      +        ],
      +        "type": "string"
      +      },
      +      "glsl_code": {
      +        "additionalProperties": {
      +          "type": "string"
      +        },
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "glsl_uniforms": {
      +        "default": [],
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "description": {
      +              "type": "string"
      +            },
      +            "kind": {
      +              "default": "float",
      +              "description": "Uniform kind: float (uniform float), vec (uniform vec2/3/4), color (rgba). float/vec use the Vectors page; color uses the Colors page.",
      +              "enum": [
      +                "float",
      +                "vec",
      +                "color"
      +              ],
      +              "type": "string"
      +            },
      +            "label": {
      +              "type": "string"
      +            },
      +            "max": {
      +              "type": "number"
      +            },
      +            "min": {
      +              "type": "number"
      +            },
      +            "name": {
      +              "description": "Uniform name as referenced in the shader, e.g. 'uFeed'.",
      +              "type": "string"
      +            },
      +            "node": {
      +              "description": "Recipe node name of the GLSL TOP that declares the uniform.",
      +              "type": "string"
      +            },
      +            "value": {
      +              "anyOf": [
      +                {
      +                  "type": "number"
      +                },
      +                {
      +                  "items": {
      +                    "type": "number"
      +                  },
      +                  "type": "array"
      +                }
      +              ],
      +              "description": "Initial value: a number for float, or an array of components for vec/color."
      +            }
      +          },
      +          "required": [
      +            "node",
      +            "name",
      +            "kind"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "id": {
      +        "type": "string"
      +      },
      +      "name": {
      +        "type": "string"
      +      },
      +      "nodes": {
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "comment": {
      +              "type": "string"
      +            },
      +            "name": {
      +              "description": "Unique node name within the recipe (used for wiring).",
      +              "type": "string"
      +            },
      +            "parameters": {
      +              "additionalProperties": {},
      +              "default": {},
      +              "propertyNames": {
      +                "type": "string"
      +              },
      +              "type": "object"
      +            },
      +            "parent": {
      +              "description": "Name of another recipe node (a COMP, e.g. a geometryCOMP) to nest this node inside of. The parent must appear earlier in `nodes`. Used to place SOPs inside a Geometry COMP.",
      +              "type": "string"
      +            },
      +            "render": {
      +              "description": "For a SOP nested in a geometryCOMP: make this the rendered geometry. Sets the render/display flags on it and clears its siblings, so the COMP renders this instead of its default torus.",
      +              "type": "boolean"
      +            },
      +            "type": {
      +              "description": "Operator type, e.g. 'noiseTOP'.",
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "name",
      +            "type",
      +            "parameters"
      +          ],
      +          "type": "object"
      +        },
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "parameters": {
      +        "default": [],
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "description": {
      +              "type": "string"
      +            },
      +            "expr": {
      +              "description": "Python expression to drive the parameter (sets the param to expression mode). `op('<recipeNodeName>')` references are rewritten to the real created paths at build time. Takes precedence over `value`.",
      +              "type": "string"
      +            },
      +            "label": {
      +              "type": "string"
      +            },
      +            "max": {
      +              "type": "number"
      +            },
      +            "min": {
      +              "type": "number"
      +            },
      +            "name": {
      +              "description": "Friendly name of the exposed control.",
      +              "type": "string"
      +            },
      +            "node": {
      +              "description": "Recipe node name the parameter belongs to.",
      +              "type": "string"
      +            },
      +            "param": {
      +              "description": "TD parameter name on that node.",
      +              "type": "string"
      +            },
      +            "value": {}
      +          },
      +          "required": [
      +            "name",
      +            "node",
      +            "param"
      +          ],
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "preview_description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "python_code": {
      +        "additionalProperties": {
      +          "type": "string"
      +        },
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "tags": {
      +        "default": [],
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "td_version_min": {
      +        "default": "2023",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id",
      +      "name",
      +      "description",
      +      "tags",
      +      "difficulty",
      +      "td_version_min",
      +      "nodes",
      +      "connections",
      +      "parameters",
      +      "glsl_uniforms",
      +      "controls",
      +      "preview_description"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  2. Addedv0.11.0

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, but the description adds specific context beyond that: 'without writing files or touching the TD bridge'. This clarifies the non-destructive and non-interactive nature of the tool, which is valuable context not fully captured by the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the most important information ('Read-only') and clearly states the action and output. Every word earns its place, with no unnecessary details or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that an output schema exists, the description need not explain return values. It adequately covers the tool's purpose, read-only nature, and output being a 'draft', which is sufficient for an agent to understand the high-level behavior. It does not mention error cases or strict mode, but those are covered by the schema and parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (78%), and the description does not add parameter-level details beyond what the schema already provides. The only mention of 'ordered TouchDesigner operator chain' aligns with the 'chain' parameter description in the schema, so the description adds no new semantic value for parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool converts an 'ordered TouchDesigner operator chain' into a 'RecipeSchema draft', using a specific verb and resource. This distinguishes it from sibling tools like draft_recipe_from_technique or draft_recipe_from_tutorial by focusing on operator chains as input.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by framing the operation as 'Read-only' and noting it avoids writing files or touching the TD bridge, which suggests safe use for conversions without side effects. However, it does not explicitly mention when to use this tool versus alternatives or provide exclusions, so guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools