Skip to content

feat(storybook): add storybook-webmcp addon for AI agents#1116

Merged
JBWatenbergScality merged 4 commits into
development/1.0from
feature/storybook-webmcp-addon
May 26, 2026
Merged

feat(storybook): add storybook-webmcp addon for AI agents#1116
JBWatenbergScality merged 4 commits into
development/1.0from
feature/storybook-webmcp-addon

Conversation

@JBWatenbergScality

Copy link
Copy Markdown
Contributor

Summary

Adds @jbwatenbergscality/storybook-webmcp to this Storybook. After this change, the deployed https://scality.github.io/core-ui/ doubles as a serverless MCP source for AI agents — no backend needed.

It's an alternative to Storybook's official @storybook/mcp self-hosted server, implemented in-browser via the W3C navigator.modelContext API (WebMCP).

Changes

  • .storybook/main.ts — added '@jbwatenbergscality/storybook-webmcp' to addons. The addon auto-enables features.componentsManifest: true and experimental_manifests: {} via its preset, so no manual manifest config is needed.
  • package.json — added "@jbwatenbergscality/storybook-webmcp": "^0.1.1" to devDependencies.
  • .npmrc — mapped the @jbwatenbergscality scope to GitHub Packages, plus an env-var auth-token line. GHPR requires a token (with read:packages) even for public packages.

What ships in storybook-static/ after this

storybook-static/
  manifests/
    components.json   ← NEW: 61 components, including reactDocgenTypescript props
    components.html   ← NEW: human-readable manifest debugger
    docs.json         ← NEW: unattached MDX docs
  sb-addons/2/manager-bundle.js  ← contains the WebMCP bootstrap
  ... (existing Storybook output)

Three tools registered

Tool What it returns
storybook.list-all-documentation Index of all 61 components + unattached docs
storybook.get-documentation Full docs (props from react-docgen-typescript, first 3 stories, story index) for one component
storybook.get-documentation-for-story Single story by storyId or componentId + storyName

How to consume (for reviewers)

  1. Install chrome-devtools-mcp ≥ the version with --category-experimental-webmcp (currently experimental).

  2. In your MCP client config (e.g. ~/.claude.json / .mcp.json):

    {
      "mcpServers": {
        "chrome-devtools": {
          "command": "npx",
          "args": ["chrome-devtools-mcp@latest", "--category-experimental-webmcp"]
        }
      }
    }
  3. Launch Chrome 149+ with --enable-features=WebMCPTesting,DevToolsWebMCPSupport.

  4. Open https://scality.github.io/core-ui/ (after merge + deploy) in that Chrome instance.

  5. In Claude Code: list_webmcp_tools should show three storybook.* tools; execute_webmcp_tool invokes them.

CI considerations

The build needs NODE_AUTH_TOKEN to resolve the GHPR-hosted addon. Locally:

export NODE_AUTH_TOKEN=$(gh auth token)
npm install

For CI (GitHub Actions running on this repo), ${{ secrets.GITHUB_TOKEN }} works out of the box — it has read:packages for the org's accessible packages. Action item: if any CI workflow runs npm install without that env, it needs to be added. I haven't audited the workflows yet; flagging for whoever's familiar with the build setup.

Test plan

  • Local: NODE_AUTH_TOKEN=$(gh auth token) npm install succeeds
  • Local: npm run build-storybook produces storybook-static/manifests/components.json with 61 components and populated props
  • CI: confirm whatever workflow runs build-storybook passes (depends on NODE_AUTH_TOKEN being set)
  • After merge + storybook:deploy: confirm https://scality.github.io/core-ui/manifests/components.json returns 200
  • End-to-end: open the deployed URL in instrumented Chrome, call list_webmcp_tools from Claude Code, confirm three storybook tools appear

Known limitations (v1)

  • Only react-docgen-typescript and vanilla react-docgen are supported. react-component-meta (experimental) is not yet handled — would return empty props for those components.
  • Consumer transport is chrome-devtools-mcp only. MCP-B local relay and Chrome extension paths are explicitly out of scope.
  • The Storybook manifest schema is officially "preview, not stable" — when Storybook bumps it, the addon will need an update. The addon has a runtime SchemaVersionError guard that fails loudly rather than silently miscarrying.

Draft because

  • Want maintainers to weigh in on the GHPR auth choice before merge (alternative: publish to npmjs.com instead — fully public, no token).
  • CI implications (NODE_AUTH_TOKEN propagation) haven't been confirmed end-to-end on this repo's workflows.

🤖 Generated with Claude Code

Adds a serverless MCP source for AI agents by registering tools in the browser
via navigator.modelContext (WebMCP). After this change, `npm run storybook:deploy`
also writes /manifests/components.json (and /manifests/docs.json) to the
GitHub Pages output, and the manager bundle registers three tools:

  - storybook.list-all-documentation
  - storybook.get-documentation
  - storybook.get-documentation-for-story

