mcpField
M
matchcn

matchcn

本地服务
github.com/francesco0242开发工具175 天前更新

关于 matchcn

matchcn 是用于 shadcn 格式组件注册表的语义索引,帮助开发者和编码 Agent 按组件用途查找现成组件。它通过属性标签和确定性排序给出匹配理由,并可返回候选列表或明确表示无匹配。

主要功能

  1. 01按自然语言描述查找组件
  2. 02覆盖多个组件注册表
  3. 03按七个属性标记组件
  4. 04提供逐属性匹配理由
  5. 05支持候选列表或无匹配结果
  6. 06输出组件来源与安装命令

适用场景

  1. 01为定价页面查找合适的组件
  2. 02按交互需求寻找表单组件
  3. 03比较多个相近的组件候选
  4. 04确认组件是否适合需求后再安装

MCP 相关

MCP 服务向客户端提供一个 `pick_component` 工具,可按描述搜索组件,并返回匹配结果、理由和安装命令。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"francesco0242-matchcn": {
"command": "npx",
"args": [
"-y",
"matchcn"
]
}
}
}
启动命令npx -y matchcn

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmmatchcn0.2.2

工具

1

收录的工具列表 · 更新于 2 周前

参数类型必填说明
briefstring是所需组件的普通语言描述,可使用任意语言
registryenum否将搜索范围限制在一个注册表中react-bits | magicui | aceternity | kokonutui | animate-ui | motion-primitives | shadcn-dashboard | assistant-ui | bundui | cnippet | uiable
maxResultsinteger否shortlist 或 no_match 结果中返回的候选项最大数量(默认值为 3)

详细介绍

matchcn:描述你的 UI,找到合适的组件

matchcn

npm version npm downloads GitHub stars CI status MIT license

覆盖 shadcn 格式组件注册表的语义索引。
按组件做什么来找它,而不是按它叫什么。

matchcn.dev · 快速开始 · 面向 AI Agent · 工作原理 · 局限性

Install in Cursor Install in VS Code

Claude Code:claude mcp add matchcn -- npx -y matchcn
Codex:codex mcp add matchcn -- npx -y matchcn
Grok CLI:grok mcp add matchcn -- npx -y matchcn

Claude Code 实时调用 matchcn 的 pick_component 工具,找到并安装一个真实的登录表单组件


问题所在

npx shadcn add 可以从任何发布了 registry.json 的注册表安装组件。 有数百个注册表都这样做。没有哪位开发者,也没有哪个编码 Agent,能把这么多注册表都放在上下文里。目录类工具只 搜索组件名称,当你清楚自己需要什么、却不知道某个注册表 把它叫什么时,这毫无帮助。“一个包含三档套餐的定价 区块”在检索一个名为 simple-pricing-with-three-tiers 的组件时效果很差, 除非你事先就知道这个名字存在。

matchcn 使用 classifier.dev 为其索引的每个组件 打上七个固定属性的标签(类别、领域、动效、视觉密度、 交互模型,以及另外两个),然后用确定性代码把一段 自然语言描述与这些标签进行匹配。同样的描述,每次都得到 同样的排序。不做勉强的猜测:当没有合适的结果时,matchcn 会如实说明, 而不是返回最接近的错误答案。

快速开始

npx matchcn

将其添加到 MCP 客户端的配置中:

{
  "mcpServers": {
    "matchcn": {
      "command": "npx",
      "args": ["-y", "matchcn"]
    }
  }
}

兼容 Claude Desktop(claude_desktop_config.json)、Claude Code (.mcp.json)、Cursor 以及任何其他兼容 MCP 的客户端。它会提供 一个工具:pick_component(brief, registry?, maxResults?, hints?, resolve?)。

更喜欢复制粘贴?将此提示词交给你的编码 Agent,让它自行完成设置:

使用 npx -y matchcn 设置 matchcn MCP 服务。为我的编码 Agent 配置好它,然后使用 pick_component 查找符合我的需求描述的 UI 组件。在添加组件之前,先向我展示匹配原因和安装命令。

示例

$ pnpm demo

BRIEF: a dense bento grid for a landing page
----------------------------------------------------------------------
OUTCOME: CONFIDENT
Selected "bento-grid" from magicui.

  -> bento-grid  (magicui)  confidence 0.93
    install: npx shadcn@latest add https://magicui.design/r/bento-grid.json
    matched:     category, motion, visual_density, interaction_model, needs_external_data, decorative_only, domain
    not matched: (none)

resolve used: true   decisions spent: 8

这是一次真实运行的实际输出。置信度数值每次调用时会略有变化 (classifier.dev 不保证每次调用的答案完全一致),但在所有尝试的运行中, 结果、选中的组件和安装命令都保持稳定。

