
coolors-mcp
io.github.x51xxx/coolors-mcp
Color tools for AI agents: WCAG/APCA contrast, Material 3 HCT themes, palettes, DESIGN.md audits
Documentation
Coolors MCP
A Model Context Protocol (MCP) server that gives AI assistants real color tools: perceptual color descriptions, WCAG 2.x and APCA contrast checks with exact fixes, Material Design 3 themes built on Google's HCT, palettes and gradients, color-vision-deficiency checks, CSS theme matching and refactoring, image color extraction, and DESIGN.md audits.
- 31 tools, all read-only and local: no API keys, no network access, stdio transport.
- Documentation: https://x51xxx.github.io/coolors-mcp/
- Changelog: CHANGELOG.md
Features
- Colors an agent can "see":
describe_colorturns a hex code into a name, temperature, lightness/vividness, OKLCH/HCT/HSL/RGB values, the best text color and likely UI roles. - Contrast without guessing: WCAG 2.x ratio and APCA Lc (matches
apca-w30.1.9) side by side;fix_contrastfinds the closest same-hue color that meets AA, AAA, UI or an APCA target. - Google's HCT: the CAM16-based HCT from
@material/material-color-utilitiesdrives Material themes, tonal palettes and scales, state colors, harmonization and dislike detection. - Material Design 3: light and dark schemes, tonal palettes, harmonization, and CSS custom properties from one source color.
- UI palettes: a contrast-checked light + dark 60-30-10 UI token set, semantic (primary/secondary/tertiary + status) palettes, Tailwind-style tonal scales, interaction-state colors and a palette cohesion score.
- Palettes and gradients: color-harmony palettes (HCT, OKLCH, RYB or HSL wheel), palettes with locked colors, gradients interpolated in OKLCH, OKLab, Lab, LCh, HCT, HSL or RGB, and color-blind-safe categorical palettes for charts.
- Color-vision deficiency: simulation of 7 deficiency types (Machado et al. 2009 matrices in linear sRGB for the protan, deutan and tritan types; achromatopsia as a grey of equal luminance) and pairwise collision audits of palettes.
- Distance metrics: ΔE2000, ΔE94, ΔE76, Euclidean RGB and weighted RGB.
- CSS theme matching: map hard-coded colors to your theme's custom properties, and rewrite a stylesheet to use them.
- Images: dominant colors with Celebi quantization, and a Material theme from an image.
- Dislike analysis: detect and fix "bile zone" dark yellow-greens.
- Export: CSS custom properties, SCSS, Tailwind config, W3C design tokens, JSON, or a DESIGN.md
colors:block. - DESIGN.md audits: contrast, color-blind collisions, duplicates and broken references in a DESIGN.md file.
Installation
Requires Node.js 20 or newer and an MCP client. The package runs with npx, so there is nothing to install first.
Claude Code
claude mcp add coolors -- npx -y @trishchuk/coolors-mcp
Run /mcp in Claude Code to check that coolors is connected.
Claude Desktop, Cursor and other MCP clients
Add the server to the client's MCP configuration (for Claude Desktop, claude_desktop_config.json), then restart the client:
{
"mcpServers": {
"coolors": {
"command": "npx",
"args": ["-y", "@trishchuk/coolors-mcp"]
}
}
}
Global install
npm install -g @trishchuk/coolors-mcp
claude mcp add coolors -- coolors-mcp
In JSON configs, use "command": "coolors-mcp" with no args.
From source
git clone https://github.com/x51xxx/coolors-mcp.git
cd coolors-mcp
pnpm install
pnpm run build
Then point your client at the built server: "command": "node", "args": ["/absolute/path/to/coolors-mcp/dist/bin/server.js"].
The server has no configuration options or environment variables. The metadata for the official MCP Registry (io.github.x51xxx/coolors-mcp) is in server.json; the registry listing goes live with the next npm release.
More setup detail: Installation · Troubleshooting
Quick example
Ask your assistant "Is #6366f1 readable on white? Fix it if not." It calls check_contrast:
{ "foreground": "#6366f1", "background": "#ffffff" }
## WCAG 2.x luminance ratio
Contrast Ratio: 4.47:1
- AA (normal text): ✗ Fail (need 4.5:1)
- AA (large text): ✓ Pass (need 3:1)
- AAA (normal text): ✗ Fail (need 7:1)
- AAA (large text): ✗ Fail (need 4.5:1)
## Agent Guidance
- **Nearest AA fix (hue-preserving)**: foreground `#6365f0` on `#ffffff` → 4.52:1 (APCA Lc 70.9, ΔE=0.4)
Tools
All 31 tools, grouped as in the tools reference. Every tool takes colors as strings in any supported format.
Agent tools (docs)
| Tool | What it does |
|---|---|
describe_color | Describes up to 20 colors in human terms: name, temperature, lightness and vividness, OKLCH/HCT/HSL/RGB, readable text color, UI roles, pitfalls. |
fix_contrast | Finds the closest same-hue color that meets aa, aaa, aa-large, ui, apca-body, apca-content or apca-large. Adjusts foreground, background or either. |
design_ui_palette | Builds a contrast-checked light + dark UI token set (60-30-10) from one brand color, as a report, CSS, JSON or W3C tokens. |
audit_ui_colors | Audits up to 100 foreground/background pairs and 64 swatches: WCAG, APCA, CVD contrast drops, vibration and disliked colors, with fixes. |
generate_categorical_palette | Generates 2–12 chart or tag colors that stay distinct for normal vision and protan/deutan/tritan viewers. |
{ "foreground": "#9e9e9e", "background": "#ffffff", "target": "aa" }
fix_contrast returns:
# Accessible Contrast Solution (aa)
- **Status**: ✓ Target achieved
- **Adjusted**: foreground (ΔE2000 shift = 14.12)
- **Before**: `#9e9e9e` on `#ffffff` → 2.68:1 (APCA Lc 52.1)
- **After**: `#767677` on `#ffffff` → **4.54:1** (APCA Lc **71.5**)
Color operations (docs)
| Tool | What it does |
|---|---|
convert_color | Converts a color to hex, rgb, hsl, lab, hct, oklab or oklch. |
color_distance | Perceptual distance between two colors: deltaE2000 (default), deltaE94, deltaE76, euclidean or weighted. |
check_contrast | WCAG 2.x ratio, APCA Lc or both, with CVD warnings and the nearest same-hue AA fix when a pair fails. |
adjust_color | lighten, darken, saturate, desaturate, hue-shift, tint, shade, grayscale, invert or mix, in OKLCH (default), HCT or HSL. |
| Call | Result |
|---|---|
convert_color {"color": "#6750a4", "to": "hct"} | hct(299.0, 47.9, 40.1) |
convert_color {"color": "rebeccapurple", "to": "oklch"} | oklch(44.0% 0.1603 303.4) |
color_distance {"color1": "#6750a4", "color2": "#7f67be"} | Distance between #6750a4 and #7f67be: 8.80 |
adjust_color {"color": "#6750a4", "operation": "lighten", "amount": 10} | #846ec5 |
adjust_color {"color": "#6750a4", "operation": "mix", "with": "#ff6b6b", "amount": 0.5} | #b1648e |
Accessibility (docs)
| Tool | What it does |
|---|---|
simulate_color_blindness | Shows how up to 64 colors look under protanopia, deuteranopia, tritanopia, the three anomalies and achromatopsia. |
check_palette_accessibility | Flags palette pairs whose ΔE2000 falls below a threshold (default 10) under each deficiency type. |
check_contrast (above) covers text/background pairs. With "algorithm": "both", black on white gives Contrast Ratio: 21.00:1 and Lc: 106.0 (dark text on light bg).
Palettes (docs)
| Tool | What it does |
|---|---|
generate_palette | Color-harmony palette (monochromatic, analogous, complementary, split-complementary, triadic, tetradic, square, compound, shades-and-tints), 3–12 colors. |
generate_palette_with_locks | Palette of 2–20 colors that keeps your locked colors, in harmony, contrast or gradient mode. |
generate_gradient | Gradient of steps total colors (every input color is kept) as an array, hex list or CSS linear-gradient/radial-gradient. |
export_palette | Exports up to 256 colors as css, scss, tailwind, tokens (W3C), json or design-md. |
{
"colors": ["#6750a4", "#ff6b6b"],
"steps": 5,
"interpolation": "oklch",
"format": "css-linear"
}
generate_gradient returns:
linear-gradient(90deg, #6750a4 0.0%, #9153a9 25.0%, #ba57a1 50.0%, #e05d8c 75.0%, #ff6b6b 100.0%)
export_palette with "format": "design-md" writes a colors: block for a DESIGN.md front matter:
{
"colors": ["#6750a4", "#625b71", "#7e5260"],
"format": "design-md",
"names": ["primary", "secondary", "tertiary"]
}
colors:
primary: "#6750a4"
secondary: "#625b71"
tertiary: "#7e5260"
Visual cohesion (docs)
| Tool | What it does |
|---|---|
generate_tonal_scale | Tailwind-style 50–950 scale (or custom stops) from a seed color; stop 50 is HCT tone 95, 500 is tone 50, 950 is tone 5. Includes CSS variables. |
generate_state_colors | Hover, active, pressed, focus, disabled and selected colors from a base color, for light or dark surfaces. |
analyze_palette_consistency | Scores tonal step uniformity, chroma cohesion and hue harmony, with an overall 0–100 cohesion score. |
generate_semantic_palette | Primary, secondary, tertiary and success/warning/error/info colors with matched tone and chroma. |
analyze_palette_consistency with {"colors": ["#6750a4", "#7f67be", "#a48dc8", "#ff0000"]} scores the palette 75/100 and reports Likely outlier: #ff0000 (chroma 113 vs avg 61).
Material Design 3 (docs)
| Tool | What it does |
|---|---|
generate_material_theme | Light and dark Material 3 schemes (primary, secondary, tertiary, error, surface roles) from a source color. |
harmonize_colors | For 2–10 colors: harmonize shifts each hue toward the first color, blend mixes them into one, temperature warms or cools them. |
generate_tonal_palette | Material tonal palette for the standard tones or your own list of tones (0–100). |
generate_material_theme with {"sourceColor": "#6750a4"} returns, among others, primary: #6750a4, primaryContainer: #e9ddff and onPrimaryContainer: #22005d for the light scheme, and primary: #cfbcff and onPrimary: #381e72 for the dark scheme.
CSS theme matching (docs)
| Tool | What it does |
|---|---|
match_theme_color | Finds the theme custom property closest to a color, with a confidence score. |
match_theme_colors_batch | The same for up to 50 colors. |
refactor_css_with_theme | Rewrites hard-coded colors in declaration values to var(--…) references, with an optional report. |
generate_theme_css | Material tonal palettes and light-theme role mappings as CSS custom properties. |
{
"css": ".button { background: #6850a0; color: #fffbfe; }",
"themeCSS": ":root { --color-primary: #6750a4; --color-surface: #fffbfe; --color-on-surface: #1c1b1f; }"
}
refactor_css_with_theme rewrites the rule to:
.button { background: /* #6850a0 */ var(--color-primary); color: /* #fffbfe */ var(--color-surface); }
Images and color psychology (docs)
| Tool | What it does |
|---|---|
extract_image_colors | Dominant colors of an RGBA image (Celebi quantization) as JSON, CSS or a palette. |
generate_theme_from_image | A Material 3 theme seeded from an image's colors. |
analyze_color_likability | Checks whether a color is a universally disliked dark yellow-green and returns a fixed version. |
fix_disliked_colors_batch | Checks up to 100 colors and returns liked versions. |
Images are passed as raw pixels: {"imageData": {"width": 4, "height": 4, "data": [103, 80, 164, 255, …]}}, a flat RGBA array of width × height × 4 integers. analyze_color_likability with {"color": "#6b6b00"} reports the color as disliked and suggests #b0b048.
DESIGN.md (docs)
| Tool | What it does |
|---|---|
audit_design_md | Audits the color tokens of a DESIGN.md file and suggests fixes. |
It reads the YAML front matter and ```yaml blocks, and checks WCAG and APCA contrast for pairs declared in components (backgroundColor/textColor) and pairs inferred from token names (on-X ↔ X, text ↔ surface tokens). It also reports color-blind collisions between accent and status colors, exact and near-duplicate tokens, disliked colors, broken {colors.x} references and a missing primary. Failing pairs get a same-hue fix. Values the auditor cannot evaluate (hwb(), lab(), lch(), color(), color-mix(), transparent) are listed, never guessed.
{
"designMd": "---\nname: Acme\ncolors:\n primary: \"#cc785c\"\n on-primary: \"#ffffff\"\n---\n",
"textThreshold": 4.5,
"cvdThreshold": 10
}
…
| `on-primary` #ffffff | `primary` #cc785c | inferred · on-X ↔ X | 3.28:1 | 4.5:1 (text) | -65.3 | ✗ | on-primary → `#262829` (4.52:1) |
…
Claude Code does not load DESIGN.md on its own: reference it as @DESIGN.md from your CLAUDE.md.
Supported color formats
Every color parameter accepts:
| Format | Examples |
|---|---|
| Hex | #639, #6750a4, #6750a4ff (alpha is ignored), bare 6750a4 |
| CSS named colors | rebeccapurple, white |
rgb() / rgba() | rgb(103, 80, 164), rgb(103 80 164), rgb(40% 31% 64%) |
hsl() / hsla() | hsl(256, 34%, 48%), hsl(256 34% 48%) |
oklch() / oklab() | oklch(49.6% 0.1305 293.7), oklab(0.496 0.03 -0.12) |
hct() | hct(299, 47.9, 40.1) |
rgb() channels are clamped to 0–255 as in CSS, hsl() hues wrap around. Not supported: hwb(), lab(), lch(), color(), color-mix() and transparent. Invalid hex such as #ggg or #12345 is rejected. convert_color can output lab(…), but that output is not accepted back as input.
Errors and limits
Errors come back as normal tool results with isError: true and a message the model can read and act on:
- Unparseable color:
Invalid color format: nope - Wrong type, missing parameter or a value over a limit:
Invalid arguments for tool 'convert_color': color: Invalid input: expected string, received number - Tool-specific checks, for example
steps (3) must be at least the number of input colors (4)fromgenerate_gradient.
Calling a tool name that does not exist is a JSON-RPC protocol error, not a tool result.
Main input limits (the tools reference lists all of them):
| Input | Limit |
|---|---|
describe_color colors | 20 |
simulate_color_blindness, check_palette_accessibility, analyze_palette_consistency colors | 64 |
generate_gradient colors / steps | 32 / 3–100 |
audit_ui_colors pairs / swatches | 100 / 64 |
fix_disliked_colors_batch colors | 100 |
export_palette colors | 256 |
themeCSS | 200 000 characters |
css (refactor_css_with_theme), designMd | 500 000 characters |
imageData | 65 536 pixels (e.g. 256×256), data.length = width × height × 4 |
How it works
- HCT is Google's CAM16-based color space from
@material/material-color-utilities: hue and chroma come from CAM16, tone is CIE L*. For example,#6750a4ishct(299.0, 47.9, 40.1). See HCT. - Theme matching scores each theme variable by HCT distance (60%), semantic role for the usage context (20%) and tone suitability (20%). See Theme matching.
- Theme parsing reads
--name: value;custom properties anywhere inthemeCSS, light and dark blocks alike. Only opaque colors count;var()aliases are not resolved. - Refactoring only touches colors inside declaration values. Selectors, comments, strings,
url(…), custom-property definitions and translucent colors are left alone; translucent colors get a warning.
Development
This project uses pnpm. Install it with npm i -g pnpm or corepack enable.
pnpm install # install dependencies
pnpm run build # build to dist/
pnpm test # run the test suite
pnpm run lint # prettier --check, eslint, tsc --noEmit
pnpm run format # prettier --write, eslint --fix
pnpm run docs:dev # documentation site
To try the tools interactively, run the built server under the MCP Inspector:
npx @modelcontextprotocol/inspector node dist/bin/server.js
Source layout:
src/
├── bin/server.ts # MCP server entry: registers all tools
├── tools/ # one file per tool group
├── color/ # conversions, HCT, APCA, CVD simulation, metrics, quantization, DESIGN.md parsing
└── theme/ # CSS theme parsing, matching and refactoring
Contributing
Contributions are welcome. Before opening a pull request, make sure pnpm test and pnpm run lint pass.
License
MIT © Taras Trishchuk
Credits
- Built on the Model Context Protocol TypeScript SDK.
- HCT, Material color schemes and the Celebi quantizer come from or follow Google's Material Color Utilities.
- APCA contrast follows
apca-w3; color-vision simulation for the protan, deutan and tritan types uses the matrices of Machado, Oliveira and Fernandes (2009).
@trishchuk/coolors-mcpnpm install @trishchuk/coolors-mcpRelated Servers
io.github.x51xxx/antigravity-mcp-server
Hand work from Claude Code or Cursor to Google Antigravity CLI: delegation, reviews, digests
io.github.x51xxx/codex-mcp-tool
MCP server bridging AI assistants to OpenAI Codex CLI for code analysis and review
io.github.x51xxx/kimi-mcp-server
MCP server bridging AI assistants to Moonshot AI Kimi Code CLI for code analysis and review