Consumers configure chrome-devtools-mcp with --category-experimental-webmcp,
launch Chrome 149+ with --enable-features=WebMCPTesting,DevToolsWebMCPSupport,
open https://scality.github.io/core-ui/ in that tab, and the tools become
callable from Claude Code via list_webmcp_tools / execute_webmcp_tool.

Notes:
- The addon auto-enables features.componentsManifest: true and
  experimental_manifests: {} via its preset, so no manual manifest config is
  needed.
- .npmrc adds the GitHub Packages scope mapping and an auth token reference.
  GHPR requires a token (with read:packages) even for public packages.
  CI builds need NODE_AUTH_TOKEN set; local dev: NODE_AUTH_TOKEN=$(gh auth token).
- Bumped storybook addon resolution to ^0.1.1 which adds react-docgen-typescript
  prop-shape support (core-ui uses react-docgen-typescript per .storybook/main.ts).

Verified locally: `npm run build-storybook` emits 61 components in
storybook-static/manifests/components.json with populated props.
@bert-e

bert-e commented May 25, 2026

Copy link
Copy Markdown
Contributor

Hello jbwatenbergscality,

My role is to assist you with the merge of this
pull request. Please type @bert-e help to get information
on this process, or consult the user documentation.

Available options
name description privileged authored
/after_pull_request Wait for the given pull request id to be merged before continuing with the current one.
/bypass_author_approval Bypass the pull request author's approval
/bypass_build_status Bypass the build and test status
/bypass_commit_size Bypass the check on the size of the changeset TBA
/bypass_incompatible_branch Bypass the check on the source branch prefix
/bypass_jira_check Bypass the Jira issue check
/bypass_peer_approval Bypass the pull request peers' approval
/bypass_leader_approval Bypass the pull request leaders' approval
/approve Instruct Bert-E that the author has approved the pull request. ✍️
/create_pull_requests Allow the creation of integration pull requests.
/create_integration_branches Allow the creation of integration branches.
/no_octopus Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead
/unanimity Change review acceptance criteria from one reviewer at least to all reviewers
/wait Instruct Bert-E not to run until further notice.
Available commands
name description privileged
/help Print Bert-E's manual in the pull request.
/status Print Bert-E's current status in the pull request TBA
/clear Remove all comments from Bert-E from the history TBA
/retry Re-start a fresh build TBA
/build Re-start a fresh build TBA
/force_reset Delete integration branches & pull requests, and restart merge process from the beginning.
/reset Try to remove integration branches unless there are commits on them which do not appear on the source branch.

Status report is not available.

@bert-e

bert-e commented May 25, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

Comment thread .npmrc
# Local dev: export NODE_AUTH_TOKEN=$(gh auth token)
# CI: pass NODE_AUTH_TOKEN via secrets (e.g. ${{ secrets.GITHUB_TOKEN }}).
@jbwatenbergscality:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}

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.

All three CI workflows (storybook-build.yml, tests.yaml, github-pages.yml) run npm ci but none set NODE_AUTH_TOKEN. Since .npmrc now routes @jbwatenbergscality to GitHub Packages with token auth, npm ci will fail with a 401 when resolving the addon — breaking every CI job, not just the Storybook build.

Each workflow needs something like:

- run: npm ci
  env:
    NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Comment thread package.json
@JBWatenbergScality

Copy link
Copy Markdown
Contributor Author

CI fixed in e1e822f — both tests and build-storybook are green now.

Root cause was missing NODE_AUTH_TOKEN env on the npm ci steps. .npmrc references ${NODE_AUTH_TOKEN} which expanded to empty, so npm sent no token and GitHub Packages returned 401.

Verified: secrets.GITHUB_TOKEN from this org has cross-account permission to read public packages from JBWatenbergScality's GHPR namespace. No PAT, org secret, or extra config needed beyond the two-line env block I added to storybook-build.yml and tests.yaml.

If you don't want CI workflows touched as part of this PR, the alternative is to publish the addon to npmjs.com instead — fully anonymous installs, no auth, no .npmrc magic. Let me know if you'd prefer that path.

Comment thread .npmrc
# the GHPR npm registry requires a token with read:packages scope.
# Local dev: export NODE_AUTH_TOKEN=$(gh auth token)
# CI: pass NODE_AUTH_TOKEN via secrets (e.g. ${{ secrets.GITHUB_TOKEN }}).
@jbwatenbergscality:registry=https://npm.pkg.github.com

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.

post-release.yml also runs npm ci (line 68, publish-npm job) without NODE_AUTH_TOKEN. That job uses setup-node with registry-url: "https://registry.npmjs.org", which may overwrite this .npmrc (404 from npmjs.org) or leave it in place without a valid GHPR token (401). Either way, the publish workflow breaks after merge.

Combined with github-pages.yml (already flagged), that's two workflows still missing the fix.

Same fix as storybook-build.yml and tests.yaml. Without this, the deploy and
post-release npm ci steps fetch @jbwatenbergscality/storybook-webmcp without a
token and get a 401 from GitHub Packages.

The env is scoped to the npm ci step only — publish-npm's npm publish step
still uses OIDC for npmjs.org auth (unaffected).
@bert-e

bert-e commented May 26, 2026

Copy link
Copy Markdown
Contributor

Waiting for approval

The following approvals are needed before I can proceed with the merge:

  • the author

  • one peer

Peer approvals must include at least 1 approval from the following list:

@JBWatenbergScality JBWatenbergScality marked this pull request as ready for review May 26, 2026 05:48
@JBWatenbergScality

Copy link
Copy Markdown
Contributor Author

Applied the same NODE_AUTH_TOKEN fix to two more workflows in 8efc869:

  • post-release.yml (publish-npm job's npm ci step)
  • github-pages.yml (deploy job's npm ci step)

These workflows don't trigger on PRs (post-release fires on release: published, deploy on push to development/1.0), so CI here can't directly prove the fixes — but they're structurally identical to the storybook-build.yml / tests.yaml fix that already passed twice. The env scope is intentionally narrow: only npm ci gets NODE_AUTH_TOKEN; npm publish in post-release.yml continues to use OIDC for npmjs.org auth (unaffected).

Comment thread .github/workflows/post-release.yml Outdated
env:
# storybook-webmcp is hosted on GitHub Packages (npm.pkg.github.com).
# Even public GHPR packages require an auth token.
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

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.

setup-node with registry-url: "https://registry.npmjs.org" writes //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} to ~/.npmrc. Setting NODE_AUTH_TOKEN to GITHUB_TOKEN here means the GitHub token is sent to registry.npmjs.org during npm ci — credential leakage to a third-party service.

The other three workflows don't use registry-url, so they're fine.

To avoid the collision, inject GHPR auth directly instead of through NODE_AUTH_TOKEN:

Suggested change
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env:
# storybook-webmcp is hosted on GitHub Packages (npm.pkg.github.com).
# Even public GHPR packages require an auth token.
# Use a separate step to avoid NODE_AUTH_TOKEN collision with setup-node's npmjs auth.
- run: echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> ~/.npmrc
- run: npm ci

This keeps GHPR auth out of the NODE_AUTH_TOKEN channel that setup-node reserves for npmjs, and also means the _authToken=${NODE_AUTH_TOKEN} line in the project .npmrc can be dropped (reducing the local-dev setup burden flagged in the PR description).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch — fixed in 7ae3673.

Switched post-release.yml's npm ci step to write the GHPR auth line directly to ~/.npmrc (your exact suggested pattern) so the GitHub token never goes through NODE_AUTH_TOKEN where setup-node's npmjs auth line could pick it up.

I kept the other three workflows (storybook-build, tests, github-pages) on the NODE_AUTH_TOKEN env pattern since none of them call setup-node with registry-url, so the leak path doesn't exist there. Happy to unify all four onto the echo pattern if you'd prefer consistency over minimal-diff.

publish-npm uses setup-node with registry-url: registry.npmjs.org, which
writes //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} to ~/.npmrc.
Setting NODE_AUTH_TOKEN to GITHUB_TOKEN on the npm ci step would cause that
token to be sent to a third-party registry during dependency resolution.

Write the GHPR auth line directly to ~/.npmrc instead, so the GitHub token
is only sent to npm.pkg.github.com. The other three workflows
(storybook-build, tests, github-pages) don't use registry-url so they're
unaffected and keep the simpler NODE_AUTH_TOKEN env pattern.

Reported in PR review by Claude bot: #1116 (comment)
# ~/.npmrc instead of via NODE_AUTH_TOKEN to avoid leaking the GitHub
# token to registry.npmjs.org through setup-node's npmjs auth line
# (//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}).
- run: echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> ~/.npmrc

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.

The echo to ~/.npmrc is shadowed by the project .npmrc, which already declares //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}. npm resolves project .npmrc over user ~/.npmrc for the same registry-scoped key, so the hardcoded token written here is never used. Since NODE_AUTH_TOKEN is not set in this job, npm resolves it to empty string and npm ci will 401 on GHPR.

Two ways to fix: (a) set NODE_AUTH_TOKEN as env on npm ci here too (same credential-leak risk the comment explains), or (b) remove the //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN} line from the project .npmrc entirely and have every CI workflow inject auth via echo >> ~/.npmrc instead.

@JBWatenbergScality JBWatenbergScality merged commit e5b86e6 into development/1.0 May 26, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants