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
Linkfor navigation, never aButtonwithonClick={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:
- 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.
- Compose on-system. The agent builds UI from contracts and semantic tokens, not from its memory of what design systems usually look like.
- 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.
- 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) withheader,bodyandfooterslots, andDescriptionListfor key-value pairs. UsingButton variant="primary"in the footer. Contract note:Cardmust not nest anotherCard.Agent: Composed. Running audit.
Audit: 2 findings. (1)
font-weight: 600on the price: use tokenfont.weight.strong. (2) Renewal date formatted withtoLocaleDateString(): content rule requiresformatDate(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:
Badgeplacement onCardheader, 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.