Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .changeset/mcp-server-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@storybook/mcp': minor
'@storybook/addon-mcp': minor
---

Add MCP server-level instructions to both packages

Both `@storybook/mcp` and `@storybook/addon-mcp` now include server instructions in the MCP `initialize` response. These instructions guide agents on how to use the available tools effectively without requiring explicit prompting from users.

**`@storybook/mcp` instructions include:**

- Tool workflow: when to use `list-all-documentation` vs `get-documentation` vs `get-documentation-for-story`
- Anti-hallucination rules: never assume component props or API shape
- Multi-source behavior guidance

**`@storybook/addon-mcp` instructions compose the `@storybook/mcp` baseline and add:**

- Always call `get-storybook-story-instructions` before writing or editing stories
- `preview-stories` usage expectations
- `run-story-tests` workflow expectations
- Toolset availability guidance (`dev`, `docs`, `test`)

The `@storybook/mcp` package also exports `STORYBOOK_MCP_INSTRUCTIONS` for consumers who want to reuse or extend the base instructions.
Comment thread
JReinhold marked this conversation as resolved.
Outdated
4 changes: 3 additions & 1 deletion packages/addon-mcp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ For clients not listed above, consult their documentation for MCP server configu

## Usage

This addon provides MCP tools that your agent can use. The goal is that the agent uses these tools automatically when doing UI development, but agents are unreliable and unpredictable, so sometimes you might need to explicitly tell it to use the tools.
This addon provides MCP tools that your agent can use. When an MCP client connects, the server sends instructions in the `initialize` response to guide agents on how to use the tools effectively — including when to call `get-storybook-story-instructions` before editing stories, how to use preview URLs, and when documentation tools are available. These instructions help agents use the correct workflow implicitly without needing explicit prompting.

The goal is that the agent uses these tools automatically when doing UI development, but agents are unreliable and unpredictable, so sometimes you might need to explicitly tell it to use the tools.
Comment thread
JReinhold marked this conversation as resolved.
Outdated

**If you are prompting from an IDE like VSCode or Cursor, be sure to use `Agent` mode and `sonnet-4.5` or better.**

Expand Down
35 changes: 35 additions & 0 deletions packages/addon-mcp/src/instructions/mcp-server-instructions.md
Comment thread
JReinhold marked this conversation as resolved.
Outdated
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Storybook Addon MCP Server Instructions

This server provides tools to help you build, preview, and test Storybook UI components.

## Before Writing or Editing Stories

Always call **get-storybook-story-instructions** first to get framework-specific guidance. This tool returns the correct imports, patterns, and conventions for the current project. Do not skip this step.

## Story Preview Workflow

After writing or modifying a component or story, call **preview-stories** to retrieve the live preview URLs. Always include these URLs in your response so the user can verify the visual output.

## Story Testing Workflow

When tests are available (run-story-tests tool is present), run tests after writing or changing stories. Fix any failures before reporting success. Do not report stories as complete if tests are failing.

## Component Documentation Workflow (docs toolset)

When the docs toolset is available:

1. Call **list-all-documentation** once to discover available components and docs IDs.
2. Call **get-documentation** with a specific ID to retrieve full component props, usage examples, and stories.
3. Call **get-documentation-for-story** when you need documentation scoped to a specific story variant.
4. Never assume prop names, variants, or component API — always retrieve documentation first.
5. Only reference IDs returned by list-all-documentation. Do not guess IDs.

## Toolset Availability

Tools are grouped into toolsets. Check which tools are available before assuming a workflow is possible:

- **dev**: preview-stories, get-storybook-story-instructions
- **docs**: list-all-documentation, get-documentation, get-documentation-for-story
- **test**: run-story-tests

Toolsets can be restricted per-request via the `X-MCP-Toolsets` header. When a toolset's tools are not listed, that toolset is disabled for this request.
Comment thread
JReinhold marked this conversation as resolved.
Outdated
3 changes: 3 additions & 0 deletions packages/addon-mcp/src/mcp-handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ describe('mcpServerHandler', () => {
},
});
expect(parsedResponse.result.serverInfo.version).toBeDefined();
expect(parsedResponse.result.instructions).toBeDefined();
expect(parsedResponse.result.instructions).toContain('get-storybook-story-instructions');
expect(parsedResponse.result.instructions).toContain('list-all-documentation');
});

