Skip to content

Commit 3096fb3

Browse files
authored
Merge pull request #31 from storybookjs/migrate-addon-mcp-to-tmcp
Migrate `@storybook/addon-mcp` from `@modelcontextprotocol/sdk` to `tmcp`
2 parents 5f60136 + 568af96 commit 3096fb3

40 files changed

+2083
-779
lines changed

.changeset/every-pumas-melt.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@storybook/addon-mcp': patch
3+
'@storybook/mcp': patch
4+
---
5+
6+
use shared tsdown config for all monorepo packages, target node 20.19

.changeset/icy-paws-dig.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@storybook/addon-mcp': patch
3+
---
4+
5+
change tool names

.changeset/wise-dingos-exist.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@storybook/addon-mcp': patch
3+
---
4+
5+
This release migrates the addon's MCP implementation from `@modelcontextprotocol/sdk` to `tmcp`.

.claude/settings.local.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"Bash(git merge:*)",
55
"Bash(git checkout:*)",
66
"Bash(git add:*)",
7-
"mcp__storybook-addon-mcp__get_ui_building_instructions",
8-
"mcp__storybook-addon-mcp__get_story_urls"
7+
"mcp__storybook-addon-mcp__get-ui-building-instructions",
8+
"mcp__storybook-addon-mcp__get-story-urls"
99
],
1010
"deny": [],
1111
"ask": []

.github/copilot-instructions.md

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
## Architecture Overview
44

5-
This is a **pnpm monorepo** with two distinct MCP implementations:
5+
This is a **pnpm monorepo** with two MCP implementations:
66

7-
- **`packages/addon-mcp`**: Storybook addon using `@modelcontextprotocol/sdk`, exposes MCP server at `/mcp` via Vite middleware
7+
- **`packages/addon-mcp`**: Storybook addon using `tmcp`, exposes MCP server at `/mcp` via Vite middleware
88
- **`packages/mcp`**: Standalone MCP library using `tmcp`, reusable outside Storybook
99
- **`apps/internal-storybook`**: Test environment for addon integration
1010

11-
**Critical distinction**: The two packages use **different MCP libraries** (`@modelcontextprotocol/sdk` vs `tmcp`). Don't confuse their APIs or patterns.
11+
**Both packages use `tmcp`** with HTTP transport and Valibot schema validation for consistent APIs.
1212

1313
### Addon Architecture
1414

1515
The addon uses a **Vite plugin workaround** to inject middleware (see `packages/addon-mcp/src/preset.ts`):
1616

1717
- Storybook doesn't expose an API for addons to register server middleware
1818
- Solution: Inject a Vite plugin via `viteFinal` that adds `/mcp` endpoint
19-
- Handler in `mcp-handler.ts` creates session-based MCP servers using `StreamableHTTPServerTransport`
19+
- Handler in `mcp-handler.ts` creates MCP servers using `tmcp` with HTTP transport
2020

2121
### MCP Library Architecture
2222

@@ -39,17 +39,26 @@ The `@storybook/mcp` package (in `packages/mcp`) is framework-agnostic:
3939
- Run `pnpm dev` at root for parallel development
4040
- Run `pnpm storybook` to test addon (starts internal-storybook + addon dev mode)
4141

42-
**Build tools differ by package:**
42+
**Build tools:**
4343

44-
- `packages/mcp`: Uses `tsdown` (rolldown-based, faster builds)
45-
- `packages/addon-mcp`: Uses `tsup` (esbuild-based)
44+
- All packages use `tsdown` (rolldown-based bundler)
45+
- Shared configuration in `tsdown-shared.config.ts` at monorepo root
46+
- Individual packages extend shared config in their `tsdown.config.ts`
4647

4748
**Testing:**
4849

4950
- Only `packages/mcp` has tests (Vitest with coverage)
5051
- Run `pnpm test run --coverage` in mcp package
5152
- Prefer TDD when adding new tools
5253

