首页
/ Storybook MCP Addon 详解:把 MCP 服务器挂进 Storybook 开发服务器,让 AI Agent 写 Story、跑测试

Storybook MCP Addon 详解:把 MCP 服务器挂进 Storybook 开发服务器,让 AI Agent 写 Story、跑测试

2026-09-06 13:09:08作者:柏廷章Berta

本文基于 Storybook 仓库中的 @storybook/addon-mcp 官方 README(code/addons/mcp/README.md)及其配套源码展开,介绍如何将一个 MCP(Model Context Protocol)服务器直接挂载到 Storybook 开发服务器上,并通过 endpointtoolsets 两个选项完成配置。读完本文,你能掌握该 Addon 的注册与配置方式、MCP 端点在源码中的注册链路、三组工具集(dev / docs / test)的启用条件,以及浏览器状态页与组合(Composition)鉴权等进阶机制。

Storybook MCP Addon 与 Claude Code 协作的演示

1. Addon 定位:让 Agent 自动编写并测试 UI 组件的 Story

README 第一句给出了 Addon 的定位:"Storybook addon for MCP-powered UI development workflows"(code/addons/mcp/README.md)。配合 code/addons/mcp/package.json 中的描述可以看得更完整:

{
  "name": "@storybook/addon-mcp",
  "version": "10.6.0-beta.1",
  "description": "Help agents automatically write and test stories for your UI components",
  "keywords": ["ai", "mcp", "storybook-addon"],
  "mcpName": "io.github.storybookjs/addon-mcp"
}

也就是说,这个 Addon 的价值在于:Storybook 开发服务器运行起来后,AI Agent(Claude Code、OpenAI Codex、Cursor、Gemini CLI 等任意支持 MCP 的客户端)可以把自己的"眼睛和手"接到你的组件库上——读取组件文档清单(manifests)、生成 Story、预览 Story、运行组件测试与可访问性检查,并在发现问题后自我修复,形成一个闭环工作流。

从依赖关系看,该 Addon 的技术栈很聚焦(code/addons/mcp/package.json):

  • tmcp@tmcp/transport-http@tmcp/adapter-valibot:MCP 服务器框架、HTTP 传输层与基于 valibot 的参数校验;
  • valibot:运行时配置/入参校验;
  • peer 依赖 storybook 与可选的 @storybook/addon-vitest(后者为 test 工具集提供测试能力)。

package.json 中同时声明了支持的框架清单(storybook.supportedFrameworks):react、vue3、angular、web-components、html、svelte、preact、react-native——MCP 服务器本体不依赖特定框架,框架只影响部分工具集的可用性(见第 5 节)。

2. 配置一:endpoint——自定义 MCP 端点路径

这是 README 中给出的唯一可配置项的核心示例,必须完整掌握。默认情况下,Addon 把 MCP 服务器暴露在 /mcp 路径上;你可以在 .storybook/main.ts 中通过 addon 的 options 指定另一个字面量端点路径:

// .storybook/main.ts
export default {
	addons: [
		{
			name: '@storybook/addon-mcp',
			options: {
				endpoint: '/custom-mcp',
			},
		},
	],
};

README 同时强调了一个约束:endpoint 必须是一个 URL pathname,例如 /custom-mcp/tools/mcp,不能是完整的带协议的 URL。

这一约束不是文档口头约定,而是源码中的运行时校验。在 code/addons/mcp/src/types.ts 中:

const isLiteralEndpointPathname = (endpoint: string) => {
  try {
    const { pathname } = new URL(endpoint, 'http://storybook.local');
    return pathname === endpoint && pathname !== '/';
  } catch {
    return false;
  }
};

export const AddonOptions = v.object({
  endpoint: v.optional(
    v.pipe(
      v.string(),
      v.check(isLiteralEndpointPathname, 'Endpoint must be a literal URL pathname')
    )
  ),
  // ...
});

校验逻辑用 new URL(endpoint, 'http://storybook.local') 把输入解析后取 pathname,要求解析结果与原字符串完全一致且不等于 /——这能同时排除完整 URL(pathname 会丢失协议前缀)、相对路径和非法字符。若配置不合法,presets 解析阶段会直接抛出 ValiError

默认值定义在 code/addons/mcp/src/constants.ts

export const DEFAULT_MCP_ENDPOINT = '/mcp';

