-
Notifications
You must be signed in to change notification settings - Fork 12
Eval: Add Storybook Dev context, rename Storybook MCP to Storybook Docs #109
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
Conversation
|
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #109 +/- ##
=======================================
Coverage 87.82% 87.82%
=======================================
Files 19 19
Lines 427 427
Branches 122 122
=======================================
Hits 375 375
Misses 8 8
Partials 44 44 ☔ View full report in Codecov by Sentry. |
| // Check for MCP server status in init message | ||
| if ( | ||
| parsed.type === 'system' && | ||
| parsed.subtype === 'init' && | ||
| parsed.mcp_servers && | ||
| parsed.mcp_servers.length > 0 | ||
| ) { | ||
| for (const server of parsed.mcp_servers) { | ||
| if (server.status === 'connected') { | ||
| clackLog.success(`MCP server "${server.name}" connected`); | ||
| } else { | ||
| clackLog.error( | ||
| `MCP server "${server.name}" failed to connect (status: ${server.status})`, | ||
| ); | ||
| process.exit(1); | ||
| } | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a new "Storybook MCP - Dev" context mode that sets up and runs a local Storybook development server with the MCP addon, while renaming the existing remote manifest-based context to "Storybook MCP - Docs" for clarity. This enables testing agents in a live development environment versus documentation-only scenarios.
Key Changes
- New
storybook-mcp-devcontext type that installs Storybook, starts a dev server on a random port, and provides HTTP MCP endpoint - Added dev server lifecycle management with automatic startup during experiment preparation and teardown after agent execution
- Renamed existing Storybook MCP context to "Storybook MCP - Docs" throughout UI, documentation, and code
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| eval/types.ts | Adds storybook-mcp-dev context type definition |
| eval/lib/storybook-dev-server.ts | New module for managing Storybook dev server lifecycle (port allocation, process management, readiness detection) |
| eval/lib/prepare-experiment.ts | Enhanced to install Storybook packages and start dev server for the new context, returns MCP config |
| eval/lib/teardown-experiment.ts | New cleanup module to stop dev server after experiment |
| eval/lib/agents/claude-code-cli.ts | Added MCP server connection validation and logging |
| eval/lib/collect-args.ts | Updated CLI parsing and help text to support new context mode |
| eval/eval.ts | Integrates teardown step and uses prepared MCP config from experiment setup |
| eval/lib/save/google-sheet.ts | Handles new context type in reporting |
| eval/lib/evaluations/prepare-evaluations.ts | Adds @storybook/addon-mcp to evaluation dependencies |
| eval/templates/evaluation/.storybook/main.ts | Simplified config, removed getAbsolutePath helper, added @storybook/addon-mcp |
| eval/README.md | Documentation updates for five context modes instead of four |
| .github/instructions/eval.instructions.md | Comprehensive documentation of new context mode and architecture |
| eval/evals/100-flight-booking-plain/prompt.md | Minor formatting fix (extra blank line) |
| eval/evals/100-flight-booking-plain/explicit-stories.md | New file with story-writing reminder |
| parsed.mcp_servers.length > 0 | ||
| ) { | ||
| for (const server of parsed.mcp_servers) { | ||
| if (server.status === 'connected') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this stage, could the MCP server be pending? Could you let us know how we know it has successfully connected at this stage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good question. I added a comment clarifying what this connection status means.
this is the status as reported by the agent, so this is the source of truth. The agent initialises connections with all servers when the session starts, and if any servers are not ready by this point, they won't be used AFAIK.
| }; | ||
|
|
||
| function getContextDetails(context: Context): string { | ||
| switch (context.type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technical improvement:
I personally like to have exhausting type checks for the default fall-through case, like demonstrated here: https://www.typescriptlang.org/play/?#code/KYOwrgtgBAwg9gGzgJygbwFBSgJWAEwBosoBxZYUY7AIQTGAwF8MMAzMEAYwBcBLOCCgBzYD3hJkAOQCGEYAAouALliIUASlUBnHsj4hh6EtoDufHlwAWUJRuPZsXGduBrJAOjz5lJR1AoeMGQhACIKfFCAbj8oZ1d3FA9yShBff2xA4LDhClBo2IB6QqgAMRRhOB4oGQAjODBqugZY-GA2GTAEHnSMrkFdKGAADytO3T4AN2AYK2AuAGtVEGBp1ABeOJiMqB4rZDhTKBWjgFFkA+QFAAMAVRAxkHwEAjj1VHjgVQASNBGxsATaazeYLJjXDTbKAsJhAA
So whenever the union context.type is extended, TypeScript will error to signal that adjustments are necessary here as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea. However it's already covered without the default case, because the function's return type errors in that scenario too, without a default: https://www.typescriptlang.org/play/?#code/KYOwrgtgBAwg9gGzgJygbwFBSgJWAEwBosoBxZYUY7AIQTGAwF8MMAzMEAYwBcBLOCCgBzYD3hJkAOQCGEYAAouALliIUASlUBnHsj4hh6EtoDufHlwAWUJRuPZsXGduBrJAOjz5lJR1AoeMGQhACIKfFCAbj8oZ1d3FA9yShBff2xA4LDhClBo2IB6QqgAMRRhOB4oGQAjODBqugYSFiYgA
which is also the case for this code specifically.
however I did something that I like even better, I configured the lint rule to handle this:
- https://github.com/storybookjs/mcp/pull/109/files#diff-2113aef2ff3d50c021fca1fb6ecf4d4553a0e3f5f51ded7302ad499e43bc2b1eR3
- https://oxc.rs/docs/guide/usage/linter/rules/typescript/switch-exhaustiveness-check.html
So we don't have to remember to add the runtime code to ensure switches are exhaustive.
| process: Result, | ||
| timeout: number = 10_000, | ||
| ): Promise<void> { | ||
| return await new Promise<void>((resolve, reject) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you returning a new Promise inside of an async function, instead of using await inside and throwing errors directly? Is it because of the onExit callback function, which is passed to the off,on event listeners?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's the basic pattern of turning callbacks into promises - onData, onExit and setTimeout. I don't think there's any other way of doing it, except for Promise.withResolvers which I'm fine with too.
Even though the function is async, there's nothing we could await here.
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

This PR introduces another context type: Storybook MCP - Dev.
When using that, Storybook is set up in the experiment, its dev server is started and the dev server's MCP server is configured for the agent.
The existing Storybook MCP context has been renamed to Storybook MCP - Docs, to signify it's the docs-only (ie "remote") Storybook MCP version.