Skip to content

MCP server

An agent writing Echo code from memory gets it subtly wrong: the old Base UI package name, a smooth ease on an LCD, a hardcoded colour. With the Echo MCP server it can look things up instead — every component's props, usage, accessibility notes and anti-patterns — before it writes a line.

Install

Every client runs the same command, npx -y echo-ui-mcp:

json
{
  "mcpServers": {
    "echo-ui": {
      "command": "npx",
      "args": ["-y", "echo-ui-mcp"]
    }
  }
}
  • Claude Code: claude mcp add echo-ui -- npx -y echo-ui-mcp
  • Codex: add it to ~/.codex/config.toml as [mcp_servers.echo-ui], with command = "npx" and args = ["-y", "echo-ui-mcp"].
  • Cursor: add the block above to .cursor/mcp.json.
  • VS Code: add it to .vscode/mcp.json, under servers instead of mcpServers.
  • Other clients: any client that runs a stdio MCP server takes the same command.

It needs Node.js 20 or later.

Hosted, for tools without a terminal

ChatGPT, claude.ai, Lovable, v0, Bolt and Claude Design connect only to a server on the web, so Echo runs one at https://mcp.echo-ui.com/mcp. It has the same tools, needs nothing installed and no account, and reads what this site publishes, so it answers what the CLI installs. It keeps nothing it's sent: code handed to check_code is checked and forgotten. check_code takes up to 200,000 characters, a request past what that needs is refused before it's read, and one address can send 300 requests in ten seconds.

In a tool with a settings page, add it as a custom connector (a remote MCP server) with that address. In Claude and ChatGPT, Echo's plugin carries this server and Echo's three skills together. Clients that take a command or a config file:

hosted
# Claude Code
claude mcp add --transport http echo-ui https://mcp.echo-ui.com/mcp

# Cursor (.cursor/mcp.json)
{
  "mcpServers": {
    "echo-ui": {
      "url": "https://mcp.echo-ui.com/mcp"
    }
  }
}

The tools

ToolTakesAnswers with
search_componentsquery?Find the Echo UI item for a job ("a settings toggle", "confirm a delete") or by name. Leads with the best fit, or says plainly that Echo has nothing for the job yet, then lists every match with its install command. Call this first — it is the cheapest way to find out what exists before writing any Echo code.
get_componentnameThe full record for one component: description, install command, usage (imports + smallest working snippet), composition (part tree), examples, accessibility, motion & sound, prop table and anti-patterns. Read this BEFORE writing code that uses the component — the anti-patterns are the part a model gets wrong from priors.
get_tokens—The token families: Layer-3 semantic colour roles (--echo-*), sound names, motion's whole vocabulary — the motion tokens, the spring presets, the morph feels and the CSS duration and ease steps — and the shadow recipes. Any name a component's record lists under Motion is here. Echo components are styled and moved only through these — never hardcode a hex, a duration or a shadow, or invent a token name.
get_examplesnameJust the usage examples for one component, without the rest of its record. Use it when you already know the component and want the calling convention.
get_accessibilityname?The accessibility rules a consumer of Echo can still get wrong — names on controls, form errors, announcements, focus and target size — and, with a name, what that component's accessibility was actually tested against. Echo guarantees WCAG 2.2 AA; this is the part the guarantee cannot cover for you. Read it before building a form, a dialog or anything icon-only.
check_codecode, file?Echo's check on a piece of code you've written or are about to write: colours, spacing, radii, shadows and timing off Echo's scales, raw elements where Echo has the component, props a component doesn't take, controls without a name, markup a keyboard or screen reader can't use, restyling Echo from outside, and the screen rules one file can show. The same rules as `npx echo-ui-cli check`, which runs on a whole project with its own theme; this one uses the default theme. Each finding says the Echo way to fix it.
list_stylesname?Echo's own styles, the looks Echo publishes, each with its one line and its fingerprint on the seven axes styles are placed on; or, with a name, one of them in full: its settings, rules, refusals, fonts, decisions and the slop police's word. The builder's own styles aren't here: they're in their library or the conversation, and fit_styles weighs them with Echo's.
fit_stylesprofile, tolerance?, yours?Style Fit's shortlist: Echo's styles, and the builder's own passed in, measured against where a product sits on the seven axes (warmth, volume, density, formality, era, craft, ornament) and put in order: a style that misses a locked axis last, then least past tolerance first, then nearest. The same arithmetic as `npx echo-ui-cli style fit`. It orders; it doesn't pick.
check_stylestyleWhether a style.json is one Echo can apply, as `npx echo-ui-cli style check` says it: what stops it, the device it makes (light or dark), what the theme corrects for AA contrast, what the slop police stops (with the question for the builder) or the builder kept, and the decisions it leaves open.
wear_stylename?, style?, files?What a style gives a project: a link that makes the whole Echo site wear its colours, the commands that put it in a project, and, for a project without a terminal, its theme CSS and a DESIGN.md with its rules. One of Echo's styles by name, or the builder's own style.json. A style the slop police stops isn't worn; the answer says what to ask the builder.

get_component returns exactly what the Copy for AI agent button on each component page copies, so a pasted page and a tool call tell the agent the same thing — plus what the component ships as: the version, the echo-ui-core range it needs, and what its accessibility was tested against. That half comes from the registry the CLI installs from, read with the CLI's own client, so the server cannot state a version npx echo-ui-cli add would then contradict.

check_code is the check the CLI runs after each edit, for an agent with no terminal: hand it a file's code and it answers with the same findings, against the default theme.

