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";

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