perfectui-mcp
A read-only MCP server that gives coding agents the real classes, markup and install instructions of Perfect UI 1.0.0, so they stop inventing pui-* classes.
get_install– the npm and other package managers' install commands, CDN stylesheet and script URLs, and import statements, all pinned to1.0.0(neverlatest).list_components– every document in the documentation's order (components, forms, layout, customization, guides) with its slug, title, section and one-line description.get_component– one document's full Markdown, its HTML examples and thepui-*classes those examples use (e.g.button,modal,dark-mode).search_docs– full-text search over document sections, prefix- and typo-tolerant, returning slug, heading, snippet and score (1–10 results, default 5).check_markup– scansclass/classNameattributes of HTML/JSX for unknownpui-*classes (with line and closest real class) and legacy 0.23.0 classes the migration guide renames (with the replacement).Everything is read-only and idempotent, with no network requests, unknown arguments rejected, and structured output matching each tool's schema.
The same five tools can also be served over another transport as a library via
buildServer(corpus)andloadCorpus().
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., "@perfectui-mcp check this HTML for unknown pui-* classes: <button class="pui-button">Save</button>"
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.
perfectui-mcp
A read-only MCP server that gives coding agents the real classes, markup and install instructions of Perfect UI 1.0.0, so they stop inventing pui-* classes.
Everything the server answers comes from one file, data/corpus-1.0.0.json, generated from the library's documents at the v1.0.0 tag and from the stylesheet of the published @chrissgon/perfectui@1.0.0 package. The server never writes, runs or downloads anything, and it makes no network requests.
The npm package is @chrissgon/perfectui-mcp.
Tools
Tool | Input | Returns |
| none | The npm command and the other package managers' commands, the CDN stylesheet and script URLs, and the import statements, all pinned to |
| none | Every document in the documentation's order (components, forms, layout, customization, guides): slug, title, section and a one-line description. |
|
| The document's full Markdown, its HTML examples and the |
|
| The best matching sections: slug, heading, snippet and score. Prefix matching and one typo from four characters. |
|
| Every |
Every tool declares readOnlyHint: true, destructiveHint: false, idempotentHint: true and openWorldHint: false, rejects unknown arguments, and returns structured content that matches its output schema.
A typical agent loop: list_components or search_docs to find the right document, get_component to copy its markup, then check_markup on the result before handing it over.
check_markup { "html": "<button class=\"pui-button\">Save</button>" }
→ line 1: pui-button → pui-btn (pui-button is not a class of Perfect UI 1.0.0; the Button document (get_component button) uses pui-btn)Related MCP server: material-web-mcp
Install
Requirements: Node.js 20 or later and npm (the server is developed and tested on Node.js 24).
The server speaks MCP over stdio. An MCP client starts it with npx, which downloads the package on first use:
npx -y @chrissgon/perfectui-mcpRun on its own, it waits for a client on stdin and prints one status line to stderr.
Client configuration
Many clients take a server as a command and its args inside an mcpServers object like the one below; check where your client keeps it:
{
"mcpServers": {
"perfectui": {
"command": "npx",
"args": ["-y", "@chrissgon/perfectui-mcp"]
}
}
}Claude Code:
claude mcp add perfectui -- npx -y @chrissgon/perfectui-mcpVS Code (.vscode/mcp.json in a workspace):
{
"servers": {
"perfectui": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@chrissgon/perfectui-mcp"]
}
}
}To pin a version, write it in the package name: @chrissgon/perfectui-mcp@0.2.0.
To try it without a client, use the MCP Inspector's command-line mode. Leave -y out of the server command here: with it, Inspector 2.8.0 fails to start the server (npx still installs the package without asking, because its input is not a terminal).
npx -y @modelcontextprotocol/inspector --cli npx @chrissgon/perfectui-mcp --method tools/list
npx -y @modelcontextprotocol/inspector --cli npx @chrissgon/perfectui-mcp --method tools/call --tool-name get_component --tool-arg name=buttonUse it as a library
From 0.2.0 the package also has a library entry, so a host can serve the same five tools over another transport. buildServer(corpus) returns a new McpServer (from @modelcontextprotocol/sdk) that is not connected yet; loadCorpus() reads and validates the bundled corpus. Importing the entry starts nothing. Types ship with the package.
import { buildServer, loadCorpus } from "@chrissgon/perfectui-mcp";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
const corpus = loadCorpus(); // once per process
// Stateless Streamable HTTP: a new server and transport for every request.
export async function handle(request: Request): Promise<Response> {
const server = buildServer(corpus);
const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true });
await server.connect(transport);
try {
return await transport.handleRequest(request);
} finally {
await transport.close();
await server.close();
}
}The entry also exports TOOL_NAMES, instructions, PACKAGE_VERSION, CORPUS_VERSION and the corpus types. The package reads data/corpus-1.0.0.json and its own package.json from files next to its code, so keep it external when you bundle (installed in node_modules, not inlined). The bin is unchanged: npx -y @chrissgon/perfectui-mcp is still the stdio server.
Run it from a checkout
git clone https://github.com/chrissgon/perfectui-mcp.git
cd perfectui-mcp
npm ci
npm run buildThen point the client at the built file, with your checkout's absolute path:
{
"mcpServers": {
"perfectui": {
"command": "node",
"args": ["/absolute/path/to/perfectui-mcp/dist/server.js"]
}
}
}npx @modelcontextprotocol/inspector --cli node dist/server.js --method tools/listWhere the data comes from
npm run corpus rebuilds data/corpus-1.0.0.json:
Documents: one entry per link in the summary of the library's
docs/README.mdat thev1.0.0tag (28 documents, including the migration guide). Each entry keeps the document's Markdown as written, its```htmlblocks as examples, and thepui-*classes those examples use.Classes: every
.pui-*selector indist/perfectui.cssof the published package (51 classes). The package's npm integrity hash is recorded in the corpus.Class renames: the tables, diff blocks and "survive as" sentence of the library's
MIGRATION.md(38 renames from 0.23.0, each checked against the stylesheet). The guide starts at 0.23.0, so classes of older releases (0.7.x, for example) are not recognised; names the guide gives nopui-*class for (dark,dropdown-trigger,field-group-error) and the removed utilities are not reported.Install instructions: read from the installation document and pinned to the package version; every CDN file and import is checked against the package's files and
exportsbefore it is written.
The library is read from PERFECTUI_SOURCE (a local checkout, as it is on disk) when set, else from .cache/library/v1.0.0/, else from one download of the tag's archive from GitHub. The package comes from .cache/package/1.0.0/, else from npm pack. Only this build step uses the network; the server does not.
Development
Task | Command |
Tests (offline) |
|
Type-check source, scripts and tests |
|
Build |
|
Rebuild the corpus |
|
Start on stdio |
|
List what the package ships |
|
Count invented classes in saved eval outputs ( |
|
The tests call every tool through the MCP SDK client over an in-memory transport, so they exercise the same schemas, validation and errors a real client sees. Design notes on the transport are in docs/spikes/stdio.md.
Releases
A release is a tag v<version> that matches package.json, pushed by the owner. .github/workflows/publish.yml then checks that the tag is on main, runs the same checks as CI, publishes to npm with trusted publishing (no npm token is stored; npm attaches provenance) and creates the GitHub release. A version with a prerelease suffix (1.0.0-beta.0) is published under the next dist-tag, never latest.
License
MIT, see LICENSE. data/corpus-1.0.0.json contains the Perfect UI documentation, also MIT, copyright Christopher Gonçalves. The summary parser in scripts/build-corpus.ts is adapted from perfectui-doc (MIT), so slugs match the documentation site.
Available Tools
5 toolscheck_markupCheck markupARead-onlyIdempotent
Lists every pui-* class in the HTML that Perfect UI 1.0.0 does not define (kind "unknown"), with its line and the closest real class, and every Perfect UI 0.23.0 class that the migration guide renames (kind "legacy"), with the guide's replacement. Reads class and className attributes only; other classes (your own, Tailwind) are ignored. Call it on any markup before returning it.
Inputs: html (required). Returns: valid, checked, version, findings
get_componentGet a documentARead-onlyIdempotent
The full Markdown of one Perfect UI 1.0.0 document, with its HTML examples and the pui-* classes they use. Copy markup from the examples instead of writing classes from memory. Names come from list_components.
Inputs: name (required). Returns: file, slug, title, classes, +5 more
get_installGet install instructionsARead-onlyIdempotent
How to install Perfect UI 1.0.0: the npm command and the other package managers' commands, the CDN stylesheet and script URLs and the import statements, all pinned to this version, from the library's installation document (get_component with name installation explains when the script is needed).
Inputs: no named parameters. Returns: cdn, npm, source, imports, +3 more
list_componentsList documentsARead-onlyIdempotent
Every document of Perfect UI 1.0.0, in the documentation's order: components, forms, layout, customization and guides, each with its slug (the name get_component takes), title, section and one-line description.
Inputs: no named parameters. Returns: version, components
search_docsSearch the documentationARead-onlyIdempotent
Full-text search over the sections of every Perfect UI 1.0.0 document (prefix and typo tolerant). Returns the document slug (for get_component), the section heading (empty for the opening section), a snippet and a score, best first.
Inputs: query (required), limit. Returns: query, results
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 5 tools
get_install and get_component both retrieve documentation content for installation, but get_install is a specialized shortcut for install commands while get_component returns full Markdown of any document; descriptions clarify the boundary. Other tools (list_components, search_docs, check_markup) have clearly distinct purposes. Minor overlap prevents a perfect score.
All tool names follow a consistent snake_case verb_noun pattern (get_install, list_components, search_docs, get_component, check_markup). This makes the set predictable and easy to parse.
Five tools cover the essential operations for a UI library documentation server: installation lookup, listing documents, searching, retrieving a document, and validating markup. Each tool has a clear role and the set is well-scoped.
The surface covers installation, discovery (list, search), retrieval, and validation, including legacy class migration. No obvious dead ends for the stated purpose of helping agents use Perfect UI correctly; the documentation lifecycle is fully covered.
Maintenance
Related MCP Connectors
Serves your design system and coding standards to coding agents, so they stop guessing.
Find UI components and themes, retrieve code, and generate with hosted 21st AI when enabled.
Query portfolio case studies, verified developer tools, and the AI-UI design system.
Live React design-system APIs, patterns, and code validation so AI agents build real UI, not slop.
Related MCP Servers
- AlicenseAqualityCmaintenanceProvides AI coding assistants with on-demand access to component specs, test scenarios, accessibility requirements, and build guides from the Web UI Component Specification.10MIT
- AlicenseAqualityDmaintenanceProvides programmatic access to Material Web documentation and components for AI agents, enabling documentation search, template generation, and HTML validation.718 npm1MIT
- AlicenseNot gradedqualityBmaintenanceProvides a real API for coding agents to look up design system components, props, and tokens, preventing guessed answers.9MIT
- AlicenseNot gradedqualityAmaintenanceEnables coding agents to ground UI work in real product screens by searching a catalogue for concrete screen references and design materials such as fonts, icons, and animated icons, then pulling the colors, typography, components, and provenance behind a chosen web screen. It also serves bundled skill documents, command playbooks, and connection diagnostics so an agent can settle a screen's states and acceptance criteria before building and verify the rendered result afterward.MIT