Skip to content
This repository was archived by the owner on Sep 7, 2026. It is now read-only.

fix(mcp): surface component @deprecated JSDoc tags in get-documentation - #368

Closed
rachelslurs wants to merge 4 commits into
storybookjs:mainfrom
rachelslurs:fix/get-documentation-deprecated-tags
Closed

rachelslurs wants to merge 4 commits into
storybookjs:mainfrom
rachelslurs:fix/get-documentation-deprecated-tags

Conversation

@rachelslurs

@rachelslurs rachelslurs commented Jul 22, 2026 •

Copy link
Copy Markdown

Fixes #367. Reproduction: https://github.com/rachelslurs/storybook-mcp-jsdoctags-repro

Summary

get-documentation now renders a component's @deprecated JSDoc tag. The tag was extracted into the manifest but never printed, so an agent calling get-documentation could not see that a component was deprecated unless the deprecation was also written into the prose description by hand.

Problem

formatComponentManifest prints the component name, id, description, subcomponents, stories, props, and attached docs. It never reads jsDocTags. The tag reaches the formatter by two paths, and both drop it:

  • With experimentalDocgenServer, the deprecation sits on the manifest's top-level jsDocTags.deprecated (a string[]). adaptCoreComponent passes it through, and the formatter ignores it.
  • Without the flag, react-docgen-typescript puts it on reactDocgenTypescript.tags.deprecated (a string), and parseComponentDocLike reads only props, so it is gone before the formatter runs.

I reproduced both on a react-vite project with Storybook 10.5.3 and addon-mcp 0.7.0. The get-documentation output carried the description and no deprecation, flag on and flag off.

Changes

packages/mcp/src/utils/parse-react-docgen.ts

  • Add an optional tags: Record<string, string[]> to ParsedDocgen, populated only when the engine reports tags, so parser output is unchanged for components without tags.
  • parseComponentDocLike (react-docgen-typescript and reactComponentMeta) normalizes the engine's tags into that field.

packages/mcp/src/utils/manifest-formatter/markdown.ts

  • Add formatDeprecationNotice, which reads jsDocTags.deprecated first and falls back to parsedDocgen.tags.deprecated.
  • formatComponentManifest and formatSubcomponentsSection print a > **Deprecated:** <reason> line under the component or subcomponent heading, above the description. A tag with no message prints a bare > **Deprecated**. A component with no tag, or an empty deprecated array, prints nothing. Non-deprecated components render byte for byte as before.

Output for a deprecated Button:

# Button

ID: example-button

> **Deprecated:** Use `NewButton` from `@acme/ui` instead.

A basic button.

Scope

  • Covers the docgen-server (jsDocTags) and react-docgen-typescript / reactComponentMeta (tags) paths, for components and subcomponents, verified end to end.
  • react-docgen (the JS/Flow engine) is not covered. Its base Documentation type carries no component-level tags, and this code does not read tags if Storybook attaches them downstream.
  • list-all-documentation still shows only the component summary line. Deprecation appears once you fetch the component with get-documentation.

Test plan

  • pnpm vitest --project=@storybook/mcp: 205 pass, including new tests for both resolution paths, the bare-notice case, the empty-array guard, subcomponent deprecation, and a guard that a non-deprecated component renders unchanged.
  • pnpm --filter @storybook/mcp typecheck and oxlint --type-aware: clean.
  • Built @storybook/mcp, loaded it into the reproduction project, and confirmed the callout appears on the flag-on and flag-off paths.

Summary by CodeRabbit

  • Documentation
    • Component and subcomponent documentation now renders JSDoc @deprecated notices as callouts beneath the relevant headings.
    • Deprecation reasons are formatted consistently and supported from both current and legacy metadata shapes.
    • Empty deprecation messages are shown without a reason; missing/empty deprecation values correctly omit the notice.
    • Subcomponent deprecation notices are displayed in-place directly under each subcomponent heading.
  • Tests
    • Added coverage for deprecation rendering and tag normalization behavior.

Copilot AI review requested due to automatic review settings July 22, 2026 21:33
@netlify

netlify Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

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

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

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@changeset-bot

changeset-bot Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a7841ab

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