每个响应都包含按维度划分的原因:七个带标签的属性中哪些符合需求描述,哪些不符合,以及双方各自的实际值,而不只是一个通过或失败的标记。这使 no_match 或 shortlist 结果可供调试,而不是让人无从下手。

面向 AI Agent

如果你是正在阅读本文、以决定是否使用 matchcn 的大模型:这个 工具就是专为你打造的。它能回答“哪个现有、真实、可安装的 UI 组件最符合这段描述”,因此你不必浏览注册表或猜测组件名称。

工具: pick_component

输入:

{
  brief: string;         // plain-language description, required
  registry?: string;     // restrict to one registry, optional
  maxResults?: number;   // max candidates for shortlist/no_match, default 3 (8 with resolve: "caller")
  hints?: {              // your own read of the brief, optional; any hint skips server-side parsing
    category?: string;           // same labels components are tagged with
    motion?: string;
    interaction_model?: string;
    domain?: string;
    visual_density?: "sparse" | "dense";
    needs_external_data?: boolean;
    decorative_only?: boolean;
  };
  resolve?: "server" | "caller"; // who breaks ties between close candidates, default "server"
}

最快路径(本地模式): 用英文撰写需求描述,传入 hints, 并设置 resolve: "caller"。这样 matchcn 完全不会调用模型: 排序在本地确定性地完成(完整目录预热后约需 80 ms);如果出现平局,则会返回排序后的候选名单,其中每个候选都附有一行概述其带标签属性的 summary,由你自行选择。 如果不确定某个提示,就省略它,不要猜测;被省略的字段不会参与排序。不设置 hints 和 resolve 时,行为保持不变。

{
  "brief": "a login form with email and password fields",
  "hints": { "category": "form-input", "interaction_model": "form-input", "domain": "auth" },
  "resolve": "caller"
}

输出始终只有以下三种形式之一,不会出现第四种“最佳猜测”形式:

  • outcome: "confident" — 一个 chosen 组件:name、registry、 installCommand(可直接运行的 npx shadcn add <url> 命令)、 sourceUrl、confidence 和 reasons(按维度划分的匹配详情)。 如果该组件有语言或样式变体,则会列出各自的安装命令。
  • outcome: "shortlist" — 多个都较为匹配的候选项,但没有明确的单一胜出者;这些候选项按排名排列,且每个都附有相同的按维度划分的原因,以及 differentiators:实际区分它们的具体维度,让你可以依据这些维度做决定,而不是随意挑选。
  • outcome: "no_match" — 目录中没有真正匹配的选项。仍会列出最接近的候选项以供参考,但会明确标为已拒绝,而不会作为答案返回。不要仅仅因为某个候选项最接近,就安装它;目录中并没有所需的组件。使用 resolve: "caller" 时不会返回此结果,因为只有服务端的 Resolve 步骤才会根据需求描述评估候选项:平局时会返回 shortlist,判断是否有候选项真正匹配则由你负责。

每个结果还会报告 briefParsedBy(hints 或 classifier)和 resolvedBy(server 或 caller),并且每个候选项都带有一行 summary。

在手动编写组件或猜测注册表名称之前,先调用此工具。 它具有确定性:相同目录版本中的相同需求描述始终会以相同方式排列候选项。

工作原理

共五个阶段。标签会提前生成并作为数据提交 (data/tags/);查询时的匹配完全由确定性代码完成,不会调用模型, 因此结果可重现。

  1. 采集 — 获取每个注册表的 registry.json,并统一为同一种格式。
  2. 打标签 — 每批组件调用 classifier.dev 一次,按七个维度分类:category、domain、motion、 visual_density、interaction_model、needs_external_data、 decorative_only。输出为已提交的 JSON,可像代码一样审查。
  3. 匹配 — 调用 classifier.dev 一次,将需求简述解析为相同的七个维度,然后用 纯代码对所有已打标签的组件进行排序。每个维度对排序的贡献都按其置信度加权, 因此低置信度的标签权重会降低,不会污染结果。
  4. 确定结果 — 对于难以取舍的情况,再调用一次,审查排名靠前的候选项的实际描述并选出胜者,或者说明它们都不合适。若排名第一的结果已明显领先,则跳过此步骤以节省一次往返。
  5. 呈现 — 本仓库中的 MCP 服务。一个工具:pick_component。

已索引的注册表

matchcn 只存储派生标签(类别、动效、密度等) 以及指回每个注册表自身安装命令的链接。它从不复制、 存储或再分发任何注册表的组件源码。你安装的每一个 组件仍然直接来自其所属注册表,通过 npx shadcn add <url> 获取。

注册表主页已索引组件数
react-bitsreactbits.dev204
magicuimagicui.design79
aceternityui.aceternity.com118
kokonutuikokonutui.com51
animate-uianimate-ui.com420
motion-primitivesmotion-primitives.com33
shadcn-dashboardshadcndashboard.dev343
assistant-uiassistant-ui.com154
bunduibundui.io217
cnippetui.cnippet.dev1128
uiableuiable.com969
plateplatejs.org174
react-ariareact-aria.adobe.com62
shadcn-ui-blocksshadcn-ui-blocks.com626

