Skip to main content
Glama

Grade Image

lab_grade

Apply a deterministic colour grade to an image already in the project gallery — no re-generation, no provider, no credits. The look is computed pixel-exact (exposure, saturation, hue, lightness, contrast, film grain) and lands as a new gallery image the sequencer and export pick up. For full control the recipe fields are open too: levels and curves per channel (rgb, r, g, b — values 0..255), a gradient map (luminance → colour ramp), exposure offset/gamma and grain seed/colour. Fixed order, like a node stack: exposure → levels → curves → hue/saturation → look (LUT) → gradient map → grain. The same recipe on the same image always yields the same result (grain is fixed-seed), so a look is reproducible across every still. Set from_colorist to start from the project's colorist crew brief (look, contrast, grain) and tune with the sliders on top. At least one adjustment OR from_colorist is required. Synchronous — the graded image_url comes straight back, no polling.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
hueNoHue rotation in degrees; zero neutral
lookNoNamed look from the bundle catalogue (e.g. filmlab-neutral, filmlab-warm, filmlab-cool, filmlab-soft, filmlab-punch) — a hand-authored LUT, applied on top of the sliders. The server resolves the name; a path is never accepted.
grainNoFilm grain amount; zero is none, monochrome
curvesNoCurves per channel as [x, y] points 0..255, x strictly increasing (smooth monotone curve through them). Example warm highlights: {"r": [[0,0],[192,205],[255,255]], "b": [[0,0],[192,180],[255,255]]}. Not together with contrast on the rgb channel
levelsNoLevels per channel (rgb = all three, r/g/b single), values 0..255: input black/white point, gamma (above 1 brightens midtones), output black/white. Example: {"rgb": {"black": 12, "white": 240, "gamma": 1.1}}
contrastNoContrast curve: high is an S-curve, low flattens it
exposureNoExposure in stops; positive brightens, zero is neutral
image_idYesId of the source image in the project gallery (from lab_list_assets / lab_generate)
lightnessNoLightness; negative darkens, zero neutral
grain_monoNoGrain in black and white (default true); false gives colour grain
grain_seedNoSeed of the grain pattern (default 0) — same seed, same grain
project_idYesProject id (from lab_list_projects)
saturationNoColour saturation; minimum is greyscale, zero neutral
gradient_mapNoGradient map: luminance 0..1 → colour ramp, blended with opacity (default 1). Example teal-orange: {"stops": [[0, "#0b2a33"], [0.5, "#7a7a72"], [1, "#ffd9a8"]], "opacity": 0.3}
look_opacityNoBlend of the named look, 0..1 (default 1)
from_coloristNoStart from the project's colorist crew brief (look/contrast/grain), then apply the sliders on top
exposure_gammaNoExposure gamma; 1 neutral, above 1 brightens midtones
exposure_offsetNoExposure offset added after the stops (lifts or crushes blacks); zero neutral

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedInput schema / additionalProperties
      Added value: +false
  2. Changed6 schema fields changed
    • changedInput schema / properties / curves / additionalProperties / items / items
      Previous value: -[
      -  {
      -    "maximum": 255,
      -    "minimum": 0,
      -    "type": "number"
      -  },
      -  {
      -    "maximum": 255,
      -    "minimum": 0,
      -    "type": "number"
      -  }
      -]New value: +{
      +  "maximum": 255,
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / curves / additionalProperties / items / maxItems
      Added value: +2
    • addedInput schema / properties / curves / additionalProperties / items / minItems
      Added value: +2
    • changedInput schema / properties / gradient_map / properties / stops / items / items
      Previous value: -[
      -  {
      -    "maximum": 1,
      -    "minimum": 0,
      -    "type": "number"
      -  },
      -  {
      -    "pattern": "^#[0-9a-fA-F]{6}$",
      -    "type": "string"
      -  }
      -]New value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 1,
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    {
      +      "pattern": "^#[0-9a-fA-F]{6}$",
      +      "type": "string"
      +    }
      +  ]
      +}
    • addedInput schema / properties / gradient_map / properties / stops / items / maxItems
      Added value: +2
    • addedInput schema / properties / gradient_map / properties / stops / items / minItems
      Added value: +2
  3. Changed7 schema fields changed
    • addedInput schema / properties / curves
      Added value: +{
      +  "additionalProperties": {
      +    "items": {
      +      "items": [
      +        {
      +          "maximum": 255,
      +          "minimum": 0,
      +          "type": "number"
      +        },
      +        {
      +          "maximum": 255,
      +          "minimum": 0,
      +          "type": "number"
      +        }
      +      ],
      +      "type": "array"
      +    },
      +    "maxItems": 16,
      +    "minItems": 2,
      +    "type": "array"
      +  },
      +  "description": "Curves per channel as [x, y] points 0..255, x strictly increasing (smooth monotone curve through them). Example warm highlights: {\"r\": [[0,0],[192,205],[255,255]], \"b\": [[0,0],[192,180],[255,255]]}. Not together with contrast on the rgb channel",
      +  "propertyNames": {
      +    "enum": [
      +      "rgb",
      +      "r",
      +      "g",
      +      "b"
      +    ],
      +    "type": "string"
      +  },
      +  "required": [
      +    "rgb",
      +    "r",
      +    "g",
      +    "b"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / exposure_gamma
      Added value: +{
      +  "description": "Exposure gamma; 1 neutral, above 1 brightens midtones",
      +  "maximum": 10,
      +  "minimum": 0.1,
      +  "type": "number"
      +}
    • addedInput schema / properties / exposure_offset
      Added value: +{
      +  "description": "Exposure offset added after the stops (lifts or crushes blacks); zero neutral",
      +  "maximum": 0.5,
      +  "minimum": -0.5,
      +  "type": "number"
      +}
    • addedInput schema / properties / gradient_map
      Added value: +{
      +  "description": "Gradient map: luminance 0..1 → colour ramp, blended with opacity (default 1). Example teal-orange: {\"stops\": [[0, \"#0b2a33\"], [0.5, \"#7a7a72\"], [1, \"#ffd9a8\"]], \"opacity\": 0.3}",
      +  "properties": {
      +    "opacity": {
      +      "maximum": 1,
      +      "minimum": 0,
      +      "type": "number"
      +    },
      +    "stops": {
      +      "items": {
      +        "items": [
      +          {
      +            "maximum": 1,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          {
      +            "pattern": "^#[0-9a-fA-F]{6}$",
      +            "type": "string"
      +          }
      +        ],
      +        "type": "array"
      +      },
      +      "maxItems": 8,
      +      "minItems": 2,
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "stops"
      +  ],
      +  "type": "object"
      +}
    • addedInput schema / properties / grain_mono
      Added value: +{
      +  "description": "Grain in black and white (default true); false gives colour grain",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / grain_seed
      Added value: +{
      +  "description": "Seed of the grain pattern (default 0) — same seed, same grain",
      +  "maximum": 1000000,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • addedInput schema / properties / levels
      Added value: +{
      +  "additionalProperties": {
      +    "properties": {
      +      "black": {
      +        "maximum": 254,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "gamma": {
      +        "maximum": 10,
      +        "minimum": 0.1,
      +        "type": "number"
      +      },
      +      "out_black": {
      +        "maximum": 255,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "out_white": {
      +        "maximum": 255,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "white": {
      +        "maximum": 255,
      +        "minimum": 1,
      +        "type": "number"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "description": "Levels per channel (rgb = all three, r/g/b single), values 0..255: input black/white point, gamma (above 1 brightens midtones), output black/white. Example: {\"rgb\": {\"black\": 12, \"white\": 240, \"gamma\": 1.1}}",
      +  "propertyNames": {
      +    "enum": [
      +      "rgb",
      +      "r",
      +      "g",
      +      "b"
      +    ],
      +    "type": "string"
      +  },
      +  "required": [
      +    "rgb",
      +    "r",
      +    "g",
      +    "b"
      +  ],
      +  "type": "object"
      +}
  4. First observed

TDQS

A4.2/5.0
Behavior5/5

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

The description richly explains behavior beyond the annotations: deterministic/reproducible output ('same recipe on the same image always yields the same result'), non-destructive write to gallery ('lands as a new gallery image'), fixed processing order ('like a node stack: exposure → levels → curves → hue/saturation → look (LUT) → gradient map → grain'), synchronous/no-polling contract ('the graded image_url comes straight back'), and the requirement 'At least one adjustment OR from_colorist'. Annotations only say readOnlyHint=false, destructiveHint=false; the description's extra disclosure is substantial.

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

Conciseness3/5

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

The content is front-loaded with purpose, then gets long with lists of fields and pipeline order that are already documented by the schema. Some sentences are dense but informative; the description is about 3-4 sentences compressed, with several details that restate schema. It's not bloated, but not sufficiently concise given schema coverage.

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?

For an 18-param mutation tool with no output schema, the description covers behavior (deterministic, sync return, gallery write), ordering, the from_colorist branch and the minimum-adjustment requirement. It doesn't cover edge cases like error conditions, or what happens to existing recipe state beyond 'new gallery image'. Given schema describes parameters fully, the contextual gaps are minor, but still not exhaustive.

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 coverage is 100%, so the schema already documents all 18 parameters with types, ranges and descriptions. The description echoes field names ('exposure, saturation, hue, lightness, contrast, film grain') and clarifies the order they apply in, plus the mutual exclusion 'Not together with contrast on the rgb channel' (present in schema). The description adds the fixed-order semantics and the from_colorist behavior ('apply the sliders on top'), which is useful, but mostly repeats the schema. Baseline 3 is appropriate.

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?

States a specific verb+resource ('Apply a deterministic colour grade to an image already in the project gallery') and immediately distinguishes itself from generation siblings with 'no re-generation, no provider, no credits'. The pipeline names (exposure, saturation, hue, lightness, contrast, film grain) make it distinguishable from lab_grade_clip and lab_grade_from_resolve.

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

Usage Guidelines4/5

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

Provides a clear context ('image already in the project gallery') and an entry condition ('At least one adjustment OR from_colorist is required'), plus a routing hint for from_colorist. It doesn't explicitly name alternate tools like lab_grade_clip or lab_grade_suggest, so it lacks sibling exclusion, but the usage context is clear.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources