tenet-ui-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tenet-ui-mcplist Button props and tokens for tenet-ui 0.4.0"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
tenet-ui-mcp
The design-to-code MCP server for the tenet-ui design system, built to the design in mcp-masterclass/design/ds-mcp-server/DESIGN.md (rev 3). The server supplies context and judgment; the agent writes the code and runs the checks.
Status: build order steps 1–4 done — ingest pipeline, five catalog tools, resources, Streamable HTTP with self-hosted auth, path one (ingest_design → match_components → resolve_tokens → plan_component) with form elicitation, run_checks judging the capture script's results, path two (audit_code, audit_page), plan_tests, the three prompts, the hooks plugin and the first dashboard. The talk needs these four. Step 5 (Figma) is dropped: no Figma source exists for tenet-ui. Next: step 6 — the eval harness, the skill moved into the plugin, external OAuth.
Run it
npm ci
npm run ingest -- latest # or use the committed snapshots/
AUTH_MODE=none npm start # http://127.0.0.1:3000/mcp, no auth (local rehearsal)With the built-in issuer (DESIGN.md §9, self-hosted row):
export AUTH_HMAC_KEY="$(openssl rand -base64 48)" # issuer secret, never a bearer credential
npm start # AUTH_MODE defaults to hs256 when the key is set
npm run token -- --sub apurv --scope ds:read # prints a bearer token for a clientClaude Code, Cursor or any Streamable HTTP client: endpoint http://127.0.0.1:3000/mcp, header Authorization: Bearer <token>. For a local stdio client: npm run stdio.
Environment: PORT, HOST, PUBLIC_URL (the aud of tokens and the resource in PRM), AUTH_MODE (none | hs256), AUTH_HMAC_KEY, AUTH_CLIENT_ID / AUTH_CLIENT_SECRET / AUTH_CLIENT_SCOPES (optional client-credentials client for CI at POST /oauth/token), ALLOWED_ORIGINS, SNAPSHOTS_DIR, DATA_DIR (design store + event spool, default .data/), TELEMETRY=off.
Dashboard: GET /dashboard (HTML) and GET /metrics.json?days=7, bearer-authenticated (header or ?token=), read the event spool the server writes for its own calls and the companion plugin posts to POST /events.
Related MCP server: Design MCP
What the server serves
Catalog tools (ds:read, read-only, idempotent; fixed order; every tool returns structuredContent + a text summary + resource_links + _meta.traceId):
Tool | Cap | What it does |
| 2 KB | Ranked, synonym-aware search (dropdown → Select, Menu). Zero results return the five nearest names. |
| 8 KB (64 KB with | Import, props from the types with defaults and deprecations, subcomponents, stories, a11y, guidelines. |
| 4 KB | Tokens by meaning or group, per theme, with documented AA contrast pairs. |
| 2 KB | Icons by keyword with the exact import statement. |
| 4 KB | Nearest token for raw values: colours by ΔE in Lab against semantic tokens, dimensions by distance, with tolerance and alternatives. |
Every tool takes dsVersion (JSON schema carries x-mcp-header: DsVersion; a DsVersion request header is validated against the argument). Resolution: exact → newest patch of that minor → nearest earlier minor → latest of that major → latest, and the effective version is echoed in every result.
Path one, design to code (design:ingest; DESIGN.md §4):
Tool | Cap | What it does |
| 6 KB | A screenshot (≤ 5 MB PNG/JPEG/WebP/GIF, sniffed) goes to the vision model with a fixed template and an output schema in the catalog's vocabulary; or the host passes a |
| 8 KB | Ranks catalog components per region (role and label synonyms, the analyser's candidates, structural cues such as icon-only, bordered vs plain containers, children) and records confidence. Where the top two are within 0.15 it asks, at most 8 questions; |
| 6 KB | Every raw value the analyser read → nearest token with delta. Off-scale values become questions: snap, use an alternative, keep as a documented exception, or propose a token. |
| 24 KB | The plan: tree with exact imports, prop mapping per node (variant from colour and state, heading level from size, placeholders, wrappers), token references, a11y per node, files, contract rules, catalog excerpts, story and test ideas. A plan, never source. |
Checks (checks:run; DESIGN.md §5, §11, rev 3):
Tool | Cap | What it does |
| 16 KB | Takes the files the agent wrote and the |
Path two, audit and test (DESIGN.md §5):
Tool | Scope | Cap | What it does |
|
| 16 KB | The static scan of |
|
| 16 KB | Judges |
|
| 12 KB | From the component's files (props interface, callbacks, unions, the primitives it imports, its stories) or from a |
Reports from run_checks, audit_code and audit_page share one shape and one store: audit://{auditId}/findings.json (every finding, beyond the inline page), delta.json, report.json; private to the principal, 24 h.
Prompts: design-to-code, audit-ui, test-ui — the path, the anti-duplicate-call rule, the stop condition (no critical or serious finding, or three rounds).
Hooks plugin (plugin/, DESIGN.md §7 layer two): a Claude Code plugin with a PostToolUse hook on the server's tools, a PostToolUse hook on Write/Edit, and a Stop hook. It records tool name, trace id and outcome; that a file changed and what it followed (plan, audit, checks, catalog lookup); and at the end of the turn the rounds of run_checks, whether the last one was green, writes after a plan, lookups before a write, suppressed findings. Spooled locally under ~/.tenet-ui/hooks/ and posted to POST /events when DS_SERVER_URL and DS_SERVER_TOKEN are set. Never arguments, contents or paths in clear. See plugin/README.md.
Dashboard (GET /dashboard): the eight questions of DESIGN.md §7 — calls and principals per tool, p50/p95 and bytes per tool, elicitation rounds and unresolved picks, first-run pass rate per check, findings per audit and fixed in session, rounds to green and writes after a plan (from hooks), zero-result searches and token exceptions, version distribution and fallbacks, full: true rate. Server events carry names, counts, durations, outcomes and per-check statuses only.
Elicitation follows the MRTR shape of DESIGN.md §8 at the result level, because the MCP SDK does not ship it yet: a tool that needs an answer returns structuredContent.resultType = "input_required" with inputRequests (form elicitation params) and a sealed requestState (AES-GCM; principal, ten-minute expiry, argument digest, partial result). The client calls the same tool again with inputResponses and the untouched requestState. Another principal, a tampered blob, changed arguments, or an expired state are rejected. An agent can answer the questions itself or show them to the user.
Design store: rows (dsg_…, mtc_…, pln_…, aud_…) are bound to the caller's sub, expire after 24 h, live under DATA_DIR (default .data/). Another principal gets not-found, never forbidden. Private resources: design://{designId}/layout.json, screenshot.png, match.json, matches/{matchId}.json, plan.md, plans/{planId}.md|.json.
Vision: @anthropic-ai/sdk, model VISION_MODEL (default claude-opus-5), structured output via betaZodOutputFormat, server-side refusal fallbacks on. Enabled when ANTHROPIC_API_KEY (or an ant auth login profile with VISION=on) is present; otherwise ingest_design accepts layouts only and says so.
Resources: ds://versions, ds://{v}/components/{name} (markdown), ds://{v}/tokens/{group}.json, ds://{v}/guidelines/{topic} (the nine system pages, any component id, contract, audit-rules), ds://{v}/gaps, ds://{v}/changelog, ds://{v}/deprecations.
Discovery: GET /healthz, GET /.well-known/oauth-protected-resource, GET /.well-known/oauth-authorization-server. No token → 401 with WWW-Authenticate: Bearer resource_metadata=…; missing scope → one 403 insufficient_scope naming every missing scope.
Telemetry: one JSON line per request / tool call / resource read on stderr with a W3C trace id (from the traceparent header when the client sends one; echoed back). Names, durations, statuses, versions, byte counts. Never arguments or findings.
Protocol note
@modelcontextprotocol/sdk 1.30 implements MCP 2025-11-25: initialize handshake, tools/list, structured output, resource templates, Tasks. The stateless, no-handshake server/discover and MRTR elicitation that DESIGN.md §8 describes for the 2026-07-28 revision are not in the SDK yet. The server is stateless today (one McpServer per request, no session id), so the handshake is a formality and the move is contained in src/http.ts; elicitation already uses the MRTR result shape. tools/list is about 26 KB for thirteen tools with output schemas — the 7 KB figure in DESIGN.md §6 is not reachable with per-tool output schemas and is tracked as a budget of 2 KB per tool in the tests.
Layout
src/ingest/ the data pipeline (DESIGN.md §10) — see below
src/catalog/store.ts snapshot reads + dsVersion resolution
src/catalog/resolve.ts nearest-token resolution (ΔE / distance)
src/catalog/synonyms.ts what people call components and token groups
src/tools/ tools as plain functions (unit-tested without a transport): catalog-, design-, audit-, test-, checks-tools
src/design/ layout schema, vision call, matcher, token resolution, plan builder, test-plan builder
src/checks/ static scan + contract rules, source parser, judgment over capture results, page judgment, SSIM, shared report plumbing
src/store/ the design store (principal-bound rows, 24 h TTL; designs, matches, plans, reports)
src/auth/seal.ts requestState AEAD sealing
src/resources.ts ds:// public, design:// and audit:// private resources
src/prompts.ts design-to-code, audit-ui, test-ui
src/metrics.ts event spool, the §7 summary, the dashboard page
src/server.ts McpServer factory: registration order, structured output, _meta, telemetry with derived metrics
src/http.ts Streamable HTTP: Origin, bearer, scopes, PRM, AS metadata, client credentials; /events, /metrics.json, /dashboard
plugin/ the companion Claude Code plugin: hooks.json + ds-hook.mjs (layer two)
src/auth/tokens.ts HS256 issuer + verifier (jose); src/auth/cli.ts mints tokens
src/content/ the component contract and audit rule catalog (ds://…/guidelines/contract, audit-rules)
snapshots/ one folder per ingested version + one per guidelines revision (committed)
.github/workflows/ ci.yml · ingest.yml
Dockerfile single container, no browserIngest
npm run ingest -- 0.4.0 # one version
npm run ingest -- --new # every registry version newer than the newest snapshot (the registry watch)
npm run ingest -- --listSource | Read from | Yields |
Provenance | npm attestations endpoint | The SLSA statement must name |
Types |
| Every export: components, hooks, props with types, literal unions expanded, required flags, |
Catalog |
| Status, |
Guidelines |
| A guidelines revision |
Tokens, icons, deprecations, changelog |
| The token registry with documented contrast pairs; the icon manifest; the migration registry; parsed releases |
Stories |
| Story ids, titles, play-function tags |
Baselines |
| 1280×800 screenshots per story per theme with a sha256 manifest |
Every snapshot carries a manifest.json (each source with sourceRef, content hash, extractedAt) and a gaps.json. The version index is only updated after the whole snapshot validates. ingest.yml runs on repository_dispatch: tenet-ui-released from tenet-ui's release workflow, on a 6-hourly schedule, and by hand, and commits new snapshots.
Next
DESIGN.md §15 step 6 (step 5, Figma, is dropped — no Figma source for tenet-ui): the dual-path eval harness over golden screenshots and golden source files, the skill moved into this repo's plugin next to the hooks, external OAuth (PRM against a real authorization server, CIMD) if the server is ever shared beyond one team. design_to_plan as a Task once the composite is worth it; a live vision run once credentials are available (the vision path is wired but has never been exercised against the model).
Related MCP Connectors
Serves your design system and coding standards to coding agents, so they stop guessing.
Access and maintain design system docs, tokens, components, skills, and contexts across any project.
Live React design-system APIs, patterns, and code validation so AI agents build real UI, not slop.
Design system contracts, docs search, and usage validation for @digitaltableteur components.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceA read-only MCP server that provides AI coding agents with a queryable contract for design system tokens, components, patterns, and anti-patterns.17 npm1Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides source-backed design context, route card validation, contract generation, critique and verification reports, evidence packages, Penpot change plans, and anti-repeat checks for design workflows. Does not directly mutate Penpot, but consumes read-only Penpot snapshots.8 npmMIT
- AlicenseAqualityAmaintenanceRead-only MCP server that exposes a design system's tokens, components, conventions, and deprecations as queryable tools, enabling agents to look up canonical values, assess change impact, and detect hardcoded value drift.87 npmMIT
- AlicenseNot gradedqualityBmaintenanceProvides a real API for coding agents to look up design system components, props, and tokens, preventing guessed answers.7MIT