Fuzz docs
Fuzz is an MCP server for coding agents. It turns a brief like “sleek fintech” into three distinct design directions, writes the one you pick into your repo, and gives your agent local checks that keep the app on that style.
A session goes like this:
- Your agent calls
suggest_styleswith your brief and shows you three directions with previews. - You pick one.
apply_stylereturns its DESIGN.md and theme tokens as new files; your agent shows the diff before writing them. - Your agent builds the screens, following DESIGN.md.
get_check_ruleschecks the code for drift from the style: stray colours, wrong radii, fonts that crept in.deslopchecks for AI tells: the signs that a screen came from a default rather than a decision.- Your agent fixes what they find and runs them again until nothing blocking is left.
Both checks run on your machine. Fuzz sends rules and scripts down and never receives your code.
Connect your agent
The server is at https://mcp.fuzz.design/mcp (Streamable HTTP). You sign in with GitHub the first time; there is no key to paste.
Claude Code
claude mcp add --transport http fuzz https://mcp.fuzz.design/mcpThen run /mcp, choose fuzz and sign in.
Cursor
Add this to ~/.cursor/mcp.json, then sign in when Cursor asks:
{ "mcpServers": { "fuzz": { "url": "https://mcp.fuzz.design/mcp" } } }Any other MCP client
Windsurf, Codex, Zed and other clients take the same URL. If a client can’t do the OAuth sign-in, create an API token on your account page and send it as a header:
Authorization: Bearer fz_…Tokens are shown once and stored only as a hash. Revoke one from the same page.
The workflow
You don’t call the tools yourself; your agent does, from a request in plain words. This is what a session looks like from the agent’s side:
# you: make the paywall sleek and modern
suggest_styles({ brief: "sleek and modern", appType: "habit tracker" })
# three directions with previews; you pick glass-noir
apply_style({ slug: "glass-noir", target: "css" })
# + DESIGN.md, styles/glass-noir.css, .fuzz/icons.json (shown as a diff first)
# ...the agent builds the screens...
get_check_rules({ slug: "glass-noir" })
node .fuzz/fuzz-check.mjs .fuzz/rules.json src/Paywall.tsx
deslop({ slug: "glass-noir", fix: "propose" })
node .fuzz/fuzz-deslop.mjs .fuzz/tells.json src/ --propose
# fix, re-run, until no high or block findings remainTools
Each call returns only what that step needs. A style’s full kit never leaves the server; tools that hand out files return only the one style you asked for.
suggest_styles
Turns a brief into three directions from different style families, each with a reason, a one-line summary of the look, what it suits and avoids, and preview image URLs. Only styles your plan can use are suggested; locked matches are listed separately.
| Input | What it is |
|---|---|
brief | Your words, up to 500 characters. Required. |
appType | For example “fintech dashboard” or “kids’ learning app”. |
mood | Up to 8 words for how it should feel: calm, playful, premium, technical, retro… |
audience | Who it’s for: developers, Gen Z, enterprise teams… |
platform | iOS, Android, web, desktop, CLI. |
avoid | Up to 8 words for looks to stay away from: generic, cute, corporate… |
preview_style
One style’s summary, colours, fonts and preview screens (home, feature, paywall). Input: slug.
list_styles
Every style and what your account can do with it: available, founder-only, pro-only, or upcoming with its drop date. No kit contents.
apply_style
The chosen style as proposed new files. Your agent should show you each one and ask before writing, and never overwrite an existing file without asking.
| Input | What it is |
|---|---|
slug | The style, for example calm-utility. Required. |
target | css (custom properties in styles/<slug>.css), tailwind (tailwind.fuzz.js), shadcn (a theme and registry file) or designmd (DESIGN.md only). Required. |
branding | Adds a small “Styled with Fuzz” comment. Off by default. |
get_check_rules
The style’s rule set and a small checker, to run locally. Input: slug. See Style check.
deslop
A rule pack and a scanner for AI tells, judged in the applied style’s terms, to run locally. See AI-tell check.
| Input | What it is |
|---|---|
slug | The applied style. Required. |
surface | app, marketing, paywall or auto (the default: decided per file). |
mode | static (the default: a code scan), render (also checks the running page in your browser) or full (render plus a screenshot review). |
fix | report (the default) or propose: the scanner also prints a patch for the mechanical fixes. |
There is no input for code, file contents or screenshots, and calls with unknown inputs are rejected.
get_pricing
The current Founder price, spots left at that price, the full ladder and Pro prices. The same data is public at https://mcp.fuzz.design/pricing.
What apply_style writes
- DESIGN.md
- The style in the DESIGN.md format: tokens in the front matter (colours, type, spacing, radii, components) and guidance in the body: overview, colours, typography, layout, elevation, shapes, components, do’s and don’ts, the paywall pattern, motion, a checklist and build steps.
- ## Never
- 10 to 15 one-line rules for what to keep out of this style, written in its tokens: the style’s own tells first, then the general ones that apply to it. The same list is machine-readable in
x-fuzz.never. The file ends by telling the agent to run get_check_rules, then deslop. - Theme tokens
- Depending on
target: CSS custom properties (--color-bg,--color-accent,--font-heading,--radius…), a Tailwind theme extension, or a shadcn theme. - .fuzz/icons.json
- The style’s icon library, weight, size and the names to use for common icons.
Style check
get_check_rules returns .fuzz/rules.json and .fuzz/fuzz-check.mjs. Write both, then run the checker on the files you changed. It needs Node 18 or later and nothing else.
node .fuzz/fuzz-check.mjs .fuzz/rules.json src/Paywall.tsx src/styles.cssIt prints JSON, one entry per file, with a score out of 100 and a list of findings. Each finding has a category, a severity (high, medium or low), what it found and a fix. Stylesheets a file links or imports are read too.
| Category | What it catches |
|---|---|
color | Colours that aren’t in the style, and Tailwind’s stock purples. |
font | Families outside the style, or a system fallback used as the main face. |
radius, spacing | Corner radii and spacing off the style’s scale. |
pattern | Gradients, blur or shadows in a style that doesn’t use them. |
paywall | App Store Review 3.1.2 checks on subscription screens: visible close, legible renewal terms, Restore, Terms and Privacy links, no fake urgency. |
tell | The style’s own neverDo rules and the simple AI-tell detectors. deslop runs the full scan. |
It exits with code 1 while any high finding remains. Fix the high ones first and re-run.
AI-tell check (deslop)
Some things make a screen look generated whatever the style: purple-to-blue gradients, a small label over every heading, one coloured word in the headline, invented ratings, a “Thanks!” with no request behind it, emoji as icons, copy like “seamless” and “effortless”. deslop finds them and judges each one in the applied style’s own terms. Terminal Grid keeps its small capitals, for example, and Glass Noir may use two gradients per screen, in its own colours.
Run it
deslop returns .fuzz/tells.json and .fuzz/fuzz-deslop.mjs, plus more files in the other modes. Pass files or folders; it scans HTML, CSS, JSX and TSX, Vue, Svelte and Tailwind class strings.
node .fuzz/fuzz-deslop.mjs .fuzz/tells.json src/| Mode | Adds | Run with |
|---|---|---|
static | The code scan. | src/ |
render | .fuzz/deslop-render.mjs. Opens the running page in your own Chrome, Chromium, Edge or Brave, headless, with nothing to install, at 390, 1280 and 1440 wide (1920 for marketing pages). Checks the first screen, sideways scroll (or, when the page hides it with overflow-x, text cut off at the edge), words per screen, empty frames, section rhythm, rendered glow, and text contrast against the real pixels behind it. Screenshots go to .fuzz/shots/. | src/ --url http://localhost:3000 |
full | .fuzz/review.md, a short rubric for the tells that need judgement, applied to the screenshots in a fresh context. Its findings go in .fuzz/review-findings.json and join the report. | Same as render. |
Add --widths 390,1280 to choose the widths, and repeat --url for several pages. Set CHROME_PATH if your browser isn’t found.
Read the result
It prints one JSON report: a score out of 100 on the same scale as the style check, a summary, and a list of tells. Each tell has an id, a severity, where it is (location: file and line, or URL and width), what it found, why it matters and a fix in your style’s tokens.
| Severity | What to do |
|---|---|
block | Fix it. The scanner exits with code 1 while any remain. |
reflex | Fix it, or record why this screen needs it. |
polish | Reported only. |
Exit codes: 0 when no block finding is left, 1 while any remain, 2 if it couldn’t run (for example no browser for render mode).
Fix it
With fix: "propose", or --propose, the report includes a unified diff for the mechanical fixes: off-token colours to token variables, stock Tailwind purples to the accent, transition: all to the properties that change, small spaced capitals, emoji icons to the style’s icon set, and 100vh to 100dvh. It never writes files: your agent shows you the diff and asks first. Layout, copy and fake proof come back as fix text only.
Keep a finding on purpose
For a reflex or polish finding that’s right for your screen, record why in .fuzz/deslop-reasons.json and it moves to waived. Block findings can’t be waived. For real proof (a rating or quote you can source), say where it comes from with data-proof-source="…" on the element.
[{ "id": "FZ-T03", "file": "src/Nav.tsx", "reason": "Nav labels match the printed signage" }]The tells
Each style also has 2 to 4 tells of its own, taken from its principles, such as Neubrutalism’s “no soft shadows”. They are in its DESIGN.md under ## Never.
| Id | Tell | Severity | Checked in |
|---|---|---|---|
FZ-T01 | No synthetic glow | block | code, browser |
FZ-T02 | No kicker over every heading | block | code, review |
FZ-T03 | No tiny spaced-out capitals | reflex | code |
FZ-T04 | One colour per headline | block | code, review |
FZ-T05 | Not the default template | reflex | review |
FZ-T06 | No made-up proof | block | code, review |
FZ-T07 | No fake success | block | code |
FZ-T08 | Tokens only | block | code |
FZ-T09 | No emoji icons, one icon set | block | code |
FZ-T10 | Copy that sounds like a person | reflex | code |
FZ-T11 | Motion hygiene | block | code |
FZ-T12 | Same hover on every card, or images that zoom on hover | reflex | code |
FZ-T13 | First screen fits | block | code, browser |
FZ-T14 | Too many words per screen | reflex | browser |
FZ-T15 | Mono as costume | reflex | code |
FZ-T16 | Fake product chrome | reflex | code, review |
FZ-T17 | Empty frames and placeholder art | reflex | code, browser |
FZ-T18 | Same rhythm everywhere | polish | browser |
FZ-T19 | Text and contrast | block | code, browser |
FZ-T20 | App screens | reflex | review |
Plans and limits
Every plan gets the same tools. What changes is which styles you can use and how many calls you get. Current prices are on the pricing section and from get_pricing.
- Free
- 6 styles, plus each weekly drop during its first 7 days. A drop you apply, check or run deslop on during that week stays yours. 100 calls a day, reset at 00:00 UTC.
- Founder
- A one-time payment for the first 100 founders, with lifetime access to everything in Pro: every style, every future drop, the 4 Founder styles and unlimited calls. The price steps up as spots fill.
- Pro
- Yearly or monthly. Every style, including the archive of past drops, with unlimited calls.
Manage your plan and API tokens on your account page.
Errors
A tool that can’t answer returns an error with a code and a message your agent can show you.
| Code | Meaning |
|---|---|
unknown_style | No style has that slug. list_styles has them all. |
founder_only | The style comes with Founder or Pro. |
pro_only | A weekly drop whose free week is over; it’s part of Pro and Founder now. |
not_released | A drop that isn’t out yet. The message has its date. |
rate_limited | You reached the free plan’s 100 calls for today. It resets at 00:00 UTC. |
invalid_token | The sign-in or API token is no longer valid. Sign in again or create a new token. |
Privacy
Fuzz never receives your code. Both checks run on your machine, and render mode opens your page in your own browser and keeps the screenshots in .fuzz/shots/.
Per call, the server logs the tool name, the brief you passed to suggest_styles, the style, a salted hash of your account id and the time. deslop calls log only the tool, style, surface and mode. No file contents, file paths, diffs, screenshots or project names are logged. At sign-in Fuzz keeps your GitHub id, login and primary email; GitHub access tokens are used once and not stored.
Troubleshooting
- Sign-in opens but never finishes
- Finish the GitHub step in the same browser, then return to your client. In Claude Code, run
/mcpagain and choose fuzz. If it still fails, create an API token on your account page and use the header instead. - “Unknown style”
- Slugs are lowercase with hyphens, like
swiss-international. Ask your agent to calllist_styles. - The checker flags colours I took from the style
- Use the token variables (
var(--color-accent)) rather than the hex values, and make sure the file is the latest one fromget_check_rulesfor the style you applied. - deslop render says no browser was found
- Install Chrome, Chromium, Edge or Brave, or set
CHROME_PATHto the browser’s executable. The code scan still runs without one. - deslop render can’t open the page
- Start your dev server first and pass its address with
--url, for example--url http://localhost:5173.