Using Merid with AI

Coding agents write better Merid code when they can read the real docs instead of guessing props. Merid ships three things for that, all generated from these docs at build time:

  • An MCP server, @meridui/mcp, that answers questions about components, props, tokens, patterns and setup from inside your editor.
  • llms.txt, plus a Markdown version of every page, for tools that read the web.
  • An official rules file that tells the agent how to write Merid code: which imports, which tokens, what not to do.

Quick setup

Run this in your project. It installs @meridui/react, imports the stylesheet, and asks whether to add the rules file and the MCP config for Claude Code, Cursor and VS Code. Every file change is shown as a diff first.

npx @meridui/cli init

See CLI for the options, or set things up by hand below.

MCP server

The server runs locally over stdio with npx -y @meridui/mcp. It is read-only and works offline: the docs are compiled into the package, so it makes no network requests and writes no files.

ToolWhat it returns
list_componentsEvery component, grouped by category. Pass category to filter.
get_componentImport line, example code, props tables, keyboard interaction and accessibility notes. section narrows it to props, examples or accessibility.
search_docsRanked sections from every docs page, with links.
get_tokensThe --mrd-* tokens with light and dark values. Filter by category (color, space, radius, shadow, typography, motion, …) or theme.
get_design_contractThe design contract (naming, colour, radius, shadow and motion rules) and the rules file.
get_patternA page pattern's guide and full source: app-shell, settings, auth, data-table, forms, confirmations, empty-and-loading.
get_setupSetup steps for next, vite or react-router.

Claude Code

Add it for the current project (writes .mcp.json, which you can commit so the whole team gets it):

claude mcp add --scope project --transport stdio merid -- npx -y @meridui/mcp

Or write .mcp.json yourself:

{
  "mcpServers": {
    "merid": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@meridui/mcp"]
    }
  }
}

Cursor

Create .cursor/mcp.json in the project (or ~/.cursor/mcp.json for every project):

{
  "mcpServers": {
    "merid": {
      "command": "npx",
      "args": ["-y", "@meridui/mcp"]
    }
  }
}

VS Code

Create .vscode/mcp.json. VS Code uses a servers key rather than mcpServers:

{
  "servers": {
    "merid": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@meridui/mcp"]
    }
  }
}

Windsurf

Open the MCP settings in Cascade, edit mcp_config.json and add:

{
  "mcpServers": {
    "merid": {
      "command": "npx",
      "args": ["-y", "@meridui/mcp"]
    }
  }
}

Other clients

Any MCP client that supports stdio servers works: the command is npx and the arguments are -y @meridui/mcp. Node.js 20 or newer is required.

Try it

Ask your agent something that needs the docs, for example:

  • "Build a settings page with Merid. Use the settings pattern."
  • "Which props does Merid's Dialog.Content take?"
  • "Add a dark mode toggle using Merid's tokens."

llms.txt

For tools that read URLs rather than MCP (chat assistants, v0 and similar), the site publishes the docs as plain text, following the llms.txt convention:

URLContents
/llms.txtAn index of every page with a one-line summary and a link to its Markdown.
/llms-full.txtThe rules file, the design contract and every English docs page in one file.
/tr/llms.txtThe index for the Turkish docs.
/docs/…/<page>.mdAny page as Markdown: add .md to its URL, for example /docs/components/button.md.

Paste https://meridui.dev/llms-full.txt into a chat to give the model the whole library in one go.

Rules file

The rules file tells an agent how Merid code should look: import from @meridui/react, style only with --mrd-* tokens (no raw hex, arbitrary spacing or inline styles), compose existing components before writing new ones, and keep the accessibility rules. It is the same file the CLI and the MCP server use.

AGENTS.md
# Merid UI rules

This project uses Merid (`@meridui/react`) for its UI. Follow these rules when you write or change interface code. Docs: https://meridui.dev/docs · full text for LLMs: https://meridui.dev/llms-full.txt

## Imports

- Import components from the package root only: `import { Button, Dialog, Field, Input } from "@meridui/react";`. Never deep-import from `@meridui/react/dist/...` or copy component source into the project.
- Import the stylesheet once, at the app entry (root layout, `main.tsx`): `import "@meridui/react/styles.css";`. Do not import it per component.
- Compound components use dot parts (`Dialog.Root`, `Dialog.Content`, `Select.Item`). In React Server Component files use the flat exports (`DialogRoot`, `DialogContent`, …).
- For router links use `asChild`: `<Button asChild><Link href="/x">…</Link></Button>`.

## Compose before you create

