Skip to content

Conversation

@JReinhold
Copy link
Contributor

@JReinhold JReinhold commented Oct 30, 2025

Replace the source property in the context with request.

Now you don't pass in a source string that might be fetched or handled by your custom manifestProvider, but instead you pass in the whole web request. (This is automatically handled if you use the createStorybookMcpHandler() function).

There is additionally a second argument to manifestProvider, path, that determines which manifest to fetch. for now it is always ./manifests/components.json, but in the future it could be other paths, such as ./manifests/docs.json, ./manifests/components/button.json, etc.

The default action is now to fetch the manifest from ../manifests/components.json assuming the server is running at ./mcp. Your custom manifestProvider()-function then also does not get a source string as an argument, but gets the whole web request, that you can use to get information about where to fetch the manifest from.

@changeset-bot
Copy link

changeset-bot bot commented Oct 30, 2025

🦋 Changeset detected

Latest commit: 1f74003

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

💥 An error occurred when fetching the changed packages and changesets in this PR
Some errors occurred when validating the changesets config:
The package or glob expression "@storybook/mcp-eval" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.
The package or glob expression "@storybook/mcp-eval--*" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.

@codecov
Copy link

codecov bot commented Oct 30, 2025

Bundle Report

Changes will increase total bundle size by 762 bytes (2.03%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
@storybook/mcp-esm* 20.65kB 694 bytes (3.48%) ⬆️
@storybook/addon-mcp-esm* 17.59kB 68 bytes (0.39%) ⬆️

ℹ️ *Bundle size includes cached data from a previous commit

Affected Assets, Files, and Routes:

view changes for bundle: @storybook/mcp-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
index.js 309 bytes 13.45kB 2.35%
index.d.ts 385 bytes 7.2kB 5.65% ⚠️

Files in index.js:

  • ./src/tools/list-all-components.ts → Total Size: 765 bytes

  • ./src/tools/get-component-documentation.ts → Total Size: 1.36kB

  • ./src/types.ts → Total Size: 756 bytes

  • ./src/index.ts → Total Size: 910 bytes

  • ./src/utils/get-manifest.ts → Total Size: 3.37kB

view changes for bundle: @storybook/addon-mcp-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
preset.js 68 bytes 17.59kB 0.39%

Files in preset.js:

  • ./src/types.ts → Total Size: 614 bytes

  • ./src/mcp-handler.ts → Total Size: 3.72kB

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 30, 2025

npm i https://pkg.pr.new/@storybook/addon-mcp@54
npm i https://pkg.pr.new/@storybook/mcp@54

commit: 1f74003

@codecov
Copy link

codecov bot commented Oct 30, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 38.77%. Comparing base (cf4ef86) to head (1f74003).
⚠️ Report is 4 commits behind head on next.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             next      #54      +/-   ##
==========================================
- Coverage   39.10%   38.77%   -0.33%     
==========================================
  Files          23       23              
  Lines         693      686       -7     
  Branches      172      167       -5     
==========================================
- Hits          271      266       -5     
+ Misses        391      390       -1     
+ Partials       31       30       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@JReinhold JReinhold marked this pull request as ready for review October 30, 2025 10:48
Copilot AI review requested due to automatic review settings October 30, 2025 10:48
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the MCP manifest loading mechanism to use the HTTP Request object instead of a string source URL. This change makes the API more flexible by allowing custom manifest providers to extract additional context (headers, origin, etc.) from the request rather than just a URL string.

Key changes:

  • The getManifest() function now accepts a Request object instead of a source URL string
  • A new getManifestUrlFromRequest() helper constructs the manifest URL by replacing /mcp with /manifests/components.json
  • The manifestProvider signature changed from (source: string) => Promise<string> to (request: Request) => Promise<string>

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/mcp/src/utils/get-manifest.ts Refactored to accept Request object, added URL construction helper, updated default provider
packages/mcp/src/utils/get-manifest.test.ts Updated all tests to pass Request objects via helper function
packages/mcp/src/types.ts Changed StorybookContext to use request property instead of source
packages/mcp/src/tools/list-all-components.ts Updated to pass request instead of source to getManifest
packages/mcp/src/tools/list-all-components.test.ts Updated tests to include request in context
packages/mcp/src/tools/get-component-documentation.ts Updated to pass request instead of source to getManifest
packages/mcp/src/tools/get-component-documentation.test.ts Updated tests to include request in context
packages/mcp/src/index.ts Modified handler to pass request object to transport.respond()
packages/mcp/serve.ts Updated development server to use request parameter in manifestProvider
packages/addon-mcp/src/mcp-handler.ts Changed context to pass request instead of source URL
.github/instructions/mcp.instructions.md Added documentation for request-based context and manifest provider API
.github/copilot-instructions.md Updated architecture descriptions to reflect request-based approach
.changeset/hip-sloths-jog.md Added changeset documenting the breaking change

@JReinhold JReinhold self-assigned this Oct 30, 2025
@JReinhold JReinhold requested a review from tmeasday October 30, 2025 10:50
@JReinhold JReinhold changed the base branch from main to next October 30, 2025 13:40
Copy link
Member

@tmeasday tmeasday left a comment

Choose a reason for hiding this comment

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

@JReinhold I think we are misaligned on this. Perhaps we need to quickly sync on a call.

@JReinhold
Copy link
Contributor Author

We discussed that figuring out the path should be handled internally. Eg. a consumer of this API, can use manifestProvider to decide on the "first part" of a fetch URL by looking at the request (mapping requests to S3 buckets, etc.). But we'll assume that the manifest will live in a built Storybook, so the path should come the MCP server itself, currently always be manifests/components.json

Copilot AI review requested due to automatic review settings November 18, 2025 19:19
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

@JReinhold
Copy link
Contributor Author

@tmeasday I addressed your feedback, could you re-review?

I'm not entirely sure on the "format" of the path:

  1. ./manifests/components.json vs
  2. /manifests/components.json vs
  3. manifests/components.json

The first is what I've done now, as it seems most correct but can also require some normalisation, removing the leading dot, which is annoying. The second seems dangerous to me, as it could lead to treating /manifests as a root fs dir, which it's not. I'm not sure if the third is valid.
Thoughts?

Copilot AI review requested due to automatic review settings November 18, 2025 19:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Comment on lines 66 to 87
const handler = await createStorybookMcpHandler({
manifestProvider: async (request, path) => {
// Custom logic: read from local filesystem
// The provider decides on the base path, MCP provides the manifest path
const basePath = '/path/to/manifests';
// Remove leading './' from path if present
const normalizedPath = path.replace(/^\.\//g, '');
const fullPath = `${basePath}/${normalizedPath}`;
return await readFile(fullPath, 'utf-8');
},
// Or map requests to different S3 buckets:
manifestProvider: async (request, path) => {
const url = new URL(request.url);
const bucket = url.hostname.includes('staging')
? 'staging-bucket'
: 'prod-bucket';
const normalizedPath = path.replace(/^\.\//g, '');
const manifestUrl = `https://${bucket}.s3.amazonaws.com/${normalizedPath}`;
const response = await fetch(manifestUrl);
return await response.text();
},
});
Copy link

Copilot AI Nov 18, 2025

Choose a reason for hiding this comment

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

Invalid JavaScript syntax: The example shows two manifestProvider properties in the same object literal (lines 67-75 and 77-86). Only the last one would be used. These should be shown as separate examples.

Suggestion: Split into two separate code blocks with appropriate headings like "Example 1: Local filesystem" and "Example 2: S3 buckets".

Copilot uses AI. Check for mistakes.
Copy link
Member

@tmeasday tmeasday left a comment

Choose a reason for hiding this comment

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

I think it looks good. I think ./manifests/components.json is fine but manifests/components.json could probably work too. I prefer the former.

On thing to think about is what happens when the MCP url isn't ./mcp -- what if it's ./path/to/mcp -- is the path passed to the handler implied to be relative to that? if so the ./ is probably good

@JReinhold JReinhold merged commit 5d18405 into next Nov 19, 2025
11 checks passed
@JReinhold JReinhold deleted the remove-source branch November 19, 2025 05:38
@storybook-app-bot storybook-app-bot bot mentioned this pull request Nov 20, 2025
JReinhold added a commit that referenced this pull request Nov 20, 2025
* enter prereelase mode on next branch

* Handle HTML in a separate file (#56)

* extract human-readable /mcp to maintainable html file

* upgrade tsdown, remove json treeshaking workaround

* add changeset

* fix tsdown types

* add changeset release branches to checks

* commit releases with gh api. see https://github.com/changesets/action#inputs

* Version Packages (next) (#57)

Co-authored-by: storybook-app-bot[bot] <175111413+storybook-app-bot[bot]@users.noreply.github.com>

* Replace Storybook canary versions with 10.1.0 prereleases (#59)

* upgrade to storybook 10.1.0-alpha.2

* changesets

* Version Packages (next) (#60)

Co-authored-by: storybook-app-bot[bot] <175111413+storybook-app-bot[bot]@users.noreply.github.com>

* Rename "examples" to "stories" in component manifest format (#61)

* Initial plan

* Rename "examples" to "stories" in component manifest format

- Updated type definitions in types.ts files to rename Example to Story
- Updated format-manifest.ts to use story terminology (story, story_name, story_description, story_code)
- Updated all fixture JSON files to use "stories" instead of "examples"
- Updated test files and descriptions to use "stories" terminology
- Updated test snapshots to reflect the new XML output format
- All tests passing, build and typecheck successful

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: Jeppe Reinhold <[email protected]>

* Support name in manifest errors (#55)

* add name to manifest errors

* add fixtures with errors

* add changeset

* improve test reports in ci

* update fixtures to use stories instead of examples

* more example -> story renaming

* Improve code quality and development setup (#64)

* replace prettier with oxfmt

* add oxlint for linting

* update actions using npx actions-up

* add publint

* fix types

* add check-everything script

* add build-storybook to check all

* split GH Workflows

* explain lint disables

* Version Packages (next) (#63)

Co-authored-by: storybook-app-bot[bot] <175111413+storybook-app-bot[bot]@users.noreply.github.com>

* Replace oxfmt with Prettier (#68)

* replace oxfmt with prettier

* typo

* Update to the latest SB alpha so the internal storybook version works with the server (#71)

Co-authored-by: Jeppe Reinhold <[email protected]>

* Revert Embed demo image from storybook.js.org#21 (#75)

* Evals (#69)

* add initial eval setup

* well, a lot happened here...

* add clack

* Add interactive prompts and styled output to eval CLI (#65)

* Initial plan

* Add interactive prompts and prettier output to eval CLI

Co-authored-by: JReinhold <[email protected]>

* Use tasks API for parallel evaluation steps

Co-authored-by: JReinhold <[email protected]>

* Apply oxfmt formatting to eval.ts

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: JReinhold <[email protected]>

* improve terminal experience

* save environment

* improve terminal experience

* only allow one eval at a time

* add support for custom context

* format

* add support for eval hooks, add log about how to rerun experiments

* prompt to start storybook at the end of the evaluation

* add message about getting into the experiment

* improve experiment dir name

* take screenshots of failed stories too

* cleanup

* improve reshaped stories, improve test+a11y summary, improve mcp server config arg

* support --[no-]storybook flag

* collect experiment description and branch name

* save result summary to google sheets

* improve plain prompt

* prompt for google sheets upload

* fix google sheets upload

* support "Storybook MCP" context, which starts up the docs-only @storybook/mcp server with a given component manifest

* Add basic Radix eval (#66)

* Add Radix eval

* Add Rsuite eval (#67)

---------

Co-authored-by: Jeppe Reinhold <[email protected]>

* format

* fix typechecking

* add reshaped component manifest

* add conversation-viewer.html with approximate token count

* cleanup

* add documentation, fixups

* format

* fix stories not having imports anymore

* fix plain and radix experiments

* experiments will have unique package names

* more eval test fixing

* more story fixes

* fix typecheck and lint summary

* improve conversation viewer

* simplify viewer content

* simplify viewer content

* result visualisations is via storybook

* upload to chromatic

* update google sheet row order

* add Chromatic link to CLI log

* add note about public results

* remove description arg from evals

* Evals: Add Radix UI website prompt (#74)

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: JReinhold <[email protected]>
Co-authored-by: Michael Shilman <[email protected]>

* Review Kasper (#70)

* Start review

* Fix

* More comments

* Fix config files and restructure

* Resolve conflicts

* Fix github actions

* Fix coverage

* Fix type error

* Fix

* Fix

* Dedupe

* Update packages/mcp/src/index.ts

Co-authored-by: Jeppe Reinhold <[email protected]>

* Update .github/workflows/check.yml

Co-authored-by: Jeppe Reinhold <[email protected]>

* Update .github/workflows/check.yml

Co-authored-by: Jeppe Reinhold <[email protected]>

* Improve get/post handling

* Dedupe vite

* lock file

* test perf of check-everything in CI

* rename

* rename

* Add turbo caching

* check cache invalidation

* refactor

* refactor

* refactor

* refactor

* Use node version file

* description

* refactor

* rollback

* use turbo for artifacts

* install node

* optimize

* install offline for faster symlinking

* optimize

* Check ci

* Only upload test results on failure

* Check github reporter

* Fix command

* Fix test

* Remove check everything

* test corepack enable

* test corepack enable

* test corepack enable

* fix

* Check if this is faster

* Check if this is faster

* no cache

* rollback

* Change nothing

* Fix prettier

* Modify changeset for MCP server GET responses

Updated the changeset to handle GET responses in the MCP server.

* Prettier

* use docker

* debug

* use node 24

* Try own caching

* Prune it

* Don't format pnpm lock

* Fix

* again

* use composite

* change

* Revert "change"

This reverts commit 8031a63.

* Revert "use composite"

This reverts commit 7f26a54.

* Revert "again"

This reverts commit 7fdccdf.

* Revert "Fix"

This reverts commit f4dd004.

* Revert "Don't format pnpm lock"

This reverts commit c11c4ec.

* Revert "Prune it"

This reverts commit 1009ad5.

* Revert "Try own caching"

This reverts commit 82eb804.

* Revert "use node 24"

This reverts commit c63f9ee.

* Revert "debug"

This reverts commit d647a91.

* Revert "use docker"

This reverts commit 766462e.

* Address feedback

* Initial plan

* Update README and Copilot instructions for script changes

Co-authored-by: JReinhold <[email protected]>

* Address feedback

* Make it loose

* Watch storybook by default

* Fix command

* Fix

* Add pnpm to ignore

* Fix dev command

* Cleanup

* get CI green

---------

Co-authored-by: Jeppe Reinhold <[email protected]>
Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: JReinhold <[email protected]>

* Make `get-component-documentation` tool only accept a single component ID instead of multiple (#79)

* cleanup

* get-component-documentation only accepts a single component id

* Fix evals (#81)

* cleanup

* get-component-documentation only accepts a single component id

* fix versions

* use vitest cli instead of node for evals

* prefix experiment scripts so they are not picked up by turborepo

* Add toolset property to telemetry payloads in addon-mcp (#78)

* Initial plan

* Add toolset property to all telemetry payloads in addon-mcp

Co-authored-by: JReinhold <[email protected]>

* add changeset

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: JReinhold <[email protected]>
Co-authored-by: Jeppe Reinhold <[email protected]>
Co-authored-by: Jeppe Reinhold <[email protected]>

* remove source API and use the request instead (#54)

* remove source API and use the request instead

* cleanup

* add changesets

* add path argument to manifestProvider

* cleanup

* update changeset

* fix serve.ts

* cleanup

* Fix internal stdio-based MCP server (#85)

* allow undefined requests when using custom manifestProvider

* changeset

* add tests for internal stdio transport

* cleanup

* Add end-to-end tests and improve unit test quality (#84)

* add e2e tests

* improve e2e scripting

* add tests for mcp index

* add preset tests

* add telemetry tests

* simplify tool test mocks

* simplify mcp-handler tests, improve disableTelemetry handling

* add tests for manifest availability

* exclude evals from coverage

* cleanup

* changeset

* fix preset registering handlers instead of middlewares

* update tests to match changes in base branch

* cleanup

* await sb process kill

* globally mock storybook deps

* clean lock file

* Output in markdown instead of XML (#86)

* add e2e tests

* improve e2e scripting

* add tests for mcp index

* add preset tests

* add telemetry tests

* simplify tool test mocks

* simplify mcp-handler tests, improve disableTelemetry handling

* add tests for manifest availability

* exclude evals from coverage

* cleanup

* changeset

* fix preset registering handlers instead of middlewares

* update tests to match changes in base branch

* cleanup

* await sb process kill

* refactor formatter, splitting into markdown and xml, configurable, defaulting to markdown

* globally mock storybook deps

* clean lock file

* fix context arg

* fix tests

* fix types

* "Examples" -> "Stories", simplify tests

* simplify tests and types

* simplify

* use ts-like prop type docs format

* add script to clean experiments

* add changeset

* exit pre mode (#88)

* Update reshaped flight booking eval (#87)

* Update reshaped flight booking eval

* format

---------

Co-authored-by: Jeppe Reinhold <[email protected]>
Co-authored-by: Jeppe Reinhold <[email protected]>

* Version Packages (#80)

Co-authored-by: storybook-app-bot[bot] <175111413+storybook-app-bot[bot]@users.noreply.github.com>

---------

Co-authored-by: storybook-app-bot[bot] <175111413+storybook-app-bot[bot]@users.noreply.github.com>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Tom Coleman <[email protected]>
Co-authored-by: Michael Shilman <[email protected]>
Co-authored-by: JReinhold <[email protected]>
Co-authored-by: Kasper Peulen <[email protected]>
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.

3 participants