@springpod/design-system-mcp
v0.2.0
Published
Model Context Protocol (stdio) server exposing the Springpod design system — components, usage rules, tokens, icons, example screens, adoption playbooks, and the brand-drift audit — as queryable tools and resources for AI agents.
Readme
@springpod/design-system-mcp
A Model Context Protocol (MCP) server that
exposes the Springpod design system
to AI agents as queryable tools and resources — component choices, do/don't
usage rules, design tokens, the 760+ icon inventory, example-screen
compositions, adoption playbooks, and the brand-drift audit — so agents fetch
exactly what they need instead of loading the full AGENTS.md index into
context.
Transports: stdio (this package, run locally) and streamable HTTP (the same server hosted behind one URL, for clients that only accept a remote server). All tools are read-only.
Hosted connector (no install)
Hosts that take a server URL instead of a config file can use:
https://springpod-design-system.replit.app/api/mcp- Claude (Cowork, Desktop, web) — Settings → Connectors → Add custom connector.
- ChatGPT — Settings → Connectors → Advanced → enable Developer mode,
then Connectors → Create, with No authentication. Deep research can use
it as a source: it calls the
searchandfetchtools below. - Gemini / Google AI Studio / Gemini CLI — add as a remote MCP server;
in Gemini CLI's
settings.jsonuse{ "httpUrl": "…/api/mcp" }.
A hosted server has no access to the caller's filesystem, so it answers from
the design-system snapshot bundled with the deployed server (never a repo's
installed version) and omits run_drift_audit, which scans a local directory.
In exchange it adds the generic search / fetch pair that non-Claude hosts
expect. It is public, cross-origin enabled, and rate limited per client.
Inside a repo, prefer the stdio route below.
Quick start
npx @springpod/design-system-mcpRun it from the root of the repo you're working in: when that repo has
@springpod/design-system installed, answers reflect the installed
version; otherwise the server falls back to design-system data bundled at
this package's own build time (each answer states its data source).
Claude Code
claude mcp add springpod-design-system -- npx @springpod/design-system-mcpor in .mcp.json:
{
"mcpServers": {
"springpod-design-system": {
"command": "npx",
"args": ["@springpod/design-system-mcp"]
}
}
}Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"springpod-design-system": {
"command": "npx",
"args": ["@springpod/design-system-mcp"]
}
}
}Cursor
.cursor/mcp.json:
{
"mcpServers": {
"springpod-design-system": {
"command": "npx",
"args": ["@springpod/design-system-mcp"]
}
}
}Tools
| Tool | What it answers |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| list_components | Every component module with its one-line purpose and import path (filter by ui / charts). |
| get_component | One module's purpose, exports, do/don't usage rules, and responsive behavior. |
| search_components | Substring search across names, purposes, exports, and usage rules. |
| which_component_when | Disambiguation for confusable families (badge vs tag vs pill, dialog vs sheet, …). |
| search_icons | Search the platform/social/menu/brand icon inventory by name or category; returns import paths, size tiers, mono flags. |
| search_tokens | Token lookup by name, hex/px value, or keyword — includes the theme CSS variable and Tailwind utility stems for colors. |
| example_screens | Index of real product screens and the design-system components each composes (capture images stay repo-only). |
| run_drift_audit | Runs the read-only springpod-audit brand-drift scan on a directory, returning JSON findings (off-palette colors, non-scale type/spacing, locally re-implemented components). (stdio only — a hosted server has no local directory to scan.) |
| request_component | Local install only. Files a gap into the design-system backlog (same record as the site's request form), or returns a paste-ready draft when no intake token is configured. |
| search | Hosted connector only. One search across components, guidance, tokens, icons, example screens, and docs; returns ids (component:ui/button, token:color.palette.teal.600, …) with titles and links. |
| fetch | Hosted connector only. The full record behind a search id. |
When nothing matches
An empty search result is where an assistant decides to invent a component,
so no-match answers are never empty: search_components,
which_component_when, get_component and the hosted search return a
noMatch block with the fallback rule (re-search by the job the UI does →
compose from package primitives using exact tokens → keep it local only when
it is genuinely product-specific, still importing primitives), the nearest
component modules to compose from, and where to file the gap.
Locally installed servers can file it directly with request_component,
which creates the same record as the request form on the design-system site,
marked as MCP-filed because the requester name is self-declared rather than
taken from a signed-in session. Filing needs an intake token:
| Variable | Purpose |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| SPRINGPOD_REQUEST_TOKEN | Intake token from a design-system maintainer. Without it request_component returns a paste-ready draft and the board's URL instead of filing. |
| SPRINGPOD_REQUESTS_URL | Override the intake endpoint (defaults to the hosted design-system API). Useful when pointing at a local API server. |
Maintainers: prefer issuing each developer a personal intake token from
the Users & roles page on the design-system site. A personal token attributes
filed requests to that developer's account (instead of a self-declared name)
and can be revoked on its own from the same page — effective on the next
call, no redeploy, nobody else cut off. The developer sets it as
SPRINGPOD_REQUEST_TOKEN exactly like the shared one.
The legacy shared token is still supported: the same value is configured on
the API server as MCP_REQUEST_INTAKE_TOKEN. The two names are deliberately
different — SPRINGPOD_REQUEST_TOKEN is what a developer's MCP client
presents, MCP_REQUEST_INTAKE_TOKEN is what the server checks it against —
and intake stays closed (503) on any deployment with no server-side shared
token and no matching personal token. Filing is throttled per caller, so a
leaked token cannot flood the backlog.
{
"mcpServers": {
"springpod-design-system": {
"command": "npx",
"args": ["@springpod/design-system-mcp"],
"env": { "SPRINGPOD_REQUEST_TOKEN": "<token from a maintainer>" }
}
}
}The search / fetch pair exists because hosts outside Claude expect it —
ChatGPT will not install a connector without it unless developer mode is on,
and its deep research mode calls nothing else. Over stdio the purpose-built
tools above are strictly better, so the pair is left out there.
Resources
springpod://design-system/agents.md— the generated package API index.springpod://design-system/docs/npm-new-project— adoption playbook (new project).springpod://design-system/docs/npm-existing-project— adoption playbook (existing app).springpod://design-system/docs/responsive— responsive behavior guide.springpod://design-system/changelog— design-system changelog.
Data contract
- Installed design system first. Everything that ships in the
@springpod/design-systemtarball (tokens, responsive rules, usage rules and example screens from 0.1.2+, docs, changelog, the audit script) is read from the consumer's installed copy, resolved from the server's working directory. - Bundled snapshot fallback. Component purposes/exports, icon metadata,
the CSS variable map, and anything the installed version predates come
from
data/snapshot.json, generated from the design-system sources when this package is built (scripts/build-snapshot.mjs) — never hand-copied.
Development (this monorepo)
pnpm --filter @springpod/design-system-mcp run build # snapshot + tsc + changelog gate
pnpm --filter @springpod/design-system-mcp run test # unit + stdio e2e round-trip
pnpm --filter @springpod/design-system-mcp run release <major|minor|patch>Releases follow the design system's conventions: pnpm-only publish
(publishConfig, npm is refused at prepack), changelog gate, and a
post-publish install/import/initialize smoke test.
