Skip to main content
Glama

analyze_colors

Extract dominant colors from images or specific regions using K-Means clustering, returning color names and frequencies for visual analysis.

Instructions

Extract dominant colors from an image region using K-Means clustering in LAB color space. Returns colors sorted by frequency with human-readable names from color.pizza.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
imageYesPath to the image file
bboxNoOptional bounding box as [ymin, xmin, ymax, xmax] normalized 0-1000. Defaults to full image.
topNoNumber of dominant colors to return (default: 5)

Implementation Reference

  • The primary handler function that executes the analyze_colors tool logic: loads image or region pixels, applies K-Means clustering for dominant colors in LAB space, computes average color, color names, percentages, confidence, and formats response as JSON.
    export async function handleAnalyzeColors(args: Record<string, unknown>) {
      const image = args.image as string;
      const bbox = args.bbox as [number, number, number, number] | undefined;
      const top = (args.top as number) || 5;
    
      let pixels: Uint8Array;
      let width: number;
      let height: number;
    
      if (bbox) {
        // Analyze specific region
        const region = await getRegionPixels(image, bbox);
        pixels = region.pixels;
        width = region.width;
        height = region.height;
      } else {
        // Analyze full image
        const { image: img, metadata } = await loadImage(image);
        const { data } = await img.raw().toBuffer({ resolveWithObject: true });
        pixels = new Uint8Array(data);
        width = metadata.width;
        height = metadata.height;
      }
    
      const totalPixels = pixels.length / 3;
    
      // Run K-Means clustering
      const result = kmeansCluster(pixels, top);
    
      // Calculate average color
      let avgR = 0,
        avgG = 0,
        avgB = 0;
      for (let i = 0; i < pixels.length; i += 3) {
        avgR += pixels[i];
        avgG += pixels[i + 1];
        avgB += pixels[i + 2];
      }
      avgR = Math.round(avgR / totalPixels);
      avgG = Math.round(avgG / totalPixels);
      avgB = Math.round(avgB / totalPixels);
    
      // Build dominant colors array sorted by count
      const sortedIndices = result.counts
        .map((count, idx) => ({ count, idx }))
        .sort((a, b) => b.count - a.count)
        .map((item) => item.idx);
    
      const dominant = await Promise.all(
        sortedIndices.map(async (idx) => {
          const [r, g, b] = result.centroids[idx];
          const percentage = (result.counts[idx] / result.labels.length) * 100;
          const name = await getColorName(r, g, b);
    
          return {
            hex: rgbToHex(r, g, b),
            rgb: [r, g, b],
            hsl: rgbToHsl(r, g, b),
            name,
            percentage: Math.round(percentage * 100) / 100,
          };
        })
      );
    
      // Determine confidence based on variance
      // Low variance = flat colors (UI), high variance = photo/gradient
      const confidence =
        result.variance < 50 ? "high" : result.variance < 200 ? "medium" : "low";
    
      const average = {
        hex: rgbToHex(avgR, avgG, avgB),
        rgb: [avgR, avgG, avgB],
        name: await getColorName(avgR, avgG, avgB),
      };
    
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              {
                dominant,
                average,
                confidence,
                region: bbox
                  ? {
                      bbox,
                      size: [width, height],
                      totalPixels,
                    }
                  : {
                      fullImage: true,
                      size: [width, height],
                      totalPixels,
                    },
              },
              null,
              2
            ),
          },
        ],
      };
    }
  • Tool definition including name, description, and inputSchema for validation (image required, optional bbox and top_k).
    export const analyzeColorsTool: Tool = {
      name: "analyze_colors",
      description:
        "Extract dominant colors from an image region using K-Means clustering in LAB color space. Returns colors sorted by frequency with human-readable names from color.pizza.",
      inputSchema: {
        type: "object",
        properties: {
          image: {
            type: "string",
            description: "Path to the image file or URL (http/https)",
          },
          bbox: {
            type: "array",
            items: { type: "number" },
            minItems: 4,
            maxItems: 4,
            description:
              "Optional bounding box as [ymin, xmin, ymax, xmax] normalized 0-1000. Defaults to full image.",
          },
          top: {
            type: "number",
            description: "Number of dominant colors to return (default: 5)",
          },
        },
        required: ["image"],
      },
    };
  • src/index.ts:37-46 (registration)
    Registers analyzeColorsTool in the listToolsRequestHandler response.
    server.setRequestHandler(ListToolsRequestSchema, async () => {
      return {
        tools: [
          describeTool,
          detectTool,
          describeRegionTool,
          analyzeColorsTool,
        ],
      };
    });
  • src/index.ts:53-67 (registration)
    Dispatches to handleAnalyzeColors in the CallToolRequestHandler switch statement for 'analyze_colors'.
    switch (name) {
      case "describe":
        return await handleDescribe(args);
      case "detect":
        return await handleDetect(args);
      case "describe_region":
        return await handleDescribeRegion(args);
      case "analyze_colors":
        return await handleAnalyzeColors(args);
      default:
        return {
          content: [{ type: "text", text: `Unknown tool: ${name}` }],
          isError: true,
        };
    }
  • src/index.ts:22-22 (registration)
    Import of analyzeColorsTool and handleAnalyzeColors from the implementation file.
    import { analyzeColorsTool, handleAnalyzeColors } from "./tools/analyze-colors.js";

Tool Definition Quality

Score is being calculated. Check back soon.

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/simen/mcp-see'

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