源码注释明确提醒:所有需要比较或回退到默认端点的地方都应导入这个常量,而不是硬编码 '/mcp'。在 code/addons/mcp/src/preset.ts 中可以看到其使用方式:

const origin = `http://localhost:${options.port}`;
const endpoint = addonOptions.endpoint ?? DEFAULT_MCP_ENDPOINT;

另外,constants.ts 还定义了一个协议级细节:请求头 X-Storybook-MCP-ProxySTORYBOOK_MCP_PROXY_HEADER)。Storybook 自带的 CLI(以及基于它构建的 Claude/Codex 插件)会在每次 MCP 请求上携带该头,标记自己为受信任的本地客户端——例如 review-create 工具对 CLI 客户端会默认放行,而对直接连接 MCP 的第三方客户端则要求显式开启特性开关。

3. 配置二:toolsets——按组开关工具集

README 之外,AddonOptions 还有第二个选项 toolsets,用于按工具集粒度开关 MCP 服务器的工具(定义见 code/addons/mcp/src/types.ts):

toolsets: v.optional(
  v.object({
    dev: v.exactOptional(v.boolean(), true),
    docs: v.exactOptional(v.boolean(), true),
    test: v.exactOptional(v.boolean(), true),
  }),
  { dev: true, docs: true, test: true }  // 三个工具集默认全部启用
)

三组工具集及默认值:

