CSS Crème MCP for coding agents

Give your agent a design system, not a guess.

Connect your coding agent to 52 design systems it can search, read and install. It studies real tokens before it builds, so the output follows a system instead of inventing one.

Free, ungated, no account and no API key. The nearest equivalent requires a paid plan.

npx -y add-mcp https://csscreme.com/mcp -g

Configures whichever MCP clients are installed. Claude Code on its own: claude mcp add --transport http csscreme https://csscreme.com/mcp

Add to Cursor Add to VS Code or paste the command above

Any client that speaks remote MCP can use it. Endpoint: https://csscreme.com/mcp

Try it right now

calls the real endpoint

This runs an actual tools/call against https://csscreme.com/mcp from your browser. Nothing is installed and nothing is faked; what comes back is what your agent would get.

Try

Set it up in your client

Each page has the one command, the exact file it writes, and how to confirm it connected. Wiring a DESIGN.md into the same tools: Claude Code, Cursor, v0, Codex, Lovable.

Twelve tools

The endpoint answers tools/list itself, so this is a description rather than a specification. Ask your agent to call them; you should not need to. Each one has its own anchor, so a link like /ai/mcp#verify_design_md lands on the tool.

search_themes First call when the user has no design system yet.

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

example call {"name":"search_themes","arguments":{"query":"calm fintech dashboard","mode":"light","limit":4}}
list_themes When the user wants options rather than one answer.

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

example call {"name":"list_themes","arguments":{"kind":"theme","mode":"dark"}}
get_design_md Before writing any UI. Save it at the repo root.

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

example call {"name":"get_design_md","arguments":{"id":"deep-ocean"}}
get_theme_tokens After the components are written and the tokens need to land.

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

example call {"name":"get_theme_tokens","arguments":{"id":"deep-ocean","format":"both"}}
how_to_use Once per project, for the wiring.

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

example call {"name":"how_to_use","arguments":{"tool":"claude-code"}}
get_install_command When the user says "install it" and the id is known.

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

example call {"name":"get_install_command","arguments":{"id":"deep-ocean"}}
get_agent_rules Once, so the rules apply every session instead of one message.

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

example call {"name":"get_agent_rules","arguments":{"id":"deep-ocean"}}
decode_url When the user says "match the design of <site>", or has fetched a page as markdown and needs what that markdown lost.

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.

example call {"name":"decode_url","arguments":{"url":"https://csscreme.com"}}
css_feature Before writing CSS that uses anything newer than flexbox, so the code is right for today and not for the model's training date.

Ask whether a CSS feature is safe to ship today and who ships it. Returns its Baseline status from the web-features dataset, how many of our decoded showcase sites use it, and the exact @supports conditions they guard it with.

example call {"name":"css_feature","arguments":{"feature":"anchor-positioning"}}
get_design_md_for_url When the user says "match <site>" and you are about to write UI. Save it at the repo root.

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.

example call {"name":"get_design_md_for_url","arguments":{"url":"https://stripe.com"}}
decode_site When the question is whether a site is really on a design system, rather than what one page happens to use.

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.

example call {"name":"decode_site","arguments":{"url":"https://stripe.com","pages":5}}
verify_design_md At the start of a session when a DESIGN.md is already present.

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.

example call {"name":"verify_design_md","arguments":{"id":"deep-ocean","fingerprint":"fnv1a-b613a475"}}

What changes

Your agent stops guessing

Without a design system an agent falls back on the average of everything it has read: an invented palette, several corner radii, a second font nobody asked for. With one it works from your tokens, and you can check the output against them.

Every number is measured

Each DESIGN.md carries real WCAG contrast ratios computed from the tokens themselves. When a pair fails AA the file says so instead of shipping it quietly. Nothing in it is an adjective the agent has to interpret.

Not limited to a fixed library

A curated catalogue can only answer for the sites somebody added in advance. Point our decoder or extractor at any live page and it produces a DESIGN.md for that page, then hands your agent the same contract shape.

It installs for real

Every theme is also a shadcn/ui registry item. After the agent writes the components, one command writes the tokens into globals.css. The loop closes instead of stopping at a suggestion.

Installing it

1

Claude Code

claude mcp add --transport http csscreme https://csscreme.com/mcp
2

