Component Library MCP

Component Library MCP

An MCP server that scans React and Vue projects, extracts component metadata (props, slots, events, imports, usage), and exposes it to AI coding agents via structured tools.

Category
访问服务器

README

Component Library MCP

An MCP (Model Context Protocol) server that scans React and Vue projects, extracts component metadata (props, slots, events, imports, usage), and exposes it to AI coding agents via structured tools.

What it solves: When an AI coding agent writes UI code without context, it produces three recurring problems:

  1. Duplicate components — creates <UserCard> when <UserProfile> already exists.
  2. Wrong prop APIs — passes label when the component expects title, or misses a required prop.
  3. Inconsistent patterns — builds a one-off dialog instead of using the project's <BaseDialog>.

This MCP gives the agent full visibility into your component library before it writes any UI code.


Requirements

  • Node.js ≥ 20
  • pnpm (other package managers also work — install deps however you like, the server is a plain Node script at runtime)

Install & build

git clone <this-repo>
cd component-library-mcp
pnpm install
pnpm build

pnpm build emits a runnable server at dist/index.js.

Configure in Claude Code

The server scans whatever directory it is launched from (process.cwd()). Pick one of the two setups below — no PROJECT_ROOT needed.

Option A — Per-project .mcp.json (recommended)

Drop a .mcp.json file at the root of every React/Vue project you want to use the MCP with:

{
  "mcpServers": {
    "component-library": {
      "command": "node",
      "args": ["/absolute/path/to/component-library-mcp/dist/index.js"]
    }
  }
}

Claude Code auto-loads .mcp.json from the open workspace. Each project can have its own env overrides (see below) without polluting other projects.

Option B — Global ~/.claude.json

If you usually work in one project at a time and always launch Claude Code from that project's directory:

{
  "mcpServers": {
    "component-library": {
      "command": "node",
      "args": ["/absolute/path/to/component-library-mcp/dist/index.js"]
    }
  }
}

With no env vars set, the server scans process.cwd() — which is the directory Claude Code is opened in. Switch projects by opening a different folder in your editor / re-launching Claude Code from a different directory.

Restart Claude Code after changing either config. The server runs on stdio — there's no port, no daemon.

Environment variables (optional)

All env vars are optional. Set them under env: { ... } in the MCP config only when you need to override defaults.

