MCP SERVER FOR COMPONENT SEARCH v0.2.7

The right component.
Just a prompt away.

matchcn gives your coding agent access to 4,578 components across 14 registries.
Describe the UI you need. Get matching components and their install commands.

Give your agent this promptSTART HERE

Paste this into your coding agent to configure matchcn.

Set up the matchcn MCP server using npx -y matchcn. Configure it for my coding agent, then use pick_component to find UI components that match my brief. Show me the match reasons and install command before adding a component.
Manual MCP setup
CLI entry point: npx matchcn

Run matchcn
in your MCP client.

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
One tool: pick_component(brief, registry?, maxResults?)

Describe a component.
Get an install command.

A semantic index for shadcn-format components. Describe behavior, motion, or layout in plain English. matchcn finds real components across fourteen registries and returns an explanation, a source, and an install command.

matchcn/pick_component
Recorded runs
WHAT DO YOU NEED?

Start with the brief.

Choose a real test from the repo.

brief:

a dense bento grid for a landing page

Magic UIReact BitsAceternity UIKokonut UI

4,578 components. Fourteen indexed registries.
One tool to query them.

Match found7 decisions · Resolve used
Magic UI/ selected component

bento-grid

0.90 recorded selection confidenceFit signal, not an accuracy score

Why it fitsBrief / component
Category
layout section/layout section
Motion
static/static
Density
dense/dense
Interaction
display only/display only
External data
0.18/0.27
Decorative only
0.00/0.02
INSTALL FROM THE REGISTRY
npx shadcn@latest add https://magicui.design/r/bento-grid.json

This component is a named example in the density criteria. This recorded result is not an independent accuracy test.

Inspect response JSON
{
  "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
}
Actual tool output. September 2026 snapshot.Use it with your own brief
01

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.

02

Get an explained match.

Components are tagged across seven dimensions. Deterministic ranking weighs those tags by confidence; Resolve evaluates the candidates.

03

Install from the source.

Your agent gets the original registry’s shadcn install command. Component code comes directly from its creator.

Install in your coding agent.

Copy a prompt for your client. The agent configures matchcn; you review the changes.

$ claude

› Configure the matchcn MCP server

✓ .mcp.json

+ matchcn → npx -y matchcn

› Find a dense bento grid ▌

Claude Code

Paste it in your coding session — Claude adds the MCP configuration to your project.

Configure matchcn +3
config.toml+ [mcp_servers.matchcn]
+ command = "npx"
+ args = ["-y", "matchcn"]
Config updatedReview changes

Codex

Give Codex the same task — review the configuration, then ask for a component.

.cursor/mcp.json M
{
  "mcpServers": {
    "matchcn": {
      "command": "npx",
      "args": ["-y", "matchcn"]
    }
  }
}
matchcn 1 tool

Cursor

Paste it in agent chat — add matchcn to your project’s MCP servers and enable the tool.

Grok

How do I set up matchcn?

Add this server to your local MCP client:

npx -y matchcn

Then call pick_component with your UI brief.

Grok

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.

Index size and test results.

Numbers from the committed tagging and demo reports.

Read the full run report
4,578

components indexed

Across 14 shadcn-format registries

890

npm downloads

Since launch, via npx matchcn

~3.5s

average query time

Brief to result, 5-brief live test including Resolve

7

tagged dimensions

Category, domain, motion, density, interaction, and two more

Results from 5 test briefs

View raw results
BRIEFOUTCOMERESULT
Hero with subtle background motionNo match3 candidates rejected
Cursor with a trailing effectConfidentreact-bits / GhostCursor-TS-TW
Dense bento grid for a landing pageConfidentmagicui / bento-grid
Three-plan pricing section, in PolishNo matchAll 5 candidates rejected
Date picker with range selectionConfidentuiable / date-picker-input

A five-brief development demo, not an accuracy evaluation, recorded before non-English support and the visual-density fix shipped. The bento grid is a named anchor in the tagging criteria. Classifier confidence can vary between runs.

About matchcn, in detail.

Implementation, tool contract, evidence, and known limits.

Read as plain text ↗

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.2.7 source and development reports inspected on September 26, 2026. The counts and findings below are a snapshot, not a live inventory or a guarantee of future registry availability.

What matchcn does

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 4,578 components from fourteen registries. matchcn is a discovery layer for the shadcn registry ecosystem. shadcn/ui supplies the registry format and installation tooling; it is not an 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.

Installation and runtime

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.2.7. The npm package matchcn is published, the source repository is public: github.com/francesco0242/matchcn, and the server is listed in the official MCP Registry as io.github.francesco0242/matchcn.

MCP tool and parameters

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. Non-English text is auto-detected and translated before matching.
registry Optional enum Restricts matching to one of the fourteen 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-eight 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.

Result fields and outcomes

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.

