Skip to content

Handle private composed sources as own-MCP notices#242

Merged
kasperpeulen merged 3 commits into
mainfrom
kasper/requires-own-mcp-notice
May 23, 2026
Merged

Handle private composed sources as own-MCP notices#242
kasperpeulen merged 3 commits into
mainfrom
kasper/requires-own-mcp-notice

Conversation

@kasperpeulen
Copy link
Copy Markdown
Member

@kasperpeulen kasperpeulen commented May 23, 2026

TL;DR

Smaller replacement for #235. This keeps the current architecture and adds one narrow path for private composed Storybooks reached through the local Storybook MCP proxy:

  • private composed sources stay visible in list-all-documentation
  • they render as non-error guidance to use that source Storybook's own MCP endpoint
  • direct non-proxy requests still get the normal OAuth 401 challenge

Behavior contract

  • list-all-documentation shows private composed sources instead of dropping the whole multi-source response into an OAuth/tool error.
  • get-documentation and get-documentation-for-story return the same own-MCP guidance when the selected source cannot be read through the local proxy.
  • X-Storybook-MCP-Proxy: true is treated as our internal proxy routing signal. It is not a security boundary.
  • The source MCP endpoint is derived from the composed source URL and preserves subpath-hosted Storybooks, e.g. https://example.com/storybook/ -> https://example.com/storybook/mcp.

Review order

  1. packages/mcp/src/utils/requires-own-mcp.ts

    • Small helper that computes the source-specific MCP endpoint and renders the guidance text.
  2. packages/mcp/src/utils/get-manifest.ts and packages/mcp/src/types.ts

    • Adds RequiresOwnMcpError and the notice variant on SourceManifests.
    • The important distinction: RequiresOwnMcpError is an exception for control flow, but it becomes non-error MCP content.
  3. packages/mcp/src/utils/manifest-formatter/markdown.ts

    • Renders notices without the error: prefix, so agents see routing guidance rather than a failed tool call.
  4. packages/mcp/src/tools/list-all-documentation.ts

    • Keeps callback behavior on actual manifest successes only; notice-only sources still render in the response but are not treated as successful manifests.
  5. packages/addon-mcp/src/auth/composition-auth.ts and packages/addon-mcp/src/preset.ts

    • The addon decides when an unauthenticated private remote should become own-MCP guidance instead of OAuth state.
    • Direct requests without the proxy header still stay on the OAuth challenge path.
  6. packages/mcp-proxy/src/utils/proxy-client.ts

    • Adds the X-Storybook-MCP-Proxy marker on proxied tool calls. The proxy does not know about private sources.
  7. Tests

    • Each package has targeted coverage for its part of the contract: endpoint formatting, multi-source notices, tool responses, addon direct-vs-proxy behavior, and proxy header propagation.

Validation

  • pnpm exec oxfmt --check ...
  • pnpm vitest --project=@storybook/mcp --run packages/mcp/src/utils/requires-own-mcp.test.ts packages/mcp/src/utils/get-manifest.test.ts packages/mcp/src/utils/manifest-formatter/markdown.test.ts packages/mcp/src/tools/list-all-documentation.test.ts packages/mcp/src/tools/get-documentation.test.ts packages/mcp/src/tools/get-documentation-for-story.test.ts
  • pnpm vitest --project=@storybook/mcp-proxy --run packages/mcp-proxy/src/utils/proxy-client.test.ts
  • pnpm vitest --project=@storybook/addon-mcp --run packages/addon-mcp/src/auth/composition-auth.test.ts packages/addon-mcp/src/preset.test.ts
  • pnpm --filter @storybook/addon-mcp run build
  • pnpm --filter @storybook/mcp run build
  • pnpm turbo run typecheck --filter=@storybook/mcp --filter=@storybook/addon-mcp --filter=@storybook/mcp-proxy
  • pnpm changeset status --since=origin/main
  • git diff --check

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 23, 2026

🦋 Changeset detected

Latest commit: 7c28163

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

This PR includes changesets to release 2 packages
Name Type
@storybook/addon-mcp Patch
@storybook/mcp Patch

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

@netlify
Copy link
Copy Markdown

netlify Bot commented May 23, 2026

Deploy Preview for storybook-mcp-self-host-example canceled.

Name Link
🔨 Latest commit 7c28163
🔍 Latest deploy log https://app.netlify.com/projects/storybook-mcp-self-host-example/deploys/6a11bd4669afe90008f1aa33

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 23, 2026

npx https://pkg.pr.new/storybookjs/mcp/@storybook/addon-mcp@242
npx https://pkg.pr.new/storybookjs/mcp/@storybook/mcp@242
npx https://pkg.pr.new/storybookjs/mcp/@storybook/mcp-proxy@242

commit: 7c28163

@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Bundle Report