The four style tools are the CLI's style command for a builder with no terminal, from the same code, so a chat and a terminal give the same answers. list_styles shows Echo's styles, or one in full. fit_styles ranks them, with the builder's own passed in by their fingerprints, against where the product sits on the seven axes. check_style reads a style.json the way style check does. wear_style hands back what a style gives a project: a link that makes this whole site wear its colours, the command that puts it in a project, and, for a project without a terminal, its theme CSS and a DESIGN.md with its rules. A builder's own styles are never stored on the server: they come in with the call.

get_accessibility is worth wiring deliberately. The rules it returns are in the instructions below too, but a client is free to ignore instructions, and a rule a model cannot look up is one it follows by luck.

When it connects, the server also sends the agent these instructions:

brief
A neo-skeuomorphic React component library you install into your own source tree with `npx echo-ui-cli`. Molded caps in recessed wells, emissive readouts, real press travel. Motion (GSAP) and sound (zero-dep WebAudio synth) are first-class token families alongside color and type.

Working rules:
- The Base UI package is `@base-ui/react` (per-component imports, e.g. `@base-ui/react/dialog`), NOT `@base-ui-components/react` (the old name). Training data may be stale.
- Set the project up once with `npx echo-ui-cli init`. It installs `echo-ui-core` (and `echo-ui-cli` as a dev dependency), writes `echo.json`, `echo-lock.json` and `echo-theme.css`, adds a marked Echo block to CLAUDE.md or AGENTS.md, a check hook to .claude/settings.json and three skills (building with Echo; Design Eye, which reads a moodboard into a style the project can wear; and Style Fit, which picks the style it wears), and prints the lines to paste. It never edits your source code, and `add` refuses to run before it.
- Components render with no colour until the theme is on the page. `init` writes `echo-theme.css` into the Echo folder — import it once from your global CSS or your root layout (or call `createEchoTheme().css` from `echo-ui-core/theme` to build it at runtime). Give the page the device's ground (`body { background: var(--echo-well); color: var(--echo-text); font-family: var(--echo-font-sans); }`), dark or light as the chassis makes it, and wrap the app in `SoundProvider` from `echo-ui-core/sound` — without it every component is silent. It starts muted until the person turns sound on, and remembers their choice; `defaultMuted={false}` starts with sound. Put `<EchoCheck />` from `echo-ui-core/check` once in the root layout: in development it says in the console what's still missing, and in production it renders nothing.
- Echo components are client components. In the Next.js App Router, a file that passes them a function (`onSave`, `onSubmit`, `onClick`) must start with `"use client"`.
- Echo is a REGISTRY, not an npm component package. Components are installed with `npx echo-ui-cli add <component>` and then live in the consumer's own source tree, importing each other by relative path inside one Echo folder. Never suggest `npm install` for a component. The one npm package is `echo-ui-core`, the grammar they all import (theme, sound, motion, tactile, presence).
- Installed files still receive Echo's later fixes. `npx echo-ui-cli diff` reports every installed item as up to date, behind, edited, or edited and behind; `npx echo-ui-cli update` brings them forward and merges Echo's change into files somebody edited; where an edit and Echo's change meet in the same lines, it leaves that item and prints the lines between git's conflict markers, to bring together before running it again. Never tell a user to re-run `add --overwrite` to upgrade — that discards their edits without showing them what it is discarding.
- Style only through the Layer-3 semantic vars (`var(--echo-*)`) from `createEchoTheme`. Never hardcode a hex, and never invent a token name — call get_tokens for the real list.
- Read a component's anti-patterns before using it. They exist because the obvious thing is wrong for this material system (a screen readout does not ease smoothly; severity is not red/amber/green).

Accessibility is part of the grammar, not a review step. Echo guarantees WCAG 2.2 AA, and these are the parts a consumer can still get wrong:
- Every control needs a name. `Switch`, `Checkbox`, `Slider`, `Segmented`, `Select`, `RadioGroup` and `Progress` take `aria-label` (or `aria-labelledby` pointing at visible text); `Field`, `Textarea` and `OtpField` take a visible `label`. Without one they do not compile.
- An icon-only `HardwareButton` (`iconOnly`) needs `aria-label`: it has no text to read.
- Forms: put the help text in `description` and the problem in `error`, both on the field. They are linked to the input and set `aria-invalid` for you. Never signal an error with colour or a red border alone.
- Announcements: mount `<Toaster>` once and call `toast()` from `useToast()`. A message rendered into the page when it happens is usually never announced.
- Sign-in: `Field` with `autoComplete` (`email`, `current-password`), and `OtpField` for a one-time code — it allows pasting, which people rely on.
- State is never colour alone: Echo has one accent, and its components already carry state in shape and words. Do not add a red for danger; use `AlertDialog`, which asks before anything destructive.
- Do not remove a focus ring, shrink a target below 24×24px, or set `aria-hidden` on something focusable.

Every component is tested against WCAG 2.2 AA: axe, keyboard, focus-visible, forced-colors, target-size, reflow — and each item's `/e/` record carries the same block. Not covered: screen-reader: not yet verified by a person.

Your own registry

The server reads two published documents and re-reads them after five minutes. To point it somewhere else — a fork of Echo, or a local build — set either in the server's env:

VariableWhat it points at
ECHO_CATALOGThe catalog: descriptions, props, examples, anti-patterns. A URL or a file path.
ECHO_REGISTRYThe /e/ registry: versions, dependencies, accessibility records. A URL.

If the registry cannot be reached the server still answers from the catalog, without the version and the delivery lines. A copy it has already read keeps answering while its source can't be read, and is tried again every minute. If a file fails its hash it stops, and says so.

Things to ask

  • "Build a settings screen with Echo. Look up each component before you use it."
  • "Which Echo components have an LED? Install the one that fits a recording indicator."
  • "Retheme this app with a sky-blue accent. Use only Echo's tokens."
  • "Check this form against the anti-patterns of every Echo component it uses."