Describe the intent.
A hero with subtle motion. A cursor with a trailing effect. Start with what it should do, even if you don’t know its name.
matchcn.dev
matchcn gives your coding agent access to 6,119 components across 10 registries.
Describe the UI you need. Get matching components and their install commands.
Paste this into your coding agent to configure matchcn.
npx matchcn
Run the stdio MCP server with npx. To make the tool available to your agent, add the MCP configuration to your client.
Node.js 20+ · npm / npx
Add the config to your client, connect the server, and start with an English brief for the most reliable results.
# Start the MCP server $ npx matchcn
pick_component(brief, registry?, maxResults?)A semantic index for shadcn-format components. Describe behavior, motion, or layout in plain English. matchcn finds real components across ten registries and returns an explanation, a source, and an install command.
Choose a real test from the repo.
a dense bento grid for a landing page



6,119 components. Ten indexed registries.
One tool to query them.
0.90 recorded selection confidenceFit signal, not an accuracy score
layout section/layout sectionstatic/staticdense/densedisplay only/display only0.18/0.270.00/0.02npx shadcn@latest add https://magicui.design/r/bento-grid.jsonThis component is a named example in the density criteria. This recorded result is not an independent accuracy test.
{
"outcome": "confident",
"message": "Selected \"bento-grid\" from magicui.",
"chosen": {
"name": "bento-grid",
"registry": "magicui",
"title": "Bento Grid",
"installCommand": "npx shadcn@latest add https://magicui.design/r/bento-grid.json",
"sourceUrl": "https://magicui.design/r/bento-grid.json",
"confidence": 0.9,
"reasons": [
{
"dimension": "category",
"briefWants": "layout-section",
"componentHas": "layout-section",
"matched": true,
"weight": 0.98
},
{
"dimension": "motion",
"briefWants": "static",
"componentHas": "static",
"matched": true,
"weight": 0.98
},
{
"dimension": "visual_density",
"briefWants": "dense",
"componentHas": "dense",
"matched": true,
"weight": 1
},
{
"dimension": "interaction_model",
"briefWants": "display-only",
"componentHas": "display-only",
"matched": true,
"weight": 0.76
},
{
"dimension": "needs_external_data",
"briefWants": 0.18,
"componentHas": 0.27,
"matched": true,
"weight": 0.64
},
{
"dimension": "decorative_only",
"briefWants": 0,
"componentHas": 0.02,
"matched": true,
"weight": 1
}
]
},
"resolveUsed": true,
"decisionsSpent": 7
}A hero with subtle motion. A cursor with a trailing effect. Start with what it should do, even if you don’t know its name.
Components are tagged across six dimensions. Deterministic ranking weighs those tags by confidence; Resolve evaluates the candidates.
Your agent gets the original registry’s shadcn install command. Component code comes directly from its creator.
Copy a prompt for your client. The agent configures matchcn; you review the changes.
› Configure the matchcn MCP server
✓ .mcp.json
+ matchcn → npx -y matchcn
› Find a dense bento grid ▌
Paste it in your coding session — Claude adds the MCP configuration to your project.
+ [mcp_servers.matchcn]
+ command = "npx"
+ args = ["-y", "matchcn"]Give Codex the same task — review the configuration, then ask for a component.
{
"mcpServers": {
"matchcn": {
"command": "npx",
"args": ["-y", "matchcn"]
}
}
}Paste it in agent chat — add matchcn to your project’s MCP servers and enable the tool.
How do I set up matchcn?
Add this server to your local MCP client:
Then call pick_component with your UI brief.
Get setup instructions in chat — then run matchcn in a local client that supports MCP.
Illustrative configuration previews. Grok provides setup guidance; running matchcn requires a local MCP client.
Numbers from the committed tagging and demo reports.
Across 10 shadcn-format registries
6 dimensions for every component
Excludes throttling and debugging
6 parsing + 1 Resolve per brief
| BRIEF | OUTCOME | RESULT |
|---|---|---|
| Hero with subtle background motion | Shortlist | 3 candidates, differences explained |
| Cursor with a trailing effect | Confident | react-bits / GhostCursor-TS-TW |
| Dense bento grid for a landing page | Confident | magicui / bento-grid |
| Three-plan pricing section, in Polish | No match | All 5 candidates rejected |
| Date picker with range selection | No match | All 5 candidates rejected |
A five-brief development demo, not an accuracy evaluation. English briefs work better in current tests. The bento grid is a named anchor in the tagging criteria. Classifier confidence can vary between runs.
Implementation, tool contract, evidence, and known limits.
matchcn is a semantic index of shadcn-format UI components, exposed through a local Model Context Protocol (MCP) server. It finds existing components from a plain-language description of the UI a developer needs and returns the original registry's installation command. It does not generate component source code or host a replacement component registry.
This reference describes the local v0.1.0 source and development reports inspected on September 20, 2026. The counts and findings below are a snapshot, not a live inventory or a guarantee of future registry availability.
A developer can ask for a component by purpose, motion, density, or interaction instead of knowing its registry-specific name. A coding agent calls pick_component, reads the outcome and explanation, and can use the returned npx shadcn@latest add <sourceUrl> command to install from the original publisher.
The current index contains 6,119 components from ten registries. matchcn is a discovery layer for the shadcn registry ecosystem. shadcn/ui supplies the registry format and installation tooling; it is not a seventh indexed catalog in this snapshot. The landing page's interactive example displays recorded responses from the development demo report, including component reasons and install commands. It does not perform a live component search.
The documented CLI entry point is npx matchcn. It starts a stdio MCP server, not an interactive search shell. Node.js 20 or newer is required. For an MCP client, configure the command as npx with arguments -y and matchcn:
{
"mcpServers": {
"matchcn": {
"command": "npx",
"args": ["-y", "matchcn"]
}
}
}
The configuration belongs in the selected client's MCP settings. Claude Code can use a project's .mcp.json; Cursor can use .cursor/mcp.json. Codex uses its own TOML configuration format rather than this JSON wrapper. The page provides separate setup prompts. The Grok prompt provides configuration guidance for a local MCP-capable client; it is not a claim that this server runs directly in Grok chat.
The inspected source package is version 0.1.0. The npm package matchcn is published and the source repository is public: github.com/francesco0242/matchcn.
The server exposes one tool: pick_component(brief, registry?, maxResults?). The MCP adapter returns a text content block containing the result serialized as JSON.
| Parameter | Type | Behavior |
|---|---|---|
brief |
Required string | Plain-language description of the required UI. English is recommended based on current tests. |
registry |
Optional enum | Restricts matching to one of the ten exact registry identifiers listed below. |
maxResults |
Optional integer, 1–10 | Maximum candidates returned for a shortlist or no-match result. Default: 3. It does not expand Resolve beyond its top-five comparison. |
Example tool arguments:
{
"brief": "a dense bento grid for a landing page",
"registry": "magicui",
"maxResults": 3
}
The tool discovers components and returns commands. Component installation is a separate action performed by the developer or coding agent. A returned component still needs to be evaluated against the application's dependencies, design, and accessibility requirements.
Source: MCP adapter.
Every result contains outcome, message, resolveUsed, and decisionsSpent. The fields chosen, candidates, and differentiators appear when applicable.
| Outcome | Meaning | How to use it |
|---|---|---|
confident |
The selection logic identifies one component. chosen contains its details. |
Review its reasons and source install command. |
shortlist |
There is no sufficiently decisive selection. candidates contains ranked options, and differentiators names differences visible to the tag schema. |
Compare those differences before choosing. |
no_match |
Resolve explicitly rejects the candidates, or no tagged components are available. There is no chosen field. |
Do not treat any diagnostic candidates as a recommended installation. |
A component result includes name, registry, nullable title, sourceUrl, installCommand, confidence, and reasons. Optional variants list available stack variants with their own registryItemName and install command. Each reason contains dimension, briefWants, componentHas, matched, and weight.
A no-match response can include nearby candidates for reference. Rejection is communicated by the overall outcome and message; the component objects do not have a separate rejected boolean. A shortlist's differentiators contain the dimension and the candidates' values. Choice dimensions differ when their known labels differ; probability dimensions differ when their known values span more than 0.2.
confidence indicates fit or selection confidence, not component quality, security, accessibility, or measured probability of success. For a chosen result it can come from Resolve when available, otherwise from the ranking score. Candidate lists use the ranking score, rounded to two decimals. These values should not be conflated with benchmark accuracy.
Source: selection logic and response types.
data/tags/ for inspection and versioning.The pipeline uses files rather than a database. Ingestion can enrich missing or short descriptions from a registry's per-item endpoint, using source excerpts as tagging input. This does not make matchcn a component-source mirror: published tag outputs contain derived data and links, not redistributed component source.
| Dimension | Representation | What it describes |
|---|---|---|
category |
Unordered label | Primary UI purpose, such as hero, navigation, card, form input, chart, layout section, background effect, cursor, or transition wrapper. Includes an escape label. |
motion |
Ordered label | static, subtle-transitions, animated-on-interaction, or continuous-background-motion. |
visual_density |
Ordered label | minimal, moderate, or dense. Describes perceived density rather than a literal element count. |
interaction_model |
Unordered label | display-only, hover, click-toggle, form-input, drag-or-gesture, or none of these. |
needs_external_data |
Probability or null | Whether useful operation requires caller-supplied data, state, or non-trivial props. |
decorative_only |
Probability or null | Whether the component is primarily a decorative effect rather than functional or informational content. |
The probability dimensions are implemented through yes/no classification scores. A value near 0.5 represents uncertainty, not a middle category. compositionLevel is derived from registry metadata; it is not a seventh model-tagged dimension.
Source: dimension definitions and exact criteria.
The ranking function computes a weighted average distance. Matching unordered labels have zero distance and mismatches have distance one. Ordered labels use normalized index distance, so adjacent values are closer than distant ones. Probability dimensions use the absolute difference between their values.
For choice dimensions, the weight is the smaller confidence of the brief and the component. For probability dimensions, certainty is 2 * abs(probability - 0.5), and the smaller certainty of the two sides is used. Null or zero-weight dimensions contribute no evidence. If all weights are zero, distance is one. Lower distance ranks first, and the ranking confidence is 1 - distance.
The ranking stage is deterministic for identical parsed dimension vectors, tag records, and input order. The complete text-to-result process is not guaranteed to return identical values on every call, because brief parsing and Resolve call an external classifier.
Resolve is skipped when the leader's ranking confidence is at least 0.55 and its distance advantage over the runner-up is at least 0.15. For a single candidate, only the confidence floor applies. Resolve compares at most five candidates using their names, registry, composition level, and tagged properties; it does not inspect full component source at query time. The 0.55 and 0.15 thresholds are MVP heuristics, not values optimized against a labeled accuracy dataset.
Sources: ranking implementation, Resolve implementation.
| Exact registry identifier | Publisher | Components in snapshot |
|---|---|---|
react-bits |
React Bits | 204 |
magicui |
Magic UI | 79 |
aceternity |
Aceternity UI | 282 |
kokonutui |
Kokonut UI | 51 |
animate-ui |
Animate UI | 420 |
motion-primitives |
Motion Primitives | 33 |
shadcnblocks |
shadcnblocks.com | 4,171 |
shadcn-dashboard |
shadcndashboard.dev | 508 |
assistant-ui |
assistant-ui.com | 154 |
bundui |
bundui.io | 217 |
These counts total 6,119 components. They describe the indexed snapshot, not the current size of each publisher's library. The first six registries are the original motion/marketing family; the last four (shadcnblocks, shadcn-dashboard, assistant-ui, bundui) are a product-UI expansion added after per-registry filter verification. cult-ui was excluded because its index was behind a bot challenge. Aceternity's 170 block/demo records were tagged using short index descriptions because their per-item endpoints returned HTTP 401; its 112 UI primitives were source-enriched.
The original full tagging run processed 1,069 components across six dimensions, spending 6,414 classification decisions, in a first-to-last tagging timestamp window of approximately 2 minutes 43 seconds. A second run added the four product-UI registries, spending 30,300 more decisions across 5,050 components, split across two IPs to cover the free tier's daily quota. Combined: 6,119 components, 36,714 tagging decisions. These exclude throttling and debugging time and are not a measurement of search latency or total setup duration.
The five-brief demo spent 35 decisions: six for parsing and one for Resolve per brief in that run. It returned a shortlist for a subtly animated hero, a confident React Bits cursor result, a confident Magic UI bento-grid result, and two no-match outcomes for a Polish pricing brief and a range date picker.
This is a development demonstration, not a labeled accuracy benchmark, a comparison against another product, or evidence that every request needs seven decisions. Resolve can be skipped. The bento grid is also a named example in the visual-density criteria, so its result is not an independent validation of those criteria.
The revised pilot reported 36% of visual-density answers below 0.6 confidence. Across the full 6,119-component catalog, 25.9% of answers on the four choice dimensions were below 0.6, up from 23.9% at the original 1,069-component size. assistant-ui is the outlier driving that increase: 37.0% of its choice-dimension answers land under 0.6 confidence, worse than aceternity's 28.7% (the prior worst registry) on every single dimension. It is now the lowest-confidence registry in the catalog, likely because its content (agent and chat UI: tool timelines, trace waterfalls, reasoning panels) is further from the schema's original motion/marketing anchors than any other registry. These are tag-confidence statistics, not error rates. Non-English behavior was examined on three Polish briefs; these tests do not establish performance across languages.
Evidence: full tagging report, five-brief demo with raw output, pilot report.
The MCP transport and deterministic ranking run locally, but the tool is not offline-only. The client sends the brief and classification criteria to https://classifier.dev/v1/classify using the fast tier. Resolve can send the brief with descriptions assembled from the top candidates' tagged properties. The inspected HTTP client supplies no API key or authorization header.
During ingestion and tagging, registry metadata and available source excerpts can be used as classification input. Raw fetch data is cached locally; derived tags are stored separately. This reference describes the source's data flow, not the external provider's retention policy or a guarantee about its future availability, pricing, or rate limits. Errors and exhausted retries are not equivalent to a no_match result.
Source: HTTP classification client.
The MVP covers ten registries rather than the full shadcn ecosystem. English briefs are currently more reliable than the tested Polish inputs. Visual density remains the weakest tagged dimension. Short or inaccessible registry descriptions can reduce tagging evidence.
There is no implemented compatibility guarantee for React, Tailwind, or other dependency versions; no accessibility-quality score; no dedicated domain/use-case dimension; and no general code-quality ranking. A description mentioning a landing page is accepted as text, but “landing page” is not a separate domain tag in v0. The tool does not generate UI code, host component source, or replace the original registry's installer.
The roadmap discusses additional dimensions, registry coverage, and evaluation. Those are future possibilities, not shipped capabilities or release commitments. The landing page is documentation and an installation entry point, not the searchable catalog UI that the source roadmap lists as a possible future feature.
matchcn is an independent MIT-licensed project. It is not affiliated with or endorsed by shadcn, the indexed registries, classifier.dev, or TypeSafe. Its license does not replace the individual licenses of components installed from other publishers.
Project: matchcn.dev. Updates: @matchcn. Built by @whosfranki. Source: github.com/francesco0242/matchcn.
For citation, use the relevant section of this reference and the linked implementation or report. Attribute the figures to the September 20, 2026 development snapshot. Distinguish implemented behavior from intended behavior, fit confidence from accuracy, and local ranking from the network-dependent pipeline.