Changes will increase total bundle size by 2.39kB (3.1%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
@storybook/mcp-esm 50.65kB 2.21kB (4.57%) ⬆️
@storybook/mcp-proxy-esm 23.71kB 176 bytes (0.75%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: @storybook/mcp-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
index.js 1.76kB 33.65kB 5.51% ⚠️
index.d.ts 456 bytes 15.8kB 2.97%

Files in index.js:

  • ./src/types.ts → Total Size: 2.06kB

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

  • ./src/tools/list-all-documentation.ts → Total Size: 1.87kB

  • ./src/utils/requires-own-mcp.ts → Total Size: 682 bytes

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

  • ./src/utils/manifest-formatter/markdown.ts → Total Size: 9.07kB

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

Assets Changed:

Asset Name Size Change Total Size Change (%)
src-DG8Ek53V.js (New) 20.61kB 20.61kB 100.0% 🚀
src-tbfJ4opt.js (Deleted) -20.44kB 0 bytes -100.0% 🗑️

Files in src-DG8Ek53V.js:

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

  • ./src/utils/proxy-client.ts → Total Size: 3.11kB

@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Codecov Report

❌ Patch coverage is 94.73684% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.26%. Comparing base (90e39fa) to head (7c28163).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/addon-mcp/src/auth/composition-auth.ts 78.57% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #242      +/-   ##
==========================================
+ Coverage   76.21%   77.26%   +1.05%     
==========================================
  Files          52       53       +1     
  Lines        1417     1465      +48     
  Branches      393      407      +14     
==========================================
+ Hits         1080     1132      +52     
+ Misses        205      202       -3     
+ Partials      132      131       -1     

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

@kasperpeulen kasperpeulen force-pushed the kasper/requires-own-mcp-notice branch 2 times, most recently from 3a24d24 to ff7948a Compare May 23, 2026 14:20
@kasperpeulen kasperpeulen force-pushed the kasper/requires-own-mcp-notice branch from ff7948a to d142450 Compare May 23, 2026 14:26
@kasperpeulen kasperpeulen marked this pull request as ready for review May 23, 2026 14:46
Copilot AI review requested due to automatic review settings May 23, 2026 14:46
Copy link
Copy Markdown
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

Adds a “requires own MCP” notice flow for private composed Storybook sources that can’t be read through the local MCP proxy, keeping those sources visible and returning routing guidance (instead of failing the whole tool call or forcing an OAuth challenge in the proxy path).

Changes:

  • Introduces a helper to compute a composed source’s /mcp endpoint and format non-error routing guidance.
  • Extends multi-source manifest fetching + markdown formatting to carry and render per-source “notice” entries (without an error: prefix).
  • Updates addon + proxy integration to mark proxied requests with X-Storybook-MCP-Proxy: true and switch proxy-originated unauthenticated private-source behavior from OAuth challenge to “use own MCP” guidance, with targeted tests and a changeset.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/mcp/src/utils/requires-own-mcp.ts Adds endpoint derivation and user-facing notice text for “use the source’s own MCP”.
packages/mcp/src/utils/requires-own-mcp.test.ts Validates endpoint derivation for root + subpath-hosted Storybooks (incl. query/hash).
packages/mcp/src/utils/get-manifest.ts Adds RequiresOwnMcpError, maps it to non-error MCP content, and surfaces notices in multi-source results.
packages/mcp/src/utils/get-manifest.test.ts Covers multi-source notice capture behavior and success-vs-notice accounting.
packages/mcp/src/types.ts Adds RequiresOwnMcpNotice and a notice field to SourceManifests.
packages/mcp/src/utils/manifest-formatter/markdown.ts Renders per-source notices as guidance (not error:) in multi-source lists.
packages/mcp/src/utils/manifest-formatter/markdown.test.ts Ensures notices render without an error: prefix.
packages/mcp/src/tools/list-all-documentation.ts Avoids treating notice-only sources as successful manifests for callback purposes.
packages/mcp/src/tools/list-all-documentation.test.ts Asserts list output includes routing notices for private composed sources.
packages/mcp/src/tools/get-documentation.test.ts Verifies selected-source own-MCP routing notice behavior.
packages/mcp/src/tools/get-documentation-for-story.test.ts Verifies selected-source own-MCP routing notice behavior for story docs.
packages/mcp/src/index.ts Exports RequiresOwnMcpError and RequiresOwnMcpNotice for consumers.
packages/mcp/README.md Documents the new notice field and RequiresOwnMcpNotice type.
packages/addon-mcp/src/auth/composition-auth.ts Adds proxy-mode “requires own MCP” behavior for unauthenticated private remotes via RequiresOwnMcpError.
packages/addon-mcp/src/auth/composition-auth.test.ts Tests the trusted-proxy unauthenticated path yields RequiresOwnMcpError (and doesn’t record auth error state).
packages/addon-mcp/src/auth/index.ts Re-exports proxy header constants + proxy-request detection helper.
packages/addon-mcp/src/preset.ts Makes manifest provider per-request and bypasses OAuth challenge only for proxy-marked requests.
packages/addon-mcp/src/preset.test.ts Tests direct unauthenticated requests still get OAuth 401, while proxy-marked requests reach MCP and get the new provider behavior.
packages/mcp-proxy/src/utils/proxy-client.ts Adds X-Storybook-MCP-Proxy: true marker header on proxied tool calls.
packages/mcp-proxy/src/utils/proxy-client.test.ts Verifies the proxy header is sent.
.changeset/loud-maps-promise.md Declares patch releases for @storybook/mcp and @storybook/addon-mcp.

Comment on lines 55 to 60
@@ -42,7 +58,18 @@ type MCPErrorResult = {
* @param error - The error to convert (can be any type)
* @returns A tool result with error content and isError flag
*/
@kasperpeulen kasperpeulen merged commit 6cf92c4 into main May 23, 2026
20 checks passed
@kasperpeulen kasperpeulen deleted the kasper/requires-own-mcp-notice branch May 23, 2026 14:50
This was referenced May 23, 2026
This was referenced Jun 2, 2026
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