OKLCH Studio · Developers
Colour and contrast MCP server: tools for AI assistants
Updated 2026-10-18
OKLCH Studio runs a small Model Context Protocol server over HTTP at https://colorise.online/api/mcp. It gives an AI assistant 9 tools that do real colour maths on the server: converting between HEX, RGB, HSL and OKLCH, scoring a text and background pair with WCAG and APCA, adjusting a text colour to reach AA or AAA, building scales and exporting palettes.
This page documents what the endpoint actually does: the tools and their input schemas, the protocol version it reports, example requests and responses produced by the server's own code while the page was built, how to connect a client, and where the implementation is deliberately minimal.
What the server is and is not
The endpoint is a stateless JSON-RPC 2.0 handler. Each POST carries one JSON-RPC message (or an array of them) and gets one JSON response. It reports protocol version 2024-11-05 and server version 0.4.0, and it advertises exactly one capability, tools. It does not implement resources or prompts, and it does not stream: there are no sessions and no server-sent events.
A GET to the same URL returns a small JSON document with the server name, the transport label, the list of tool names and a link to the server card, which is the discovery file some clients and registries read.
There is no authentication and no API key. The tools only compute; they do not read or store anything about you. The responses are informational colour maths and not a legal accessibility audit.
Tools and input schemas
This table is generated from the same list the server returns for tools/list, so a tool added to the server appears here on the next build. Colour arguments are strings. Where a tool parses a colour it accepts HEX with or without #, rgb(), hsl() and oklch().
| Tool | What it does | Arguments |
|---|---|---|
| site_info | Return OKLCH Studio URLs and tool summaries for agents. | No arguments |
| list_intents | List locale-prefixed intent landing pages (default locale en). | locale (string) |
| convert_color | Convert HEX / RGB / HSL / oklch() to another format. Returns studio deep link. | color (string, required); to (string: hex | oklch | rgb | hsl | css) |
| check_contrast | WCAG 2.1 + APCA for a text/surface pair. Returns studio deep link. | fg (string, required); bg (string, required) |
| fix_contrast | Adjust text OKLCH lightness to WCAG AA or AAA (normal text) while keeping hue/chroma. Returns cannot_pass when impossible. | fg (string, required); bg (string, required); target (string: AA | AAA) |
| generate_scale | Build tint/shade/UI/default scale from one seed color; optional Tailwind @theme snippet. | color (string, required); kind (string: default | tints | shades | ui); steps (number) |
| export_palette | Export a palette as HEX list, CSS, SCSS, Tailwind @theme, or JSON tokens. | colors (array, required); format (string: hex | css | scss | tailwind | json); semantic (boolean) |
| share_link | Build a shareable URL with prefilled contrast or picker state (returns traffic to the site). | intent (string: contrast | picker | from-image, required); locale (string); fg (string); bg (string); c (string); color (string) |
| lookup_reference | Look up a Tailwind v4 stop (e.g. blue-500) or CSS named color (e.g. rebeccapurple): HEX, oklch(), AA suggestion on the swatch, page URL. | name (string, required) |
Every schema sets additionalProperties to false. Most maths tools return a studio_url field, a link that opens the same colours in the interactive tool, so an assistant can hand the result to a person.
A tools/list entry (check_contrast)
{
"name": "check_contrast",
"description": "WCAG 2.1 + APCA for a text/surface pair. Returns studio deep link.",
"inputSchema": {
"type": "object",
"properties": {
"fg": {
"type": "string",
"description": "Foreground (text) color"
},
"bg": {
"type": "string",
"description": "Background (surface) color"
}
},
"required": [
"fg",
"bg"
],
"additionalProperties": false
}
}JSON-RPC requests and responses
Start with initialize. The server answers with its protocol version, capabilities and name:
initialize request
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {}
}initialize response
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {}
},
"serverInfo": {
"name": "OKLCH Studio",
"version": "0.4.0"
}
}
}The handler does not negotiate: it returns the same protocol version whatever the client offers, and it does not read the request parameters. tools/list takes no parameters and returns { tools: [...] } with the entries described above.
tools/list request
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}A tool call puts the tool name and its arguments in params. The result is always a content array with one text item whose text is the pretty-printed JSON payload of the tool. In the examples below the payload is shown decoded, not as an escaped string.
tools/call: check_contrast
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "check_contrast",
"arguments": {
"fg": "#767676",
"bg": "#ffffff"
}
}
}Payload inside result.content[0].text
{
"fg": "#767676",
"bg": "#FFFFFF",
"wcag": {
"ratio": 4.542224959605253,
"ratioLabel": "4.54:1",
"lc": 72,
"lcLabel": "72",
"wcagNormal": "AA",
"wcagLarge": "AAA",
"apcaUi": "Pass",
"apcaBody": "Fail"
},
"studio_url": "https://colorise.online/en/contrast?fg=767676&bg=ffffff",
"disclaimer": "Informational WCAG/APCA readout — not a legal accessibility audit."
}tools/call: fix_contrast
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "fix_contrast",
"arguments": {
"fg": "#777777",
"bg": "#ffffff"
}
}
}Payload inside result.content[0].text
{
"fg_before": "#777777",
"fg_after": "#6B6B6B",
"bg": "#FFFFFF",
"target": "AA",
"changed": true,
"achieved": true,
"cannot_pass": false,
"hue_preserved": true,
"wcag_before": {
"ratio": 4.478089453577214,
"ratioLabel": "4.48:1",
"lc": 71,
"lcLabel": "71",
"wcagNormal": "Fail",
"wcagLarge": "AA",
"apcaUi": "Pass",
"apcaBody": "Fail"
},
"wcag_after": {
"ratio": 5.32921162976606,
"ratioLabel": "5.33:1",
"lc": 77,
"lcLabel": "77",
"wcagNormal": "AA",
"wcagLarge": "AAA",
"apcaUi": "Pass",
"apcaBody": "Pass"
},
"oklch_after": "oklch(0.529 0.000 0.0)",
"studio_url": "https://colorise.online/en/contrast?fg=6b6b6b&bg=ffffff",
"disclaimer": "Fix adjusts OKLCH lightness for WCAG AA normal text while keeping hue/chroma — not a legal audit."
}fix_contrast moves only the OKLCH lightness of the text colour and keeps hue and chroma. changed says whether a different colour is suggested, achieved says whether it reaches the target, and cannot_pass is true when no lightness works. The target defaults to AA and can be set to AAA.
Errors and edge cases
- Tool-level failures are ordinary results. A colour that cannot be parsed returns a payload with an
errorkey, not a JSON-RPC error and not anisErrorflag, so check forerrorin the payload. - Unknown tools and methods return a JSON-RPC error object with code
-32601. Invalid JSON returns-32700. These arrive with HTTP status 200, as JSON-RPC over HTTP usually does. - Notifications such as
notifications/initialized, andping, are answered with an empty result rather than an HTTP 202. - Batches are handled message by message, but only the response to the last message is returned.
- Rounding:
check_contrastreportsratioLabelrounded to two decimals, so a ratio of 4.4781 is labelled 4.48:1. Use the rawratioand thewcagNormallevel, which are computed unrounded, for decisions. The contrast API floors its ratio string instead.
Connecting a client
The only thing a client needs is the URL https://colorise.online/api/mcp and a transport that talks HTTP. There are no headers to set. Configuration formats differ between clients and change often, so for anything not listed below check your client's documentation for remote or HTTP MCP servers.
Claude Code
claude mcp add --transport http colorise https://colorise.online/api/mcp- Claude Desktop and claude.ai: add a custom connector (remote MCP server) in the app's connector settings and paste the URL. Menu names change, so follow Anthropic's current instructions.
- Cursor and other editors or agents: look for the remote or HTTP MCP server option in their MCP settings, and enter the same URL.
- Your own code: any MCP client library that supports HTTP transport, or plain HTTP POSTs as shown above.
Because the server is minimal, test the connection by hand first if a client misbehaves. This request should return the tool list:
Smoke test
curl -s https://colorise.online/api/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'The endpoint does not send CORS headers, so call it from a server or from an MCP client, not from browser JavaScript. For browser use, the contrast API is CORS-enabled.
Limits and fair use
The server is free and has no key or signup. There is no service-level agreement and no uptime promise, and the tool list or response shapes may change as the site evolves; the version above is bumped when they do. The code does not enforce a rate limit, but the host can throttle abusive traffic.
Tools are deterministic, so cache results where you can. The assistant on the other end decides when to call a tool, so keep an eye on how often your own client does it.
FAQ
- What is the colour MCP server's URL?
https://colorise.online/api/mcp. Send JSON-RPC 2.0 messages with POST. A GET returns a short JSON description of the server.- Which tools does it provide?
- 9 tools: site_info, list_intents, convert_color, check_contrast, fix_contrast, generate_scale, export_palette, share_link, lookup_reference. The table above lists the arguments for each.
- Does it need an API key or sign-in?
- No. There is no authentication. Because it is unauthenticated and has no SLA, treat it as a convenience and cache results.
- Which MCP protocol version does it use?
- It reports
2024-11-05frominitializeand does not negotiate. It implements the tools capability only, over plain request and response HTTP with no streaming. - Can an assistant fix a failing colour pair with it?
- Yes.
fix_contrastadjusts the text colour's OKLCH lightness, keeping hue and chroma, until the pair reaches WCAG AA (or AAA), and says when that is impossible. It returns the new colour as HEX and as oklch(). - Is there a plain REST endpoint instead?
- Yes, for contrast only: the contrast API is a CORS-enabled GET endpoint with WebAIM-compatible fields.
Try it
See what the check_contrast and fix_contrast tools compute, interactively, with a before and after preview.