Color tools for LLMs
  • JavaScript 99.4%
  • Dockerfile 0.6%
Find a file
brad 993f963a0c
All checks were successful
Test / test (push) Successful in 40s
Delete .claude/color-accessibility-metrics.md
2026-03-02 17:32:04 -08:00
.forgejo/workflows fix: pin workflow-dispatch action to @main and add explicit ref 2026-02-26 22:19:28 +00:00
examples feat: just describe_color 2026-02-26 16:46:42 -08:00
lib feat: add Lab+HWB, color_info/describe_color should use resolveColorInput 2026-02-26 15:02:42 -08:00
test feat: just describe_color 2026-02-26 16:46:42 -08:00
tools feat: just describe_color 2026-02-26 16:46:42 -08:00
.dockerignore
.gitignore
app.js
Dockerfile fix: color-names needs node 22 2026-02-26 14:01:54 -08:00
index.js
package-lock.json
package.json
README.md feat: just describe_color 2026-02-26 16:46:42 -08:00
vitest.config.js

color-theory-mcp

MCP server exposing color tools, semantic context, and accessibility scores to AI agents - powered by David Aerne's color-name-list (31,000+ named colors), pro-color-harmonies, and rampensau. You should give those projects a star and a follow, this is simply a vibe coded wrapper for them.

Tools

Lookup & Description

Tool Description
find_color Find closest named colors to any input — first match includes full color space data (RGB, HSL, CMYK, OKLCH, Lab, HWB)
search_colors Filter colors by keyword and/or hue range — first match includes full color space data
list_color_groups List hue-based color groups with counts
describe_color Comprehensive color analysis: all color spaces, descriptive words, color family with meanings/usage, WCAG accessibility, closest named colors

Conversion & Generation

Tool Description
convert_color Convert any color format → all color spaces (hex, RGB, HSL, CMYK, OKLCH, Lab, HWB)
generate_palette Generate 6-color harmony palettes (analogous, complementary, triadic, tetradic, splitComplementary, tintsShades) with style variants, modifiers, and pairwise WCAG contrast data
generate_ramp Generate color ramps/gradients with configurable hue cycling, saturation/lightness ranges, and curve methods — ideal for infographics and charts
generate_swatch Generate PNG swatch images with color squares and name/hex labels — single colors or palette strips

Accessibility

Tool Description
check_contrast Check WCAG 2.2 contrast ratio between any two colors — returns ratio, human-friendly score (AAA/AA/FAIL), and pass/fail for all WCAG thresholds

Setup

Running the server

npm install
node index.js

The server starts on port 3013 by default (configurable via MCP_PORT environment variable).

  • Health check: GET http://localhost:3013/health
  • MCP endpoint: POST http://localhost:3013/mcp

Docker

docker pull git.brads.house/brad/color-mcp:latest
docker run -d --name color-mcp -p 3013:3013 git.brads.house/brad/color-mcp:latest

Or build locally:

docker build -t color-mcp .
docker run -d --name color-mcp -p 3013:3013 color-mcp

Connecting to Claude Desktop

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):

{
  "mcpServers": {
    "color": {
      "url": "http://localhost:3013/mcp"
    }
  }
}

Connecting to Claude Code

Add to your project's .mcp.json:

{
  "mcpServers": {
    "color": {
      "type": "url",
      "url": "http://localhost:3013/mcp"
    }
  }
}

Or add it via the CLI:

claude mcp add color --transport http http://localhost:3013/mcp

Other MCP clients

Any MCP-compatible client can connect using the HTTP+SSE transport. Point it at http://localhost:3013/mcp — the server speaks JSON-RPC 2.0.

Examples

Generate a harmony palette

{
  "name": "generate_palette",
  "arguments": {
    "color": "#e85d26",
    "harmony": "analogous"
  }
}

Analogous harmony palette from #e85d26

Split complementary palette

{
  "name": "generate_palette",
  "arguments": {
    "color": "#ff1493",
    "harmony": "splitComplementary",
    "style": "square"
  }
}

Split complementary palette from #ff1493

Generate a color ramp

{
  "name": "generate_ramp",
  "arguments": {
    "color": "#006994",
    "total": 7,
    "hCycles": 0,
    "sRange": [0.6, 0.8],
    "lRange": [0.15, 0.9]
  }
}

Monochromatic teal ramp from #006994

Generate a swatch strip

{
  "name": "generate_swatch",
  "arguments": {
    "colors": ["#ff5733", "#006994", "#2ecc71", "#9b59b6", "#f39c12"]
  }
}

Swatch strip with five colors

Find closest named colors

{
  "name": "find_color",
  "arguments": { "color": "ocean" }
}
{
  "query": "ocean",
  "hex": "#005493",
  "results": [
    {
      "name": "Ocean", "hex": "#005493", "distance": 0,
      "rgb": { "r": 0, "g": 84, "b": 147 },
      "hsl": { "h": 206, "s": 100, "l": 29 },
      "cmyk": { "c": 100, "m": 43, "y": 0, "k": 42 },
      "oklch": { "l": 0.439, "c": 0.124, "h": 249.93 },
      "lab": { "l": 34.24, "a": -2.28, "b": -41.51 },
      "hwb": { "h": 205.71, "w": 0, "b": 42.35 }
    },
    { "name": "Standing Waters", "hex": "#005599", "distance": 0.84 },
    { "name": "Blue Olympus", "hex": "#015193", "distance": 1.22 }
  ]
}

Convert a color to all formats

All tools accept any color format as input: hex, color name, rgb(), hsl(), cmyk(), oklch(), lab(), or hwb().

{
  "name": "convert_color",
  "arguments": { "color": "rgb(255, 87, 51)" }
}
{
  "input": "rgb(255, 87, 51)",
  "hex": "#ff5733",
  "rgb": { "r": 255, "g": 87, "b": 51 },
  "hsl": { "h": 11, "s": 100, "l": 60 },
  "cmyk": { "c": 0, "m": 66, "y": 80, "k": 0 },
  "oklch": { "l": 0.68, "c": 0.21, "h": 33.69 },
  "lab": { "l": 61.03, "a": 63.55, "b": 55.96 },
  "hwb": { "h": 10.59, "w": 20, "b": 0 },
  "nearestName": { "name": "Poppy Surprise", "hex": "#ff5630", "exact": false, "distance": 0.47 }
}

Describe a color

{
  "name": "describe_color",
  "arguments": { "color": "#006994" }
}
{
  "input": "#006994",
  "hex": "#006994",
  "name": "Sea Blue",
  "rgb": { "r": 0, "g": 105, "b": 148 },
  "hsl": { "h": 197, "s": 100, "l": 29 },
  "cmyk": { "c": 100, "m": 29, "y": 0, "k": 42 },
  "oklch": { "l": 0.492, "c": 0.105, "h": 235.54 },
  "lab": { "l": 41.09, "a": -13.73, "b": -31.3 },
  "hwb": { "h": 197.43, "w": 0, "b": 41.96 },
  "descriptors": ["dark", "dim", "gloomy", "dull", "shady", "cold", "cool", "blue", "blueish"],
  "bestContrast": "white",
  "family": {
    "name": "blue",
    "description": "Blue often feels calm, steady, and trustworthy...",
    "meanings": ["mystery", "trust", "reliability", "calmness", "..."],
    "usage": ["backgrounds", "contrast", "security", "finance", "technology", "..."]
  },
  "accessibility": {
    "luminance": 0.1224,
    "contrastOnWhite": {
      "ratio": 6.09,
      "aa": { "normalText": true, "largeText": true, "uiComponents": true },
      "aaa": { "normalText": false, "largeText": true }
    },
    "contrastOnBlack": {
      "ratio": 3.45,
      "aa": { "normalText": false, "largeText": true, "uiComponents": true },
      "aaa": { "normalText": false, "largeText": false }
    }
  },
  "closestNamed": [
    { "name": "Hydra", "hex": "#006995", "distance": 0.3 },
    { "name": "Port au Prince", "hex": "#006a93", "distance": 0.78 }
  ]
}

Check contrast between two colors

{
  "name": "check_contrast",
  "arguments": { "foreground": "#006994", "background": "#ffffff" }
}
{
  "foreground": { "hex": "#006994", "luminance": 0.1224 },
  "background": { "hex": "#ffffff", "luminance": 1 },
  "contrast": {
    "ratio": 6.09,
    "score": "AA",
    "wcag": {
      "aa": { "normalText": true, "largeText": true, "uiComponents": true },
      "aaa": { "normalText": false, "largeText": true }
    }
  }
}

Architecture

Architecture diagram

  • Transport: JSON-RPC 2.0 over HTTP (POST /mcp)
  • Port: 3013 (configurable via MCP_PORT)
  • Data: color-name-list npm package (bundled at build time)
  • Color spaces: hex, RGB, HSL, CMYK, OKLCH, CIELab, HWB
  • Color matching: CIEDE2000 perceptual distance (via culori)
  • Accessibility: culori (WCAG 2.2 luminance + contrast ratio)
  • Palettes: pro-color-harmonies (OKLCH perceptual color space)
  • Ramps: rampensau (HSL with configurable easing curves)
  • Images: @napi-rs/canvas (Skia-based PNG rendering)

Project structure

app.js            ← Express app + JSON-RPC dispatch (importable)
index.js          ← Server entrypoint (calls app.listen)
tools/
  lookup.js       ← find/search/describe tools
  convert.js      ← color space conversion
  palette.js      ← harmony palette generation
  ramp.js         ← gradient ramp generation
  swatch.js       ← PNG swatch image generation
  accessibility.js ← WCAG contrast checking
lib/
  color-math.js   ← Color math utilities + universal input parser
  color-convert.js ← OKLCH/Lab/HWB conversions + WCAG accessibility (via culori)
  swatch-renderer.js ← Canvas drawing for swatch images
test/             ← Vitest test suite

Testing

npm test            # run all tests
npm run test:watch  # watch mode