ds-canon
The ds-canon server provides a read-only MCP interface to query a design system's tokens, components, conventions, and deprecations, serving as an authoritative source of truth for agents and developers.
Tokens: List all design tokens with optional filters (group, status, substring search). Get a specific token's full details (value, type, group, status, aliases, and which components consume it), with suggestions if misspelled.
Components: List components with optional status/tag filters, including summaries. Get full component details (props, variants, tokens used, deprecation info, and anti-pattern guidance), with suggestions if misspelled.
Dependency analysis: Perform reverse-dependency lookup to see what depends on a token or component, helping you understand the impact of changes.
Deprecations: Get a list of all deprecated tokens and components, their replacements, and how many active items still depend on them.
Conventions: Retrieve house rules for naming, spacing, color, accessibility, and deprecation, optionally filtered by topic.
Token drift detection: Scan code snippets (CSS, JSX, plain text) for hardcoded colors/px values and suggest matching design tokens to enforce token usage.
Click on "Install 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., "@ds-canonI want to change space.inset.md. What will it affect?"
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.
ds-canon
Your design system's canon, queryable by agents. What exists, what is deprecated, what breaks if you touch it.
Design systems decay into tribal knowledge the moment the token sheet drifts from the code and the person who remembers why gets pulled onto another project. Agents writing UI code make this worse: they hallucinate plausible token names and confident-sounding component APIs because they have nothing authoritative to check against. ds-canon puts your design system's tokens, components, conventions, and deprecations behind a read-only MCP server, so agents and the humans directing them query the same system of record instead of guessing.
The 60-second demo
Run it straight from npm, nothing to clone:
npx -y ds-canonYou'll see a one-line banner on stderr confirming what loaded:
ds-canon v0.1.0 serving Nimbus DS (40 tokens, 9 components) from /path/to/ds-canon/fixtures, read-onlyThe server ships with a fixture design system called Nimbus DS so you can try it immediately, no setup required. Point an MCP-aware agent at it and ask it real questions.
"Which accent color should I use, and is anything deprecated?"
The agent calls list_tokens with group: "color", query: "color.accent", then whats_deprecated. Real output, verbatim:
{
"tokens": [
{
"name": "color.accent.primary",
"value": "#3B5BDB",
"type": "color",
"group": "color",
"status": "active",
"description": "Primary brand accent. Used for primary actions, active navigation state, and focus affordances."
},
{
"name": "color.accent.secondary",
"value": "#5C7CFA",
"type": "color",
"group": "color",
"status": "active",
"description": "Secondary accent for lower-emphasis interactive elements that still need to read as brand-colored."
},
{
"name": "color.accent.legacy",
"value": "#4C6EF5",
"type": "color",
"group": "color",
"status": "deprecated",
"description": "Original brand blue from the v1.x palette. Slightly less saturated than accent.primary; kept only for Banner and LegacyButton until both migrate.",
"deprecatedBy": "color.accent.primary"
}
]
}(The query parameter is a substring match on name and description, so a looser query like "accent" also surfaces tokens whose descriptions mention accent usage. Scoping the query to the name prefix keeps the answer tight.)
{
"deprecated": [
{ "name": "color.accent.legacy", "kind": "token", "deprecatedBy": "color.accent.primary", "dependentCount": 1 },
{ "name": "LegacyButton", "kind": "component", "deprecatedBy": "Button", "dependentCount": 0 }
]
}The agent now knows to recommend color.accent.primary and to flag color.accent.legacy as on its way out, with one live component (Banner) still depending on it.
"I want to change space.inset.md. What will it affect?"
This is the question a design system actually needs to answer before anyone touches a shared value. The agent calls find_usages:
{
"entity": "space.inset.md",
"usages": [
{ "dependent": "Button", "dependentKind": "component", "relation": "consumes token" },
{ "dependent": "Card", "dependentKind": "component", "relation": "consumes token" },
{ "dependent": "Field", "dependentKind": "component", "relation": "consumes token" },
{ "dependent": "Modal", "dependentKind": "component", "relation": "consumes token" }
]
}Blast radius, in one call: four components, named exactly. No spelunking through a component library to find every place 12px got typed in by hand.
"Write a secondary button that follows our conventions."
The agent calls get_component for Button (props, variants, the tokens it consumes, and its doNotUse guidance) and get_conventions for the color topic, then writes the component. Now suppose it (or a human) had instead hardcoded the color:
<button style={{ background: '#3B5BDB', padding: '12px' }}>Save</button>Running that snippet through check_token_drift catches both literals:
{
"findings": [
{
"severity": "warn",
"raw": "#3B5BDB",
"suggestion": "color.accent.primary",
"message": "Hardcoded value #3B5BDB matches token \"color.accent.primary\". Use the token instead of the raw value."
},
{
"severity": "warn",
"raw": "12px",
"suggestion": "space.inset.md",
"message": "Hardcoded value 12px matches token \"space.inset.md\". Use the token instead of the raw value."
}
]
}#3B5BDB and 12px are exact token values, so the finding names the token, not just the problem.
Related MCP server: Design System MCP Server
Install
ds-canon runs as a local MCP server over stdio. There is no separate service to deploy.
mcp.json (Claude Desktop, or a project-level .mcp.json for Claude Code):
{
"mcpServers": {
"ds-canon": {
"command": "npx",
"args": ["-y", "ds-canon"]
}
}
}Claude Code, one line:
claude mcp add ds-canon -- npx -y ds-canonClaude Desktop: add the same mcpServers entry to your claude_desktop_config.json and restart the app.
Working from a clone instead (for development or custom fixtures): git clone, npm install, npm run build, then point command at node with args: ["/absolute/path/to/ds-canon/dist/index.js"].
Tools
Eight tools, all read-only.
Tool | What it answers | Key inputs |
| What tokens exist? |
|
| What is this token and who uses it? |
|
| What components exist? |
|
| What does this component look like? |
|
| What breaks if I change this? |
|
| What should I stop using? | none |
| What are the house rules? |
|
| Does this code drift from the token system? |
|
get_token, get_component, and find_usages look up by exact name; a miss returns a not_found error with up to three closest-name suggestions instead of an empty result, so a typo doesn't read as "this doesn't exist."
Point it at your own system
ds-canon reads three files from a fixture directory: tokens.json, components.json, and conventions.md. By default it loads the bundled Nimbus DS fixtures. Set DS_CANON_FIXTURES to point it at your own:
DS_CANON_FIXTURES=/path/to/your/design-system node dist/index.jsor in mcp.json:
{
"mcpServers": {
"ds-canon": {
"command": "npx",
"args": ["-y", "ds-canon"],
"env": { "DS_CANON_FIXTURES": "/path/to/your/design-system" }
}
}
}tokens.json is plain W3C DTCG format: nested groups, each leaf with $value, $type, and $description. If you already export tokens from Style Dictionary or Tokens Studio in DTCG format, that file works here with no transformation. Deprecation and aliasing use two extensions on top of the base spec: an $extensions["ds-canon"] block for status/deprecatedBy, and DTCG's own {token.path} reference syntax for aliases. components.json is a flat { meta, components } shape matching the DsComponent type in src/types.ts. conventions.md is Markdown: one ## topic section per convention (naming, spacing, color, accessibility, deprecation), each with Rule:, Rationale:, and Example: lines. The loader validates all three at startup and throws a specific, file-and-field-level error message on anything malformed, rather than serving a partially-loaded system.
Why read-only, why stdio, why no network
Every tool in ds-canon reads from an in-memory index built once at startup. Nothing in this server writes to the fixture files, calls out to a network, or accepts write operations of any kind. That's not an implementation gap, it's the point: a design system's system of record should not be mutable by the same agents that consume it, and a tool that only answers "what exists" cannot be tricked into becoming a tool that changes what exists.
Running over stdio instead of as a network service means ds-canon has no port to scan, no auth to misconfigure, and no attack surface beyond the local process that spawns it. The deployment model doubles as the governance model: install it, point it at your tokens, and every agent that would otherwise guess now has one, unwritable, source of truth to query instead.
How this was built
ds-canon was built by a multi-agent factory in an afternoon: parallel contract-first builders working from frozen type definitions, adversarial challengers doing black-box QA and architecture review against the built server, and agent-to-agent fix loops closing every finding before the next phase started. The full build log, prompts, and challenge reports are in factory/.
License
MIT. See LICENSE.
Jay Trainer, Sr. Director of Product Design (AI-Native). jaytrainerdesign.com
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityBmaintenanceMCP server that exposes your design system components and tokens to AI agents, preventing duplicate component creation and hardcoded token values.Last updated189MIT
- Alicense-qualityDmaintenanceProvides resources, tools, and prompts for a Design System via MCP protocol, enabling component search, reading, and related component discovery.Last updated321MIT
- Alicense-qualityAmaintenanceA read-only MCP server that provides AI coding agents with a queryable contract for design system tokens, components, patterns, and anti-patterns.Last updated301Apache 2.0
- AlicenseAqualityCmaintenanceManages design tokens (colors, spacing, fonts) in a JSON file and enables agents to read, write, export, and detect drift between tokens and CSS via MCP.Last updated5MIT
Related MCP Connectors
Read-only MCP server for Robinhood Chain token discovery, research, and due diligence via GMGN.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
MCP server for AgentDocs (agentdocs.eu): read, search, write, comment on & share Markdown docs.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jtrainer357/ds-canon'
If you have feedback or need assistance with the MCP directory API, please join our Discord server