Everything else

Pick your client and paste the block. There is no token in any of them, because there is nothing to authenticate.

Claude Code Run it in the project directory. Nothing to paste.
claude mcp add --transport http csscreme https://csscreme.com/mcp
Claude Desktop claude_desktop_config.json
{
  "mcpServers": {
    "csscreme": {
      "type": "http",
      "url": "https://csscreme.com/mcp"
    }
  }
}
Cursor .cursor/mcp.json, or the global one
{
  "mcpServers": {
    "csscreme": {
      "url": "https://csscreme.com/mcp"
    }
  }
}
VS Code .vscode/mcp.json
{
  "servers": {
    "csscreme": {
      "type": "http",
      "url": "https://csscreme.com/mcp"
    }
  }
}
Cline cline_mcp_settings.json
{
  "mcpServers": {
    "csscreme": {
      "url": "https://csscreme.com/mcp",
      "disabled": false
    }
  }
}
Windsurf ~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "csscreme": {
      "serverUrl": "https://csscreme.com/mcp"
    }
  }
}
3

Then just ask

“Build a settings page for a calm fintech dashboard.” The agent searches, reads the DESIGN.md, and follows its rules. You do not have to name the tools.

Limits

There is no quota to publish, so this is the list of ceilings that do exist. Each one names the file that enforces it, because a limit nobody can find in the code is a rumour.

AuthenticationNone. No account, no API key, no OAuth.api/mcp.js
Rate limitNone 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.api/mcp.js
Time per call30 seconds. The catalogue tools answer from static data in milliseconds; only a URL decode does network work.api/mcp.js · maxDuration
search_themes results1 to 25 per call, 8 by default.api/mcp.js
decode_site pages2 to 8 per call, 5 by default.src/lib/site-scan.js · MAX_PAGES
Stylesheets per decodeThe first 12 linked stylesheets, up to 2 MB of CSS, 12 seconds to fetch them.src/lib/design-md-url.js · collectCss
RedirectsAt most 4 hops, and every hop is re-checked against the public-address guard.api/_ssrf.js · MAX_REDIRECT_HOPS
What a decode can reachPublic http and https addresses only. Private, loopback and link-local ranges are refused. It reads CSS and never executes a page’s JavaScript.api/_ssrf.js
StateNone. No session, nothing to resume, and the tool list does not change between deploys.api/mcp.js
What is recordedAt 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.api/_hits.js

Changelog