54+
**Type checking:**
55+
56+
- All packages have TypeScript strict mode enabled
57+
- Run `pnpm typecheck` at root to check all packages
58+
- Run `pnpm typecheck` in individual packages for focused checking
59+
- CI enforces type checking on all PRs
60+
- Type checking uses `tsc --noEmit` (no build artifacts, just validation)
61+
5362
**Debugging MCP servers:**
5463

5564
```bash
@@ -89,36 +98,37 @@ import pkgJson from '../package.json' with { type: 'json' };
8998
1. Create `src/tools/my-tool.ts`:
9099

91100
```typescript
92-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
93-
import z from 'zod';
101+
import type { McpServer } from 'tmcp';
102+
import * as v from 'valibot';
103+
import type { AddonContext } from '../types.ts';
94104

95105
export const MY_TOOL_NAME = 'my_tool';
96106

97-
export function registerMyTool({
98-
server,
99-
options,
100-
}: {
101-
server: McpServer;
102-
options: Options;
103-
}) {
104-
server.registerTool(
105-
MY_TOOL_NAME,
107+
const MyToolInput = v.object({
108+
param: v.string()
109+
});
110+
111+
type MyToolInput = v.InferOutput<typeof MyToolInput>;
112+
113+
export async function addMyTool(server: McpServer<any, AddonContext>) {
114+
server.tool(
106115
{
116+
name: MY_TOOL_NAME,
107117
title: 'My Tool',
108118
description: 'What it does',
109-
inputSchema: z.object({ param: z.string() }),
119+
schema: MyToolInput,
110120
},
111-
async ({ param }, { sessionId }) => {
121+
async (input: MyToolInput) => {
112122
// Implementation
113123
return {
114-
/* result */
124+
content: [{ type: 'text', text: 'result' }],
115125
};
116126
},
117127
);
118128
}
119129
```
120130

121-
2. Register in `src/mcp-handler.ts` after existing tools
131+
2. Import and call in `src/mcp-handler.ts` within `createAddonMcpHandler`
122132

123133
### In mcp package (`packages/mcp`):
124134

@@ -157,11 +167,14 @@ export async function addMyTool(server: McpServer<any, StorybookContext>) {
157167

158168
## Special Build Considerations
159169

160-
**JSON tree-shaking:**
170+
**Shared tsdown configuration:**
161171

162-
- `packages/mcp/tsdown.config.ts` has custom plugin to work around rolldown bug
172+
- `tsdown-shared.config.ts` at monorepo root contains shared build settings
173+
- Targets Node 20.19 (minimum version supported by Storybook 10)
174+
- Includes custom JSON tree-shaking plugin to work around rolldown bug (see [rolldown#6614](https://github.com/rolldown/rolldown/issues/6614))
163175
- Only includes specified package.json keys in bundle (name, version, description)
164-
- If adding new package.json properties to code, update plugin
176+
- If adding new package.json properties to code, update the `jsonTreeShakePlugin` keys array in shared config
177+
- Individual packages extend this config and specify their entry points
165178

166179
**Package exports:**
167180

@@ -191,3 +204,16 @@ For detailed package-specific guidance, see:
191204

192205
- `packages/addon-mcp/**``.github/instructions/addon-mcp.instructions.md`
193206
- `packages/mcp/**``.github/instructions/mcp.instructions.md`
207+
208+
## Documentation resources
209+
210+
When working with the MCP server/tools related stuff, refer to the following resources:
211+
212+
- https://github.com/paoloricciuti/tmcp/tree/main/packages/tmcp
213+
- https://github.com/paoloricciuti/tmcp/tree/main/packages/transport-http
214+
- https://github.com/paoloricciuti/tmcp
215+
216+
When working on data validation, refer to the following resources:
217+
218+
- https://valibot.dev/
219+
- https://github.com/paoloricciuti/tmcp/tree/main/packages/adapter-valibot

0 commit comments

Comments
 (0)