Agent-native design system
Design system agent demo
Machine-readable contracts, intent benchmarks and MCP tools so agents reuse @dt/* before inventing markup. Colophon covers the full stack.
MCP & docs
- MCP:
/mcp(POST, Streamable HTTP) - Card: /.well-known/mcp/server-card.json
- Agent card: /.well-known/agent.json
- Case study (repo):
docs/AGENTIC_DS_CASE_STUDY.md - Catalog policy (repo):
docs/CATALOG-POLICY.md
Intent golden set
20 queries verified by npm run agent:eval.
| alert-dismissible | “dismissible warning banner” | AlertBanner (top 1) |
|---|---|---|
| button-primary | “primary action button” | Button, MCPActionButton (in top 3) |
| title-semantic | “semantic page title heading” | Title (top 1) |
| submit-loading | “loading submit button” | Button (in top 3) |
| modal | “modal dialog” | Modal (in top 3) |
| cookie-consent | “cookie consent” | CookieConsent (top 1) |
| text-input | “labeled text input” | TextInput (in top 3) |
| pagination | “pagination controls” | Pagination (top 1) |
| chat-widget | “chat widget send” | ChatWidget, ChatComposer, ChatHeader (in top 3) |
| file-upload | “file upload” | FileUpload (top 1) |
| toast | “toast message” | Toast (top 1) |
| hero | “hero section landing” | HeroSection, Hero, CTASection (in top 3) |
| card-actions | “card with actions” | Card (top 1) |
| select | “dropdown select options” | Select (top 1) |
| checkbox | “checkbox with label” | Checkbox (in top 3) |
| switch | “toggle switch” | Switch (top 1) |
| badge | “status badge” | Badge (top 1) |
| tabs | “tabs navigation” | Tabs (top 1) |
| icon-button | “icon only button” | IconButton (top 1) |
| helper-text | “tooltip help” | HelperText, Label (in top 3) |
Component taxonomy
184 components from the generated docs registry. Expand a group and select a component to see the dense contract line agents retrieve.
Select a component to see the dense contract line agents retrieve.
Agent benchmark
Coding agents on the same tasks, in 4 arms that differ in one thing only: how the design system is offered to them. 264 published runs across Claude Code and OpenAI Codex CLI. Metered spend on these runs: $66.94; subscription runs report output tokens instead and spend on superseded runs is in the notes. Acceptance tests user-visible semantics and contract conformance, not implementation; reuse of @dt/* is reported separately and never gates a pass. Methodology: docs/AGENT_BENCH_METHODOLOGY.md.
- WITH (dt CLI documented in workspace)
- MCP (design-system MCP attached, generic workspace)
- MCP + POINTER (same server, plus one line in the workspace naming it)
- WITHOUT (generic workspace)
| Arm | First-try pass | Final pass (repair loop) | Mean cost / run | Affordance used | DS reuse (build tasks) |
|---|---|---|---|---|---|
| WITH | 31/33 | 33/33 (2 via repair) | $0.53 ± 0.25 | MCP 0/33, dt CLI 29/33 | 20/24 |
| MCP | 33/33 | 33/33 | $0.46 ± 0.22 | MCP 4/33, dt CLI 0/33 | 10/24 |
| MCP + POINTER | 32/33 | 33/33 (1 via repair) | $0.58 ± 0.20 | MCP 31/33, dt CLI 0/33 | 21/24 |
| WITHOUT | 32/33 | 33/33 (1 via repair) | $0.46 ± 0.21 | MCP 0/33, dt CLI 0/33 | 12/24 |
| Arm | First-try pass | Final pass (repair loop) | Mean cost / run | Affordance used | DS reuse (build tasks) |
|---|---|---|---|---|---|
| WITH | 33/33 | 33/33 | subscription, 5.8k output tokens | MCP 0/33, dt CLI 33/33 | 21/24 |
| MCP | 33/33 | 33/33 | subscription, 5.3k output tokens | MCP 0/33, dt CLI 2/33 | 4/24 |
| MCP + POINTER | 33/33 | 33/33 | subscription, 6k output tokens | MCP 33/33, dt CLI 2/33 | 21/24 |
| WITHOUT | 33/33 | 33/33 | subscription, 5.4k output tokens | MCP 0/33, dt CLI 1/33 | 4/24 |
| Task | WITH | MCP | MCP + POINTER | WITHOUT | DS reuse (WITH / MCP / MCP + POINTER / WITHOUT) |
|---|---|---|---|---|---|
| dialog | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 / 3/3 / 3/3 / 3/3 |
| composition | 2/3 | 3/3 | 3/3 | 3/3 | 3/3 / 3/3 / 3/3 / 3/3 |
| forced-colors | 3/3 | 3/3 | 3/3 | 3/3 | 0/3 / 0/3 / 1/3 / 1/3 |
| form | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 / 1/3 / 3/3 / 2/3 |
| migration | 2/3 | 3/3 | 2/3 | 2/3 | n/a / n/a / n/a / n/a |
| repair | 3/3 | 3/3 | 3/3 | 3/3 | n/a / n/a / n/a / n/a |
| composition | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 / 3/3 / 3/3 / 3/3 |
| table | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 / 0/3 / 3/3 / 0/3 |
| refactor | 3/3 | 3/3 | 3/3 | 3/3 | n/a / n/a / n/a / n/a |
| tokens | 3/3 | 3/3 | 3/3 | 3/3 | 2/3 / 0/3 / 2/3 / 0/3 |
| tree | 3/3 | 3/3 | 3/3 | 3/3 | 3/3 / 0/3 / 3/3 / 0/3 |
- Two model families, same tasks, same graders, same repository state per task: Claude Code (claude-sonnet-5) and the OpenAI Codex CLI (gpt-5.6-sol, high effort). Four arms each, differing in one thing only. WITH: the workspace instructions document the dt CLI. MCP: generic instructions plus the repository's stdio design-system MCP server attached. MCP + POINTER: the MCP arm plus one line naming the server. WITHOUT: generic instructions. Each runtime reads the arm text from its own instruction file (CLAUDE.md or AGENTS.md).
- Headline, replicated across both families: an MCP server is only as good as the pointer to it. Attached alone, Claude called it in 4 of 33 runs and Codex in 0 of 33, and design-system reuse stayed at the control's level (Claude 10 of 24 vs 12 of 24; Codex 4 of 24 vs 4 of 24). With one line naming the server, Claude called it in 31 of 33 runs and Codex in 33 of 33, and reuse rose to 21 of 24 in both, level with documenting the CLI (Claude 20 of 24, Codex 21 of 24). The clients defer MCP tools behind a tool search, so an agent that is not told the server exists rarely or never looks.
- The pointer line, verbatim: "This repository's design system is available through the `design-system` MCP server; use its tools to find components and validate usage before finishing."
- Pass rates saturated for both families. Eleven tasks, including three multi-component and cross-file tasks added to separate the arms (a tabbed settings panel with shared state, a filterable paginated directory, and a three-page migration off hand-rolled tabs). First-try pass is 31 to 33 of 33 for every Claude arm and 33 of 33 for every Codex arm. Today's differences are in how agents build, not whether they succeed. Tasks whose briefs say to use the design system correctly if used saw high reuse in every arm; compare arms within a task.
- Isolation: Claude runs pass --strict-mcp-config and --setting-sources project,local; Codex runs use a throwaway CODEX_HOME holding only the login. Neither sees the operator's own instructions, skills, plugins or MCP servers.
- Cost: Claude spend $95.13 including $28.19 on superseded runs (see supersededRuns: a stale hardcoded consumer list and a colour scan that flagged var(--color-white), both fixed and guarded in the selftest before re-running). Codex ran on a subscription, so it reports output tokens instead of dollars; token counts are not comparable across families.
- Harness notes: a result-file name collision between parallel arms lost three Codex migration runs; filenames are now unique and the three runs were re-run from the same source commit. n=3 per arm per task per family. Treat per-task differences as anecdotes; the MCP call rates and the reuse gaps are consistent enough to read.
Raw artifact: /ds-health/agent-bench.json. n=3 per arm per task; cost is mean ± sample sd. Runs are nondeterministic, so treat single deltas as noise and distributions as the signal. The earlier two-arm batch (August 2026, 90 runs, different isolation) is archived at /ds-health/agent-bench-2026-08.json.
Evidence per publish
Seven artifacts regenerate inside the publish preflight and ship stamped at the published version — currently @digitaltableteur/react@0.1.26. Numbers below are derived from the committed artifacts, never hand-written; each raw file carries its own provenance (source commit, generator, tree state) and timings live outside the stamped substance because they vary by machine.
| Artifact | What it records | Headline | Raw |
|---|---|---|---|
| Bundle cost | Minified+gzip bytes per exported component, in two honest modes: the package's own code (self) and the marginal cost to a consumer that satisfies the peer contract (withDeps). | 143 exports, package self 732.7 kB JS + 47.0 kB CSS gzip | JSON |
| SSR + hydration | renderToString in plain Node (no DOM globals), then hydrateRoot over that HTML with zero recoverable hydration errors. | 90 SSR pass, 90 hydrate clean, 2 provider-required errors | JSON |
| Override precedence | A consumer's single-class className override wins over component base styles in real Chromium (the owner-decided contract), plus the container × child encapsulation matrix on child-pinned properties. | 47 pass, 0 fail, 64 matrix pairs, 0 affected | JSON |
| Interaction cost | Mount/re-render commit cost (flushSync, informational) and DOM render weight per component, plus interaction recipes over the data primitives' documented hot paths. | 90 measured, 4 recipes completed | JSON |
| React peer-range matrix | The declared react range (>=19.0.0) exercised at its endpoints in isolated consumer installs; outcome sets must match across combos. | react 19.0.0 & 19.3.0, 0 divergent components | JSON |
| Web-component parity | React↔native rendered parity (pixels + geometry across the viewport/theme matrix); enforced components fail the publish on regression. | 20 enforced clean, fleet visual 145/413, geometry 197/413 of 413 | JSON |
| Compatibility manifest | The toolchain combinations ACTUALLY exercised by the gates — resolved versions, never ranges. Absence means untested, not incompatible. | react 19.3.0, next 16.3.5, typescript 6.0.3 | JSON |
Pattern recipes
MCP tool suggest_pattern_for_layout
@dt/CTASection
marketing call-to-action band at section end
Avoid: inline alert or toast feedback
@dt/HeroSection
full-bleed marketing hero with alignment and background variants
Avoid: blog article hero — prefer ArticleHero pattern
@dt/HomeHero
production homepage hero with kinetic title and scroll indicator
Avoid: generic marketing hero without homepage-specific motion
@dt/SiteHeader
Next.js app shell sticky header with brand and nav
Avoid: embedded header inside a card or modal
@dt/SiteFooter
site-wide footer with link columns and social links
Avoid: legacy Footer pattern with different IA
@dt/NewsBulletin
homepage news strip with three topical slots above footer
Avoid: full blog index or article grid
@dt/ArticleHero
blog article hero with title metadata and optional image
Avoid: marketing homepage hero — prefer HeroSection
@dt/ContactInquiryPanel
contact page message vs book-a-call tab panel
Avoid: standalone contact form without tab chrome
@dt/PricingPageContent
pricing page with package tiers and agency comparison
Avoid: single pricing card inline on homepage
Local verification
npm run build:tokens npm run agent:eval npm run agentic-ds-audit npm run ds:mcp