0%
Messay Denbel

November 1, 2026 · Build log · 7 min read

I built a design system for AI teammates.

A growing share of the code that touches a design system is written by agents, not people. Instead of a point-of-view deck, I built a working demo: tokens served over MCP, one linter for humans and machines, and adoption measured as data. Here is how it works.

I kept running into the same question in design leadership conversations: what happens to a design system when a growing share of its users are AI agents instead of people? Most answers I heard were slideware. I wanted a working answer, so I built one: Messay's Design System, a live demo of an AI-native design system you can run step by step in the browser at messay-ds-demo.netlify.app.

The demo plays one scenario end to end. An engineer types a single line of intent: plan an associate price-check screen. An agent builds the screen entirely on-system, a linter catches drift the moment it appears, and every scan and tool call lands in an adoption warehouse the design system team reads the next morning. None of that is hand-waved. Every step actually runs, live, with a call counter keeping score.

The core idea: the design system is the context layer

AI output quality is a direct function of context quality. If your tokens live in a Figma file and your usage rules live in people's heads, an agent will guess, and it will guess off-system. So the first decision was to make the system machine-readable at the point of use: an MCP server any agent can query. get_tokens returns the semantic tokens for a surface. find_component answers "what do I use for a barcode field?" with ScanField and its import path. check_usage scores the written code against the system's rules.

The components themselves are shadcn/ui primitives plus MDS compositions built on top of them: ScanField, DataTable, ProductCard, TaskQueue. They publish to a registry, so an agent installs them exactly the way an engineer does: npx shadcn add @mds/scan-field. Code and tokens live in the repo, which is where agents work best.

Engineer/messay:plan a price-check screenClaude Code + messay.aiskills · token guard · commit gateMDS MCP serverget_tokens · find_component · check_usageProduct repo + CIon-system code · mds-check on every PRAdoption warehousenightly repo scans · logged tool callsDesign system teampublishes tokens, components, migrations01 · intent02 · tokens + components03 · shadcn add · code04 · nightly scan05 · reports06 · next feature picks them up
One connected loop: the build loop runs per feature, the insight loop runs nightly and feeds what teams actually use back into the system.

Two loops, one system

The architecture is two loops. The build loop runs once per feature: intent, then tokens and components over MCP, then code, then checks. The insight loop runs continuously: a nightly scanner reads every repo's imports and lockfile, the MCP server logs every tool call it serves, and both land in the same warehouse. The design system team reads coverage, version lag and the deprecation backlog, then publishes new tokens, components and migrations to the registry. The next feature picks them up automatically at step two.

One linter, three gates

Guardrails only work if humans and agents are held to the same rules. So there is exactly one linter, mds-check, and it runs in three places: as a token guard on every edit the agent makes, as a commit gate on every git commit, and in CI on every pull request. The agent fixes findings until the usage score hits 100 before it ever shows the code. Drift gets caught at the moment it is cheapest to fix, not in a design review three weeks later.

mds-checkone rule settokens · importsvariants · a11yEDITToken guard hookblocks raw colors liveCOMMITCommit gateruns mds-check locallyPULL REQUESTCI checksame linter, every PRhumans and agents,held to the same rules
The same rules enforced at the edit, the commit, and the pull request.

Adoption is data, not a survey

Most teams measure design system adoption with screenshots and vibes. Here it is a schema. Nightly scans write each repo's component coverage and registry version; the MCP server writes every tool call. That one warehouse answers the questions that actually decide a roadmap: which teams sit below the coverage target, who is a major version behind, where the deprecated Modal still lives, and what agents ask the system for most. In the demo the warehouse is seeded with fictional teams so the reports have something to say, but the schema and the queries are the real design.

Product reposimports + lockfile, nightlyMCP serverevery tool call loggedscanscallsAdoption warehousescans · tool_calls · 13 SQL reportsWhat the team readscoverage vs the 60% target · version lagdeprecated Modal backlog · what agents ask fornew tokens · components · migrations → registry
Human adoption and AI usage land in the same tables, so one dashboard tells the team where to spend effort.

How the demo itself is built

The demo is a single-page app with no backend. The MCP server, the linter and the warehouse are simulated by a small in-browser engine, so every step runs live in your browser: you watch the agent's tool calls stream, see the linter catch an off-system color, then refresh the adoption dashboard and find the evidence. For the real thing, a companion MCP server runs locally, and the demo can send its tool calls there instead, the same tools Claude Code would call.

It is also dogfooding. The customer surface's theme is messay.design's own palette, brand orange on near-black, expressed as shadcn semantic tokens with light and dark modes. The demo documents a system that looks like me, and it marks honestly what runs today versus what a production rollout still needs: SSO in front of the MCP server, the gates packaged for CI, the scanner as real infrastructure.

A design system used to be a promise that people would build consistently. Now it has to be an API that makes consistency the path of least resistance, for people and for agents.

That is the shift I wanted to make tangible. Treat the design system as a product whose users now include machines. Give it an interface those machines can call, hold them to the same rules as everyone else, and measure what they do with it. Then let what you measure decide what you build next.

Comments

No comments yet — start the conversation.