Agents

How agents use a design system

MCP gets an agent to your design system. It does not make the agent use it correctly. What an agent actually needs, the lookup-compose-audit-propose loop, and how governance catches the failure modes.

Connecting an agent to a design system does not mean the agent will use it correctly. Ask a coding agent to "add a billing settings page" and observe what it does. It reads a few files, infers a pattern and writes UI. If your design system is in its context, it will try to use it. If it is not, the agent will invent something that looks plausible.

The plausible answer is the problem. Consider a codebase where the prop is called variant. An agent writes <Button kind="primary">. In some setups this compiles, renders incorrectly and passes a quick review. Repeat that in every agent session across every team, and the result is drift that no human audit can keep up with.

This article explains how to make agents use a design system correctly, and what to put around them when they do not.

MCP is a connection, not a contract

The Model Context Protocol (MCP) has become the standard way for agents to reach external tools and data. It moved to the Linux Foundation's Agentic AI Foundation in December 2025, and secondary reports cite more than 10,000 public servers, and a Stacklok survey found 41% of organisations running MCP in production. Claude, Cursor, Copilot and Codex all support it in some form.

Every major design-system vendor now has an MCP server. Supernova, zeroheight, Knapsack and Figma ship one. Storybook has an MCP addon built on component manifests, and Chromatic hosts published Storybook MCP servers. MCP access is even becoming a metered unit, which vendors measure and limit by plan: Figma rate-limits MCP calls by plan and zeroheight limits search volume by tier, according to their pricing pages.

Having an MCP server is therefore not a differentiator. MCP works like a cable between the agent and your system. It tells you that the agent can ask a question. It tells you nothing about whether the answer is correct, complete or enforceable. That is the job of a contract: a precise description of what each component is and how it must be used.

An MCP server that serves an outdated documentation site gives an agent fast access to wrong information. This is worse than no access, because the agent can now point to a source for its mistake.

Fast access to wrong information is worse than no access at all.

What an agent actually needs

A designer can look at a component page and fill the gaps with judgement. An agent cannot. It needs the contract written out in fields it can parse. For each component, the contract needs:

  • Exact import. import { Button } from "@acme/ui/button", not "use our Button."
  • Props with types, defaults and allowed values. variant: "primary" | "secondary" | "ghost" | "danger", default "secondary".
  • States. Default, hover, focus, active, disabled, loading, and what triggers each one.
  • Accessibility obligations. "Icon-only buttons require aria-label." "Dialog must trap focus and return it on close." These are written as requirements, not as tips.
  • Tokens. Which semantic tokens the component uses, so that the agent never uses a raw hex value.
  • When to use it, and when not to. "Use Link for navigation, never a Button with onClick={navigate}." The rule about when not to use a component is often more useful than the rule about when to use it.
  • Content rules. Label length, sentence case, preferred verbs ("Save", not "Submit"), banned phrases, and how the string behaves when German or Finnish text makes it longer.

Most systems have about half of this information, and it is spread across Storybook args, a documentation site and a Slack thread. The conversion step exists to bring it together into one typed contract per component, stored in the repository, that both people and agents read.

Correct use is a loop: lookup, compose, audit, propose

Correct use by an agent is a loop, not a single retrieval. Loom's MCP server exposes four tools that map to this loop, and these are working at launch:

  1. Lookup. The agent asks what exists for its need. "Is there a component for a key-value summary?" The server returns the contract, or says that nothing exists and suggests the closest pattern.
  2. Compose on-system. The agent builds UI from contracts and semantic tokens, not from its memory of what design systems usually look like.
  3. Audit. Before it hands the work back, the agent runs its output through an on-system check. The check looks for unknown components, invalid props, raw values where a token exists and missing accessibility attributes.
  4. Propose. If the need is genuinely not met, the agent does not invent a local component. It drafts a proposal for the system that describes the gap, the use case and a suggested API. A person decides.

Step four is the one that most setups lack. Without it, every unmet need becomes a local re-implementation. With it, unmet needs become a queue that the design-system team can see and prioritise.

An illustrative transcript

Illustrative only. This is a composite written to show the loop, not a recorded session.

Developer: Add a plan summary card to the billing page. Show plan name, price, renewal date and an "Upgrade" action.

Agent: Looking up the system for a summary card. Found Card (@acme/ui/card) with header, body and footer slots, and DescriptionList for key-value pairs. Using Button variant="primary" in the footer. Contract note: Card must not nest another Card.

Agent: Composed. Running audit.

Audit: 2 findings. (1) font-weight: 600 on the price: use token font.weight.strong. (2) Renewal date formatted with toLocaleDateString(): content rule requires formatDate(date, "long") for locale-safe output.

Agent: Fixed both. Audit clean.

Agent: The design shows a "Most popular" ribbon on the card. No component or pattern covers this. I have not built a local one. Drafted a proposal: Badge placement on Card header, with use cases from billing and pricing pages. Filed for review.

The agent did three things that a simple integration would not do. It followed the rule about when not to use a component. It corrected its own work against tokens and content rules. It refused to invent a component.

Agents fail in predictable ways

Each failure mode needs a specific check.

Hallucinated components. The agent imports <Stat> because most design systems have one. Yours does not. Check: the audit resolves every import against the registry of contracts. Unknown components fail.

Invented props. The agent writes size="xl" on a component that only supports sm | md | lg. Check: props are validated against the typed contract, not only against TypeScript, because many systems type props loosely as string.

Hard-coded values. #D92D20, padding: 12px, border-radius: 6px. Each value is close to a token, and none of them is a token. Check: the audit maps raw values to the nearest semantic token and flags the bypass. Over time, the token bypass rate becomes a metric the team can watch.

Local re-implementations. A team needs a footer slot that Card does not have, so the agent copies Card into components/BillingCard.tsx. Check: usage scanning finds components that are structurally close copies of system components, and reports them as unmet needs, not only as violations.

Drift between design and code. The Figma library says radius.md is 8px, and the code says 6px. Agents that read either side produce inconsistent work. Check: drift detection compares the generated Figma library with the repository. At launch, Loom pushes tokens to Figma as variables, generates the component library and detects drift between them.

Off-brand content. The agent writes "Oops! Payment failed." Check: content rules stored as data and checked in the same audit. In our launch demo, microcopy and localisation enforcement are shown as concepts, not as working features. They are next on the build list because agents write more UI text than anyone.

Governance is the layer that makes it hold

Every check above produces a finding. Findings without owners are noise. This is why we treat agent output as one more contribution to the system. It follows the same path as a contribution from a person: audit, propose, review, accept, release.

The job of the AI is to make the correct path the easiest one and to make every deviation visible. The job of the people is to decide which deviations are bugs, which are legitimate exceptions and which are signals that the system itself needs to change.

Design-system teams that connect agents to their system should not stop at the connection. They should invest in the contracts, the audit and the governance that make the connection useful.

MCP brings your system into the agent's context. Contracts make it readable. Audits make it checkable. Governance makes it hold.

Continue the conversation

These sources, cited above, describe how MCP is being adopted and how design-system tools are exposing components to agents.

MCP adoption statistics 2026 by Digital Applied

A secondary summary of MCP adoption figures, including the number of public servers.

Storybook MCP for React by Storybook

The Storybook MCP addon, built on component manifests.

Introducing published Storybook MCP servers by Chromatic

How Chromatic hosts published Storybook MCP servers.

Figma pricing and zeroheight pricing

The vendor pages that show how MCP calls and search volume are limited by plan and tier.