Read out of the repository, not remembered: the version the server declared at each commit and the tools it carried. Current version 1.8.1. These releases also appear in the site changelog, alongside everything else that shipped, with an RSS feed.

  1. 1.8.1Says why a host could not be reached
    • A host name that does not resolve is HOST_NOT_FOUND. It used to be refused as a private address, which sent the reader looking for a network problem that was a typo or a lapsed domain.
    • A failed HTTPS handshake is TLS_FAILED, with the hint to try the http:// address, and a host that never accepts the connection is TIMEOUT. Both used to be reported as an unreadable robots.txt. Nothing is read in either case.
    • Registrar parking pages (Porkbun, Namecheap, GoDaddy, Hostinger, IONOS) are recognised by their own wording, matched against the visible text rather than the markup. Porkbun's was missed before because a link splits its phrase.
  2. 1.8.0Knows when a page is not the site, and reads each site once
    • A bot challenge (Cloudflare, DataDome, HUMAN, Imperva, AWS WAF, Akamai, Vercel), a parked or for-sale domain, a host's default page or a suspended account is refused with NOT_THE_SITE, the kind and the evidence. It used to be measured as if it were the site's design. Challenges are recognised, never solved.
    • maxAge on decode_url, get_design_md_for_url and decode_site: a read made in the last ten minutes is reused (up to an hour, 0 for fresh), shared across instances, with its own fetchedAt kept and cache.hit saying so. Asking for JSON, then the DESIGN.md, then tokens.json is now one read of the site, with one fingerprint.
    • A site that fails three reads in two minutes is left alone with BACKOFF and a Retry-After, doubling up to thirty minutes, with one trial read when it expires. The site's own Retry-After wins when it is longer.
    • Every result carries work: the requests made of the site, how many went to its own host and how many to a CDN, robots.txt reads reused, redirects, bytes and time, with a per-request log. Stylesheets now load four at a time, in source order.
    • expectSpec checks a whole brand spec (roles, typefaces, radius, base and root size, spacing grid, dark mode, named tokens) and returns a verdict per field with what it was compared against. A field with nothing to compare is not-declared, never the nearest guess.
  3. 1.7.0Obeys robots.txt, and says whether to retry
    • decode_url, get_design_md_for_url and decode_site read the target's robots.txt as CSSCremeBot before anything else, under RFC 9309, and refuse a disallowed path with ROBOTS_DENIED. decode_site leaves disallowed sitemap entries out of its sample instead of spending a page on a refusal.
    • Every tool error now starts with a code and a retry verdict, such as [ROBOTS_DENIED] retry: never., and carries the same pair in _meta. The list is published at /ai/errors.
    • decode_url returns fetchedAt, the robots receipt, and root: what 1rem means on that site, which every spacing and radius px is now resolved against. Each of those rows keeps its value as written beside the px, and an empty list is named in notMeasured with the reason.
  4. 1.6.1Old property names, corrected
    • css_feature now returns renamed: a name the feature shipped under before, and the name to write instead. A model whose training predates a rename writes the old one with complete confidence, and this is the cheapest place to catch it.
    • It also returns limits: the documented ways a feature surprises people, such as an unsupported :has() invalidating the whole rule. Every entry cites the page it was read on.
    • The same notes are on each /css/<feature> page under "Before you ship it". A build gate refuses any note without a source on a known documentation host, and refuses to ship a demo that still uses a name we call outdated.
  5. 1.6.0CSS that is accurate for today
    • New tool css_feature: a feature's Baseline status from the web-features dataset, how many of our decoded showcase sites ship it, and the @supports conditions they guard it with. With no argument it returns the Ship Gap.
    • decode_url now returns a css block: the modern features a site ships with their Baseline status, its @supports conditions, its cascade-layer order with rules per layer, and structural counts (rules, selectors, !important, maximum specificity, units, colour formats).
    • The same report is on /api/decode-url?deep=1 and drawn on the decode page.
  6. 1.5.0Speaks 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.
  7. 1.4.0A 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.
  8. 1.3.0Whole-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.
  9. 1.2.0Decode 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.
  10. 1.1.0Install, 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.
  11. 1.0.0Launch
    • Five tools: search_themes, list_themes, get_design_md, get_theme_tokens, how_to_use. Free, no account, no key.

Questions

Is the CSS Crème MCP really free?

Yes. There is no account, no API key and no plan. The endpoint is https://csscreme.com/mcp, it answers tools/list to anyone, and the demo on this page calls it from your browser. The nearest equivalent requires a paid plan and an OAuth login.

What does an agent get from it that it cannot get from a prompt?

A contract instead of adjectives. Each DESIGN.md carries the full token set in light and dark, typography, radius, spacing, WCAG contrast ratios computed from the tokens themselves, and numbered rules the output can be checked against. If a colour pair fails AA, the file says so.

How does an agent know its DESIGN.md is still current?

Every DESIGN.md carries a Fingerprint line, a hash of its token set. The verify_design_md tool takes that fingerprint and answers "current" or returns the tokens that changed. Competing files are static snapshots with no way to tell.

Which clients work with it?

Any client that speaks remote MCP over HTTP: Claude Code, Cursor, VS Code, Windsurf and Codex among them. There is a one-click install for Cursor and VS Code above, and a one-line command for Claude Code.

Can it decode a site that is not in the catalogue?

Not through the MCP yet; the server reads static build-time data, which is why it needs no key. Point the decoder or the extractor on this site at any URL and hand your agent the resulting DESIGN.md; it has the same shape.

What it does not do

It does not make an agent a designer. It removes one specific failure: inventing a visual system because nobody supplied one. Layout, hierarchy, information design and whether the screen is any good remain yours.

The server is stateless and reads static build-time data, which is why it needs no key and cannot lose your work: it has nothing of yours to lose. If you want a design system from a page that is not in the catalogue, use the decoder or the extractor and hand your agent the resulting file.

Full format spec: what a DESIGN.md holds and why.

Machine-readable manifest, in the official registry format: /.well-known/mcp/server.json