Storybook MCP Addon 详解:把 MCP 服务器挂进 Storybook 开发服务器,让 AI Agent 写 Story、跑测试
本文基于 Storybook 仓库中的 @storybook/addon-mcp 官方 README(code/addons/mcp/README.md)及其配套源码展开,介绍如何将一个 MCP(Model Context Protocol)服务器直接挂载到 Storybook 开发服务器上,并通过 endpoint、toolsets 两个选项完成配置。读完本文,你能掌握该 Addon 的注册与配置方式、MCP 端点在源码中的注册链路、三组工具集(dev / docs / test)的启用条件,以及浏览器状态页与组合(Composition)鉴权等进阶机制。
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-Proxy(STORYBOOK_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-changed、get-storybook-story-instructions、stories-preview、stories-find-by-component、review-create |
toolsets.docs |
boolean |
true |
文档工具集:docs-show、docs-show-story、docs-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 中逐行验证):
-
配置解析无容错:源码注释直言此处没有 error handling——如果
endpoint不是字面量 pathname,v.parse会让整个 Storybook 应用以ValiError: Invalid type崩溃。这是刻意设计:配置错误应在启动时尽早暴露。 -
同一端点同时服务两种客户端:
POST endpoint(以及GET且Accept头不含text/html的请求)进入mcpServerHandler,即真正的 MCP 协议处理(实现见 code/addons/mcp/src/mcp-handler.ts),走@tmcp/transport-http的 HTTP 传输;GET endpoint且Accept: text/html(即浏览器直接访问)返回一个渲染自 code/addons/mcp/src/template.html 的状态页面。
-
状态页内容是可验证的自检工具:状态页会用
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-create对storybook aiCLI 客户端(Claude/Codex 插件)默认启用,直接 MCP 客户端则需要experimentalReview特性开关;- test 工具集需要 Storybook 10.3.0+ 与
@storybook/addon-vitest,并提示加装@storybook/addon-a11y以获得可访问性检查。
因此安装后打开
http://localhost:6006/mcp(端口以实际为准),你看到的不只是一个宣传页,而是一份"当前实例哪些工具可用、不可用的原因是什么"的诊断报告。 - docs 工具集缺少 manifest 时,提示需要
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.json、full-story-index.fixture.json、monorepo-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.ts 与 extractBearerToken):
- 若组合源需要鉴权,
GET /mcp与POST /mcp会先执行requireAuth中间件:缺少 Bearer token 时返回401及WWW-Authenticate头; - 服务器额外提供
GET /.well-known/oauth-protected-resource端点,输出 MCP 规范要求的 OAuth 受保护资源描述 JSON(见 code/addons/mcp/src/preset.ts)。
这意味着把 MCP 服务器发布给团队或外部 Agent 使用时,可以按远程资源的标准 OAuth 流程受保护,而不是裸奔的本地端口。
7. 上手验证清单
结合 README 与源码,安装后建议按以下顺序自测(仓库只读,以下均针对你自己的 Storybook 工程操作):
- 安装并注册
@storybook/addon-mcp,启动 Storybook 开发服务器; - 浏览器访问
http://localhost:6006/mcp(或使用你自定义的endpoint),确认状态页显示 dev/docs/test 三组工具集的 enabled/disabled 状态,不可用的项会给出具体原因与修复提示; - 按 MCP 协议客户端(或任意 MCP 客户端工具)以
http://localhost:6006/mcp为 URL 连接,列出可用工具,核对与状态页一致——源码注释特别强调这两处使用同一套 gate 判断,"页面声称可用"与"协议里实际注册"不会失真; - 调用
docs-list验证 manifest 是否生成(未生成时参考第 5.2 节的框架要求); - 若使用 composition,检查启动日志中的
Initialized composition with N remote Storybook(s)与Sources:行。
8. 测试与文档索引
Addon 自身带有完整的单元测试,可作为行为验证的权威依据:
- code/addons/mcp/src/preset.test.ts:preset 路由与状态页行为;
- code/addons/mcp/src/mcp-handler.test.ts:MCP 协议处理;
- code/addons/mcp/src/tools/tool-registry.test.ts 与 tool-registry-composition.test.ts:单源与组合场景下的工具注册;
- code/addons/mcp/src/auth/composition-auth.test.ts、resolve-composition-sources.test.ts:鉴权与组合解析;
- code/addons/mcp/src/types.test.ts:
endpoint/toolsets配置的 valibot 校验。
配套官方文档(仓库内维护,与本 README 互为补充):
- docs/ai/mcp/index.mdx:MCP 服务器文档目录;
- docs/ai/mcp/overview.mdx:框架支持表、安装步骤(
storybook add @storybook/addon-mcp)、四类典型工作流(生成 UI、预览 Story、跑测试、生成测试)与各工具说明; - docs/ai/mcp/api.mdx:
endpoint与toolsets选项的 API 参考及默认值; - docs/ai/mcp/sharing.mdx:发布/自托管 MCP 服务器供团队使用;
- docs/ai/manifests.mdx:docs 工具集依赖的 components manifest 机制与调试器。
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 组件库。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
