# CSS Crème MCP server

> A free, ungated Model Context Protocol server that gives a coding agent measured design systems: search
> them, pull a DESIGN.md with computed WCAG contrast and a fingerprint, verify a saved copy is still current,
> get an agent-rules block, install the tokens, and decode any public URL into tokens.

Page: https://csscreme.com/ai/mcp

## Cost and access

Free. No account, no API key, no OAuth, no rate gate. This is deliberate: the nearest equivalents gate an
MCP server behind a subscription, and an agent that has to stop and ask a human for a credential mid-task is
worth less than one that does not.

## Install

```bash
# Claude Code
claude mcp add --transport http csscreme https://csscreme.com/mcp

# Any detected client (Cursor, VS Code, Codex, Windsurf, Claude Desktop, …)
npx -y add-mcp https://csscreme.com/mcp -g
```

JSON, for a client that wants it written out:

```json
{ "mcpServers": { "csscreme": { "type": "http", "url": "https://csscreme.com/mcp" } } }
```

## Transport and protocol

- Endpoint: `https://csscreme.com/mcp`, streamable HTTP, POST JSON-RPC. Stateless: no session header, nothing to resume.
- Revisions spoken: `2026-07-28` and `2025-06-18`. An `initialize` echoes the revision you asked for when
  we speak it, and `server/discover` answers without a handshake.
- CORS is open, so a browser can call it directly.
- GET the same URL for a plain descriptor: server, revisions, tool names, catalogue size.

## Tools (11)

### `search_themes`

Describe what you are building ("calm fintech dashboard") and get matching design systems back, each with its DESIGN.md URL and install command.

When: First call when the user has no design system yet.

```json
{
  "name": "search_themes",
  "arguments": {
    "query": "calm fintech dashboard",
    "mode": "light",
    "limit": 4
  }
}
```

### `list_themes`

Browse the whole catalogue, filtered by theme or template and light or dark.

When: When the user wants options rather than one answer.

```json
{
  "name": "list_themes",
  "arguments": {
    "kind": "theme",
    "mode": "dark"
  }
}
```

### `get_design_md`

Pull the full DESIGN.md: roles, tokens, typography, measured contrast, the fingerprint, and the rules to follow.

When: Before writing any UI. Save it at the repo root.

```json
{
  "name": "get_design_md",
  "arguments": {
    "id": "deep-ocean"
  }
}
```

### `get_theme_tokens`

Fetch the shadcn registry item and paste-ready CSS variables when it is time to write globals.css.

When: After the components are written and the tokens need to land.

```json
{
  "name": "get_theme_tokens",
  "arguments": {
    "id": "deep-ocean",
    "format": "both"
  }
}
```

### `how_to_use`

Ask where the file belongs for a given editor, since every tool expects it somewhere different.

When: Once per project, for the wiring.

```json
{
  "name": "how_to_use",
  "arguments": {
    "tool": "claude-code"
  }
}
```

### `get_install_command`

The exact one-line install for a theme the agent has already chosen, plus its registry, DTCG and rules URLs.

When: When the user says "install it" and the id is known.

```json
{
  "name": "get_install_command",
  "arguments": {
    "id": "deep-ocean"
  }
}
```

### `get_agent_rules`

A block for CLAUDE.md, AGENTS.md or .cursor/rules that makes every future session read DESIGN.md before touching UI.

When: Once, so the rules apply every session instead of one message.

```json
{
  "name": "get_agent_rules",
  "arguments": {
    "id": "deep-ocean"
  }
}
```

### `decode_url`

Read a live site's CSS and return its design tokens: declared custom properties, colours by frequency, font stacks, radii, spacing values and the framework it was built with. Also returns the Drop Report: roughly how many words a markdown reader would keep, against the design decisions it would throw away. Reads stylesheets, does not render, and says how much it found. Pass format for one artefact from the same read: md (DESIGN.md), tokens (DTCG with the declared names by scope), css, tailwind, registry (npx shadcn add), agents, aliases (every value mapped back to its declared names) or figma (a use_figma script). Pass expect with a brand hex to get the nearest declared value and its distance.

When: When the user says "match the design of <site>", or has fetched a page as markdown and needs what that markdown lost.

```json
{
  "name": "decode_url",
  "arguments": {
    "url": "https://csscreme.com"
  }
}
```

### `get_design_md_for_url`

A complete DESIGN.md for any public URL: roles with provenance, measured contrast, the tokens the site itself declares, the type scale with step ratios, colour frequency, radii, spacing, an elevation ladder, breakpoints, the z-index ladder, interaction-state counts, motion and dark mode.

When: When the user says "match <site>" and you are about to write UI. Save it at the repo root.

```json
{
  "name": "get_design_md_for_url",
  "arguments": {
    "url": "https://stripe.com"
  }
}
```

### `decode_site`

Read a sample of pages from one site and report what is consistent across them: the tokens, colours, fonts, radii and spacing found on every page read, and the ones found on only some. Counts, never a score.

When: When the question is whether a site is really on a design system, rather than what one page happens to use.

```json
{
  "name": "decode_site",
  "arguments": {
    "url": "https://stripe.com",
    "pages": 5
  }
}
```

### `verify_design_md`

Pass the Fingerprint line from a DESIGN.md already in the repo; get back "current" or the tokens that changed. A stale copy is worse than none.

When: At the start of a session when a DESIGN.md is already present.

```json
{
  "name": "verify_design_md",
  "arguments": {
    "id": "deep-ocean",
    "fingerprint": "fnv1a-b613a475"
  }
}
```

## Per-client setup

- [Claude Code](https://csscreme.com/ai/mcp/claude-code): `claude mcp add --transport http csscreme https://csscreme.com/mcp` writes `.mcp.json`
- [Claude Desktop](https://csscreme.com/ai/mcp/claude-desktop): `npx -y add-mcp https://csscreme.com/mcp -a claude-desktop -n csscreme -g` writes `~/Library/Application Support/Claude/claude_desktop_config.json`
- [Cursor](https://csscreme.com/ai/mcp/cursor): `npx -y add-mcp https://csscreme.com/mcp -a cursor -n csscreme` writes `.cursor/mcp.json`
- [VS Code](https://csscreme.com/ai/mcp/vscode): `npx -y add-mcp https://csscreme.com/mcp -a vscode -n csscreme` writes `.vscode/mcp.json`
- [Codex](https://csscreme.com/ai/mcp/codex): `npx -y add-mcp https://csscreme.com/mcp -a codex -n csscreme` writes `.codex/config.toml`
- [Windsurf](https://csscreme.com/ai/mcp/windsurf): `npx -y add-mcp https://csscreme.com/mcp -a windsurf -n csscreme -g` writes `~/.codeium/windsurf/mcp_config.json`
- [Gemini CLI](https://csscreme.com/ai/mcp/gemini-cli): `npx -y add-mcp https://csscreme.com/mcp -a gemini-cli -n csscreme` writes `.gemini/settings.json`
- [Cline](https://csscreme.com/ai/mcp/cline): `npx -y add-mcp https://csscreme.com/mcp -a cline -n csscreme -g` writes `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`
- [GitHub Copilot CLI](https://csscreme.com/ai/mcp/github-copilot-cli): `npx -y add-mcp https://csscreme.com/mcp -a github-copilot-cli -n csscreme` writes `.mcp.json`
- [Zed](https://csscreme.com/ai/mcp/zed): `npx -y add-mcp https://csscreme.com/mcp -a zed -n csscreme` writes `.zed/settings.json`
- [OpenCode](https://csscreme.com/ai/mcp/opencode): `npx -y add-mcp https://csscreme.com/mcp -a opencode -n csscreme` writes `opencode.jsonc`
- [Goose](https://csscreme.com/ai/mcp/goose): `npx -y add-mcp https://csscreme.com/mcp -a goose -n csscreme` writes `.goose/config.yaml`

## Limits

- **Authentication**: None. No account, no API key, no OAuth.
- **Rate limit**: None of ours. There is no quota, no credit meter and no per-tool cap. The hosting platform may shed traffic that looks like an attack.
- **Time per call**: 30 seconds. The catalogue tools answer from static data in milliseconds; only a URL decode does network work.
- **`search_themes` results**: 1 to 25 per call, 8 by default.
- **`decode_site` pages**: 2 to 8 per call, 5 by default.
- **Stylesheets per decode**: The first 12 linked stylesheets, up to 2 MB of CSS, 12 seconds to fetch them.
- **Redirects**: At most 4 hops, and every hop is re-checked against the public-address guard.
- **What a decode can reach**: Public http and https addresses only. Private, loopback and link-local ranges are refused. It reads CSS and never executes a page’s JavaScript.
- **State**: None. No session, nothing to resume, and the tool list does not change between deploys.
- **What is recorded**: At most one row per tool, per visitor, per hour: the tool name, the theme id if there was one, the hour, and a salted hash of the address that rotates daily. Never the URL you decoded and never your arguments.

## Changelog

### 1.5.0 (2026-09-18): Speaks the 2026-07-28 revision

- Both protocol revisions are answered: `2026-07-28` and `2025-06-18`. `initialize` now echoes the revision the client asked for instead of always negotiating down.
- `server/discover` is implemented, so a client can learn the supported revisions, capabilities and instructions with no handshake.
- `tools/list` carries `ttlMs` and `cacheScope` for clients on the new revision. Older clients receive exactly the bytes they did before.
- Listed in the official MCP registry as `com.csscreme/design-systems`.

### 1.4.0 (2026-09-13 to 2026-09-17): A full DESIGN.md for any URL

- New tool `get_design_md_for_url`: roles with provenance, measured contrast, the tokens a site itself declares, type scale, elevation, breakpoints, motion and dark mode.
- `decode_url` gained `format` (DESIGN.md, DTCG tokens, CSS, Tailwind, shadcn registry, agent rules, aliases, a Figma script) and `expect`, which returns the nearest declared value to a brand hex and its distance.
- Every tool now declares a `title` and read-only annotations. One fetch per request, and every fetch passes the public-address guard on every redirect hop.

### 1.3.0 (2026-09-08): Whole-site reads

- New tool `decode_site`: reads a sample of pages and reports what is consistent across them. Counts, never a score.
- `decode_url` returns the Drop Report: roughly how many words a markdown reader keeps, against the design decisions it throws away.

### 1.2.0 (2026-09-03): Decode a live site

- New tool `decode_url`: reads a public site’s stylesheets into tokens, with a stated confidence. It reads CSS and does not render.

### 1.1.0 (2026-09-02): Install, rules, verification

- New tools `get_install_command`, `get_agent_rules` and `verify_design_md`.
- Every DESIGN.md carries a Fingerprint line, so a saved copy can be checked against the live one.

### 1.0.0 (2026-08-28): Launch

- Five tools: `search_themes`, `list_themes`, `get_design_md`, `get_theme_tokens`, `how_to_use`. Free, no account, no key.

## What it does not do

It does not render pages, log in to anything, write to your repo, or store what you ask it. A decode reads a
public URL's CSS; it does not execute the page. Nothing is uploaded and nothing is kept.

## Honesty contract

Every contrast ratio is computed from the colours rather than asserted, and a DESIGN.md that fails WCAG AA
says so instead of hiding it. Each DESIGN.md carries a Fingerprint line: pass it to `verify_design_md` to
learn whether a copy in your repo is still current before building from it.