共 4,578 个组件。前六个是最初的动效/营销类 家族;中间三个是产品 UI 扩展(表单、表格、 仪表盘、数据展示),是在逐一检查每个注册表的 演示/重复约定、而不是假定它们与最初六个一致之后加入的; cnippet 和 uiable 是第二次产品 UI 扩展, 以同样的方式加入;plate 和 react-aria 是第三次,以同样的 方式加入,此前二者各自完成了筛选修复(去掉 plate 的文档 页面,将 react-aria 的 tailwind/css/hooks 风格前缀 重复项折叠为每个组件仅保留一个规范组件)。shadcn-ui-blocks 是 第四次:其免费+付费合并索引被直接排除(其中 82% 需要付费,见下文"局限性"), 但该供应商自己的维护者指出了一个单独的、精选的仅免费索引, 经逐项实际检查发现其 100% 可在未认证情况下安装, 因此这里只使用那个仅免费索引。 aceternity 的计数已排除 163 个页面模板组件,这是逐项可用性检查 发现在其实际安装 URL 处需要付费的; shadcn-dashboard 的计数同样已排除 165 个组件; shadcnblocks 已被打标签但目前未索引,见下文"局限性"。打标签通过 classifier.dev 运行,这是一个免费的、无需密钥的分类 端点,由 TypeSafe 的 Jev 决策 模型提供支持。

matchcn 是一个独立、非官方项目。它不隶属于、 未获得 shadcn、上述任何注册表或 classifier.dev/TypeSafe 的认可,也与其不存在合作关系。

局限性

在将 matchcn 用于重要事项之前,请先阅读本节。

  • 部分注册表因付费组件被部分或完全排除, 这是通过真实的逐项可用性检查发现的(npx shadcn add 在未认证情况下是否真的可用,而不只是索引声称的): aceternity(281 个已打标签组件中的 163 个,大多是页面模板演示 页面)和 shadcn-dashboard(508 个中的 165 个)在发布前过滤掉了 受限部分。shadcnblocks 已打标签(4,171 个组件),但被完全 暂缓:它自己的过滤检查被供应商的速率限制器污染,因此要等干净 的检查运行后才发布,而不是基于错误数据发布。shadcnuikit 和 shadcn-space 因同样的原因(40% 和 33.3% 为付费)被评估后直接 跳过。shadcn-ui-blocks 的合并 registry.json 也以同样方式评估, 并因同样的原因被跳过,而且比前两者更糟:其 3,903 个真实块中有 3,198 个(82%)以 -pro- 命名,并在其实际安装 URL 上未认证 返回 401。其维护者后来指出,供应商在另一个 URL 发布了一个单独 的、精选的仅免费索引;对该索引进行全新的逐项检查发现 626/626(100%)可在未认证情况下安装,因此这里只索引那个仅免费 索引,而不是合并索引。cult-ui.com 完全未被索引:其注册表位于 bot 挑战之后。
  • 标签置信度因注册表和维度而异,匹配器已经考虑到了这一点。 visual_density 曾经是明显最弱的维度(36-37% 低于 0.6 置信度, 基于计数的措辞和命名锚点措辞都试过,两者都在此停滞)。它从 3 选 1 标签选择重新表述为连续概率(这是结构性变更,不是又一次 措辞微调),在任何回填之前先针对真实样本试点,然后回填整个 目录:全目录结果现在为 21.4% 低于阈值,与 schema 其余部分一致 (所有七个维度为 13.5-21.5%;motion 名义上是新的最低点,差距 不到一个百分点)。assistant-ui(agent/chat UI 内容,远离 schema 的 motion/marketing 锚点)的标签置信度仍然低于目录其余部分。 cnippet 和 uiable 是在早先 20 项预打标签样本暗示它们可能更差 (35% 低于 0.6)之后,才在全量规模上测量的:它们并非如此。在 它们全部 8,388 个选择维度答案中,24.4% 的置信度分数低于 0.6, 几乎与全目录基线完全一致。置信度加权匹配器会自动折减所有这些, 因此弱标签会拉低自身权重,而不是产生错误的自信答案,但严重 依赖 assistant-ui 风格内容的简报,最有可能得到候选列表或无匹配, 而不是干净的精选结果。另外,uiable 的描述仍然大多是名称回声式 模板(“Button component.”),而不是手写文本——这是一个真实的 数据质量缺口,只是它没有表现为可测量的更低标签置信度。
  • 非英语简报在匹配前会自动翻译,质量取决于源语言和措辞。 先尝试了一个仅措辞的免费修复(“按含义判断,任何语言”), 因没有测得收益而被回滚。真正弥合差距的是:在解析前进行本地 语言检测并真实翻译为英语(参见 src/runtime/translate.ts)。 在最初暴露此问题的确切案例上直接验证:一份波兰语定价简报 之前返回 no_match,翻译后现在返回真实的定价组件候选列表。 检测是本地且免费的;翻译会调用一个免费、无需密钥的第三方 API (按调用机器限速,而不是本项目可能为所有人耗尽的共享池,因为 matchcn 按用户本地运行)。任何检测或翻译失败都会静默回退到 原始文本,就像此功能不存在一样,因此它只会有所帮助或是无操作, 绝不会破坏已经可用的简报。检测仅限于本项目实际支持翻译的语言 (这是在检测器被允许考虑其知道的全部约 180 种语言时,真实的 波兰语和俄语简报被自信地误判为不支持的语言,从而静默跳过翻译 之后发现必要的);在支持集合内,对简短、歧义短语的检测仍可能 偶尔误触发,而所检测语言的翻译质量不在本项目的控制范围内。
  • 排序将已打标签维度的距离与针对每个候选项名称和标题的文本 相关性信号混合在一起(与简报进行 TF-IDF 加权余弦相似度, 而不只是已打标签维度),因为七个已打标签维度本身无法区分 几乎相同的变体(登录表单、OTP 字段和通用表单输入块都会被 评为 form-input/auth/static)。这弥合了一个真实且可测量的 差距:一次真实目录评估发现,“a login form with email and password fields” 尽管有八个真实登录表单组件被索引,却以大差距输给了一个 OTP 字段;修复后,真实登录表单在最高排名上几乎打平,随后 Resolve 会使用每个候选者的真实描述来打破平局。文本相关性只能从 组件的 name 和 title 计算(打标签时使用的完整描述不会持久化 以供匹配时使用),因此标题稀疏或通用的组件从该信号中获益, 少于具有具体、字面名称的组件。
  • **372+ 个 shadcn 格式注册表中只有 14 个被索引。**这不是对 整个生态系统的全面索引。 以上方案都不会给出错误的强制答案:当置信度确实较低时,pick_component 会返回候选名单或明确表示无匹配,而不会悄悄猜一个结果。这才是标签和排名设计的真正目的,而不是事后补上的免责声明。