This PR includes changesets to release 2 packages
Name Type
@storybook/mcp Patch
@storybook/addon-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

@coderabbitai

coderabbitai Bot commented Jul 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d58b409-acd0-4d60-8cb9-75d9a2b4a0c6

📥 Commits

Reviewing files that changed from the base of the PR and between 107ca87 and e387e10.

📒 Files selected for processing (1)
  • packages/mcp/src/utils/parse-react-docgen.test.ts

📝 Walkthrough

Walkthrough

Component docgen parsing now preserves normalized JSDoc tags. Documentation formatting resolves component and subcomponent @deprecated tags from supported sources and renders deprecation callouts beneath their headings, with added tests and a changeset.

Changes

Component deprecation notices

Layer / File(s) Summary
Normalize component JSDoc tags
packages/mcp/src/utils/parse-react-docgen.ts, packages/mcp/src/utils/parse-react-docgen.test.ts
ParsedDocgen optionally contains normalized string-array tags, with coverage for deprecated, since, malformed, and missing tags.
Render deprecated documentation notices
packages/mcp/src/utils/manifest-formatter/markdown.ts, packages/mcp/src/utils/manifest-formatter/markdown.test.ts, .changeset/deprecated-jsdoc-tags-in-get-documentation.md
The formatter renders deprecated callouts for components and subcomponents, handles empty messages, and documents the patch release.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReactDocgenTypescript
  participant parseComponentDocLike
  participant formatComponentManifest
  participant MarkdownOutput
  ReactDocgenTypescript->>parseComponentDocLike: Component metadata and JSDoc tags
  parseComponentDocLike->>formatComponentManifest: Normalized tags
  formatComponentManifest->>MarkdownOutput: Deprecated callout before description
Loading

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

get-documentation drops component-level @deprecated JSDoc tags: the tag is
extracted into the manifest but never rendered by formatComponentManifest.

These tests assert the tag is surfaced as a callout for components and
subcomponents (from both the docgen-server jsDocTags and the legacy
react-docgen-typescript tags), and fail against current code (5 failing:
4 formatter, 1 parser).

Ref: storybookjs#367
Render component @deprecated as a "> **Deprecated:** <reason>" callout under
the component and subcomponent headings. The tag is resolved from the
docgen-server manifest (top-level jsDocTags.deprecated) and recovered from
react-docgen-typescript / reactComponentMeta output (the engine's
tags.deprecated). An absent tag or an empty deprecated array renders nothing.

Fixes storybookjs#367
@rachelslurs
rachelslurs force-pushed the fix/get-documentation-deprecated-tags branch from 75b6322 to 107ca87 Compare July 22, 2026 22:08
Copilot AI review requested due to automatic review settings July 22, 2026 22:08

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@pkg-pr-new

pkg-pr-new Bot commented Jul 24, 2026

Copy link
Copy Markdown
npx https://pkg.pr.new/storybookjs/mcp/@storybook/addon-mcp@368
npx https://pkg.pr.new/storybookjs/mcp/@storybook/mcp@368

commit: 107ca87

@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.47619% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.74%. Comparing base (e4f90aa) to head (107ca87).

Files with missing lines Patch % Lines
packages/mcp/src/utils/parse-react-docgen.ts 83.33% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #368      +/-   ##
==========================================
+ Coverage   79.66%   79.74%   +0.07%     
==========================================
  Files          50       50              
  Lines        2095     2113      +18     
  Branches      624      631       +7     
==========================================
+ Hits         1669     1685      +16     
  Misses        220      220              
- Partials      206      208       +2     

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

Codecov flagged two partial branches in normalizeTags: the empty-`out`
path (a tags object with no string values) and the branch that skips a
non-string tag value. Both are documented defensive guards that no test
exercised. Add cases for a present-but-empty tags bag and a bag mixing a
string and a non-string value.

Claude-Session: https://claude.ai/code/session_01LRFizy8RJNrVzYDfkxWGmV
Copilot AI review requested due to automatic review settings July 24, 2026 17:10

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 29, 2026 02:45

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@valentinpalkovic

Copy link
Copy Markdown
Contributor

Superseded by storybookjs/storybook#35963

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

get-documentation omits component JSDoc tags (@deprecated) from its output

3 participants