The five-stage pipeline

  1. Ingest: fetch registry indexes, normalize metadata, and filter known demo wrappers, duplicate stack variants, and non-component entries. In the development snapshot, 2,012 raw records became 1,069 taggable components after 943 exclusions.
  2. Tag: classify each retained component across seven dimensions using classifier.dev. The derived tag data is stored as per-registry JSON under data/tags/ for inspection and versioning.
  3. Match: classify the incoming brief into the same dimension schema, then rank the stored components locally using a confidence-weighted distance function.
  4. Resolve: when the leading match is not decisive, compare up to eight candidates through one additional classification decision, with an explicit “none of these” option.
  5. Surface: expose the result through the stdio MCP tool. The development demo calls the same core selection function without the MCP transport.

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.

The seven matching dimensions

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.
domain Unordered label What real-world task the component is FOR (auth, scheduling, commerce, messaging, analytics, content, settings, search, marketing, or general-purpose), independent of its structural shape. Added to separate components that share the same shape but serve different purposes, such as a calendar and a login form.
motion Ordered label static, subtle-transitions, animated-on-interaction, or continuous-background-motion.
visual_density Probability or null How visually dense the component reads, from sparse (one focal element) to dense (multiple regions sharing attention). Reformulated from a 3-label choice to a continuous probability after the labeled version proved consistently unreliable.
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 model-tagged dimension.

Source: dimension definitions and exact criteria.

Ranking, determinism, and Resolve

The ranking function blends two distances: a structural distance from the tagged dimensions, and a text-relevance distance between the brief and each candidate's name/title. Structural distance treats matching unordered labels as zero distance and mismatches as 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 structural 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 structural evidence.

The text-relevance distance is TF-IDF-weighted cosine similarity between the brief and each candidate's name/title, not a plain word-overlap count: a shared word that appears in only a handful of indexed components (e.g. "login") counts far more than one that appears in hundreds (e.g. "form"). This exists because the seven tagged dimensions alone cannot separate near-identical variants of the same structural shape (a login form, an OTP field, and a generic form-input block all tag as form-input/auth/static), which a real catalog measurement found: without a text-relevance term, "a login form with email and password fields" ranked an OTP field above all of the catalog's genuine login-form components. The text-relevance term is weighted more heavily than the structural distance in the final blend (1.5 : 1), reflecting how load-bearing this signal turned out to be in practice, not an arbitrary tiebreaker. If all weights (structural and text-relevance combined) 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 eight candidates (widened from five after the same catalog measurement above found genuine matches occasionally ranking as low as position six through eight) 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.

Indexed registries and coverage

Exact registry identifier Publisher Components in snapshot
react-bits React Bits 204
magicui Magic UI 79
aceternity Aceternity UI 119
kokonutui Kokonut UI 51
animate-ui Animate UI 420
motion-primitives Motion Primitives 33
shadcn-dashboard shadcndashboard.dev 343
assistant-ui assistant-ui.com 154
bundui bundui.io 217
cnippet ui.cnippet.dev 1128
uiable uiable.com 969
plate platejs.org 174
react-aria react-aria.adobe.com 62
shadcn-ui-blocks shadcn-ui-blocks.com 626

