@yoka-ui/mcp
v1.0.2
Published
Yoka UI MCP Server - Model Context Protocol server for @yoka-ui/ui components and documentation
Readme
@yoka-ui/mcp
Model Context Protocol Server for @yoka-ui/ui
为
@yoka-ui/ui数据部前端组件库提供 AI 助手实时文档查询能力的 MCP 服务器。 支持 Claude Desktop、Claude Code、Cursor 等所有兼容 MCP 协议的 AI 客户端。
目录
为什么需要 @yoka-ui/mcp
AI 助手在使用 @yoka-ui/ui 组件时经常面临以下挑战:
| 痛点 | 解决方案 |
|------|----------|
| AI 不了解组件的具体 Props 和类型 | 实时读取 index.tsx 获取精确 TypeScript 类型定义 |
| AI 容易臆造不存在的组件名 | get_yoka_exports 返回完整的 46 个导出符号 |
| 组件源文件太大(500+ 行),占用过多 context | get_component_source 自动截断函数体,只保留结构 |
| 不清楚组件的使用示例 | get_stories 返回 Storybook 完整示例 |
| 需要多轮调用才能获取完整信息 | get_yoka_document 合成三路信息(文档 + 类型 + 示例) |
核心价值:
- 消除幻觉:AI 可直接查询官方导出符号表,不再臆造组件名
- 精确类型:直接读取组件源码中的 TypeScript 定义,确保类型正确
- 实时更新:挂载本地仓库时,AI 获得与仓库同步的最新文档
- 上下文友好:自动截断大文件、智能合并多源信息,保护 context window
功能概览
| MCP Tool | 描述 | 无需本地仓库 |
|----------|------|------------|
| get_yoka_document | 获取组件文档(API + Props + Stories 合成) | 部分支持 |
| get_component_source | 读取组件源文件,大文件自动截断函数体 | 否 |
| get_component_file_list | 列出组件目录下所有文件路径 | 否 |
| get_yoka_exports | 返回完整导出符号表(exports.generated.md) | 发布后支持 |
| get_stories | 读取组件 Storybook 使用示例 | 否 |
MCP Resource:yoka://components — 组件列表 JSON(供 AI 工具发现使用)
架构说明
yoka-ui-mcp/
├── src/
│ ├── index.ts # 公共 API 入口(re-export 供外部集成使用)
│ ├── server.ts # MCP Server 工厂(注册所有 tools + resource)
│ ├── stdio.ts # stdio 传输入口(Claude Desktop / Code / Cursor)
│ ├── http.ts # HTTP 传输入口(团队共享服务、WebUI 集成)
│ ├── tools/ # 5个 MCP Tool 实现
│ │ ├── index.ts 聚合所有 tools 定义和 handlers
│ │ ├── get-yoka-document.ts 组件文档合成工具
│ │ ├── get-component-source.ts 源文件读取工具
│ │ ├── get-component-file-list.ts 文件列表工具
│ │ ├── get-yoka-exports.ts 导出符号表工具
│ │ └── get-stories.ts Storybook 示例工具
│ └── utils/ # 工具函数(数据访问层)
│ ├── resolve-repo-path.ts 仓库路径解析(优先级策略)
│ ├── read-local-file.ts 本地文件读取(带内存缓存)
│ ├── list-component-files.ts 递归列出组件文件
│ ├── get-exports-table.ts 解析 exports.generated.md
│ ├── fetch-npm-file.ts npm CDN fallback 获取文件
│ ├── file-cache.ts 磁盘缓存(用于 npm 远端数据)
│ └── remove-function-body.ts AST 函数体截断(oxc-parser)
├── package.json # 包声明、scripts、依赖
├── tsconfig.json # TypeScript 编译配置
├── .fatherrc.ts # father 构建配置(ESM → dist/)
└── docker-compose.yml # Docker Compose 编排配置层次关系
AI 客户端(Claude / Cursor)
│ MCP JSON-RPC
▼
stdio.ts / http.ts ← 传输层:处理协议通信
│
▼
server.ts ← 注册层:将 tools/resources 绑定到 MCP Server
│
▼
tools/index.ts ← 路由层:按工具名分发请求
│
▼
tools/get-*.ts ← 业务层:工具实现,组织返回内容
│
▼
utils/ ← 数据层:读取本地文件 / 远程 CDNMCP Tools 详解
get_yoka_document
用途:组件文档的综合入口,合并多个来源的信息。
参数:
componentName?: string— 组件名(大小写不敏感)。不传时返回所有组件列表。
内部流程(无参数时):
- 读取
@Docs-yoka/exports.generated.md(本地 → npm CDN fallback) - 按分类整理导出符号,格式化为 Markdown 返回
内部流程(有 componentName 时):
- 从
.opencode/skills/yoka-ui/SKILL.md中查找该组件相关行(上下文 ±5 行) - 用
listComponentFiles找到index.tsx/typing.ts,读取前 120 行(Props 类型定义通常在这里) - 找到
index.stories.tsx,读取前 80 行作为使用示例 - 将以上三部分拼接为 Markdown 文档
- 若总行数超过 888 行,将代码块替换为占位提示(节省 LLM context)
设计原因:AI 助手需要在 一次调用 内获得足够完整的文档,避免多轮 tool call 的延迟。三路信息合并(说明文档 + 类型定义 + 真实示例)覆盖了 AI 使用组件的主要信息需求。
get_component_source
用途:读取任意源文件内容,大文件自动截断函数体以节省 context。
参数:
filePath: string— 相对仓库根目录的路径,如src/ui/YkButton/index.tsxfullCode?: boolean— 是否返回完整内容(默认false)
截断规则:
.ts/.tsx文件 且 行数 ≥ 500 且fullCode=false→ 用oxc-parser将所有函数体替换为{ ... }- 其他情况:返回完整内容
设计原因:业务组件(如 AiChat、ModCommonFilter)源文件往往超过 500 行。直接返回全文会占用大量 context token,而 AI 通常只需要了解结构(类名、方法签名、Props 接口),函数体细节可按需用 fullCode: true 获取。
get_component_file_list
用途:列出某组件目录下所有文件路径,是 get_component_source 的前置步骤。
参数:
componentName?: string— 不传时列出所有可用组件名
搜索顺序:src/ui → src/components → src/business → src/creative → src/layout → src/Themes
返回格式:
组件: YkButton
总文件数: 2
文件类型统计:
.tsx: 2
===== 文件列表 =====
src/ui/YkButton/index.stories.tsx
src/ui/YkButton/index.tsxget_yoka_exports
用途:返回 @Docs-yoka/exports.generated.md 完整内容,让 AI 知道哪些符号可以导入。
为什么重要:AI 容易臆造不存在的组件名(如 YkTable、YkModal)。调用此工具可以精确知道 44 个导出符号,完全杜绝幻觉。
数据源:本地文件 → 解析后的结构化数据 → npm CDN���fallback)
get_stories
用途:读取组件的 Storybook index.stories.tsx 完整内容。
与 get_yoka_document 的区别:
get_yoka_document只返回 stories 前 80 行(快速预览)get_stories返回完整 stories 文件(深入了解所有使用场景)
数据源策略
MCP 服务器按优先级依次尝试以下数据源:
优先级 1:YOKA_UI_REPO_PATH 环境变量
↓ 直接读取指定路径下的仓库文件
优先级 2:自动检测(__dirname 向上查找)
↓ 从 dist/utils/ 向上 8 层寻找含 src/index.tsx 的目录
↓ 适用于:在 yoka-ui 仓库内部 (ecosystem/yoka-ui-mcp/) 运行时
优先级 3:npm CDN fallback
↓ 从 unpkg.com 或 registry.npmmirror.com 获取
↓ 仅对 @Docs-yoka/ 目录下的文件有效(需要包已发布)
↓ 使用 Promise.race 同时请求两个源,取最快响应
↓ 结果缓存到 ~/.yoka-ui-mcp/cache/何时各优先级生效:
| 场景 | 生效优先级 | |------|-----------| | 开发者在 yoka-ui 仓库内运行 MCP | 优先级 2(自动检测) | | 用户通过 npx 安装使用,设置了环境变量 | 优先级 1 | | 用户通过 npx 安装使用,未设置环境变量,包已发布 | 优先级 3(仅文档) | | 用户通过 npx 安装使用,未设置环境变量,包未发布 | 无数据(报错提示) |
快速上手(使用方)
方式一:npx 一次性运行(无需全局安装)
最简单的使用方式,适合临时查询或不想全局安装:
{
"mcpServers": {
"yoka-ui-mcp": {
"command": "npx",
"args": ["-y", "@yoka-ui/mcp"],
"env": {
"YOKA_UI_REPO_PATH": "D:/projects/yoka-ui"
}
}
}
}说明:
-y参数自动确认 npx 安装提示- 每次启动时从 npm 拉取最新版本(约 1-2 秒)
- 适合:临时使用、想保持最新版本
方式二:全局安装后使用(推荐长期使用)
# 1. 全局安装(只需一次)
pnpm add -g @yoka-ui/mcp
# 2. 验证安装成功
yoka-ui-mcp --version
# 输出: 1.0.0
# 3. 直接运行(stdio 模式)
YOKA_UI_REPO_PATH=/path/to/yoka-ui yoka-ui-mcpClaude Desktop / Claude Code 配置(全局安装后):
{
"mcpServers": {
"yoka-ui-mcp": {
"command": "yoka-ui-mcp",
"env": {
"YOKA_UI_REPO_PATH": "/path/to/yoka-ui"
}
}
}
}优势:
- 启动更快(无 npx 拉取延迟)
- 版本固定(除非手动升级
pnpm update -g @yoka-ui/mcp) - 适合:每天频繁使用
配置文件位置:
- Claude Desktop(macOS):
~/Library/Application Support/Claude/claude_desktop_config.json - Claude Desktop(Windows):
%APPDATA%/Claude/claude_desktop_config.json - Claude Code:
~/.claude/claude_code_config.json或通过/mcp命令添加 - Cursor:
.cursor/mcp.json(项目级)或~/.cursor/mcp.json(全局)
方式三:HTTP 模式(服务器部署)
适合在服务器上部署,供多个团队成员共享同一个 MCP 服务端。详见下文 服务器部署。
方式四:OpenCode(本项目 AI 工具)
OpenCode 通过 .opencode/skills/yoka-ui/SKILL.md 的 MCP 章节自动配置,无需额外设置。
AI 客户端配置大全
以下汇总所有主流 AI 客户端的 MCP 配置方式。
选择传输模式
| 场景 | 推荐模式 | 说明 | |------|----------|------| | 个人本地使用 | stdio | 无需启动服务器,启动快 | | 团队共享服务 | HTTP | 统一服务,统一管理 | | 临时测试 | HTTP --stateless | 无 session,每次请求独立 |
Claude Desktop
stdio 模式(本地)
配置文件位置:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json
npx 方式(无需安装):
{
"mcpServers": {
"yoka-ui-mcp": {
"command": "npx",
"args": ["-y", "@yoka-ui/mcp"],
"env": {
"YOKA_UI_REPO_PATH": "D:/projects/yoka-ui"
}
}
}
}全局安装后方式(推荐):
pnpm add -g @yoka-ui/mcp{
"mcpServers": {
"yoka-ui-mcp": {
"command": "yoka-ui-mcp",
"env": {
"YOKA_UI_REPO_PATH": "D:/projects/yoka-ui"
}
}
}
}HTTP 模式(连接团队服务器)
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}Claude Code
stdio 模式
方式一:命令添加
claude mcp add yoka-ui-mcp npx -y @yoka-ui/mcp --env YOKA_UI_REPO_PATH=D:/projects/yoka-ui方式二:编辑配置文件
# 配置文件位置
~/.claude/claude_code_config.json{
"mcpServers": {
"yoka-ui-mcp": {
"command": "npx",
"args": ["-y", "@yoka-ui/mcp"],
"env": {
"YOKA_UI_REPO_PATH": "D:/projects/yoka-ui"
}
}
}
}HTTP 模式
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}Cursor
项目级配置(推荐放入仓库)
配置文件位置:项目根目录 .cursor/mcp.json
{
"mcpServers": {
"yoka-ui-mcp": {
"command": "npx",
"args": ["-y", "@yoka-ui/mcp"],
"env": {
"YOKA_UI_REPO_PATH": "${workspaceFolder}"
}
}
}
}全局配置
配置文件位置:~/.cursor/mcp.json
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}Windsurf
配置示例
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}Zed
配置方式
编辑 ~/.zed/config.json 或项目级 .zed/mcp.json:
{
"mcp_servers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}OpenCode
OpenCode 通过 .opencode/skills/yoka-ui/SKILL.md 的 MCP 章节自动配置,无需额外设置。
如果需要手动配置,编辑项目根目录 .opencode/mcp.json:
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}Cline /cline
配置示例
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://localhost:3001/mcp"
}
}
}快速验证配置
配置完成后,在 AI 客户端中输入以下命令验证:
请列出所有可用的 yoka-ui 组件期望返回组件列表(46 个导出符号),如 YkButton、YkCard、ModCommonFilter 等。
常见配置问题
| 问题 | 解决方案 |
|------|----------|
| 连接失败 | 检查服务器地址和端口是否正确 |
| 工具不可用 | 检查 YOKA_UI_REPO_PATH 环境变量是否设置正确 |
| 版本过旧 | pnpm update -g @yoka-ui/mcp 或重新 npx |
团队配置建议
- 统一使用 HTTP 模式:服务器地址
http://localhost:3001 - 配置文件放入仓库:
.cursor/mcp.json、.opencode/mcp.json等,让团队成员 clone 后自动获得配置 - 定期更新:关注
@yoka-ui/mcp版本更新,及时升级获取新工具
服务器部署(团队共享)
当需要团队成员共享同一个 MCP 服务时,在服务器上部署 HTTP 模式。
方案一:直接运行(适合临时测试)
# 安装
pnpm add -g @yoka-ui/mcp
# 启动(前台运行,Ctrl+C 停止)
YOKA_UI_REPO_PATH=/path/to/yoka-ui yoka-ui-mcp-http --port 3001
# 或指定监听地址(IPv4)
YOKA_UI_REPO_PATH=/path/to/yoka-ui yoka-ui-mcp-http --port 3001 --host 0.0.0.0方案二:systemd 服务(Linux 推荐)
适合生产环境,开机自启、自动重启。
步骤 1:创建服务文件 /etc/systemd/system/yoka-ui-mcp.service
[Unit]
Description=Yoka UI MCP HTTP Server
After=network.target
[Service]
Type=simple
User=your-user
Group=your-group
Environment=YOKA_UI_REPO_PATH=/path/to/yoka-ui
ExecStart=/usr/local/bin/yoka-ui-mcp-http --port 3001 --host 0.0.0.0
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target步骤 2:启用并启动
# 重载 systemd 配置
sudo systemctl daemon-reload
# 启用开机自启
sudo systemctl enable yoka-ui-mcp
# 启动服务
sudo systemctl start yoka-ui-mcp
# 查看状态
sudo systemctl status yoka-ui-mcp
# 查看日志
journalctl -u yoka-ui-mcp -f方案三:Docker 容器(推荐容器化部署)
适合容器化部署环境,提供隔离、可移植、易管理的优势。
环境变量配置:复制 .env.example 为 .env 并修改:
# 端口配置
PORT=3001
# yoka-ui 仓库本地路径 (只读挂载)
# 如果不设置,将使用容器内的默认路径
YOKA_UI_REPO_PATH=/opt/yoka-ui方式 A:使用 Docker Compose(推荐)
# 1. 修改 .env 中的卷挂载路径
# YOKA_UI_REPO_PATH=/your/actual/yoka-ui/path
# 2. 启动服务
docker compose up -d
# 3. 查看日志
docker compose logs -f
# 4. 查看状态
docker compose ps
# 5. 停止服务
docker compose down方式 B:使用部署脚本
# 设置环境变量
export PORT=3001
export YOKA_UI_REPO_PATH=/opt/yoka-ui
# 运行部署脚本
sudo bash mcp-deploy.sh start
# 或使用 docker compose
sudo bash mcp-deploy.sh updatemcp-deploy.sh 命令:
| 命令 | 说明 |
|------|------|
| build | 构建 Docker 镜像 |
| start | 启动容器 |
| stop | 停止并删除容器 |
| restart | 重启容器 |
| logs | 查看容器日志 |
| clean | 清理未使用的镜像 |
| update | 更新并重启服务 |
| status | 查看容器状态 |
Docker Compose 配置说明(docker-compose.yml):
version: "3.8"
services:
yoka-ui-mcp:
build:
context: .
dockerfile: Dockerfile
image: yoka-ui-mcp:latest
container_name: yoka-ui-mcp
restart: unless-stopped
ports:
- "${PORT:-3001}:3001"
volumes:
- ${YOKA_UI_REPO_PATH:-/opt/yoka-ui}:/data/yoka-ui:ro
environment:
- YOKA_UI_REPO_PATH=/data/yoka-ui
- NODE_ENV=production
- TZ=Asia/Shanghai
- PORT=3001
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001/health"]
interval: 30s
timeout: 10s
retries: 3Docker 常用管理命令:
# 查看容器状态
docker ps | grep yoka-ui-mcp
# 查看资源使用
docker stats yoka-ui-mcp
# 进入容器
docker exec -it yoka-ui-mcp sh
# 重启容器
docker restart yoka-ui-mcp
# 停止容器
docker stop yoka-ui-mcp
# 查看容器详细信息
docker inspect yoka-ui-mcpHTTP 服务可用端点
| 端点 | 方法 | 说明 |
|------|------|------|
| /mcp | POST | MCP JSON-RPC 请求端点 |
| /mcp | GET | SSE 流端点(服务器推送消息) |
| /health | GET | 健康检查(返回 {status: "ok", version: "x.x.x"}) |
| / | GET | 服务信息(名称、版本、端点列表) |
团队成员配置���连���服务器)
{
"mcpServers": {
"yoka-ui-mcp": {
"url": "http://your-server-ip:3001/mcp"
}
}
}安全建议:
- 生产环境建议添加反向代理(nginx)并启用 HTTPS
- 可通过 nginx 限制访问 IP(内网访问)
- 使用
--host 127.0.0.1+ nginx 反向代理,避免直接暴露 0.0.0.0
开发流程(贡献者)
环境准备
# 1. 进入包目录
cd ecosystem/yoka-ui-mcp
# 2. 安装依赖
pnpm install
# 3. 确认 TypeScript 无错误
pnpm exec tsc --noEmit开发调试
开发时可以直接用 tsx 运行 TypeScript 源码,无需预先构建:
# stdio 模式(模拟 Claude Desktop 调用)
YOKA_UI_REPO_PATH=D:/projects/yoka-ui \
node --import tsx/esm src/stdio.ts
# HTTP 模式(模拟团队共享服务)
YOKA_UI_REPO_PATH=D:/projects/yoka-ui \
node --import tsx/esm src/http.ts --port 3100测试单个 Tool(不依赖 MCP 客户端,直接 Node.js 调用):
# 在构建后的 dist/ 测试
node --input-type=module -e "
import('./dist/tools/index.js').then(async m => {
const r = await m.toolHandlers['get_yoka_exports']({});
console.log(r.content[0].text.slice(0, 500));
})"添加新 Tool
在
src/tools/新建get-xxx.ts,导出两个内容:export const getXxxTool: Tool = { name: 'get_xxx', description: '...', inputSchema: {...} }; export async function handleGetXxx(args): Promise<CallToolResult> { ... }在
src/tools/index.ts注册:import { getXxxTool, handleGetXxx } from './get-xxx.js'; export const tools = [...existingTools, getXxxTool]; export const toolHandlers = { ...existing, get_xxx: handleGetXxx };运行
pnpm exec tsc --noEmit验证类型运行
pnpm build构建
修改工具函数(utils/)
所有 utils 函数遵循纯函数或简单副作用原则:
- 不抛出异常给调用方(返回
null表示失败) - 缓存在进程内(
memCache)或磁盘(file-cache)
构建说明
使用 father 构建工具(与主仓库 @yoka-ui/ui 保持一致)。
# 完整构建(清理 + 编译)
pnpm build
# 开发监听(文件修改后自动重新编译)
pnpm dev构建产物(dist/ 目录):
dist/
├── index.js / index.d.ts # 公共 API 入口
├── server.js / server.d.ts # MCP Server 工厂
├── stdio.js # stdio 入口(可执行 bin)
├── http.js # HTTP 入口(可执行 bin)
├── tools/
│ ├── index.js / index.d.ts
│ ├── get-yoka-document.js
│ ├── get-component-source.js
│ ├── get-component-file-list.js
│ ├── get-yoka-exports.js
│ └── get-stories.js
└── utils/
├── resolve-repo-path.js
├── read-local-file.js
├── list-component-files.js
├── get-exports-table.js
├── fetch-npm-file.js
├── file-cache.js
└── remove-function-body.js为什么选择 father:与主仓库 @yoka-ui/ui 使用相同构建工具,降低维护成本;father 的 bundless 模式保持文件结构不变(与 rslib 的打包模式不同),便于按需导入各子模块。
发布到 npm
发布前检查清单
# 1. 确认 TypeScript 无类型错误
pnpm exec tsc --noEmit
# 2. 构建(prepublishOnly 脚本会自动触发)
pnpm build
# 3. 检查发布内容(确保只包含 dist/、README.md、package.json)
pnpm pack --dry-run
# 4. 检查 bin 文件是否有执行权限(Linux/macOS)
# 注意:father 输出的文件需要确认 shebang 行
head -1 dist/stdio.js # 应为 #!/usr/bin/env node
head -1 dist/http.js # 应为 #!/usr/bin/env node发布到公共 npm
# 登录(若未登录)
npm login
# 发布(public 包)
pnpm publish --access public
# 发布指定 tag(如 beta)
pnpm publish --access public --tag beta发布到私有 npm 仓库(内部 GitLab/Nexus)
# 在 package.json 的 publishConfig 中指定仓库
# "publishConfig": {
# "registry": "http://your-registry.internal/",
# "access": "public"
# }
pnpm publish版本管理
遵循 semver 规范:
# 修复 bug(patch)
pnpm version patch # 1.0.0 → 1.0.1
# 新增 Tool(minor)
pnpm version minor # 1.0.0 → 1.1.0
# 破坏性变更(major,如修改 Tool 名称/参数)
pnpm version major # 1.0.0 → 2.0.0何时需要升版:
patch:修复 bug、优化文档提取逻辑minor:新增 MCP Tool、新增 HTTP 端点、优化数据源策略major:修改已有 Tool 的名称或参数结构(会破坏 AI 客户端的配置)
prepublishOnly 脚本
package.json 中的 "prepublishOnly": "npm run build" 确保每次发布前都会重新构建,避免发布旧产物。
配置参考
环境变量
| 变量名 | 类型 | 说明 |
|--------|------|------|
| YOKA_UI_REPO_PATH | string | yoka-ui 仓库根目录的绝对路径。优先级最高。示例:D:/projects/yoka-ui |
| PORT | string | HTTP 服务监听端口(默认:3001) |
| TZ | string | 时区(默认:Asia/Shanghai) |
HTTP 服务器命令行参数
yoka-ui-mcp-http [options]
--port, -p PORT 监听端口(默认: 3001)
--host, -h HOSTS 监听地址,逗号分隔(默认: ::,即所有 IPv6)
--stateless 无状态模式(每个请求独立,不保持 session)
--timeout, -t MINUTES session 超时时间,分钟(默认: 30)
--help 显示帮助缓存目录
npm CDN fallback 的结果缓存在:
- Windows:
C:\Users\<用户名>\.yoka-ui-mcp\cache\file-content\ - macOS:
~/.yoka-ui-mcp/cache/file-content/ - Linux:
~/.yoka-ui-mcp/cache/file-content/
缓存文件命名规则:将 @yoka-ui/ui@latest/@Docs-yoka/exports.generated.md 中的特殊字符替换为 _ 得到文件名。
项目结构注解
src/utils/resolve-repo-path.ts
核心职责:找到 yoka-ui 仓库根目录的绝对路径。
设计要点:
- 用模块级变量
cachedRepoPath做进程内缓存,避免每次 Tool 调用都重复查找 isValidYokaRepoRoot()通过检查src/index.tsx和@Docs-yoka/目录判断合法性(两个条件都需满足),防止误匹配findRepoRootUpward()最多向上 8 层(足够覆盖ecosystem/yoka-ui-mcp/dist/utils/→yoka-ui/这 4 层 + 余量)
src/utils/read-local-file.ts
核心职责:读取仓库内任意文件,带进程级内存缓存。
设计要点:
Map<string, string>内存缓存:同一进程内同一文件只读取一次磁盘,后续调用直接返回缓存- 使用
existsSync提前检查文件存在性,避免 try/catch 的性能开销 - 缓存无 TTL(进程级,重启即失效),适合 MCP 服务器的使用模式
src/utils/list-component-files.ts
核心职责:从仓库的 src/ 各子目录中定位并递归列出组件文件。
设计要点:
COMPONENT_DIRS定义了 6 个搜索目录,顺序对应组件分类(ui/components/business/creative/layout/Themes)- 组件名匹配使用
toLowerCase()大小写不敏感,方便 AI 不区分大小写地调用 - 过滤
EXCLUDE_DIRS(node_modules、__tests__等)和只包含INCLUDE_EXTS(.ts/.tsx/.less/.css/.json),避免返回无用文件 - 路径统一转换为正斜杠(
/),与 AI 调用时的习惯一致
src/utils/get-exports-table.ts
核心职责:解析 @Docs-yoka/exports.generated.md,提取结构化的导出符号信息。
设计要点:
- 该文件由
pnpm generate:yoka-llms自动生成,格式固定,正则可以精确匹配 - 解析策略:逐行扫描,遇到
### xxx更新分类,遇到|表格行提取反引号内的符号名 - 过滤条件:去除包含
.或/的符号(路径类)、去除重复 - 优先使用"纯符号列表"段落(末尾的逗号分隔列表)——这是最权威的完整列表
- 模块级
cachedTable缓存解析结果,整个进程只解析一次
src/utils/fetch-npm-file.ts
核心职责:从 npm CDN 获取已发布包中的文件(降级兜底)。
设计要点:
- 同时向
unpkg.com和registry.npmmirror.com发请求,用Promise.race取最快响应 - 失败时返回
never(永不 resolve 的 Promise)而非 reject,使 race 能等待另一个源 - 设置 10 秒超时(
AbortSignal.timeout),避免网络问题导致工具长时间无响应 - 结果写入磁盘缓存(
~/.yoka-ui-mcp/cache/),下次请求直接从缓存读取
src/utils/remove-function-body.ts
核心职责:用 AST 分析将 TypeScript 代码中的函数体替换为 { ... }。
设计要点:
- 使用 oxc-parser(Rust 实现,极速)解析 TypeScript/TSX
- 支持 7 种函数节点类型:函数声明、函数表达式、箭头函数、类方法、类属性、对象方法、变量声明中的箭头函数
- 替换顺序:从
bodyStart最大的函数开始(从后往前),避免字符串索引偏移问题 - 跳过嵌套函数体(已经包含在父函数的
{ ... }内的不再替换) - 逻辑直接移植自
semi-mcp/src/utils/remove-function-body.ts,保持一致性
src/server.ts
核心职责:MCP Server 工厂函数,注册所有 handlers,供 stdio 和 HTTP 两种入口共享。
设计要点:
createMCPServer()每次调用创建新的Server实例,支持 HTTP 模式下的多 session 隔离- 版本号从
package.json动态读取,支持生产(dist/server.js → ../package.json)和开发(src/server.ts → ../../package.json)两种路径 - 注册
yoka://componentsresource,让 AI 工具可以发现可用组件(MCP resource 是可订阅的数据,tool 是可调用的函数)
src/stdio.ts
核心职责:stdio 传输入口,适配 Claude Desktop、Claude Code、Cursor 等客户端。
注意:stdio 模式下绝对不能向 stdout 输出任何非 JSON 内容,否则会破坏 JSON-RPC 协议。错误信息只能写入 stderr。
src/http.ts
核心职责:HTTP 传输入口,支持多 session 并发、graceful shutdown。
设计要点:
- 每个 session 独立持有
Server实例和StreamableHTTPServerTransport(session 间完全隔离) - 请求队列(
requestQueue+isProcessing)保证同一 session 内请求串行执行,避免并发竞争 - 30 分钟 session 超时,每分钟清理一次过期 session
- 支持
--stateless模式(无 session,适合无状态代理场景)
src/tools/get-yoka-document.ts
核心职责:从多个数据源合成组件文档,是 AI 助手最常用的工具。
文档合成策略(有 componentName 时):
- SKILL.md 片段:提供 API 说明和 Props 表格(结构化文档)
index.tsx前 120 行:提供精确的 TypeScript 类型定义index.stories.tsx前 80 行:提供真实可运行的代码示例
为什么限制行数:SKILL.md + Props + Stories 三路信息合并后可能很长,限制每路信息量可将总输出控制在 2000 行以内(通常),保护 context window。超过 888 行时触发代码块折叠���
