Skip to main content
ClaudeWave

MCP server that answers what CSS you can actually ship today — live Baseline data, MDN browser-compat-data, and stylesheet audits. Runs on Cloudflare Workers.

MCP ServersOfficial Registry0 stars0 forksTypeScriptMITUpdated today
Install in Claude Code / Claude Desktop
Method: NPX · wrangler
Claude Code CLI
claude mcp add css-sota-mcp -- npx -y wrangler
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "css-sota-mcp": {
      "command": "npx",
      "args": ["-y", "wrangler"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Use cases

MCP Servers overview

# css-sota-mcp

An MCP server that answers **what CSS you can actually ship today** — from live Baseline data and
MDN browser-compat-data, not from a model's training set.

Agents are confidently wrong about browser support. They will tell you `anchor-name` is fine, or
that `:has()` needs a polyfill, depending on when their weights were frozen. This server replaces
the guess with the current answer.

- **Endpoint** — `https://css-sota-mcp.lusrodri.workers.dev/mcp` (Streamable HTTP, no auth)
- **Docs** — [css-sota-mcp.pages.dev](https://css-sota-mcp.pages.dev)
- **Registry** — `io.github.LuSrodri/css-sota-mcp`, listed in the
  [official MCP Registry](https://registry.modelcontextprotocol.io)

## Tools

| Tool | Answers | Source |
| --- | --- | --- |
| `search_css_features` | "Which features exist for this, and are they safe yet?" | webstatus.dev |
| `whats_new` | "What can I start using that I couldn't before?" | webstatus.dev |
| `get_feature` | "Tell me everything about this one feature." | webstatus.dev + mdn/content |
| `check_support` | "Which browser versions support this exactly?" | bundled browser-compat-data |
| `audit_css` | "Does this stylesheet work for my users?" | bundled browser-compat-data |
| `dont_make_me_think` | "How should this UI be designed — and is this page any good?" | bundled UX guidelines |

`check_support` and `audit_css` answer with no network call at all — the data they need is compiled
into the Worker.

### `dont_make_me_think`

Named after Steve Krug's rule: a page should be self-evident. Two modes.

`mode: "guidelines"` returns the principles to design against — Nielsen's 10 heuristics, Hick's
and Fitts's laws, WCAG 2.2, neurodiversity-inclusive design, motion and microinteractions
(including when Lottie or Rive earn their bundle cost), SVG craft and animation, light-first
theming, lightness, responsiveness. Filter with `topic`. The knowledge base is
[`mcp/src/data/ux-guidelines.json`](mcp/src/data/ux-guidelines.json); every principle carries its
rationale, actionable rules and a source.

`mode: "review"` checks HTML and CSS — or a fetched `url` — and reports what violates which
principle, with the line and the evidence.

**It reads source; it does not render it.** A Worker has no layout engine, so the review cannot
measure computed contrast, real target sizes, or where focus actually lands. It catches what is
visible in the markup: missing `alt`, blocked zoom, animation with no reduced-motion path, a
removed focus ring, a dark-only palette, vague link text, a nav past Hick's range. A clean result
is a floor, not a pass, and the tool says so in its own output.

### `audit_css` targets

Two target styles, because they answer different questions:

- **A Baseline level** — `baseline-widely`, `baseline-newly`. Asks "is this interoperable enough to
  ship?", judged against `web-features`' Baseline status.
- **An explicit browser list** — `chrome 120, safari 17.4, firefox 128`. Asks "does this work for
  *my* users?", judged against per-browser versions.

Browserslist queries (`last 2 versions`, `>0.5%`) are **not** accepted. Resolving them needs usage
data this server does not carry, and approximating them would produce confidently wrong audits —
exactly the failure mode the server exists to fix. The tool says so rather than guessing.

## Connect

```bash
claude mcp add --scope user --transport http css-sota https://css-sota-mcp.lusrodri.workers.dev/mcp
```

`--scope user` registers it once for every project on the machine. Leave it out and the server is
added to the current project only.

<details>
<summary>Claude Desktop</summary>

Remote servers go in through Connectors, not through `claude_desktop_config.json` — that file only
takes local stdio servers. Open **Settings → Connectors → Add custom connector** and paste:

```
https://css-sota-mcp.lusrodri.workers.dev/mcp
```

The endpoint is unauthenticated, so the connector asks for no client id and no secret.

</details>

<details>
<summary>Cloudflare AI Playground</summary>

Open [playground.ai.cloudflare.com](https://playground.ai.cloudflare.com/), paste the endpoint into
the MCP server field, and connect. The six tools appear immediately.

</details>

<details>
<summary>MCP Inspector</summary>

```bash
npx @modelcontextprotocol/inspector@latest
```

Set transport to Streamable HTTP and connect to the endpoint.

</details>

## Limits on the hosted endpoint

The endpoint is public and unauthenticated on purpose: every tool is read-only over public
datasets, so there is nothing to protect from disclosure. What is worth protecting is the account's
request budget and the server's standing with the upstreams it proxies.

| Limit | Value | On exceeding |
| --- | --- | --- |
| Requests per client IP | 120 / minute, per Cloudflare location | `429` with `Retry-After: 60` |
| Request body | 1 MB | `413` |
| `audit_css` source | 400 000 characters | schema validation error |

120/minute is sized against real usage rather than a round number: an agent working through a task
calls a handful of tools per turn, so a burst of twenty is unremarkable and 120 leaves room for a
shared address running several clients.

Cloudflare's own guidance prefers keying rate limits on a user or tenant id rather than an IP,
since an IP can be shared behind NAT or a privacy relay. This endpoint has no authentication and so
no such id; the limit is set generously enough that the trade is a fair one.

If you expect sustained traffic above this, run your own instance — the whole thing is one Worker
and deploys in a minute.

## Layout

```
mcp/       The MCP server — a Cloudflare Worker
landing/   Documentation site — Vite, on Cloudflare Pages
```

### How the data is put together

`@mdn/browser-compat-data` unpacks to ~20 MB, far past a Worker's bundle budget. At build time
`mcp/scripts/build-data.js` extracts the CSS slice of it plus the `web-features` catalog, drops
every field the server never reads, and encodes per-browser support positionally. The result is
about 1 MB of JSON — 120 KB gzipped — which ships inside the Worker.

The generated files are gitignored. Every build, test and deploy regenerates them, so the data
always matches whatever version npm resolved.

Two details worth knowing, both found the hard way:

- `web-features` encodes Baseline as `"high"` / `"low"` / `false`, while api.webstatus.dev and all
  Baseline documentation say `widely` / `newly` / `limited`. The build normalises to the latter so
  the two halves of the server never disagree.
- MDN reorganised its CSS reference under `Web/CSS/Reference/…`. Compat data records the slug a page
  had when the entry was written, so building a raw GitHub path from `mdn_url` 404s. `get_feature`
  resolves the canonical slug through MDN first, then reads the source.

## Development

```bash
npm install

npm run dev --workspace mcp        # wrangler dev on :8787
npm test --workspace mcp           # vitest
npm run typecheck                  # both workspaces

node mcp/scripts/smoke.js          # real MCP protocol call against :8787
node mcp/scripts/smoke.js <url>    # ...or against a deployment
```

`smoke.js` speaks the 2025-era Streamable HTTP flow — the same one the AI Playground and MCP
Inspector use — so a passing run means those clients will work too.

### Deploy

Pushing to `main` deploys both. Cloudflare builds from this repo directly — no API token is
stored in GitHub, and Cloudflare issues its own build credential.

| Target | Product | Root | Build | Deploy |
| --- | --- | --- | --- | --- |
| Worker | Workers Builds | `mcp` | `npm run build:data` | `npx wrangler deploy` |
| Landing | Pages Git integration | `landing` | `npm run build` | output `dist` |

The Worker's build command is **not** optional: `mcp/src/data/generated/` is gitignored, and
`src/data/index.ts` imports it statically, so a build that skips it fails to bundle.

Because the two are independent products, neither waits for the other. `.github/workflows/verify.yml`
covers that gap — it smoke-tests the live endpoint on a schedule and on demand.

#### Publishing to the registry

[`server.json`](server.json) is the registry's record of this server. Because the server is remote,
it carries a `remotes` entry pointing at the Worker rather than a `packages` one — there is no
artifact to install, and so no package-ownership marker to place anywhere.

`.github/workflows/publish-mcp.yml` republishes it on a `v*` tag:

```bash
git tag v0.2.0 && git push origin v0.2.0
```

The tag sets the version, so `server.json`'s own value is only a fallback for a manual
`workflow_dispatch` run. The job authenticates with OIDC — proving it runs in this repository is
what grants the `io.github.LuSrodri/*` namespace — so there is no token stored in GitHub, matching
how the rest of this repo deploys.

It deliberately does not run on every push. The registry record points at a URL, not at a build, so
it stays correct across deploys; only a metadata change needs a new version.

#### Previewing a pull request

Every push to a PR branch uploads a Worker version and builds the landing site, each reachable
before merge:

| | URL |
| --- | --- |
| Worker, by branch | `https://<branch-with-dashes>-css-sota-mcp.lusrodri.workers.dev/mcp` |
| Worker, by version | `https://<version-prefix>-css-sota-mcp.lusrodri.workers.dev/mcp` |
| Landing | `https://<deployment-id>.css-sota-mcp.pages.dev` |

The branch alias is the useful one — it stays put as you push. A branch named
`fix/thing` becomes `fix-thing-css-sota-mcp.lusrodri.workers.dev`. Point the
[AI Playground](https://playground.ai.cloudflare.com/) or MCP Inspector at it to try a PR's server
for real; `node mcp/scripts/smoke.js <url>/mcp` works against it too.

A landing preview calls **its own branch's Worker**, not production. `landing/vite.config.ts`
derives the alias from `CF_PAGES_BRANCH` at build time, so a PR touching both halves is previewed
as a matched pair. Without this the preview would show a new front en

What people ask about css-sota-mcp

What is LuSrodri/css-sota-mcp?

+

LuSrodri/css-sota-mcp is mcp servers for the Claude AI ecosystem. MCP server that answers what CSS you can actually ship today — live Baseline data, MDN browser-compat-data, and stylesheet audits. Runs on Cloudflare Workers. It has 0 GitHub stars and was last updated today.

How do I install css-sota-mcp?

+

You can install css-sota-mcp by cloning the repository (https://github.com/LuSrodri/css-sota-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is LuSrodri/css-sota-mcp safe to use?

+

LuSrodri/css-sota-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.

Who maintains LuSrodri/css-sota-mcp?

+

LuSrodri/css-sota-mcp is maintained by LuSrodri. The last recorded GitHub activity is from today, with 0 open issues.

Are there alternatives to css-sota-mcp?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy css-sota-mcp to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: LuSrodri/css-sota-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/lusrodri-css-sota-mcp)](https://claudewave.com/repo/lusrodri-css-sota-mcp)
<a href="https://claudewave.com/repo/lusrodri-css-sota-mcp"><img src="https://claudewave.com/api/badge/lusrodri-css-sota-mcp" alt="Featured on ClaudeWave: LuSrodri/css-sota-mcp" width="320" height="64" /></a>

More MCP Servers

css-sota-mcp alternatives