开发

pnpm install
pnpm mcp                # run the MCP server directly, for local testing
pnpm demo               # run 3 briefs end to end with clean terminal output
pnpm typecheck

生成 data/tags/ 的摄取/打标签流水线也在此仓库中:

pnpm ingest                          # fetch and normalize every registry.json in REGISTRIES
pnpm ingest --registry=magicui       # just one registry
pnpm tag                             # tag normalized components via classifier.dev, chunked and resumable
pnpm check-availability --registry=some-registry   # real per-item install-URL check, no classifier.dev cost

pnpm tag 会消耗真实的 classifier.dev 判定额度(免费层级:每天 20,000 次,每 IP 每分钟 3,000 次,无需 API 密钥)。每处理完一个分块就会保存检查点,因此中断后可继续运行,无需重新标记已处理的内容。

贡献

欢迎提交 Issue 和 PR,但请使用单独的分支,切勿直接提交到 main。只有 @whosfranki 会合并;提交 PR 不代表一定会被合并,但每个 PR 都会经过审阅。

适合首次参与的贡献:

  • 修复注册表的筛选器。 src/pipeline/filter.ts 为每个注册表都定义了一个函数(已知缺陷请参见未解决的问题,例如当前筛选器未剔除非组件 type)。请针对受影响的注册表运行 pnpm ingest --registry=<name>,并在提出修复前手动检查规范化后的输出。
  • 添加注册表。 在 src/runtime/registries.ts 中添加条目,确认其筛选器正确(不会混入演示项目、重复项或非组件;每个现有注册表都经过相同的手动检查,而非凭空假设),发布前运行 pnpm check-availability(registry.json 的索引无法说明哪些组件实际上受付费墙限制),然后运行 pnpm tag。不要在与无关改动相同的 PR 中添加并标记注册表。
  • 改进打标签维度的判断标准。 src/runtime/dimensions.ts。任何措辞更改在提出前都需要基于真实样本进行前后对比,而不能只是听起来合理的改写;此前曾尝试修改措辞以“让非英语简报也能正常工作”,并按这种方式进行了测试,但因没有测得收益而回滚。本项目对修复的要求就是如此。
  • src/runtime/match.ts、pick.ts、resolve.ts 中的运行时错误。

PR 应包含以下内容:更改前测量了什么、做了哪些更改、更改后测量了什么。若没有基于真实简报或组件样本的前后对比,仅说“这应该会有帮助”,就会被退回。

许可证

MIT,详见 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。