Skip to content

feat(storybook): expose component docs to agents via official MCP addon (#3527) - #3736

Open
chinawch007 wants to merge 3 commits into
apache:mainfrom
chinawch007:feat/storybook-mcp-3527
Open

feat(storybook): expose component docs to agents via official MCP addon (#3527)#3736
chinawch007 wants to merge 3 commits into
apache:mainfrom
chinawch007:feat/storybook-mcp-3527

Conversation

@chinawch007

Copy link
Copy Markdown
Contributor

Summary

Agents writing UI code in this repo had no machine-readable interface to
learn which components exist and how to use them, so they grepped and read
component sources to guess props and usage. This PR self-hosts Storybook's
official MCP addon at http://localhost:6006/mcp, exposing the docs
toolset only, so agents can query the existing story catalog before
writing code.

  • apps/desktop: install @storybook/addon-mcp and register it in
    .storybook/main.ts with toolsets: { dev: false, test: false, docs: true }
    (test toolset needs @storybook/addon-vitest and stays a follow-up per
    the issue)
  • new root .mcp.json registering the endpoint for agent clients
  • new root AGENTS.md: start Storybook on demand, query
    list-all-documentation / get-documentation before writing UI code,
    prefer existing packages/ui components

Fixes #3527

Verification

Manual verification succeeded against a running dev server:

  • npm --workspace @maka/desktop run storybook -- --no-open boots
    unchanged; existing stories render as before

  • MCP initialize over POST /mcp returns a session id

  • tools/list exposes exactly the three docs tools — list-all-documentation,
    get-documentation, get-documentation-for-story — confirming the
    dev/test toolsets are off:

    tool count: 3
    - list-all-documentation
    - get-documentation
    - get-documentation-for-story
    
  • all three tools return real content, e.g. get-documentation for
    primitives-toast returns the story list with usage snippets

  • npm run lint and npm run format:check pass

Not run / known gaps: full npm run build and npm test (config-only
change, no unit suite covers Storybook config); desktop-workspace
typecheck reports 40 pre-existing errors that reproduce identically on
clean main in this environment (stale workspace dists) — none touch the
changed files, which typecheck clean.

Review focus

  • .mcp.json uses the "type": "http" + "url" client convention
    (Claude Code / Cursor-class agent CLIs), not an MCP spec format; it is
    dev-time tooling config, unrelated to packages/mcp's product config.
    $schema is omitted — no official schema covers this client format.
  • .github/copilot-instructions.md (code-review guidance only) and the new
    AGENTS.md cover disjoint topics; AGENTS.md is the cross-tool
    canonical location. Mirroring into copilot-instructions.md is left as a
    maintainer decision.

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: ZCode authored the config and documentation changes and
ran the verification above; the human contributor reviewed the result and
performed the final verification on a live server.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — described under Summary above
  • No

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this head and found blocking issues.

[P2] MCP addon docs-only claim is not a server boundary and the endpoint is exposed on LAN

@storybook/addon-mcp replaces options via X-MCP-Toolsets (main.ts:45). The live tools/list with a dev header changes from 3 docs tools to 4 dev tools. The storybook script does not bind to loopback, so *:6006 is reachable from 10.7.0.13:6006 without auth — an on-LAN caller can re-enable the dev toolset and obtain a filesystem existence oracle (/etc/passwd vs pathNotFound).

Fix: bind to loopback (and --exact-port) and intersect request-selected toolsets with the configured allowlist; cover with header-injection tests.

[P2] Root .mcp.json is not discovered by Codex

AGENTS.md claims the endpoint is registered, but Codex discovers via .codex/config.toml [mcp_servers], not the Claude-style root JSON. Result: Codex sees the mandatory query instruction but has no tools.

Fix: ship a real project config for each claimed client or narrow the claim; verify via actual client discovery.

Checks on d75281cb67 are test: failure (unrelated CLI EOF backoff flake, but still red — not green). Code issues are independent of CI.

简体中文存在局域网暴露与 Codex 发现失败两项阻断。

@chinawch007

Copy link
Copy Markdown
Contributor Author

Thanks — both P2s are addressed in d9671e0. Details per finding:

[P2] Toolset override + LAN exposure

  • storybook dev now runs with --host 127.0.0.1 --exact-port. Verified on a
    live server: lsof reports TCP 127.0.0.1:6006 where it previously reported
    *:6006, and the endpoint still serves the three docs tools (initialize →
    tools/list → get-documentation) over both localhost and 127.0.0.1.
  • On intersecting the header selection with a configured allowlist: agreed in
    principle, but the X-MCP-Toolsets handling lives inside
    @storybook/addon-mcp itself — getToolsets() in dist/preset.js replaces
    the configured selection wholesale whenever the header is present — so the
    intersection has to happen upstream in storybookjs/mcp. I've filed
    addon-mcp: X-MCP-Toolsets request header fully replaces the configured toolsets — config acts as a default, not an allowlist storybookjs/mcp#406. With loopback-only binding the residual audience is
    local processes, which have no need of an MCP detour to probe the
    filesystem, so the attack path you demonstrated is closed.
  • The main.ts comment now states explicitly that the toolsets config is a
    default selection, not an allowlist, so no reader mistakes it for a
    boundary. Happy to add a small source-contract test pinning the loopback
    flags on the script if you want that locked.
  • Header-injection tests would be testing the addon's behavior, which lives
    in node_modules; once upstream ships the allowlist semantics I'll revisit
    what can be asserted from this repo.

[P2] Root .mcp.json not discovered by Codex

  • Went with narrowing the claim, as suggested. AGENTS.md is now client-neutral:
    the endpoint URL is stated up front, clients that read the root .mcp.json
    discover it automatically, and other clients (Codex, Cursor) are pointed at
    a one-time registration of the same URL in their own config.
  • I did not ship per-client configs: Cursor would need a separate
    .cursor/mcp.json, and Codex only reads the user-global
    ~/.codex/config.toml, which a repo cannot provision — so per-client files
    would be unshippable or untestable from here. Can add .cursor/mcp.json on
    top if maintainers prefer explicit opt-in files per client.
  • On verification: confirmed at the protocol level (initialize / tools/list /
    tool call). For discovery I can only vouch for the agent client used to
    develop this change, whose native discovery is the root .mcp.json; I have
    no Codex or Cursor environment available, which is exactly why the claim no
    longer extends to them.

CI

The red run is the CLI-workspace EOF-backoff flake you identified. Nothing in
this PR is consumed by that workspace; re-running now.

@M4n5ter
M4n5ter force-pushed the feat/storybook-mcp-3527 branch 2 times, most recently from f3427b8 to 9289175 Compare August 26, 2026 10:01
@github-actions github-actions Bot added the effort/S Under 100 readable lines label Aug 27, 2026

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds @storybook/addon-mcp to apps/desktop/.storybook/main.ts so an agent can query component docs over MCP instead of reading source, wires .mcp.json, pins the dev server with --exact-port, and adds a root AGENTS.md.

The plumbing is clean and I want to credit that before the findings. The addon goes into apps/desktop devDependencies, lock-pinned, and I confirmed it stays out of the shipped closure: third-party-closure.mjs:98-129 defines that closure as the prod closure plus maka.rendererBundledDependencies, and the addon is in neither, so audit-shipped-dependencies.mjs and the generated THIRD_PARTY_NOTICES are unaffected and there is no NOTICE obligation. The twelve transitive packages are MIT except one ISC, all ASF Category A. There is no CI install gap either — every isStorybookPath trigger in ci-test-plan.mjs:398-415 also sets code = true, which is what gates npm ci. Telemetry is a non-issue: the addon gates on core.disableTelemetry, which main.ts already sets.

The problem is not the plumbing. It is what this installs as an authority.

P1 — the root AGENTS.md is a tracked file at a path this project deliberately keeps untracked, and it is injected into Maka's own system prompt.

Two separate reasons this cannot land as part of this PR.

First, AGENTS.md is not tracked on main, and maintainer checkouts keep a local one via .git/info/exclude. Committing a tracked root AGENTS.md will make git pull refuse in every checkout that has a local file at that path. That is not a style objection; it breaks the working tree of anyone set up the current way.

Second, and more important: WORKSPACE_INSTRUCTION_FILES in packages/runtime/src/system-prompt/workspace-instructions.ts:40 is ['AGENTS.md', 'CLAUDE.md', 'GEMINI.md']. Maka injects the project's AGENTS.md into the system prompt. So this file is not documentation — it is behavior, for every agent run inside this repository. And what it says is "Prefer composing existing packages/ui components. Introduce a new component only when nothing existing fits", with no mention of Astryx at all. Our actual authority is DESIGN.md:186, "Use Astryx primitives as the default seam", backed by the CI-gated surface inventory. An agent that reads only the injected instruction will build a new packages/ui component where DESIGN.md requires an Astryx primitive, and the surface-inventory gate will grade the result.

Please split the AGENTS.md out of this PR. If you want project instructions for agents, that is a worthwhile change but it is its own decision, it has to reconcile with DESIGN.md rather than restate it more weakly, and it needs the untracked-file collision resolved first.

P2 — the addon injects vendor-authored instructions that claim exclusive authority over component APIs, and our catalog cannot back that claim.

@storybook/addon-mcp's preset puts STORYBOOK_MCP_INSTRUCTIONS into the MCP server's instructions field, which clients inject into the system prompt. That text says to answer questions about component props and usage from the documentation tools and never from source or type definitions, and that if something is not documented, it does not exist.

Against our tree that instruction is actively wrong. Only 5 of 32 story files declare meta.component, there is no autodocs tag anywhere, and @astryxdesign/core — the primitive layer DESIGN.md makes the default seam — has no stories at all. So: an agent needs a busy button. DESIGN.md:229 requires the Astryx isLoading prop, "always — no hand-swapped labels, icons, or disable-plus-spinner recreations". The manifest has no such component, the injected instruction says the prop does not exist, and the agent hand-rolls a disable-plus-spinner. That is precisely the drift DESIGN.md exists to prevent, now instructed.

Unlike the AGENTS.md above, this string is vendor-controlled and can change on any npm update inside ^0.7.0, so it cannot be reviewed per change. If we want this addon, the honest sequencing is to get meta.component and autodocs coverage up — and Astryx covered at all — before an instruction that says "if it is not documented, it does not exist" is true enough to inject.

Three P3s:

  • The main.ts comment says the security boundary is the dev server's loopback binding. It is not. The addon's X-MCP-Toolsets: dev header overrides the configured toolsets per request against registrations that are toolset-blind, and what actually blocks a malicious page today is that the transport is constructed with no cors option, so no Access-Control-Allow-Origin is emitted. The addon never validates Origin. Consequence is bounded — I found no fs writes in the bundle; the dev toolset's worst reach is execSync('git status --porcelain') and story-source reads the Vite dev server already serves on that port. One thing I could not verify: whether Storybook's own host check runs before the addon's /mcp route. If it does not, DNS rebinding lands same-origin and the CORS absence buys nothing. Worth checking with curl -X POST -H 'Host: evil.example' -H 'Origin: https://evil.example' -H 'X-MCP-Toolsets: dev' http://127.0.0.1:6006/mcp before merge. Please fix the comment either way — a wrong stated boundary is worse than none.
  • --exact-port turns a port collision into process.exit(-1) instead of falling forward to 6007. This project's workflow encourages multiple worktrees, and apps/desktop/tests/smoke.md:71 documents that command. A deliberate trade for the hardcoded .mcp.json URL, but say so.
  • .mcp.json is unclassified by ci-test-plan.mjs, so it falls through to unknownCode = true and forces a full run. Any future .mcp.json-only PR runs the entire suite for nothing.

Ungraded notes: the body answers "does this PR entail a change in behavior?" with No, but the addon unconditionally sets features.componentsManifest: true and Storybook applies that to builds, so CI's build-storybook now generates component manifests — and the body does not claim build-storybook was run locally. "Exposes exactly the three docs tools" holds only for the default request path; the header override is disclosed in the main.ts comment but not in the summary. Separately, .gitattributes:8-11 export-ignores /.claude as repository-local agent configuration; .mcp.json is the same category and is not export-ignored, so it would ship in the ASF source artifact — my call to make, flagging it. Finally, npm run lint is Biome only while CI runs npx knip --workspace apps/desktop separately; the addon publishes no "." export and knip's storybook plugin routes addon names through deferred resolution. I could not verify whether that resolves cleanly — please confirm the knip step passes.

Root cause: right seam, wrong authority. Extending the existing Storybook config instead of building a parallel harness is the correct instinct. But what gets installed is a second, vendor-authored source of truth about component APIs, in a repository whose authority is DESIGN.md plus Astryx primitives plus the generated surface inventory — and then a root AGENTS.md restates that authority a third time, more weakly and without Astryx. One fact, three representations, one of them written by a third party and shipped inside a caret range.

AI use: Claude Code (Opus) produced the initial findings, including unpacking @storybook/addon-mcp@0.7.0 and its transitive tree to read the actual bundles and license set. I independently re-verified the P1 — that AGENTS.md is absent from origin/main, excluded via .git/info/exclude, and listed in WORKSPACE_INSTRUCTION_FILES — and the DESIGN.md authority lines it conflicts with. The DNS-rebinding ordering question is explicitly unverified. The reviewer of record reviewed and accepted this.

简体中文

apps/desktop/.storybook/main.ts 中加入 @storybook/addon-mcp,使 agent 可以通过 MCP 查询组件文档而非读源码;同时接入 .mcp.json、用 --exact-port 固定开发服务器端口,并新增根目录 AGENTS.md

管道部分是干净的,先肯定这一点。addon 进的是 apps/desktop 的 devDependencies 并已锁定版本,我确认它不进入分发闭包:third-party-closure.mjs:98-129 把该闭包定义为生产闭包加 maka.rendererBundledDependencies,而 addon 两者都不在,因此 audit-shipped-dependencies.mjs 与生成的 THIRD_PARTY_NOTICES 不受影响,也没有 NOTICE 义务。十二个传递依赖除一个 ISC 外均为 MIT,都属 ASF Category A。CI 也没有安装缺口——ci-test-plan.mjs:398-415 中每个 isStorybookPath 触发都会同时置 code = true,而后者正是 npm ci 的门槛。遥测不是问题:addon 会检查 core.disableTelemetry,而 main.ts 已将其置为 true。

问题不在管道,而在于它安装了什么样的权威。

P1 —— 根目录 AGENTS.md 是一个被纳入版本控制的文件,而本项目刻意让该路径不受版本控制;并且它会被注入 Maka 自己的系统提示。

两个各自独立的理由使它不能作为本 PR 的一部分落地。

其一,AGENTS.mdmain 上并未被跟踪,维护者的检出通过 .git/info/exclude 保留本地副本。提交一个被跟踪的根 AGENTS.md,会让所有在该路径存在本地文件的检出 git pull 失败。这不是风格意见,而是会破坏按现有方式配置者的工作树。

其二,也更重要:packages/runtime/src/system-prompt/workspace-instructions.ts:40WORKSPACE_INSTRUCTION_FILES['AGENTS.md', 'CLAUDE.md', 'GEMINI.md']。Maka 会把项目的 AGENTS.md 注入系统提示。因此该文件不是文档,而是行为,作用于本仓库内每一次 agent 运行。而它写的是"优先组合已有的 packages/ui 组件,只有在没有现成组件合适时才引入新组件",全文未提 Astryx。我们真正的权威是 DESIGN.md:186——"Use Astryx primitives as the default seam",并有 CI 把关的 surface inventory 支撑。只读到注入指令的 agent,会在 DESIGN.md 要求使用 Astryx 原语的地方新建 packages/ui 组件,然后被 surface-inventory 闸门判定。

请把 AGENTS.md 从本 PR 拆出。若你想为 agent 提供项目指令,这是有价值的改动,但它是独立决策,需要与 DESIGN.md 调和而非更弱地复述,并且要先解决未跟踪文件的冲突。

P2 —— addon 注入了由第三方撰写、宣称对组件 API 拥有排他权威的指令,而我们的目录支撑不了该主张。

@storybook/addon-mcp 的 preset 会把 STORYBOOK_MCP_INSTRUCTIONS 放进 MCP 服务器的 instructions 字段,客户端会将其注入系统提示。该文本要求:关于组件 props 与用法的问题一律用文档工具回答,绝不依据源码或类型定义;且"若未被文档记录,它就不存在"。

对照我们的代码树,这条指令是主动错误的。32 个 story 文件中只有 5 个声明了 meta.component,全仓没有任何 autodocs 标签,而 DESIGN.md 指定为默认接缝的原语层 @astryxdesign/core 完全没有 story。于是:agent 需要一个 busy 按钮,DESIGN.md:229 要求"always"使用 Astryx 的 isLoading prop,"不得手工替换文案、图标,或用 disable 加 spinner 重造"。而清单里没有这个组件,注入的指令说该 prop 不存在,agent 于是手搓了 disable 加 spinner——这正是 DESIGN.md 要防止的漂移,如今被写成了指令。

与上面的 AGENTS.md 不同,这个字符串由第三方控制,可能在 ^0.7.0 范围内的任何一次 npm update 中改变,无法逐次评审。若我们要用这个 addon,诚实的次序是:先把 meta.component 与 autodocs 覆盖率提上去、并让 Astryx 有覆盖,再注入"未记录即不存在"这类足够为真的指令。

三条 P3:

  • main.ts 注释称安全边界是开发服务器的 loopback 绑定。并非如此。addon 的 X-MCP-Toolsets: dev 请求头可逐请求覆盖已配置的工具集,而注册本身对工具集无感知;今天真正阻挡恶意页面的,是传输层构造时未传 cors 选项,因而不会输出 Access-Control-Allow-Origin。addon 从不校验 Origin。后果是有界的——我在整个 bundle 中未发现 fs 写操作,dev 工具集最大触达是 execSync('git status --porcelain') 和 story 源码读取,而后者 Vite 开发服务器本就在同一端口提供。有一点我无法核实:Storybook 自身的 host 检查是否先于 addon 的 /mcp 路由运行。若否,DNS rebinding 将落在同源,CORS 的缺失也就毫无意义。合并前值得用 curl -X POST -H 'Host: evil.example' -H 'Origin: https://evil.example' -H 'X-MCP-Toolsets: dev' http://127.0.0.1:6006/mcp 验一下。无论结果如何请修正该注释——错误的边界声明比没有更糟。
  • --exact-port 把端口冲突从回退到 6007 变成 process.exit(-1)。本项目的工作流鼓励多 worktree,且 apps/desktop/tests/smoke.md:71 记录了该命令。作为写死 .mcp.json URL 的有意取舍可以接受,但请写明。
  • .mcp.json 未被 ci-test-plan.mjs 分类,会落到 unknownCode = true 而强制全量运行。将来任何只改 .mcp.json 的 PR 都会白跑整套测试。

未定级说明:正文对"本 PR 是否带来行为变化"回答 No,但 addon 无条件设置 features.componentsManifest: true,而 Storybook 会把它应用于构建,因此 CI 的 build-storybook 现在会生成组件清单——正文也未声明本地跑过 build-storybook。"仅暴露三个文档工具"只在默认请求路径成立;请求头覆盖在 main.ts 注释中有交代,但摘要里没有。另外 .gitattributes:8-11/.claude 标为 export-ignore,理由是仓库本地的 agent 配置;.mcp.json 属同一类别却未被 export-ignore,会进入 ASF 源码制品——这由我来定,先标出。最后,npm run lint 只有 Biome,而 CI 另外跑 npx knip --workspace apps/desktop;该 addon 未发布 "." 导出,knip 的 storybook 插件对 addon 名走延迟解析。我无法核实它能否干净解析——请确认 knip 步骤通过。

根因:接缝对,权威错。 扩展既有 Storybook 配置而非另建一套 harness,直觉是对的。但被安装进来的,是关于组件 API 的第二个、由第三方撰写的事实来源,而本仓库的权威是 DESIGN.md 加 Astryx 原语加生成的 surface inventory;随后根 AGENTS.md 又把该权威第三次复述,更弱且不提 Astryx。一个事实,三份表示,其中一份由第三方撰写并随 caret 范围分发。

@chinawch007
chinawch007 force-pushed the feat/storybook-mcp-3527 branch from 9289175 to 5d21a93 Compare September 3, 2026 06:32
@chinawch007

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review. I agree with the “right seam, wrong authority” framing. I have rebased the branch onto the latest main and taken the local-patch path discussed above, with this update focused specifically on the two blocking findings in your review.

Summary of the update

  • Removed the root AGENTS.md.
  • Moved the on-demand Storybook startup workflow into CONTRIBUTING.md, with the corresponding update in CONTRIBUTING.zh-CN.md.
  • Added a repository-owned dependency patch for @storybook/addon-mcp@0.7.0.
  • Replaced the addon's vendor-authored documentation instructions with instructions that accurately describe Maka's current, incomplete Storybook catalog.
  • Documented the reason for the patch, its removal condition, and the third-party MIT-licensed material in patches/README.md and LICENSE.
  • Kept the existing Storybook/MCP integration intact: the addon dependency, Storybook configuration, .mcp.json, loopback binding, and --exact-port.
  • Kept Storybook strictly on demand; this PR does not introduce a background service or automatic startup.

P1 — root AGENTS.md

I resolved this finding by removing the tracked root AGENTS.md entirely.

That addresses both problems identified in the review:

  1. It no longer collides with the repository's existing convention of keeping maintainer-local AGENTS.md files untracked.
  2. It no longer becomes implicit product behavior through WORKSPACE_INSTRUCTION_FILES, so this PR does not inject a second, weaker description of the project's UI authority into Maka's own system prompt.

The operational guidance that remains useful to contributors now lives in CONTRIBUTING.md:

  • Storybook is development-only and starts on demand with
    npm --workspace @maka/desktop run storybook -- --no-open.
  • The MCP endpoint is available at http://localhost:6006/mcp.
  • The root .mcp.json registers that endpoint for clients that support repository MCP configuration.
  • The Storybook catalog is explicitly described as incremental rather than exhaustive.
  • UI work should query Storybook first, then fall back to DESIGN.md and Astryx's official API or published type declarations when documentation is missing.
  • Props must be verified rather than guessed.

I do not consider CONTRIBUTING.md a fully equivalent replacement for an always-injected AGENTS.md: it does not auto-start Storybook, and not every agent client is guaranteed to read it. The replacement is deliberately split across two appropriate seams:

  • CONTRIBUTING.md owns the repository workflow and the on-demand startup command.
  • Once Storybook is running and an MCP client connects, the MCP server instructions carry the Storybook-first rule and the correct fallback authority.

Together, these preserve much of the original intent of the issue without creating the checkout collision or installing another competing system-prompt authority.

P2 — vendor instructions claim authority the catalog cannot support

I used the repository's existing dependency-patch mechanism to replace the addon's documentation instructions.

The upstream addon currently tells agents that undocumented props do not exist and that component API questions must not be answered from source or type definitions. That is unsafe for Maka because the current Storybook catalog does not cover the complete UI surface, particularly Astryx.

The patched MCP instructions now establish the following workflow:

  1. Use Storybook documentation tools first to discover documented components, props, and examples.
  2. Treat the Storybook catalog as incremental and incomplete; absence from the catalog is not evidence that a component or prop does not exist.
  3. For documentation gaps, follow the repository's DESIGN.md.
  4. Verify Astryx components and props against Astryx's official API or published type declarations.
  5. Never infer or guess props from names, conventions, or unrelated libraries.

This specifically fixes the failure mode from the review: if an agent needs the Astryx Button loading state and Storybook does not document it, the MCP instructions no longer tell the agent that isLoading does not exist. They direct the agent back to DESIGN.md and the authoritative Astryx API/types instead.

The patch is version-specific to @storybook/addon-mcp@0.7.0 and is applied by the existing root postinstall path through patch-package --error-on-fail. The installed version is lock-pinned. An incompatible addon update will therefore require the patch to be deliberately regenerated and reviewed rather than silently replacing the repository-owned instructions.

patches/README.md records why the patch exists and says to remove it when the addon provides a supported project-owned instructions override. LICENSE now records the patched MIT-licensed Storybook source as well.

Current scope and follow-up coverage

This change intentionally separates “make the existing catalog safe and useful” from “complete the catalog.”

With the patch in place, Storybook can provide useful MCP documentation immediately for the components and stories it already covers. Its usefulness is limited to that documented surface, but the limitation is now stated honestly, and missing documentation no longer pushes agents away from the repository's actual design authority.

This PR does not attempt to create superficial stories for 100+ components merely to increase a coverage number. Useful coverage requires design judgment and human review: stories need to demonstrate DESIGN.md-canonical states and usage rather than merely render each export.

I plan to track the remaining Storybook coverage in a separate follow-up issue and grow it incrementally, beginning with the Astryx primitives explicitly governed by DESIGN.md, then expanding through the remaining high-value UI surfaces. That work is valuable as human-facing documentation and as an Astryx upgrade canary, but it no longer needs to block this integration.

In short:

  • this PR installs and preserves the Storybook/MCP interface;
  • the local patch makes the currently documented subset immediately useful without granting it false exclusive authority;
  • CONTRIBUTING.md plus the MCP instructions replace the safe portion of the removed AGENTS.md guidance;
  • catalog completeness is acknowledged as follow-up work rather than claimed by this PR.

Preserved integration behavior

The following parts of the existing PR remain unchanged:

  • @storybook/addon-mcp remains an apps/desktop development dependency;
  • the Storybook config enables the docs toolset by default and keeps dev/test off by default;
  • .mcp.json continues to point to http://localhost:6006/mcp;
  • Storybook binds to 127.0.0.1;
  • --exact-port prevents the hardcoded MCP URL from silently pointing at the wrong port;
  • Storybook remains on demand.

Verification

I verified the revised behavior as follows:

  • npm run lint passes.
  • npm run format:check passes.
  • npm --workspace @maka/desktop run typecheck:stories passes.
  • npx knip --workspace apps/desktop passes.
  • ASF source-header and legal-inventory tests pass.
  • The dependency patch passes a reverse/forward application check through patch-package.
  • A clean install reached postinstall and successfully applied all dependency patches, including @storybook/addon-mcp@0.7.0; the overall npm ci command subsequently stopped only because the existing Electron installer exhausted its network download retries.
  • Storybook starts successfully using the documented on-demand command.
  • A live MCP initialize request returns the patched instructions, including the incomplete-catalog disclosure, the DESIGN.md/Astryx fallback, and the prohibition on guessing props.

The full root typecheck is not being claimed as green locally: after rebasing, it currently reports unrelated errors in unchanged non-Storybook source paths. The Storybook-specific typecheck passes.

@chinawch007

chinawch007 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

如果我们添加agents.md,会跟开发者自己的agents.md相冲突,当前替代方案是用contribute.md引导开发者agent使用storybook-mcp。
虽然当前maka的storybook覆盖率不够,但仍然可以用local patch的方式使得其立刻发挥有限的效用。
因为前端组件的story描述需要契合design.md的要求,推进需要人工仔细审查,所以没办法用ai机械地修改,所以对于当前未被覆盖的前端组件,建议另开issue来逐步推进覆盖率,不在这个PR中进行。

…on (apache#3527)

Self-host the Storybook MCP endpoint at http://localhost:6006/mcp with only
the docs toolset enabled:

- install @storybook/addon-mcp in apps/desktop and register it in
  .storybook/main.ts with dev/test toolsets off (test needs
  @storybook/addon-vitest and stays a follow-up per the issue)
- register the endpoint for agent clients in a new root .mcp.json
  ("type": "http" client convention; $schema omitted since no official
  schema covers this client config format)
- add AGENTS.md guidance to query the MCP before writing UI code in
  packages/ui or apps/desktop, preferring existing components

Verified: storybook boots unchanged, tools/list exposes exactly the three
docs tools, and list-all-documentation / get-documentation /
get-documentation-for-story return real story docs over the endpoint.

Generated-by: ZCode
…pe (apache#3527)

Review follow-up addressing the two P2s:

- storybook script now passes --host 127.0.0.1 --exact-port, so the
  unauthenticated /mcp endpoint is loopback-only. The X-MCP-Toolsets
  override itself is addon-level behavior (see getToolsets() in
  @storybook/addon-mcp) and needs an upstream fix; with loopback-only
  binding a caller already has direct local filesystem access, so the
  override grants nothing it could not do directly.
- .storybook/main.ts comment now states the toolsets config is a default
  selection, not an allowlist.
- AGENTS.md no longer claims universal .mcp.json registration: clients
  that read the root .mcp.json auto-discover the endpoint; other clients
  (Codex, Cursor) register the same URL in their own config.

Verified: lsof reports 127.0.0.1:6006 (previously *:6006); MCP initialize,
tools/list, and get-documentation still work over both localhost and
127.0.0.1; lint and format:check pass.

Generated-by: ZCode
Keep Storybook on demand while moving its startup guidance into the contributor docs. Patch the addon instructions so the incremental catalog remains useful without hiding undocumented Astryx APIs.

Generated-by: Codex
@chinawch007
chinawch007 force-pushed the feat/storybook-mcp-3527 branch from 5d21a93 to 75c93cb Compare September 3, 2026 09:43
@github-actions github-actions Bot added effort/M Under 500 readable lines and removed effort/S Under 100 readable lines labels Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adopt Storybook's official MCP addon to give agents a queryable component interface

2 participants