it('should respect disableTelemetry setting', async () => {
Expand Down
5 changes: 5 additions & 0 deletions packages/addon-mcp/src/mcp-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
addListAllDocumentationTool,
addGetDocumentationTool,
addGetStoryDocumentationTool,
STORYBOOK_MCP_INSTRUCTIONS,
type Source,
} from '@storybook/mcp';
import type { Options } from 'storybook/internal/types';
Expand All @@ -21,6 +22,9 @@ import { addRunStoryTestsTool } from './tools/run-story-tests.ts';
import { estimateTokens } from './utils/estimate-tokens.ts';
import { isAddonA11yEnabled } from './utils/is-addon-a11y-enabled.ts';
import type { CompositionAuth } from './auth/index.ts';
import addonInstructions from './instructions/mcp-server-instructions.md';

const MCP_SERVER_INSTRUCTIONS = `${STORYBOOK_MCP_INSTRUCTIONS}\n\n${addonInstructions}`;

let transport: HttpTransport<AddonContext> | undefined;
let origin: string | undefined;
Expand All @@ -41,6 +45,7 @@ const initializeMCPServer = async (options: Options, multiSource?: boolean) => {
},
{
adapter: new ValibotJsonSchemaAdapter(),
instructions: MCP_SERVER_INSTRUCTIONS,
capabilities: {
tools: { listChanged: true },
resources: { listChanged: true },
Expand Down
8 changes: 8 additions & 0 deletions packages/mcp/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# `@storybook/mcp`

The hype is real.

## Server Instructions

When an MCP client connects to this server, it receives server-level instructions in the `initialize` response. These instructions guide agents on how to use the available tools effectively:

- **Tool workflow**: When to use `list-all-documentation`, `get-documentation`, and `get-documentation-for-story`
- **Anti-hallucination rules**: Never assume component props or API shape — always retrieve documentation first
- **Multi-source behavior**: How to scope requests when multiple Storybook sources are configured
Comment thread
JReinhold marked this conversation as resolved.
Outdated
10 changes: 9 additions & 1 deletion packages/mcp/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,14 @@ import { addGetDocumentationTool } from './src/tools/get-documentation.ts';
import type { StorybookContext } from './src/types.ts';
import { parseArgs } from 'node:util';
import * as fs from 'node:fs/promises';
import { basename } from 'node:path';
import { readFileSync } from 'node:fs';
import { basename, resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

const serverInstructions = readFileSync(
resolve(dirname(fileURLToPath(import.meta.url)), './src/instructions.md'),
'utf-8',
);

const adapter = new ValibotJsonSchemaAdapter();
const server = new McpServer(
Expand All @@ -33,6 +40,7 @@ const server = new McpServer(
},
{
adapter,
instructions: serverInstructions,
capabilities: {
tools: { listChanged: true },
},
Expand Down
4 changes: 4 additions & 0 deletions packages/mcp/src/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module '*.md' {
const content: string;
export default content;
}
11 changes: 11 additions & 0 deletions packages/mcp/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,17 @@ describe('createStorybookMcpHandler', () => {
);
});

it('should include server instructions in initialize response', async () => {
const handler = await createStorybookMcpHandler();
await setupClient(handler);

const instructions = client.getInstructions();
expect(instructions).toBeDefined();
expect(instructions).toContain('list-all-documentation');
expect(instructions).toContain('get-documentation');
expect(instructions).toContain('Anti-Hallucination');
});

it('should call onSessionInitialize handler when provided', async () => {
const onSessionInitialize = vi.fn();
const handler = await createStorybookMcpHandler({ onSessionInitialize });
Expand Down
4 changes: 4 additions & 0 deletions packages/mcp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { addListAllDocumentationTool } from './tools/list-all-documentation.ts';
import { addGetStoryDocumentationTool } from './tools/get-documentation-for-story.ts';
import { addGetDocumentationTool } from './tools/get-documentation.ts';
import type { StorybookContext } from './types.ts';
import serverInstructions from './instructions.md';

export { serverInstructions as STORYBOOK_MCP_INSTRUCTIONS };

// Export tools for reuse by addon-mcp
export { addListAllDocumentationTool, LIST_TOOL_NAME } from './tools/list-all-documentation.ts';
Expand Down Expand Up @@ -82,6 +85,7 @@ export const createStorybookMcpHandler = async (
},
{
adapter,
instructions: serverInstructions,
capabilities: {
tools: { listChanged: true },
},
Expand Down
23 changes: 23 additions & 0 deletions packages/mcp/src/instructions.md
Comment thread
JReinhold marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Storybook MCP Server Instructions

This server provides access to Storybook component and documentation manifests.

## Tool Workflow

Comment thread
JReinhold marked this conversation as resolved.
Use tools in this order:

1. **list-all-documentation** — Call once at the start of a task to discover available components and docs entries. Use the returned IDs for subsequent calls. Pass `withStoryIds: true` when you also need story IDs (e.g., for use with `preview-stories` or `get-documentation-for-story`) — this adds story sub-entries to the list.

2. **get-documentation** — Call with a specific `id` from the list to retrieve full component documentation including props, usage examples, and stories. Prefer this over re-calling list when you already know the ID.

3. **get-documentation-for-story** — Call with a story ID when you need documentation scoped to a specific story variant rather than the whole component.

## Anti-Hallucination Rules

- Never assume component props, variants, or API shape. Always retrieve documentation before using a component.
- If a component or prop is not in the documentation, do not invent it. Tell the user the component was not found.
- Only reference IDs returned by list-all-documentation. Do not guess IDs.

## Multi-Source Behavior

When multiple Storybook sources are configured, list-all-documentation returns entries from all sources. Use the `storybookId` field in get-documentation to scope requests to a specific source when needed.