AI agents

A coding agent that has never heard of Dowel does the worst possible thing: it writes its own Button. A second button, with a different focus ring, different disabled semantics and hardcoded colours — and now the design system has a hole in it that nobody notices until someone tabs into it.

The fix is not a better prompt. It is giving the agent the catalogue, generated from the registry so it cannot go stale.

In your project

One command writes documentation for every agent that works in this repository. It reads the registry you install from and your components.json, so the catalogue is accurate and marks what you already have.

Terminal
pnpm dlx @dowel-ui/cli agents
TargetWritesWhat it is for
dowel.dowel/conventions.md, components.md, ai.md, themes.mdThe reference set. Read by any agent that reads the repository.
agentsAGENTS.mdA marked block appended to the file, replaced in place on regeneration. The rest of the file is yours.
claude.claude/skills/dowel-ui/SKILL.mdA Claude Code skill, loaded when the work is React UI.
cursor.cursor/rules/dowel-ui.mdcA Cursor project rule, scoped to .tsx and .jsx files.

Name targets to narrow it: dowel agents claude cursor. With none, it writes them all.

It is generated output, so regenerate it after an upgrade rather than editing it. --check writes nothing, reports what is stale and exits non-zero, which is what you want in CI — a catalogue that has fallen a release behind is worse than none, because the agent trusts it.

MCP server

The files above are a snapshot. The MCP server is the live version: the agent queries the registry directly, gets a component’s real source rather than a description of it, and is told when it has typed a name that does not exist.

.mcp.json
{
  "mcpServers": {
    "dowel": {
      "command": "npx",
      "args": ["-y", "@dowel-ui/mcp"],
      "env": {
        "DOWEL_IMPORT_FROM": "@/components/ui"
      }
    }
  }
}

Set DOWEL_IMPORT_FROM to the alias your components live under — the server has no way to see your components.json, and an agent told the wrong import path writes code that does not resolve. Point DOWEL_REGISTRY at a fork or an internal mirror if you have one.

ToolWhat it answers
search_componentsFind what already exists, by name, description or category.
get_componentOne component in full — accessibility notes, what it installs alongside, and optionally its source.
get_guideConventions, theming, the AI components, or the whole catalogue.
install_commandThe exact command, and everything it will write.

llms.txt

For an agent that can fetch a URL but cannot run a server, this site serves the whole catalogue as plain text — generated from the same registry, at build time, so it is never a release behind.

  • /llms.txt — the index: every one of the 184 components and 51 blocks, with a link to its page.
  • /llms-full.txt — everything in one request: conventions, accessibility rules, theming, the AI components, and per-component detail.

What the agent is told

Not a general lecture on accessibility, which gets ignored. A short list of the places this library differs from the ones a model has already read a million lines of:

  • A loading Button uses aria-disabled, never disabled — disabling a control mid-action strands keyboard focus.
  • Alert is not a live region by default. One that exists on first paint announces for no reason.
  • Separator, Skeleton and Spinner are decorative. Do not add ARIA to them by reflex.
  • Semantic tokens only. Never raw hex, never Tailwind’s own palette.
  • Check for a block before assembling a page out of primitives.