Skip to main content
Glama

generate_linear_gradient

Create linear gradients with mathematical precision and CSS output by specifying colors, positions, angle, and interpolation methods for web design and UI development.

Instructions

Generate linear gradients with precise mathematical control and CSS output

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
colorsYesArray of color strings for the gradient
positionsNoStop positions (0-100). If not provided, colors are evenly distributed
angleNoGradient angle in degrees (0-360, default: 90)
interpolationNoInterpolation method for color transitionslinear
color_spaceNoColor space for interpolationrgb
stepsNoNumber of steps for stepped gradients (creates discrete color bands)

Implementation Reference

  • The core handler function `generateLinearGradient` that validates inputs, processes colors and positions, applies interpolation, generates CSS, and creates the tool response.
    async function generateLinearGradient(
      params: LinearGradientParams
    ): Promise<ToolResponse | ErrorResponse> {
      const startTime = Date.now();
    
      try {
        // Validate parameters
        const { error, value } = linearGradientSchema.validate(params);
        if (error) {
          return createErrorResponse(
            'generate_linear_gradient',
            'INVALID_PARAMETERS',
            `Invalid parameters: ${error.details.map(d => d.message).join(', ')}`,
            startTime,
            {
              details: error.details,
              suggestions: [
                'Ensure colors array has 2-20 valid color strings',
                'Check that positions (if provided) match color count and are in ascending order',
                'Verify angle is between 0-360 degrees',
                'Use supported interpolation methods: linear, ease, ease_in, ease_out, bezier',
              ],
            }
          );
        }
    
        const validatedParams = value as LinearGradientParams;
    
        // Validate colors
        const validatedColors = validateColors(validatedParams.colors);
    
        // Calculate positions
        const positions = calculatePositions(
          validatedColors.length,
          validatedParams.positions
        );
    
        // Apply interpolation
        const interpolatedPositions = applyInterpolation(
          positions,
          validatedParams.interpolation || 'linear'
        );
    
        // Generate CSS
        const angle =
          validatedParams.angle !== undefined ? validatedParams.angle : 90;
        const css = generateLinearGradientCSS(
          validatedColors,
          interpolatedPositions,
          angle,
          validatedParams.steps
        );
    
        // Prepare response data
        const colorData = validatedColors.map((colorObj, index) => ({
          color: colorObj.original,
          position: interpolatedPositions[index] || 0,
          hex: colorObj.color.toHex(),
          rgb: colorObj.color.toRgbString(),
          hsl: colorObj.color.toHslString(),
        }));
    
        const data: LinearGradientData = {
          css,
          type: 'linear',
          angle,
          colors: colorData,
          interpolation: validatedParams.interpolation || 'linear',
          color_space: validatedParams.color_space || 'rgb',
          total_stops: validatedParams.steps || validatedColors.length,
        };
    
        const executionTime = Date.now() - startTime;
    
        // Generate recommendations
        const recommendations: string[] = [];
        if (validatedColors.length > 5) {
          recommendations.push(
            'Consider using fewer colors for better performance'
          );
        }
        if (angle % 45 !== 0) {
          recommendations.push(
            'Consider using multiples of 45° for common gradient angles'
          );
        }
        if (validatedParams.steps && validatedParams.steps > 20) {
          recommendations.push(
            'High step counts may impact performance on older devices'
          );
        }
    
        return createSuccessResponse(
          'generate_linear_gradient',
          data,
          executionTime,
          {
            colorSpaceUsed: validatedParams.color_space || 'rgb',
            accessibilityNotes: [
              'Ensure sufficient contrast between gradient colors and any overlaid text',
              'Test gradient visibility with color vision deficiency simulators',
            ],
            recommendations,
            exportFormats: {
              css: css,
              scss: `$gradient: ${css};`,
              json: {
                type: 'linear',
                angle: validatedParams.angle || 90,
                colors: colorData,
                css: css,
              },
            },
          }
        );
      } catch (error) {
        logger.error('Error generating linear gradient', { error: error as Error });
        const errorMessage =
          error instanceof Error ? error.message : 'Unknown error occurred';
    
        return createErrorResponse(
          'generate_linear_gradient',
          'GRADIENT_GENERATION_ERROR',
          errorMessage,
          startTime,
          {
            details: { error: errorMessage },
            suggestions: [
              'Check that all colors are in valid formats (hex, rgb, hsl, named)',
              'Ensure positions array matches color count if provided',
              'Verify all parameters are within valid ranges',
            ],
          }
        );
      }
    }
  • JSON Schema definition for the tool parameters, defining types, constraints, and descriptions for inputs like colors, positions, angle, etc.
    parameters: {
      type: 'object',
      properties: {
        colors: {
          type: 'array',
          items: { type: 'string' },
          minItems: 2,
          maxItems: 20,
          description: 'Array of color strings for the gradient',
        },
        positions: {
          type: 'array',
          items: { type: 'number', minimum: 0, maximum: 100 },
          description:
            'Stop positions (0-100). If not provided, colors are evenly distributed',
        },
        angle: {
          type: 'number',
          minimum: 0,
          maximum: 360,
          default: 90,
          description: 'Gradient angle in degrees (0-360, default: 90)',
        },
        interpolation: {
          type: 'string',
          enum: ['linear', 'ease', 'ease_in', 'ease_out', 'bezier'],
          default: 'linear',
          description: 'Interpolation method for color transitions',
        },
        color_space: {
          type: 'string',
          enum: ['rgb', 'hsl', 'lab', 'lch'],
          default: 'rgb',
          description: 'Color space for interpolation',
        },
        steps: {
          type: 'number',
          minimum: 2,
          maximum: 100,
          description:
            'Number of steps for stepped gradients (creates discrete color bands)',
        },
      },
      required: ['colors'],
    },
  • Registration of the `generateLinearGradientTool` into the central `toolRegistry`.
    toolRegistry.registerTool(generateLinearGradientTool);
  • Helper function `generateLinearGradientCSS` that constructs the final CSS linear-gradient string from processed colors and positions.
    function generateLinearGradientCSS(
      colors: Array<{ color: Colord; original: string }>,
      positions: number[],
      angle: number,
      steps?: number
    ): string {
      let cssStops: string[];
    
      if (steps) {
        // Generate stepped gradient
        const steppedColors = generateSteppedPositions(
          colors.map(c => c.color.toHex()),
          steps
        );
        cssStops = steppedColors.map(
          ({ color, position }) => `${color} ${position}%`
        );
      } else {
        // Generate smooth gradient
        cssStops = colors.map((colorObj, index) => {
          const color = colorObj.color.toHex();
          const position = positions[index];
          return `${color} ${position}%`;
        });
      }
    
      return `linear-gradient(${angle}deg, ${cssStops.join(', ')})`;
    }
  • Joi runtime validation schema mirroring the tool's JSON schema for additional server-side validation.
    const linearGradientSchema = Joi.object({
      colors: Joi.array()
        .items(Joi.string())
        .min(2)
        .max(20)
        .required()
        .description('Array of color strings for the gradient'),
    
      positions: Joi.array()
        .items(Joi.number().min(0).max(100))
        .optional()
        .description(
          'Stop positions (0-100). If not provided, colors are evenly distributed'
        ),
    
      angle: Joi.number()
        .min(0)
        .max(360)
        .optional()
        .description('Gradient angle in degrees (0-360, default: 90)'),
    
      interpolation: Joi.string()
        .valid('linear', 'ease', 'ease_in', 'ease_out', 'bezier')
        .default('linear')
        .description('Interpolation method for color transitions'),
    
      color_space: Joi.string()
        .valid('rgb', 'hsl', 'lab', 'lch')
        .default('rgb')
        .description('Color space for interpolation'),
    
      steps: Joi.number()
        .integer()
        .min(2)
        .max(100)
        .optional()
        .description(
          'Number of steps for stepped gradients (creates discrete color bands)'
        ),
    });
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions 'CSS output' which hints at the return format, but doesn't describe what the CSS output looks like, whether it's a complete CSS rule or just the gradient value, error conditions, or performance characteristics. For a tool with 6 parameters and no output schema, this is insufficient.

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, efficient sentence that states the core purpose without unnecessary words. It's appropriately sized for this tool and front-loads the essential information. Every word earns its place.

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

Completeness2/5

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

Given the tool's complexity (6 parameters, mathematical operations, CSS generation) and the absence of both annotations and output schema, the description is incomplete. It doesn't explain what the tool returns (CSS string? complete rule?), error handling, or practical usage examples. The agent must rely heavily on the input schema alone.

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 100%, so the schema already documents all parameters thoroughly. The description adds no additional parameter semantics beyond what's in the schema. It mentions 'precise mathematical control' which vaguely relates to parameters like 'positions', 'angle', and 'interpolation', but provides no specific guidance. Baseline 3 is appropriate when schema does the heavy lifting.

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

Purpose4/5

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

The description clearly states the tool's purpose: 'Generate linear gradients with precise mathematical control and CSS output'. It specifies the verb ('generate'), resource ('linear gradients'), and output format ('CSS output'), though it doesn't explicitly distinguish it from sibling tools like 'generate_radial_gradient' or 'create_gradient_html'.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'generate_radial_gradient' for different gradient types or 'create_gradient_html' for HTML output instead of CSS. The agent must infer usage from the tool name and parameters alone.

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

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/keyurgolani/ColorMcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server