Instruction files tell the model your components exist; a registry MCP server lets it look them up — real props, real variants, real install commands. Wired correctly, the agent stops hallucinating look-alike components and starts fetching and installing the actual ones, with their actual APIs.
Tier: Advanced · Workflow area: Component development · Tools: shadcn registry MCP, Storybook MCP, Claude Code, Cursor
The failure mode this kills: the model confidently writes <DataTable columns={...} onRowSelect={...}> when your DataTable has neither prop. Hallucinated props typecheck-fail at best and silently no-op at worst. Grounding generation in a live registry turns component APIs from something the model guesses into something it reads.
Wire the shadcn MCP server into your agent. For a shadcn-based system (or any registry following the shadcn registry spec), one command per tool:
npx shadcn@latest mcp init --client claude
npx shadcn@latest mcp init --client cursor
This writes the MCP server entry into .mcp.json / Cursor's MCP config. Verify from inside the agent:
List the registries you can reach and show the first 10 components in the
default registry, with one line each.
Good output names your registry and lists real component names — not a generic shadcn catalog dump (unless that is your registry).
Point it at your internal registry, not just the public one. In components.json:
{
"registries": {
"@acme": "https://registry.acme.dev/r/{name}.json"
}
}
If your registry needs auth, export the token where the MCP server runs: ACME_REGISTRY_TOKEN=... claude. Re-run the listing prompt and confirm @acme/* components appear.
Add Storybook MCP for prop-level truth on non-registry components. Registries know install payloads; Storybook knows rendered stories and argTypes. Run Storybook with the MCP addon enabled, then register it:
npm run storybook
claude mcp add storybook --transport http http://localhost:6006/mcp
Now the agent can answer "what props does OrdersTable accept and what do its stories look like" from the source of truth.
Bake retrieval into the workflow with one instruction-file rule. Grounding only works if the agent actually looks things up:
Before using ANY @acme/ui component in generated code:
1. Query the registry/Storybook MCP for its current props and variants.
2. If the component is not installed, install it via the registry
(npx shadcn@latest add @acme/<name>) — never re-implement it.
3. If no matching component exists, stop and list the closest three
candidates with their differences. Do not invent a component.
Run the A/B that proves the wiring. Same task, MCP off vs. on:
Build an OrdersPage: filterable data table of orders (status, customer,
total, date), row selection with bulk archive, date-range filter,
pagination, empty state. Use our design system.
With MCP on, a good transcript shows tool calls like search_items_in_registries("table"), view_items_in_registries("@acme/data-table"), then an install command, then code using only props that exist. Diff the two outputs and count hallucinated props — that number is your before/after metric.
Verify by compilation, not vibes. The point of grounding is that this now passes:
npx tsc --noEmit && npx eslint src/features/orders --max-warnings 0
Any remaining prop error means the registry metadata and the shipped types disagree — fix the registry, because every future generation reads it.
An MCP server is a supply-chain surface. Wire only registries you control or trust, pin the server package version, and review .mcp.json changes in PRs like any dependency change — a poisoned registry can inject code into every agent session on the team.
registry.json with registry:block / registry:component items) and both distribution and AI-grounding come free.tsc --noEmit passing untouched..mcp.json is committed and reviewed so the whole team shares the wiring, with server versions pinned.Run the registry A/B (step 5) once a quarter and keep the two diffs. It is the single most persuasive artifact for skeptical teammates and for the design-system budget conversation — "with grounding: zero hallucinated props, one command install; without: four fake props and a duplicated table implementation."