1. Check whether a Merid component already does the job (Button, IconButton, Link, Field, Input, Textarea, Select, NativeSelect, Checkbox, Radio, Switch, SegmentedControl, Card, Stack, Grid, Container, Section, Heading, Text, Table, Badge, Avatar, Tabs, Accordion, Alert, `ToastProvider` + `useToast`, Progress, Spinner, Skeleton, EmptyState, Dialog, AlertDialog, Drawer, Popover, Tooltip, DropdownMenu, Breadcrumb, Pagination, Stepper, SidebarNav, Separator, Kbd, Code, VisuallyHidden).
2. If not, compose existing components (for example a settings row is `Section` + `Field` + `Switch`; a toolbar is `Stack direction="row"` + `Button`/`IconButton`).
3. Only then write a new component, and style it with Merid tokens as below. Do not wrap Merid components just to rename them or restyle them with overrides.
4. Look up props before using them (docs page or the `get_component` MCP tool). Do not invent props, variants or sizes.

## Styling: tokens only

- Colours come only from semantic `--mrd-*` tokens: `--mrd-ink`, `--mrd-body`, `--mrd-muted` for text; `--mrd-bg`, `--mrd-surface`, `--mrd-tray`, `--mrd-subtle` for surfaces; `--mrd-line` for borders; `--mrd-accent*` for interactive and selected states; `--mrd-danger*`, `--mrd-warning-*`, `--mrd-success*` for status.
- No raw hex, `rgb()`, `hsl()` or named colours in components or CSS. No primitive palette tokens (`--mrd-blue-500`) either; they do not follow themes or accent presets.
- Spacing comes from the scale (`--mrd-space-1` … `--mrd-space-28`, or the `gap`/`padding` props of `Stack`, `Grid`, `Card`, `Section`). No arbitrary pixel values such as `margin: 13px` or Tailwind arbitrary values like `p-[13px]`.
- Radius from `--mrd-radius-*`, shadows from `--mrd-shadow-*`, type from `--mrd-text-*` / `--mrd-leading-*` / `--mrd-weight-*`, motion from `--mrd-duration*` / `--mrd-ease`.
- No inline `style={{ … }}` for colour, spacing, radius or typography. Use component props, a CSS class that reads tokens, or `data-*` attributes. (Setting a single CSS variable inline, such as `style={{ "--mrd-button-height": "32px" }}`, is the one allowed exception.)
- Borders are 1px `--mrd-line`. Never 2px, never dark borders. Separate regions by surface (`--mrd-tray`) before adding a border.
- One `variant="primary"` button per view. No gradients. Font weight 700 is never used.
- Theme, accent and density are attributes, not classes: `data-theme="dark"`, `data-accent="violet"`, `data-density="compact"` on `<html>` or any subtree.
- Write your own CSS outside Merid's layers (or in a later layer). Never use `!important` to beat Merid; its rules live in `@layer merid.*` and lose to unlayered CSS.

## Accessibility

- Every form control has a visible label: wrap it in `Field label="…"` (which wires `id`, `aria-describedby`, invalid and required) or use `Label`.
- Icon-only actions use `IconButton` with a `label`. Never a bare `<button>` with only an icon.
- Use `Button` for actions and `Link` for navigation. Do not put `onClick` on a `div` or `span`.
- Every `Dialog` and `AlertDialog` has a `Dialog.Title` (use `VisuallyHidden` if it must not show). Destructive confirmations use `AlertDialog`, not `Dialog`.
- Do not remove focus outlines. Do not set `tabIndex` greater than 0. Let Merid manage focus in overlays.
- Show errors with `Field`'s `error` prop, in text, not with colour alone.
- Keep headings in order (`Heading level`), and give images meaningful `alt` (empty `alt=""` for decoration).
- Respect `prefers-reduced-motion`; do not add animations that ignore it.

## When unsure

Ask the Merid MCP server (`npx -y @meridui/mcp`): `list_components`, `get_component`, `get_tokens`, `get_pattern`, `get_design_contract`, `search_docs`. Or read https://meridui.dev/llms.txt.

Where to put it:

ToolFile
Codex, Cursor, Copilot, Jules and other agents that read AGENTS.mdAGENTS.md at the project root
Cursor project rules.cursor/rules/merid.mdc, with description and globs frontmatter
Claude CodeCLAUDE.md at the project root

npx @meridui/cli init --rules writes all three. In AGENTS.md and CLAUDE.md it adds a section between <!-- merid:start --> and <!-- merid:end -->, so your own notes stay untouched and running it again only updates that section.