-
Notifications
You must be signed in to change notification settings - Fork 29
Improve documentation #172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Changes from 17 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
a610073
initial mcp docs
JReinhold 5674e20
Merge branch 'main' of https://github.com/storybookjs/mcp into docs
JReinhold 06c620e
improve self host docs
JReinhold 0d1db52
add netlify to self hosting doc
JReinhold 07ebfce
include manifests in netlify functions
JReinhold e33b204
try netlify again
JReinhold f7d79b4
cleanup self-host readme
JReinhold 81e580a
improve self-hosting docs
JReinhold d8e9ae0
simplify readmes
JReinhold e2f7700
format
JReinhold 4bc38d3
Move self-hosting docs into README
kylegach 6e499a6
Merge branch 'main' into docs
kylegach 64186ef
Replace TKs
kylegach 97c6947
Remove redundant docs
kylegach 512a696
Fix formatting
kylegach 7b7f573
Update packages/mcp/README.md
kylegach d7ce79c
cleanup
JReinhold 42469dc
add correct minimal example
JReinhold 0d487bb
Merge branch 'main' into docs
JReinhold 27bbbad
allow lock file changes to netlify example
JReinhold f119704
Merge branch 'docs' of https://github.com/storybookjs/mcp into docs
JReinhold 4e77aea
Update packages/mcp/README.md
JReinhold 816abcb
bring back self-hosting lockfile
JReinhold 3308464
update lock file
JReinhold dee42ed
try building packages first
JReinhold 91d0388
try bundling with esbuild
JReinhold c22aee2
try externalising @storybook/mcp
JReinhold f1e7e68
stop netlify from bundling source
JReinhold 180e8bc
cleanup
JReinhold 445f3a0
cleanup
JReinhold 5af6b6d
cleanup
JReinhold File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| '@storybook/addon-mcp': patch | ||
| '@storybook/mcp': patch | ||
| --- | ||
|
|
||
| Simplify package READMEs for docs-site-first documentation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| # Self-hosting example (`@storybook/mcp`) | ||
|
|
||
| This app shows the smallest practical way to run `@storybook/mcp` as an HTTP endpoint in Node.js or Netlify Functions. | ||
|
|
||
| It is available to experiment with at https://storybook-mcp-self-host-example.netlify.app/mcp | ||
|
|
||
| ## Run | ||
|
|
||
| From the repository root: | ||
|
|
||
| ```bash | ||
| pnpm install | ||
| cd apps/self-host-mcp | ||
| pnpm start | ||
| ``` | ||
|
|
||
| MCP endpoint: `http://localhost:13316/mcp` | ||
|
|
||
| ## Options | ||
|
|
||
| ```bash | ||
| cd apps/self-host-mcp | ||
| pnpm start -- --port 13316 --manifestsPath ./manifests | ||
| ``` | ||
|
|
||
| - `--port`: HTTP port to serve | ||
| - `--manifestsPath`: local directory or remote base URL containing `components.json` and optionally `docs.json` | ||
|
|
||
| ## Use your own components | ||
|
|
||
| To try this server with your own component library, first build your Storybook so it generates manifests, then copy the content of the `manifests` directory from the build-output (usually `./storybook-static/manifests`) into this example's `manifests/` directory. | ||
|
|
||
| In practice, you want `components.json` (and `docs.json` if available) in `apps/self-host-mcp/manifests/` before running `pnpm start`. | ||
|
|
||
| ## Run on Netlify Functions | ||
|
|
||
| This example also includes a Netlify function at `netlify/functions/mcp.ts` and routing in `netlify.toml`. | ||
|
|
||
| 1. Build your Storybook and copy generated manifests into `apps/self-host-mcp/manifests/` (or set `MANIFESTS_PATH` to a remote URL). | ||
| 2. Deploy `apps/self-host-mcp` as a Netlify project. | ||
| 3. Your MCP endpoint is available at `/mcp` (rewritten to `/.netlify/functions/mcp`). | ||
|
|
||
| ## What this demonstrates | ||
|
|
||
| - Instantiate a handler with `createStorybookMcpHandler` | ||
| - Route only `/mcp` requests to MCP transport | ||
| - Provide a custom `manifestProvider` for local or remote manifest sources | ||
| - Use the same handler implementation for both Node and Netlify Functions | ||
|
|
||
| For full guidance and Netlify Functions adaptation notes, see [packages/mcp/docs/self-hosting.md](../../packages/mcp/docs/self-hosting.md). | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| { | ||
| "v": 1, | ||
| "components": { | ||
| "button": { | ||
| "id": "button", | ||
| "name": "Button", | ||
| "path": "./src/components/Button.tsx", | ||
| "import": "./src/components/Button.tsx", | ||
| "summary": "A basic action trigger used throughout the interface.", | ||
| "stories": [ | ||
| { | ||
| "id": "button--primary", | ||
| "name": "Primary", | ||
| "summary": "Primary button style for main actions.", | ||
| "snippet": "<Button variant=\"primary\">Save</Button>" | ||
| }, | ||
| { | ||
| "id": "button--secondary", | ||
| "name": "Secondary", | ||
| "summary": "Secondary button style for supporting actions.", | ||
| "snippet": "<Button variant=\"secondary\">Cancel</Button>" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "v": 1, | ||
| "docs": { | ||
| "getting-started": { | ||
| "id": "getting-started", | ||
| "name": "Getting Started", | ||
| "title": "Docs/Getting Started", | ||
| "path": "./docs/getting-started.mdx", | ||
| "summary": "Introduces the design system and component usage conventions.", | ||
| "content": "Use Button for interactive actions. Prefer primary for primary actions and secondary for alternate actions." | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| [build] | ||
| base = "apps/self-host-mcp" | ||
| command = "pnpm install --frozen-lockfile" | ||
| publish = "." | ||
|
|
||
| [[redirects]] | ||
| from = "/mcp" | ||
| to = "/.netlify/functions/mcp" | ||
| status = 200 | ||
|
|
||
| [functions] | ||
| included_files = ["manifests/**"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import { createMcpHandler } from '../../server.ts'; | ||
|
|
||
| const manifestsPath = process.env.MANIFESTS_PATH ?? './manifests'; | ||
|
|
||
| let cachedHandlerPromise: ReturnType<typeof createMcpHandler> | undefined; | ||
|
|
||
| export default async function handler(request: Request): Promise<Response> { | ||
| const pathname = new URL(request.url).pathname; | ||
| if (pathname !== '/mcp' && pathname !== '/.netlify/functions/mcp') { | ||
| return new Response('Not found', { status: 404 }); | ||
| } | ||
|
|
||
| if (!cachedHandlerPromise) { | ||
| cachedHandlerPromise = createMcpHandler(manifestsPath); | ||
|
JReinhold marked this conversation as resolved.
JReinhold marked this conversation as resolved.
|
||
| } | ||
|
|
||
| const mcpHandler = await cachedHandlerPromise; | ||
| return mcpHandler(request); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "name": "@storybook/mcp-self-host", | ||
| "version": "0.0.0", | ||
| "private": true, | ||
| "description": "Self-hosting example for @storybook/mcp", | ||
| "type": "module", | ||
| "scripts": { | ||
| "start": "node ./server.ts" | ||
|
JReinhold marked this conversation as resolved.
|
||
| }, | ||
| "dependencies": { | ||
| "@storybook/mcp": "latest", | ||
|
JReinhold marked this conversation as resolved.
|
||
| "srvx": "^0.8.16" | ||
| }, | ||
| "devDependencies": { | ||
| "@types/node": "^24.0.0", | ||
| "typescript": "~5.9.0" | ||
| } | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| import { createStorybookMcpHandler } from '@storybook/mcp'; | ||
| import fs from 'node:fs/promises'; | ||
| import { basename, resolve } from 'node:path'; | ||
|
|
||
| export function createMcpHandler(manifestsPath: string) { | ||
| return createStorybookMcpHandler({ | ||
| manifestProvider: async (_request: Request | undefined, path: string) => { | ||
| const fileName = basename(path); | ||
|
|
||
| if (manifestsPath.startsWith('http://') || manifestsPath.startsWith('https://')) { | ||
| const response = await fetch(`${manifestsPath}/${fileName}`); | ||
| if (!response.ok) { | ||
| throw new Error( | ||
| `Failed to fetch manifest from ${manifestsPath}/${fileName}: ${response.status} ${response.statusText}`, | ||
| ); | ||
| } | ||
| return await response.text(); | ||
| } | ||
|
|
||
| return await fs.readFile(resolve(manifestsPath, fileName), 'utf-8'); | ||
| }, | ||
| }); | ||
| } | ||
|
|
||
| // when running node ./server.ts | ||
| if (import.meta.main) { | ||
| const [{ serve }, { parseArgs }] = await Promise.all([import('srvx'), import('node:util')]); | ||
|
|
||
| const args = parseArgs({ | ||
| options: { | ||
| port: { | ||
| type: 'string', | ||
| default: '13316', | ||
| }, | ||
| manifestsPath: { | ||
| type: 'string', | ||
| default: './manifests', | ||
| }, | ||
| }, | ||
| }); | ||
|
|
||
| const port = Number(args.values.port); | ||
| const manifestsPath = args.values.manifestsPath ?? './manifests'; | ||
|
JReinhold marked this conversation as resolved.
Outdated
|
||
| const storybookMcpHandler = await createMcpHandler(manifestsPath); | ||
|
|
||
| serve({ | ||
| port, | ||
| async fetch(request: Request) { | ||
| if (new URL(request.url).pathname !== '/mcp') { | ||
| return new Response('Not found', { status: 404 }); | ||
| } | ||
|
|
||
| return await storybookMcpHandler(request); | ||
| }, | ||
| }); | ||
|
|
||
| console.log(`@storybook/mcp example server listening on http://localhost:${port}/mcp`); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "extends": "../../tsconfig.json", | ||
| "compilerOptions": { | ||
| "outDir": "./dist" | ||
| }, | ||
| "include": ["**/*.ts"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.