选项 类型 默认值 控制的内容
toolsets.dev boolean true 开发工具集:stories-changedget-storybook-story-instructionsstories-previewstories-find-by-componentreview-create
toolsets.docs boolean true 文档工具集:docs-showdocs-show-storydocs-list(依赖 components manifest)
toolsets.test boolean true 测试工具集:test-run(依赖 @storybook/addon-vitest

完整配置写法示例:

export default {
	addons: [
		{
			name: '@storybook/addon-mcp',
			options: {
				endpoint: '/mcp',
				toolsets: {
					dev: true,
					docs: false,
					test: true,
				},
			},
		},
	],
	features: {
		componentsManifest: true,
	},
};

需要强调:toolsets 只是"用户侧开关",工具最终是否可用还要叠加运行时能力判断(第 5 节),两者取交集。

4. 端点是怎么注册到开发服务器的:experimental_devServer preset

理解了配置项后,来看 Addon 如何把它们变成运行中的 HTTP 路由。核心实现在 code/addons/mcp/src/preset.ts。该文件导出了四个 preset 属性:

4.1 挂载 MCP 路由:experimental_devServer

export const experimental_devServer: PresetPropertyFn<
  'experimental_devServer',
  StorybookConfigRaw,
  AddonOptionsInput
> = async (app, options) => {
  const addonOptions = v.parse(AddonOptions, {
    endpoint: options.endpoint,
    toolsets: options.toolsets ?? {},
  });

  const origin = `http://localhost:${options.port}`;
  const endpoint = addonOptions.endpoint ?? DEFAULT_MCP_ENDPOINT;
  // ...
  app!.post(endpoint, (req, res) => { /* mcpServerHandler(...) */ });
  app!.get(endpoint, (req, res) => { /* HTML 状态页 或 mcpServerHandler(...) */ });
  return app;
};

要点如下(均可在 code/addons/mcp/src/preset.ts 中逐行验证):

  1. 配置解析无容错:源码注释直言此处没有 error handling——如果 endpoint 不是字面量 pathname,v.parse 会让整个 Storybook 应用以 ValiError: Invalid type 崩溃。这是刻意设计:配置错误应在启动时尽早暴露。

  2. 同一端点同时服务两种客户端

    • POST endpoint(以及 GETAccept 头不含 text/html 的请求)进入 mcpServerHandler,即真正的 MCP 协议处理(实现见 code/addons/mcp/src/mcp-handler.ts),走 @tmcp/transport-http 的 HTTP 传输;
    • GET endpointAccept: text/html(即浏览器直接访问)返回一个渲染自 code/addons/mcp/src/template.html 的状态页面。
  3. 状态页内容是可验证的自检工具:状态页会用 getEffectiveToolAvailability 计算各工具/工具集的真实可用性(而不是只读 toolsets 开关),把 {{DEV_STATUS}}{{DOCS_STATUS}}{{TEST_STATUS}} 等占位符替换成 enabled/disabled,并针对"为什么不可用"插入具体提示,例如:

    • docs 工具集缺少 manifest 时,提示需要 componentsManifest 特性(vue3-vite 还需 experimentalDocgenServer);
    • stories-find-by-component 需要支持 module graph 的 builder(Vite 或 Webpack 5);
    • stories-changed 需要 changeDetection 特性开关;
    • review-createstorybook ai CLI 客户端(Claude/Codex 插件)默认启用,直接 MCP 客户端则需要 experimentalReview 特性开关;
    • test 工具集需要 Storybook 10.3.0+ 与 @storybook/addon-vitest,并提示加装 @storybook/addon-a11y 以获得可访问性检查。

    因此安装后打开 http://localhost:6006/mcp(端口以实际为准),你看到的不只是一个宣传页,而是一份"当前实例哪些工具可用、不可用的原因是什么"的诊断报告。

4.2 自动启用 manifest:features preset

export const features: PresetPropertyFn<'features'> = async (existingFeatures) => {
  return {
    ...existingFeatures,
    componentsManifest: true,
  };
};

注册 @storybook/addon-mcp 会隐式把 componentsManifest 特性打开——这是 docs 工具集能读取组件 API 清单的前提,也解释了为什么官方文档中"启用 components manifest"可以被视为安装流程的一部分。

4.3 注入 preview 层:previewAnnotations

export const previewAnnotations: PresetPropertyFn<'previewAnnotations'> = async (
  existingAnnotations = []
) => {
  return [...existingAnnotations, path.join(import.meta.dirname, 'preview.js')];
};

Addon 把自己的 preview 注解(code/addons/mcp/src/preview.ts)追加到既有注解之后,用于在 preview 侧支撑如 Story 预览(MCP Apps)等能力。

4.4 元数据:experimental_storybookAi

preset.ts 还导出 experimental_storybookAi preset,调用 code/addons/mcp/src/storybook-ai-metadata.ts 中的 buildStorybookAiMetadata,把 MCP 服务器相关信息(端点、工具可用性等)暴露给 Storybook 的 AI 元数据体系,供 CLI(如 storybook ai)发现和使用。

5. 工具集详解与启用条件

MCP 服务器对外提供的工具按三组组织,工具定义集中在 code/addons/mcp/src/tools/ 目录(工具注册表见 tool-registry.ts,工具名常量见 tool-names.ts)。

5.1 开发工具集(dev)

面向"写好用、可测试的 Story 并预览结果":

  • stories-changed:返回被本地文件改动(直接或可能间接)影响的 Story 列表。依赖 change detection 能力,从源码看需要 changeDetection 特性开关。
  • get-storybook-story-instructions:返回如何写好 Story 的最新指导,包括应捕获哪些 props、如何为 Story 编写交互测试(实现见 code/addons/mcp/src/tools/get-storybook-story-instructions.ts)。
  • stories-preview:在支持 MCP Apps 的客户端中直接把 Story 渲染进聊天界面;不支持时回退为 Storybook 中的 Story 链接。预览应用的脚本与模板位于 code/addons/mcp/src/tools/preview-stories/
  • stories-find-by-component:通过 Storybook 实时的反向依赖图(module graph),把组件源文件映射到渲染它的 Story。源码层面要求 builder 支持 module graph(Vite 或 Webpack 5),相关逻辑见 code/addons/mcp/src/utils/module-graph.ts
  • review-create:把当前改动的精选评审页推送出去并返回评审页 URL;启用门槛最高(changeDetection + experimentalReview 或可信 CLI 客户端)。

5.2 文档工具集(docs)

面向"生成 UI 时复用已有组件"。它读取 components manifest,因此可用性取决于框架能否生成 manifest(这是该工具集与其他两组的本质差异):

  • docs-list:返回包含组件与未挂载文档条目的索引;
  • docs-show:返回某组件的详细文档,包括 props、前 3 个 Story 及其余 Story 的索引;
  • docs-show-story:返回某个 Story 的完整定义与关联文档。

code/addons/mcp/src/preset.ts 的状态页提示文案可以确认框架支持边界:manifest 由 React 系框架、@storybook/angular-vite@storybook/vue3-vite(另需 experimentalDocgenServer)生成;其余框架(如 Webpack 版 Angular、Svelte 等)暂不生成 manifest,docs 工具集会显示为不可用,但 dev 与 test 工具集不受影响。测试夹具 code/addons/mcp/fixtures/ 中的 small-story-index.fixture.jsonfull-story-index.fixture.jsonmonorepo-story-index.fixture.json 则覆盖了单源与 monorepo 组合两种形态的索引数据,可用来理解该工具集处理的数据结构。

5.3 测试工具集(test)

  • test-run:为指定 Story 运行测试并返回结果(含可访问性问题,若配置了 a11y),同时向 Agent 说明如何解读结果、如何修复。从 code/addons/mcp/src/preset.ts 的提示文案可确认其前提:Storybook 10.3.0+ 且安装了 @storybook/addon-vitest;要获得可访问性检查还需 @storybook/addon-a11y

正是这一工具集让"Agent 生成 UI → 跑测试 → 修复 → 重跑确认"的自我修复闭环成为可能。

6. 进阶:组合(Composition)与鉴权

当项目需要跨多个 Storybook 开发 UI 时,@storybook/addon-mcp 支持 Storybook composition:配置 refs 后,MCP 服务器会自动把各被组合 Storybook 的 manifest 内容合并进响应。这一能力在 preset 中通过 resolveCompositionSources(options) 解析 refs(code/addons/mcp/src/auth/resolve-composition-sources.ts),并在初始化时打印来源日志:

if (refs.length > 0) {
  logger.info(`Initialized composition with ${refs.length} remote Storybook(s)`);
  if (compositionAuth.requiresAuth) {
    logger.info(`Auth required for: ${compositionAuth.authUrls.join(', ')}`);
  }
  logger.info(`Sources: ${(sources ?? []).map((s) => s.id).join(', ')}`);
  // ...
}

鉴权方面(实现见 code/addons/mcp/src/auth/,含 composition-auth.tsextractBearerToken):

  • 若组合源需要鉴权,GET /mcpPOST /mcp 会先执行 requireAuth 中间件:缺少 Bearer token 时返回 401WWW-Authenticate 头;
  • 服务器额外提供 GET /.well-known/oauth-protected-resource 端点,输出 MCP 规范要求的 OAuth 受保护资源描述 JSON(见 code/addons/mcp/src/preset.ts)。

这意味着把 MCP 服务器发布给团队或外部 Agent 使用时,可以按远程资源的标准 OAuth 流程受保护,而不是裸奔的本地端口。

7. 上手验证清单

结合 README 与源码,安装后建议按以下顺序自测(仓库只读,以下均针对你自己的 Storybook 工程操作):

  1. 安装并注册 @storybook/addon-mcp,启动 Storybook 开发服务器;
  2. 浏览器访问 http://localhost:6006/mcp(或使用你自定义的 endpoint),确认状态页显示 dev/docs/test 三组工具集的 enabled/disabled 状态,不可用的项会给出具体原因与修复提示;
  3. 按 MCP 协议客户端(或任意 MCP 客户端工具)以 http://localhost:6006/mcp 为 URL 连接,列出可用工具,核对与状态页一致——源码注释特别强调这两处使用同一套 gate 判断,"页面声称可用"与"协议里实际注册"不会失真;
  4. 调用 docs-list 验证 manifest 是否生成(未生成时参考第 5.2 节的框架要求);
  5. 若使用 composition,检查启动日志中的 Initialized composition with N remote Storybook(s)Sources: 行。

8. 测试与文档索引

Addon 自身带有完整的单元测试,可作为行为验证的权威依据:

配套官方文档(仓库内维护,与本 README 互为补充):

9. 小结

@storybook/addon-mcp 的设计可以概括为三句话:它通过 experimental_devServer preset 在 Storybook 开发服务器上挂出一个 MCP 端点(默认 /mcp,可用 endpoint 选项改为任意字面量 pathname,且由 valibot 强校验);端点同时服务 MCP 协议客户端与浏览器(后者看到工具可用性状态页);所有工具按 dev/docs/test 三组组织,由 toolsets 选项与运行时能力(manifest、module graph、changeDetection、addon-vitest/a11y 等)双重门控。掌握 endpoint 的约束、toolsets 的默认值、以及状态页上各 enabled/disabled 标记的触发条件,就足以在日常开发中可靠地把 AI Agent 接入自己的 Storybook 组件库。

登录后查看全文
热门项目推荐
相关项目推荐