These counts total 4,578 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 middle three are a product-UI expansion added after per-registry filter verification; cnippet and uiable are a second product-UI expansion, added the same way; plate and react-aria are a third, each added after fixing a real filter gap (plate's documentation pages were being indexed as components; react-aria published the same component up to three times under a style-prefix naming convention). shadcn-ui-blocks is a fourth: its combined free-and-paid index was evaluated and rejected outright (82% of its real blocks return 401 unauthenticated), but the registry's own maintainer later pointed at a separate, curated free-only index the vendor publishes, and a fresh per-item check against that one found 100% installable unauthenticated, so only that free-only index is used. Two other candidates from the cnippet/uiable expansion, shadcnuikit and shadcn-space, were evaluated and excluded: a real per-item availability check found genuine paywalls on 40% and 33.3% of a sample from each. uiable's descriptions are largely name-echoed templates rather than hand-written text; cnippet and uiable were later measured at full scale (8,388 choice-dimension answers) and scored 24.4% under 0.6 confidence, in line with the rest of the catalog, not the outlier a 20-item pre-tagging sample had suggested. shadcn-dashboard's count (343) already excludes 165 components that a real per-item availability check found returned 401/403 at their actual install URL ("License required"), not visible in the registry index itself. Aceternity's count (118) already excludes 163 page-template components found paywalled the same way, and one duplicate listing (the same component catalogued twice under two different types, pointing at the same install URL) collapsed into one entry. shadcnblocks was tagged (4,171 components) and re-evaluated with a clean, from-scratch availability check (not just the original one): 55.6% of a 3,358-item confident sample return real 401s, so it remains excluded, the same conclusion as the original check, now confirmed rather than suspected. cult-ui was excluded because its index sits behind a bot challenge; a real fix is possible (a headless browser passes it) but was not built, since doing so would mean building a tool specifically to bypass an anti-bot control the vendor put there on purpose.

Benchmark evidence and its limits

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 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. That run tagged 6,119 components across ten registries; the shipping catalog was then smaller, 1,783 components across nine registries, after a real per-item availability check found a meaningful share of shadcnblocks and shadcn-dashboard paywalled at their actual install URL and shadcnblocks was pulled entirely rather than shipped on contaminated data (see the known limits section). A third run added cnippet and uiable, spending 12,582 more decisions across 2,097 components. A subsequent real per-item availability check, run for the first time against the original six registries, found aceternity's page-template demo pages 57.8% paywalled and excluded 163 of its 282 tagged components. A fourth expansion added plate, react-aria, and shadcn-ui-blocks (626 components from its vendor-curated free-only index), and a new domain dimension was backfilled across the entire catalog in a single-dimension pass rather than a full re-tag. The current shipping catalog is 4,578 components across fourteen registries. These decision and timing figures 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.

visual_density was the schema's clear weakest dimension for most of this project's history: 36-37% of its answers scored below 0.6 confidence after two different labeling schemes (a counting heuristic, then a perceptual judgment anchored to named examples) both plateaued there. It was reformulated from a 3-way label choice into a continuous probability, the same representation already used for two other dimensions, piloted against a real sample before any backfill, then backfilled across the full catalog: full-catalog result is now 21.4% under-threshold, in line with the rest of the schema (13.5-21.5% across all seven dimensions). assistant-ui is a separate, persistent outlier: its choice-dimension answers land under 0.6 confidence at a materially higher rate than any other registry, 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. cnippet and uiable, initially estimated at 35% under 0.6 from a 20-item pre-tagging sample, were later measured at full scale across their full 8,388 choice-dimension answers: 24.4%, in line with the catalog-wide baseline, not the outlier the small sample suggested. These are tag-confidence statistics, not error rates. Non-English behavior was examined on three Polish briefs and found measurably weaker; a real fix (local language detection plus translation to English before matching, not just a prompt-wording change) closed that gap, verified directly on the case that first exposed it.

Evidence: full tagging report, five-brief demo with raw output, pilot report.

Network behavior and data handling

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.

Known limits and project scope

The MVP covers fourteen registries rather than the full shadcn ecosystem. shadcnblocks is not indexed, despite being tagged. A real per-item availability check (does npx shadcn add actually work unauthenticated, not just what the index claims) found roughly half of its components return 401/403 "License required" at their real install URL, something invisible in the registry's own index data. The original full-scale check was contaminated by the vendor's rate limiter partway through; a later clean re-check, run from scratch with proper backoff and explicitly separating rate-limit noise from real answers, confirmed the same conclusion on a 3,358-item confident sample: 55.6% genuinely paywalled, well past the threshold that already excludes other registries below. It remains excluded, not pending. shadcn-dashboard had the same problem at a smaller scale (32.5%) and was fixed by filtering the paywalled components out before shipping. Aceternity, one of the original six registries, was found to have the same problem much later: 163 of its 170 page-template demo pages (95.9%) are paywalled and excluded, found only after real-world use surfaced a confident match whose install command required Aceternity Pro, because the availability check was built after aceternity's original tagging run and had never been applied to it retroactively until then; a separate, unrelated data issue in the same registry (one component listed twice under two different types, both pointing at the same install URL) was later found and collapsed into one entry. shadcnuikit and shadcn-space were evaluated for a second product-UI expansion and excluded outright: a real per-item availability check found genuine paywalls on 40% and 33.3% of a sample from each. shadcn-ui-blocks' combined free-and-paid index was excluded the same way (82% paywalled), but a separate free-only index the vendor also publishes was verified clean (100% installable) and is indexed instead. cult-ui is excluded because its index sits behind a bot challenge; a headless browser does pass it, but building a tool specifically to bypass an anti-bot control the vendor put there on purpose was a line not crossed, so this stays unindexed by choice, not by inability. uiable's descriptions are mostly name-echoed templates rather than hand-written text, so its tags carry less real signal than the rest of the catalog, though a full-scale confidence measurement found this does not show up as measurably lower tag confidence. Visual density was historically the weakest tagged dimension; reformulating it from a 3-label choice to a continuous probability closed most of that gap. Non-English briefs were measurably weaker until a real translation step was added; detection is restricted to the languages this project actually supports translating, after real Polish and Russian briefs were confidently misdetected as unsupported languages when the detector was allowed to consider all languages it knows, silently skipping translation. Detection on short or ambiguous phrases within the supported set can still occasionally misfire, though translation is never worse than doing nothing, since a failed detection or translation falls back to the original text unchanged. A separate catalog measurement found the ranking function returning no-match far too often for how large the catalog is (40% across a mixed-difficulty real sample), traced to the tagged dimensions alone being unable to separate near-identical structural variants; adding a TF-IDF-weighted text-relevance signal (see the ranking section above) cut that rate to 13% on the same sample without any change to tag data or an extra network call. 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; and no general code-quality ranking. A domain dimension (auth, scheduling, commerce, messaging, analytics, content, settings, search, marketing, or general-purpose) separates same-shape, different-purpose components, such as a calendar and a login form, that six purely-structural dimensions alone could not tell apart. 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: @matchcndev. 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 26, 2026 development snapshot. Distinguish implemented behavior from intended behavior, fit confidence from accuracy, and local ranking from the network-dependent pipeline.