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
Any client that speaks remote MCP can use it. Endpoint: https://csscreme.com/mcp
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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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.
{"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
Claude Code
claude mcp add --transport http csscreme https://csscreme.com/mcpEverything 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"
}
}
} 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.
| Authentication | None. No account, no API key, no OAuth.api/mcp.js |
|---|---|
| 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.api/mcp.js |
| Time per call | 30 seconds. The catalogue tools answer from static data in milliseconds; only a URL decode does network work.api/mcp.js · maxDuration |
search_themes results | 1 to 25 per call, 8 by default.api/mcp.js |
decode_site pages | 2 to 8 per call, 5 by default.src/lib/site-scan.js · MAX_PAGES |
| Stylesheets per decode | The first 12 linked stylesheets, up to 2 MB of CSS, 12 seconds to fetch them.src/lib/design-md-url.js · collectCss |
| Redirects | At most 4 hops, and every hop is re-checked against the public-address guard.api/_ssrf.js · MAX_REDIRECT_HOPS |
| 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.api/_ssrf.js |
| State | None. No session, nothing to resume, and the tool list does not change between deploys.api/mcp.js |
| 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.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.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 isTIMEOUT. 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.
- A host name that does not resolve is
- 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. maxAgeondecode_url,get_design_md_for_urlanddecode_site: a read made in the last ten minutes is reused (up to an hour, 0 for fresh), shared across instances, with its ownfetchedAtkept andcache.hitsaying 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
BACKOFFand 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. expectSpecchecks 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 isnot-declared, never the nearest guess.
- 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
- 1.7.0Obeys robots.txt, and says whether to retry
decode_url,get_design_md_for_urlanddecode_siteread the target's robots.txt asCSSCremeBotbefore anything else, under RFC 9309, and refuse a disallowed path withROBOTS_DENIED.decode_siteleaves 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_urlreturnsfetchedAt, therobotsreceipt, androot: 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 innotMeasuredwith the reason.
- 1.6.1Old property names, corrected
css_featurenow returnsrenamed: 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.
- 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@supportsconditions they guard it with. With no argument it returns the Ship Gap. decode_urlnow returns acssblock: the modern features a site ships with their Baseline status, its@supportsconditions, 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=1and drawn on the decode page.
- New tool
- 1.5.0Speaks the 2026-07-28 revision
- Both protocol revisions are answered:
2026-07-28and2025-06-18.initializenow echoes the revision the client asked for instead of always negotiating down. server/discoveris implemented, so a client can learn the supported revisions, capabilities and instructions with no handshake.tools/listcarriesttlMsandcacheScopefor 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.
- Both protocol revisions are answered:
- 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_urlgainedformat(DESIGN.md, DTCG tokens, CSS, Tailwind, shadcn registry, agent rules, aliases, a Figma script) andexpect, which returns the nearest declared value to a brand hex and its distance.- Every tool now declares a
titleand read-only annotations. One fetch per request, and every fetch passes the public-address guard on every redirect hop.
- New tool
- 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_urlreturns the Drop Report: roughly how many words a markdown reader keeps, against the design decisions it throws away.
- New tool
- 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.
- New tool
- 1.1.0Install, rules, verification
- New tools
get_install_command,get_agent_rulesandverify_design_md. - Every DESIGN.md carries a Fingerprint line, so a saved copy can be checked against the live one.
- New tools
- 1.0.0Launch
- Five tools:
search_themes,list_themes,get_design_md,get_theme_tokens,how_to_use. Free, no account, no key.
- Five tools:
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