forgekit故事书mcp
A. 模型上下文协议(MCP)服务器 用于故事书故事生成、组件分析和验证。
自动检测 Next.js、Chakra UI、shadcn/UI、Tamagui和Gluestack UI。适用于任何React项目——无法识别的框架使用vanilla默认值。
______________________________________________________________________
🎉 v1.2的新增功能
▲ Next.js支持——一流
- 自动检测Next.js项目 当
next处于依赖关系中 *和* 一next.config.{js,ts,mjs,cjs}存在于项目根目录。两个信号都必须存在(避免传递错误nextdeps)。 - 脚手架
@storybook/nextjs--官方Storybook框架包——而不是@storybook/react-vite.Stories类型检查与Next.js框架的StorybookConfig,与next/image,next/link,next/font,以及next/navigation开箱即用。 - 生成的故事从导入
@storybook/nextjs—import type { Meta, StoryObj } from '@storybook/nextjs'对于Next.js项目,'@storybook/react'对于其他一切。 - 不再
withRouterNext.js故事中的装饰器 —@storybook/nextjs船舶内置模拟next/navigation/next/router有线直通parameters.nextjs.appDirectory: true在生成preview.tsx. - UI库+Next.js组合正确 --Next.js+Chakra仍然会发出 `
室内装饰师preview.tsx`Next.js赢得了框架包的决定,但UI库仍然驱动着提供者。 - 新
isNextjs场上storybook-mcp.config.json(仅在以下情况下持续存在true). - 新
validator.ts接受@storybook/react,@storybook/react-vite, 和@storybook/nextjs作为有效的Meta/StoryObj导入源。
🛠 设置检修
- 检测到的故事书版本受到尊重 —
runSetup现在读取已安装的storybook版本(从node_modules首先,回到package.json声明的范围)和引脚全部@storybook/*精确到这个范围。较旧的v9及以下安装会发出升级notice而不是默默地降级。 @nx/storybook对等依赖检测 --当没有直接安装时,会回退到Nx插件声明的Storybook版本。- 更严格的检测合同 --出口
detectInstalledStorybookVersion(),detectNxStorybookVersion(),以及detectNextjs()对于程序化消费者。 addons明确地发出 —@storybook/addon-docs和@storybook/addon-a11y现在显示在main.ts对于v10(基本要素/交互仍然捆绑在主storybook包装)。- shadcn检测撒下了更宽的网 --比赛开始
components.json,任何@radix-ui/*,@base-ui-components/react,class-variance-authority,tailwindcss, *或*lucide-react. - 单一事实来源 —
cli.ts和setup.ts不再重复框架检测;cli.ts现在进口自setup.ts.
✅ 同步是最终任务
sync_all仍然是扫描、生成和充值的协调器。缺乏交互测试的现有故事是 *非破坏性* 增强appendMissingGeneratedStories--您的自定义导出将保留,缺少模板导出(变体、尺寸、, 互动游戏故事)附。
🐛 修复
- TypeScript不再出错
NON_COMPONENT_FILES.includes(...)--theas const数组的窄类型拒绝任意字符串。
升级? 跑 npm install forgekit-storybook-mcp@latest 和 npx forgekit-storybook-mcp --setup --force 刷新 .storybook/main.ts 如果你想选择加入Next.js框架包。对现有的非Next.js设置没有突破性的更改。看 更新日志 了解全部细节。
______________________________________________________________________
目录
______________________________________________________________________
快速开始
# 1. Install the package
npm install forgekit-storybook-mcp
# 2. Create storybook-mcp.config.json in your project root (see Configuration)
# 3. Add to your MCP client (see MCP Client Setup below)______________________________________________________________________
先决条件
安装之前,请确保您的项目已设置Storybook及其核心依赖项。
故事书
如果你还没有故事书:
npx storybook@latest init这个脚手架 .storybook/ config目录,安装核心包,并添加示例故事。 需要故事书10.2+。 不支持早期版本。
所需套餐
node≥ 20react≥ 18react-dom≥ 18storybook≥ 10.2@storybook/react≥ 10.2@storybook/react-vite≥10.2(或@storybook/react-webpack5如果使用Webpack)
安装核心故事书包:
npm i -D storybook@^10.2.0 @storybook/react@^10.2.0 @storybook/react-vite@^10.2.0推荐插件
安装这些插件后,一些模板和功能效果最佳:
| 插件 | 使用人 | 安装 |
|---|---|---|
storybook/test | 交互式模板、播放功能 | 随附 storybook@10+ |
@storybook/addon-vitest | 测试(Vite项目) | npm i -D @storybook/addon-vitest |
@storybook/addon-a11y | 无障碍故事生成 | npm i -D @storybook/addon-a11y |
msw + msw-storybook-addon | with-msw 模板 | npm i -D msw msw-storybook-addon |
@storybook/addon-interactions | 交互测试面板 | npm i -D @storybook/addon-interactions |
您不需要预先了解所有这些内容——MCP可以在没有它们的情况下工作,并在模板需要缺少依赖关系时建议安装什么。
______________________________________________________________________
主要功能:启动时自动同步
当MCP服务器启动时,它会自动:
- 扫描 已配置库中的所有组件
- 创造 缺少故事、测试和MDX文档
- 更新 组件更改时的现有文件
- 缓存 用于高效变化检测的组件哈希
这意味着您的故事书文档会自动与您的组件保持同步。
______________________________________________________________________
安装
npm install forgekit-storybook-mcp
# or
pnpm add forgekit-storybook-mcp
# or
yarn add forgekit-storybook-mcp______________________________________________________________________
配置
按优先级顺序,您有三个配置选项:
选项1:配置文件(推荐)
创建 storybook-mcp.config.json 在项目根目录中:
{
"framework": "chakra",
"libraries": [
{
"name": "ui",
"path": "libs/ui/src",
"storyTitlePrefix": "UI",
"importAlias": "@ui"
},
{
"name": "shared",
"path": "libs/shared/src",
"storyTitlePrefix": "Shared",
"decorators": ["withRouter"]
}
],
"storyFilePattern": "**/*.stories.{ts,tsx}",
"componentPatterns": [
"**/src/**/*.tsx",
"!**/*.stories.tsx",
"!**/*.test.tsx"
],
"excludePatterns": ["**/node_modules/**", "**/dist/**"]
}选项2:package.json
添加一个 storybook-mcp 字段到您的 package.json:
{
"name": "my-app",
"storybook-mcp": {
"framework": "shadcn",
"libraries": [
{
"name": "components",
"path": "src/components",
"storyTitlePrefix": "Components"
}
]
}
}选项3:自动检测
如果没有找到配置,MCP将自动检测:
- 组件目录:
src/components,libs/ui/src,packages/ui/src等等。 - 框架:从您的
package.json依赖关系(脉轮、shadcn、Tamagui、Gluestack)
配置参考
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
rootDir | string | 自动检测到 | 项目根目录 |
framework | string | 'vanilla' | UI框架: 'chakra', 'shadcn', 'tamagui', 'gluestack', 'vanilla' |
libraries | array | [] | 组件库位置(见下文) |
storyFilePattern | string | '**/*.stories.{ts,tsx}' | 故事文件的球形图案 |
componentPatterns | string[] | ['**/src/**/*.tsx', '!**/*.stories.tsx', '!**/*.test.tsx'] | 组件文件的球形图案 |
excludePatterns | string[] | ['**/node_modules/**', '**/dist/**'] | 要排除的目录 |
templatesDir | string | - | 自定义模板目录 |
storybookVersion | number | 10 | 故事书版本(要求10+) |
库配置
每个图书馆 libraries 阵列支持:
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
name | string | ✅ | 用于筛选的库标识符 |
path | string | ✅ | 相对于的路径 rootDir |
storyTitlePrefix | string | ✅ | 故事书标题的前缀(例如。, "UI" → "UI/Button") |
decorators | string[] | - | 应用于所有故事的默认装饰器 |
importAlias | string | - | 导入路径别名(例如。, "@ui") |
______________________________________________________________________
CLI标志
# Run with auto-sync (default behavior)
npx forgekit-storybook-mcp
# Skip auto-sync on startup - useful when you just want the MCP tools
npx forgekit-storybook-mcp --skip-init
# Preview what would be synced without writing any files
npx forgekit-storybook-mcp --dry-run
# Only run sync, then exit (useful for CI pipelines)
npx forgekit-storybook-mcp --init-only
# Disable specific generators during sync
npx forgekit-storybook-mcp --no-stories # Don't generate story files
npx forgekit-storybook-mcp --no-tests # Don't generate test files
npx forgekit-storybook-mcp --no-docs # Don't generate MDX docs
# Only create missing files, don't update existing ones
npx forgekit-storybook-mcp --no-update
# Force overwrite existing story/test/doc files
npx forgekit-storybook-mcp --force
# Only sync a specific library (must match library.name in config)
npx forgekit-storybook-mcp --lib=ui
# Run interactive setup wizard (creates storybook-mcp.config.json)
npx forgekit-storybook-mcp --setup组合标志
# CI pipeline: sync stories only, exit when done
npx forgekit-storybook-mcp --init-only --no-tests --no-docs
# Development: skip sync, just run the MCP server
npx forgekit-storybook-mcp --skip-init
# Preview: see what would change without modifying files
npx forgekit-storybook-mcp --dry-run --no-update
# Force-regenerate only the ui library, then exit
npx forgekit-storybook-mcp --init-only --force --lib=ui______________________________________________________________________
MCP客户端设置
光标/VS代码
添加 .cursor/mcp.json (或 .vscode/mcp.json):
{
"mcpServers": {
"forgekit-storybook": {
"command": "npx",
"args": ["forgekit-storybook-mcp"]
}
}
}使用CLI标志:
{
"mcpServers": {
"forgekit-storybook": {
"command": "npx",
"args": ["forgekit-storybook-mcp", "--skip-init"]
}
}
}如果在本地安装(启动速度更快):
{
"mcpServers": {
"forgekit-storybook": {
"command": "node",
"args": ["node_modules/forgekit-storybook-mcp/dist/cli.js"]
}
}
}克劳德桌面版
添加 claude_desktop_config.json:
{
"mcpServers": {
"forgekit-storybook": {
"command": "npx",
"args": ["forgekit-storybook-mcp"],
"cwd": "/path/to/your/project"
}
}
}______________________________________________________________________
工具参考
| 工具 | 说明 |
|---|---|
list_components | 列出所有React组件,按库或故事状态过滤 |
analyze_component | 提取道具、依赖关系,并获取故事建议 |
generate_story | 生成包含变体和测试的完整故事文件 |
update_story | 在保留自定义导出的同时重新生成故事 |
generate_test | 生成Vitest或Playwright测试文件 |
generate_docs | 生成MDX文档 |
generate_code_connect | 生成Figma代码连接 .figma.tsx 文件 |
validate_story | 查看故事以了解最佳实践和问题 |
sync_all | 一次同步所有组件 |
sync_component | 同步单个组件的故事/测试/文档 |
get_story_template | 获取特定模板 |
list_templates | 列出所有可用模板 |
get_component_coverage | 获取故事报道统计数据 |
suggest_stories | 获取需要故事的组件的优先级列表 |
check_health | 检查故事书安装状况 |
______________________________________________________________________
list_components
列出已配置库中的所有React组件。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
library | string | - | all | 按库名称筛选 |
hasStory | boolean | - | all | 按故事状态筛选: true =只有故事, false =只有没有 |
示例:
// List ALL components across all libraries
{}
// List only components in the "ui" library
{
"library": "ui"
}
// List components that DON'T have stories yet
{
"hasStory": false
}
// List components in "shared" library that need stories
{
"library": "shared",
"hasStory": false
}答复:
{
"components": [
{
"name": "Button",
"filePath": "libs/ui/src/button/button.tsx",
"library": "ui",
"hasStory": false,
"exportType": "named"
},
{
"name": "Card",
"filePath": "libs/ui/src/card/card.tsx",
"library": "ui",
"hasStory": true,
"storyPath": "libs/ui/src/card/card.stories.tsx",
"exportType": "default"
}
],
"total": 2,
"withStories": 1,
"withoutStories": 1,
"summary": "Found 2 components: 1 with stories, 1 without stories"
}______________________________________________________________________
analyze_component
分析React组件以提取其结构、道具和依赖关系。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
componentPath | string | ✅ | 组件文件的路径 |
例子:
{
"componentPath": "libs/ui/src/button/button.tsx"
}答复:
{
"analysis": {
"name": "Button",
"filePath": "libs/ui/src/button/button.tsx",
"library": "ui",
"hasStory": false,
"exportType": "named",
"props": [
{
"name": "variant",
"type": "'solid' | 'outline' | 'ghost'",
"required": false,
"defaultValue": "'solid'",
"description": "Visual style variant",
"controlType": "select",
"controlOptions": ["solid", "outline", "ghost"]
},
{
"name": "size",
"type": "'sm' | 'md' | 'lg'",
"required": false,
"defaultValue": "'md'",
"controlType": "select",
"controlOptions": ["sm", "md", "lg"]
},
{
"name": "disabled",
"type": "boolean",
"required": false,
"defaultValue": "false",
"controlType": "boolean"
},
{
"name": "children",
"type": "ReactNode",
"required": true,
"controlType": "text"
}
],
"dependencies": {
"usesRouter": false,
"usesReactQuery": false,
"usesChakra": true,
"usesGluestack": false,
"usesReactNative": false,
"usesEmotion": false,
"usesTailwind": false,
"usesFramerMotion": true,
"usesMSW": false,
"usesGlobalState": false,
"otherImports": ["@chakra-ui/react", "framer-motion"]
},
"suggestions": [
"Use 'with-variants' template to showcase all size/variant combinations",
"Add Framer Motion decorator for animation testing",
"Consider adding interactive tests for click/focus states"
],
"sourcePreview": "export const Button = ({ variant = 'solid', size = 'md', ... }) => { ... }"
},
"summary": "Analyzed Button: 4 props, no story",
"recommendations": [
"Use 'with-variants' template to showcase all size/variant combinations",
"Add Framer Motion decorator for animation testing"
]
}______________________________________________________________________
generate_story
为组件生成故事书故事文件。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
componentPath | string | ✅ | - | 组件文件的路径 |
includeVariants | boolean | - | true | 添加展示所有尺寸/变体组合的故事 |
includeInteractive | boolean | - | true | 为用户交互添加播放功能测试 |
includeA11y | boolean | - | false | 添加可访问性测试故事 |
includeResponsive | boolean | - | false | 添加移动/平板/桌面视口故事 |
template | string | - | auto | 要使用的模板(请参阅 模板) |
overwrite | boolean | - | false | 替换现有故事文件 |
dryRun | boolean | - | false | 预览而不写入磁盘 |
示例:
// Basic: generate with defaults (variants + interactive)
{
"componentPath": "libs/ui/src/button/button.tsx"
}
// Minimal: just the basic story, no extras
{
"componentPath": "libs/ui/src/button/button.tsx",
"includeVariants": false,
"includeInteractive": false
}
// Full coverage: everything including a11y and responsive
{
"componentPath": "libs/ui/src/button/button.tsx",
"includeVariants": true,
"includeInteractive": true,
"includeA11y": true,
"includeResponsive": true
}
// Use a specific template
{
"componentPath": "libs/ui/src/user-list/user-list.tsx",
"template": "with-msw"
}
// Preview what would be generated
{
"componentPath": "libs/ui/src/button/button.tsx",
"dryRun": true
}
// Replace an existing story
{
"componentPath": "libs/ui/src/button/button.tsx",
"overwrite": true
}答复:
{
"story": {
"content": "import type { Meta, StoryObj } from '@storybook/react'\nimport { Button } from './Button'\n\nconst meta: Meta = {\n title: 'Components/Button',\n component: Button,\n tags: [],\n ...\n}\n\nexport default meta\ntype Story = StoryObj\n\nexport const Default: Story = { ... }\nexport const Sizes: Story = { ... }\nexport const Variants: Story = { ... }",
"filePath": "libs/ui/src/button/button.stories.tsx",
"imports": ["@storybook/react", "./Button"],
"stories": ["Default", "Sizes", "Variants", "ClickTest"],
"warnings": []
},
"written": true,
"path": "libs/ui/src/button/button.stories.tsx",
"summary": "Created story at libs/ui/src/button/button.stories.tsx"
}______________________________________________________________________
generate_test
为组件生成测试文件。默认情况下使用vitest+@测试库。仅在以下情况下使用剧作家 @playwright/test 位于项目的依赖项中。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
componentPath | string | ✅ | - | 组件文件的路径 |
overwrite | boolean | - | false | 替换现有测试文件 |
dryRun | boolean | - | false | 预览而不写入磁盘 |
示例:
// Generate test for a component
{
"componentPath": "libs/ui/src/button/button.tsx"
}
// Preview without writing
{
"componentPath": "libs/ui/src/button/button.tsx",
"dryRun": true
}
// Replace existing test
{
"componentPath": "libs/ui/src/button/button.tsx",
"overwrite": true
}答复:
{
"test": {
"content": "import { describe, it, expect } from 'vitest'\nimport { render, screen } from '@testing-library/react'\nimport { Button } from './Button'\n\ndescribe('Button', () => {\n it('renders correctly', () => {\n render(Click me)\n expect(screen.getByText('Click me')).toBeInTheDocument()\n })\n})\n...",
"filePath": "libs/ui/src/button/button.test.tsx"
},
"written": true,
"path": "libs/ui/src/button/button.test.tsx",
"summary": "Created test at libs/ui/src/button/button.test.tsx"
}______________________________________________________________________
generate_docs
为组件生成MDX文档。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
componentPath | string | ✅ | - | 组件文件的路径 |
overwrite | boolean | - | false | 替换现有文档文件 |
dryRun | boolean | - | false | 预览而不写入磁盘 |
示例:
// Generate docs for a component
{
"componentPath": "libs/ui/src/button/button.tsx"
}
// Preview without writing
{
"componentPath": "libs/ui/src/button/button.tsx",
"dryRun": true
}答复:
{
"docs": {
"content": "import { Canvas, Meta, ArgTypes } from '@storybook/blocks'\nimport * as ButtonStories from './Button.stories'\n\n\n\n# Button\n\n## Usage\n\n\n\n## Props\n\n\n...",
"filePath": "libs/ui/src/button/button.mdx"
},
"written": true,
"path": "libs/ui/src/button/button.mdx",
"summary": "Created docs at libs/ui/src/button/button.mdx"
}______________________________________________________________________
validate_story
验证现有的故事文件以了解最佳实践和问题。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
storyPath | string | ✅ | 故事文件的路径 |
例子:
{
"storyPath": "libs/ui/src/button/button.stories.tsx"
}答复:
{
"validation": {
"valid": false,
"score": 72,
"errors": [
{
"type": "error",
"code": "MISSING_META_TITLE",
"message": "Story is missing a title in meta",
"line": 5,
"fix": "Add 'title' property to meta object"
}
],
"warnings": [],
"suggestions": [
{
"type": "suggestion",
"code": "ADD_PLAY_FUNCTION",
"message": "Consider adding interaction tests with play functions",
"fix": "Add a story with a play function for testing user interactions"
}
]
},
"summary": "Story has 1 errors (score: 72/100)"
}______________________________________________________________________
sync_all
同步所有组件-创建缺失的故事/测试/文档并更新更改的内容。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
library | string | - | all | 仅同步此库中的组件 |
generateStories | boolean | - | true | 生成故事文件 |
generateTests | boolean | - | true | 生成测试文件 |
generateDocs | boolean | - | true | 生成MDX文档 |
updateExisting | boolean | - | true | 组件更改时更新文件 |
dryRun | boolean | - | false | 预览而不写入磁盘 |
示例:
// Sync everything with defaults
{}
// Sync only the "ui" library
{
"library": "ui"
}
// Only generate stories, no tests or docs
{
"generateStories": true,
"generateTests": false,
"generateDocs": false
}
// Only create missing files, don't update existing
{
"updateExisting": false
}
// Preview what would change
{
"dryRun": true
}
// Sync only stories for "shared" library, don't update existing
{
"library": "shared",
"generateStories": true,
"generateTests": false,
"generateDocs": false,
"updateExisting": false
}答复:
{
"scanned": 24,
"created": {
"stories": 8,
"tests": 8,
"docs": 8
},
"updated": {
"stories": 3,
"tests": 2,
"docs": 3
},
"skipped": 0,
"errors": [],
"summary": "Synced 24 components: Created 8 stories, 8 tests, 8 docs. Updated 8 files."
}______________________________________________________________________
sync_component
同步单个组件的故事、测试和文档。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
componentPath | string | ✅ | - | 组件文件的路径 |
generateStories | boolean | - | true | 生成故事文件 |
generateTests | boolean | - | true | 生成测试文件 |
generateDocs | boolean | - | true | 生成MDX文档 |
dryRun | boolean | - | false | 预览而不写入磁盘 |
示例:
// Sync everything for one component
{
"componentPath": "libs/ui/src/button/button.tsx"
}
// Only sync the story, not tests or docs
{
"componentPath": "libs/ui/src/button/button.tsx",
"generateStories": true,
"generateTests": false,
"generateDocs": false
}
// Preview what would change
{
"componentPath": "libs/ui/src/button/button.tsx",
"dryRun": true
}答复:
{
"result": {
"component": "Button",
"story": {
"action": "created",
"path": "libs/ui/src/button/button.stories.tsx"
},
"test": {
"action": "created",
"path": "libs/ui/src/button/button.test.tsx"
},
"docs": {
"action": "skipped",
"path": "libs/ui/src/button/button.mdx",
"reason": "Already exists and unchanged"
}
},
"summary": "Button: story: created, test: created"
}______________________________________________________________________
get_story_template
按名称获取特定模板。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
template | string | ✅ | 模板名称(请参见 模板) |
例子:
{
"template": "with-msw"
}答复:
{
"template": {
"name": "with-msw",
"description": "Story with MSW API mocking",
"useCase": "Components that fetch data and need mocked API responses",
"content": "import type { Meta, StoryObj } from '@storybook/react'\nimport { http, HttpResponse } from 'msw'\nimport { {{ComponentName}} } from './{{ComponentName}}'\n\nconst meta: Meta = {\n title: 'Components/{{ComponentName}}',\n component: {{ComponentName}},\n tags: [],\n}\n\nexport default meta\ntype Story = StoryObj\n\nexport const Default: Story = {\n parameters: {\n msw: {\n handlers: [\n http.get('/api/data', () => {\n return HttpResponse.json({\n items: [\n { id: 1, name: 'Item 1' },\n ],\n })\n }),\n ],\n },\n },\n}\n...",
"placeholders": ["ComponentName", "component-name"]
},
"usage": "Replace placeholders: ComponentName, component-name"
}______________________________________________________________________
list_templates
列出所有可用的故事模板。
参数: 无
例子:
{}答复:
{
"templates": [
{
"name": "basic",
"description": "Simple story with basic args",
"useCase": "Quick component documentation with minimal setup",
"available": true
},
{
"name": "with-controls",
"description": "Story with full argTypes controls",
"useCase": "Interactive component exploration with all props exposed",
"available": true
},
{
"name": "with-variants",
"description": "Story showcasing all variants and sizes",
"useCase": "Design system documentation showing all visual options",
"available": true
}
],
"count": 8
}______________________________________________________________________
get_component_coverage
获取项目的故事报道统计数据。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
library | string | - | all | 按库名称筛选 |
示例:
// Coverage for entire project
{}
// Coverage for "ui" library only
{
"library": "ui"
}答复:
{
"total": 24,
"withStories": 16,
"withoutStories": 8,
"coverage": "67%",
"byLibrary": {
"ui": {
"total": 15,
"withStories": 12
},
"shared": {
"total": 9,
"withStories": 4
}
},
"componentsNeedingStories": [
{
"name": "Tooltip",
"path": "libs/ui/src/tooltip/tooltip.tsx",
"library": "ui"
},
{
"name": "DataTable",
"path": "libs/shared/src/data-table/data-table.tsx",
"library": "shared"
}
]
}______________________________________________________________________
suggest_stories
获取需要故事的组件的优先级列表。
参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
limit | number | - | 10 | 建议的最大数量 |
library | string | - | all | 按库名称筛选 |
示例:
// Get top 10 suggestions
{}
// Get top 5 suggestions from "ui" library
{
"limit": 5,
"library": "ui"
}答复:
{
"suggestions": [
{
"component": "Button",
"path": "libs/ui/src/button/button.tsx",
"library": "ui",
"command": "generate_story with componentPath: \"libs/ui/src/button/button.tsx\""
},
{
"component": "Card",
"path": "libs/ui/src/card/card.tsx",
"library": "ui",
"command": "generate_story with componentPath: \"libs/ui/src/card/card.tsx\""
}
],
"total": 8,
"showing": 2,
"summary": "8 components without stories. Showing top 2."
}______________________________________________________________________
check_health
检查Storybook安装健康状况——缺少包、过时的配置和版本不匹配。可用于诊断安装问题,特别是在迁移到Storybook 10时。
参数: 无
例子:
{}答复:
{
"passed": false,
"checks": [
{ "name": "package:storybook", "status": "pass", "message": "storybook is installed" },
{ "name": "config:main:addon:@storybook/addon-essentials", "status": "warn", "message": "@storybook/addon-essentials is bundled into storybook in v10 — can be removed from addons list", "fix": "Remove '@storybook/addon-essentials' from addons array in .storybook/main" }
],
"installCommands": [],
"summary": "Preflight: 1 warning(s) out of 8 checks"
}______________________________________________________________________
update_story
使用最新的组件分析重新生成故事文件,同时保留您手写的任何导出。
不像 generate_story 随着 overwrite: true (这会破坏一切), update_story 检测哪个 export const X: Story 您添加的块,并将其附加到重新生成的内容下方,用注释标记分隔。
参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
componentPath | string | 必需 | 组件文件的路径 |
includeVariants | 布尔值 | true | 重新生成变体故事 |
includeInteractive | 布尔值 | true | 重新生成播放功能测试 |
includeA11y | 布尔值 | false | 重新生成可访问性故事 |
includeResponsive | 布尔值 | false | 重新生成视口故事 |
template | string | auto | 要使用的特定模板 |
dryRun | 布尔值 | false | 预览合并结果而不写入 |
例子:
{
"componentPath": "src/components/Button.tsx"
}答复包括:
preserved--保留的用户编写的故事名称数组removed--不在合并输出中的故事(通常为空)validation.warnings--非阻塞导入警告summary--保存故事列表的人类可读结果
它是如何工作的:
该工具寻找 export const X: Story 不在新生成内容中的块。这些是你的定制故事。它们被附加在分隔符之后:
// ─── User-added stories (preserved by update_story) ───
export const MyEdgeCase: Story = {
args: { label: 'Edge case' },
}注: 版本条目记录在.forgekit/story-history.json每次写作(动作:merged).
______________________________________________________________________
generate_code_connect
生成一个 @figma/code-connect .figma.tsx 将您的组件链接到Figma开发模式的文件。
当与一起发布时 npx figma connect publish在Figma中检查组件的设计师可以看到真实的React代码——道具、变体和使用示例——而不是自动生成的代码片段。
参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
componentPath | string | 必需 | 组件文件的路径 |
figmaNodeUrl | string | -- | Figma组件URL(https://figma.com/design//...?node-id=...).省略使用占位符。 |
overwrite | 布尔值 | false | 替换现有 .figma.tsx 文件 |
dryRun | 布尔值 | false | 无需写入即可预览输出 |
例子:
{
"componentPath": "src/components/Button.tsx",
"figmaNodeUrl": "https://figma.com/design/abc123/MyDesignSystem?node-id=1%3A2"
}道具类型映射:
| TypeScript类型 | Figma绑定 | |
|---|---|---|
string | figma.string('PropName') | |
boolean | figma.boolean('PropName') | |
| `'a' \ | 'b'` 工会 | figma.enum('PropName', { a: 'a', b: 'b' }) |
ReactNode / children | figma.children(['*']) | |
number | figma.number('PropName') |
事件处理程序, className, style,以及 ref 自动排除。
生成的输出 (src/components/Button.figma.tsx):
import figma from '@figma/code-connect/react'
import { Button } from './Button'
figma.connect(Button, 'https://figma.com/design/abc123/MyDesignSystem?node-id=1%3A2', {
props: {
variant: figma.enum('Variant', {
"primary": "primary",
"secondary": "secondary",
"ghost": "ghost",
}),
disabled: figma.boolean('Disabled'),
children: figma.children(['*']),
},
example: ({ variant, disabled, children }) => (
{children}
),
})发表给Figma:
npm install --save-dev @figma/code-connect
npx figma connect login
npx figma connect publish看 Figma集成 完整的工作流程。
______________________________________________________________________
Figma集成
该项目支持两个互补的Figma集成:
代码连接——将组件链接到Figma开发模式
Figma代码连接 将真实的React组件附加到Figma组件。Dev模式下的设计师看到的是实际的道具、变体和工作代码示例,而不是占位符片段。
工作流程:
- 为每个组件生成一个代码连接文件:
{
"componentPath": "src/components/Button.tsx",
"figmaNodeUrl": "https://figma.com/design/abc123/MyDesignSystem?node-id=1%3A2"
}- 安装并发布:
npm install --save-dev @figma/code-connect
npx figma connect login
npx figma connect publish- 打开Figma中的组件→ 开发模式→ 代码面板。将显示您的组件代码。
提示: 通过右键单击画布上的组件复制Figma节点URL→ “复制链接”。
Canvas代码——将故事渲染推送到Figma(通过 forgekit-context)
这 sync_stories_to_figma 工具(部分 forgekit-context)连接到Figma桌面应用程序的Dev Mode MCP服务器,并将每个组件的默认故事作为可编辑的框架推送到画布上。
要求:
- Figma桌面应用程序(非浏览器)
- 启用开发模式MCP服务器: Figma菜单→ 偏好→ 启用开发者模式MCP服务器
forgekit-context已安装并正在运行- 本地故事书运行(
npm run storybook)
示例呼叫方式 forgekit-context:
{
"storybookUrl": "http://localhost:6006",
"dryRun": true
}移除 dryRun 把故事推到画布上。
______________________________________________________________________
模板
模板是为不同用例预先构建的故事结构。使用它们与 template 参数在 generate_story.
| 模板 | 用例 | 示例 |
|---|---|---|
basic | 快速的文档记录,最少的设置 | 简单的演示组件 |
with-controls | 与所有道具互动探索 | 设计系统组件 |
with-variants | 展示所有尺寸/变体 | 按钮、徽章、头像 |
with-msw | 获取数据的组件 | 用户列表、仪表板 |
with-router | 使用React Router的组件 | 导航,面包屑 |
page | 全页面组件 | 登录页面、仪表板 |
interactive | 具有用户交互功能的组件 | 窗体、模态、下拉菜单 |
form | 具有验证功能的表单组件 | 登录表单、设置面板 |
模板示例
basic -最小设置:
import type { Meta, StoryObj } from '@storybook/react'
import { Button } from './Button'
const meta: Meta = {
title: 'Components/Button',
component: Button,
tags: [],
}
export default meta
type Story = StoryObj
export const Default: Story = {
args: {
children: 'Button content',
},
}with-variants -展示所有组合:
export const Sizes: Story = {
render: () => (
Small
Medium
Large
),
}
export const AllVariants: Story = {
render: () => (
{(['solid', 'outline', 'ghost'] as const).map((variant) => (
Small
Medium
Large
))}
),
}with-msw -模拟API响应:
import { http, HttpResponse } from 'msw'
export const Default: Story = {
parameters: {
msw: {
handlers: [
http.get('/api/users', () => {
return HttpResponse.json({
users: [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
],
})
}),
],
},
},
}
export const Loading: Story = {
parameters: {
msw: {
handlers: [
http.get('/api/users', async () => {
await new Promise((r) => setTimeout(r, 5000))
return HttpResponse.json({})
}),
],
},
},
}
export const Error: Story = {
parameters: {
msw: {
handlers: [
http.get('/api/users', () => {
return HttpResponse.json({ error: 'Failed' }, { status: 500 })
}),
],
},
},
}interactive -播放功能测试:
import { expect, userEvent, within } from 'storybook/test'
export const ClickTest: Story = {
args: { children: 'Click me' },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement)
const button = canvas.getByText(/click me/i)
await expect(button).toBeInTheDocument()
await userEvent.click(button)
// Add assertions for post-click state
},
}
export const KeyboardNavigation: Story = {
args: { children: 'Focus me' },
play: async ({ canvasElement }) => {
const canvas = within(canvasElement)
const button = canvas.getByText(/focus me/i)
await userEvent.tab()
await expect(button).toHaveFocus()
await userEvent.keyboard('{Enter}')
},
}______________________________________________________________________
资源
MCP提供以下只读资源:
| 资源URI | 描述 |
|---|---|
storybook://libraries | 已配置的库信息 |
storybook://patterns | 常见的故事模式和最佳实践 |
storybook://config | 当前MCP配置 |
______________________________________________________________________
程序化使用
您还可以通过编程方式使用MCP服务器:
import { createStorybookMCPServer } from 'forgekit-storybook-mcp'
const server = createStorybookMCPServer({
rootDir: process.cwd(),
framework: 'chakra',
libraries: [
{
name: 'ui',
path: 'src/components',
storyTitlePrefix: 'UI',
importAlias: '@ui',
},
],
storybookVersion: 10,
})
// Server is now ready to handle MCP requests______________________________________________________________________
路线图
看 ROADMAP.md 接下来是什么——迁移助手、观察模式、Figma集成等等。
______________________________________________________________________
相关项目
- 福吉特·费马mcp --Figma设计代币→ 脉轮/顺风/沙纹同步MCP
- @故事书/插件mcp -官方故事书MCP(阅读故事)
本MCP侧重于 生成 故事,而官方的重点是 阅读 现有故事书数据。它们相辅相成。
______________________________________________________________________
许可证
麻省理工学院