Variable Default Description
PROJECT_ROOT process.cwd() Absolute path to scan. Usually you don't need to set this — the server uses the directory it was launched from. Only set it when that isn't what you want.
COMPONENT_DIRS auto Comma-separated dirs to scan. auto probes src/components, src/ui, src/shared, components, lib/components, app/components and falls back to src/ or the project root.
FRAMEWORK auto react | vue | auto. Auto detects from package.json deps.
EXCLUDE_PATTERNS node_modules,dist,.next,.nuxt Comma-separated dir names or globs. Bare names become **/<name>/**.
MAX_DEPTH 10 Max recursion depth for fast-glob.
INCLUDE_STORIES true Parse .stories.(ts|tsx|js|jsx) and attach story examples to components.
LOG_LEVEL silent silent | info | debug. All logs go to stderr.

Example .mcp.json with overrides:

{
  "mcpServers": {
    "component-library": {
      "command": "node",
      "args": ["/absolute/path/to/component-library-mcp/dist/index.js"],
      "env": {
        "COMPONENT_DIRS": "src/components,src/ui",
        "FRAMEWORK": "react",
        "EXCLUDE_PATTERNS": "node_modules,dist,__tests__,stories",
        "INCLUDE_STORIES": "false",
        "LOG_LEVEL": "info"
      }
    }
  }
}

Available tools

All 7 tools accept Zod-validated JSON input and return both content (text) and structuredContent (same data as structured output).

1. list_components

Summary of every component in the project. Agents typically call this first.

{ "framework": "react", "min_usage": 1, "include_props": false }

Returns an alphabetically sorted array: { name, file_path, framework, prop_count, usage_count, has_stories, description?, tags? }.

2. get_component_details

Full metadata for one component — props, slots, events, description, story examples.

{ "name": "Button" }
// or
{ "file_path": "src/components/Button.tsx" }

Fuzzy fallback: if name has no exact match, suggestions within Levenshtein distance ≤ 3 are returned.

3. search_components

Natural-language + structured search.

{
  "query": "dialog modal",
  "prop_type": "boolean",
  "has_slot": "footer",
  "limit": 10
}

Returns ranked { name, score, reasons[] } hits. Weights: name 1.0, description 0.5, tags 0.6, prop names 0.35, path 0.2.

4. get_import_graph

Who imports what.

{ "component_name": "Button", "direction": "both", "depth": 2 }

Returns dependencies[] (what this component imports) and dependents[] (who imports it, with is_page: true for pages/routes). Barrel files are followed through but not counted as dependents.

5. check_duplicatehighest-value tool

Call this before creating a new component.

{
  "proposed_name": "UserCard",
  "proposed_props": ["user", "size", "avatarUrl"],
  "purpose": "display user profile card"
}

Returns { has_duplicates, existing_matches[], recommendation } where recommendation is use_existing | extend_existing | create_new. Score combines name similarity (0.45), prop overlap (0.35), and purpose/description overlap (0.2), with a short-circuit to use_existing when proposed props are a full subset of an existing component.

6. get_component_usage_example

Real usage snippets from the codebase.

{ "component_name": "Button", "limit": 3 }

Returns up to limit { file_path, code_snippet, props_used[] } examples (5–15 lines around the import line), plus story_examples[] from any matching .stories.(t|j)sx files.

7. refresh_cache

Force re-scan. Incremental by default.

{ "full_scan": true }

Returns { components_found, scan_duration_ms, new_components[], removed_components[], reparsed_files[] }.

How it works

  • First tool call triggers a full scan. Subsequent calls do an mtime-based incremental scan — only re-parses files that changed.
  • React parsing handles function/arrow/FC components, HOC unwrapping (memo, forwardRef, observer, nested), legacy propTypes, JSDoc, and cross-file type expansion via the TypeScript compiler API.
  • Vue parsing handles <script setup> typed + runtime defineProps / defineEmits, Options API, defineComponent, named + scoped slots.
  • Import graph includes page/route directories as consumers (so usage_count reflects imports from src/pages/**), follows barrel re-exports to source files, and resolves tsconfig paths aliases.
  • Performance — 200-component project scans in ~150ms; 2-file incremental scans in ~30ms.

Development

pnpm dev          # tsx watch mode
pnpm test         # vitest, all tests
pnpm test:perf    # perf tests only
pnpm test:watch   # vitest watch mode
pnpm build        # tsc → dist/

Troubleshooting

The server returns { components: [], total: 0 } for my project.

  • Make sure Claude Code was launched from (or has opened) the project root — where package.json lives. The server scans process.cwd() by default.
  • If the project root is somewhere else, set PROJECT_ROOT in the MCP config's env block as a last resort.
  • Run with LOG_LEVEL=info. stderr will show which dirs the scanner tried and how many files it found.
  • If you have a non-standard layout, set COMPONENT_DIRS explicitly (e.g., "lib/ui,packages/core/components").

Framework is wrong.

  • Set FRAMEWORK=react or FRAMEWORK=vue explicitly. Auto-detection reads package.json deps (react, next, vue, nuxt).

Cross-file types show up as "Props" instead of "a" | "b".

  • The TS type resolver runs automatically. If it fails, the parser falls back to the alias name. Check LOG_LEVEL=debug for resolver errors — usually a missing tsconfig.json path alias.

usage_count is 0 for a component that's clearly used.

  • Your importing files must live inside the scanned directories, or inside one of the auto-detected page dirs (src/pages, src/routes, src/app, pages, routes, app). If imports come from a non-standard dir, add it to COMPONENT_DIRS.

JSON-RPC protocol errors from the client.

  • The server writes only JSON-RPC to stdout. If you see garbage there, a dependency is using console.log — open an issue. All of our logging goes to stderr via src/logger.ts.

Project layout

src/
  index.ts                  # stdio entry point
  server.ts                 # MCP server + tool registration
  config.ts                 # env var parsing
  logger.ts                 # stderr-only logger
  lib/
    types.ts                # ComponentInfo, PropInfo, etc.
    schemas.ts              # Zod schemas for tool inputs
  scanner/
    file-scanner.ts         # component dir discovery
    page-scanner.ts         # page/route dir discovery (for graph only)
    framework-detector.ts   # react vs vue
    import-resolver.ts      # relative + tsconfig paths
    import-extractor.ts     # AST → import statements
    import-graph.ts         # dependencies / dependents / usages
  parsers/
    react-parser.ts         # TSX + HOC unwrap
    vue-sfc-parser.ts       # <script setup> / Options API / template slots
    vue-tsx-parser.ts       # Vue TSX (thin wrapper over react parser)
    story-parser.ts         # .stories.tsx
    jsdoc-parser.ts         # @tag, @param, description
    ts-type-resolver.ts     # cross-file type expansion via ts.Program
    shared.ts
  search/
    fuzzy-match.ts          # Levenshtein + token overlap
    text-search.ts          # ranked + structured filters
    duplicate-detector.ts   # name + prop + purpose scoring
  cache/
    component-cache.ts      # in-memory file_path → entry
    incremental-scan.ts     # mtime diff + graph rebuild + story join
  tools/
    list-components.ts
    get-component-details.ts
    search-components.ts
    get-import-graph.ts
    check-duplicate.ts
    get-usage-example.ts
    refresh-cache.ts
tests/
  fixtures/                 # react-project, vue-project, mixed, nonstandard
  parsers/ scanner/ search/ cache/ tools/ perf/

License

ISC.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选