@via-ds/mcp
v0.0.3
Published
MCP server for the Via Design System
Readme
@via-ds/mcp
An MCP (Model Context Protocol) server for the Via Design System. It exposes component documentation and interactive story previews from Storybook, making Via components discoverable and usable by AI tools.
How it works
The server wraps the Via Storybook instance and surfaces its component manifest over HTTP as MCP tools. On startup it checks that Storybook's manifest is reachable before accepting JSON-RPC requests at http://{host}:{port}/mcp. In production this check retries with backoff for a bounded window (Storybook is a separately deployed instance, so it may still be rolling out) before exiting if it's still unreachable; in development it prompts interactively instead.
AI client → MCP HTTP endpoint → tool handlers → Storybook manifest / iframeTools
| Tool | Description |
| ----------------------------- | -------------------------------------------------- |
| list-all-documentation | Lists all available Via components |
| get-documentation | Returns documentation for a component |
| get-documentation-for-story | Returns documentation for a specific story variant |
| get-story-ui | Returns an interactive iframe preview of a story |
The Storybook tools (list-all-documentation, get-documentation, get-documentation-for-story) come from @storybook/mcp. get-story-ui is a custom tool that generates an HTML resource (ui://get-story-ui/{storyId}) pointing to the Storybook iframe.
Resources
| URI template | MIME type | Description |
| ----------------------------- | ----------- | --------------------------------------- |
| ui://get-story-ui/{storyId} | text/html | Sandboxed iframe rendering a live story |
Running locally
The MCP server requires a running Storybook instance (default: http://127.0.0.1:6006).
Development (auto-reloads on source changes):
# In repo root — start Storybook
pnpm storybook
# In packages/mcp — start the MCP server
pnpm devTesting with an MCP client:
We recommend using MCPJam to inspect and interact with the server during local development. It provides a visual interface for browsing tools, resources, and sending requests — useful for verifying changes without wiring up a full AI client.
Adding to an MCP client
The recommended way to connect is through MongoDB's shared devprod-mcp-gateway, which proxies Via alongside other internal MCP backends (Jira, Confluence, Evergreen, etc.) behind a single connection. Any MCP client that supports stdio servers can run devprod-mcp-proxy --gateway <url> — for example, in Claude Code (user scope), this will prompt you to sign in to Dex using your Okta credentials:
claude mcp add --scope user devprod-mcp-gateway \
--transport stdio \
-- devprod-mcp-proxy \
--gateway https://app.devprod-mcp-gateway.prod.corp.mongodb.com/mcpThen enable the via-mcp backend for your session — ask your AI assistant to call manage_tools with action: "subscribe" and backend: "via-mcp" (in Claude Code, just ask Claude directly).
Deployment
Deployments are managed by Drone CI and run automatically on every push to main.
Staging and production builds are deployed using Kubernetes on Kanopy as the via-mcp release. Helm values for each environment live alongside the package (e.g. helm.staging.yml).
The staging deployment is reachable at:
https://via-mcp.ux-foundations.staging.corp.mongodb.com/mcpThe server exposes a /healthz endpoint used by Kubernetes liveness and readiness probes.
Storybook is deployed separately as its own via-storybook Kanopy release (see .storybook/Dockerfile and its Helm values) — VIA_STORYBOOK_URL on this deployment points at that instance's ingress host rather than a Storybook bundled into this image. Any self-hosted deployment of this image must point VIA_STORYBOOK_URL at its own running Storybook instance with the components manifest enabled.
Evals
The evals/ directory measures how well a model uses this MCP server to build real
Via UI. Results are tracked in Braintrust under the "Via MCP" project.
The eval harness and the full guide to writing evals live in
@via-ds/eval-library — read that first for
prerequisites, commands, scorers, and the step-by-step recipe for adding an eval.
This section covers only what is specific to the MCP evals.
Run them with:
pnpm -w eval:mcpThis needs a running MCP server, seeded datasets, and (for the Coding eval) the sandbox container image built. See Prerequisites.
The two MCP evals
| Eval | Pattern | Runner | Measures |
| ---------- | ------- | ---------------- | ------------------------------------------------------------------------------------ |
| Coding | Coding | runCodingAgent | An agent gets a UI task, consults the MCP docs tools, and writes a working component |
| Quiz | Q&A | runAgenticEval | An agent answers design-guidance questions using the MCP server |
Coding is scored on MCP tool usage, import correctness, build quality, docs adherence, and design correctness. Quiz is scored on semantic similarity to hand-authored expected answers.
Coding scenarios
| Scenario | withVia | Description |
| -------------------- | --------- | --------------------------------------------------- |
| welcome-banner | false | Fresh project — agent must discover and install Via |
| status-dashboard | true | Via pre-installed — build a multi-card dashboard |
Quiz scenarios
Design-guidance questions on component selection, variant rules, and accessibility. Expected answers are hand-authored against the Via documentation.
Seeding the datasets
Scenarios live in Braintrust, not in this repo. Re-run the relevant seed script
whenever you add or edit a scenario (records upsert by id, so this is safe to
repeat):
npx braintrust eval packages/mcp/evals/coding.dataset.tsnpx braintrust eval packages/mcp/evals/quiz.dataset.tsHigh-level flow
flowchart TD
Datasets["Braintrust Datasets\ncoding.dataset.ts · quiz.dataset.ts"]
Datasets --> CodingEval["coding.eval.ts"]
Datasets --> QuizEval["quiz.eval.ts"]
MCP["Via MCP server"]
subgraph CodingPath ["Coding eval"]
CodingEval --> CodingAgent["runCodingAgent\nopencode in sandbox container"]
CodingAgent --> Output["IsolatedEvalOutput"]
Output --> Scorers["Scorers\ntool-calls · code-imports\ncode-quality · docs-adherence\ndesign-correctness"]
end
subgraph QuizPath ["Quiz eval"]
QuizEval --> AgenticEval["runAgenticEval\nGrove agentic loop"]
AgenticEval --> TextOut["text response"]
TextOut --> AnsCorrectness["Scorers\nAnswerCorrectness\nsemantic similarity"]
end
CodingAgent <-->|MCP tool calls| MCP
AgenticEval <-->|MCP tool calls| MCP
Scorers --> Braintrust["Braintrust\nexperiment results + traces"]
AnsCorrectness --> BraintrustEval files in this package
| File | Role |
| -------------------------------------------------- | -------------------------------------- |
| evals/coding.eval.ts | Coding eval (Braintrust Eval) |
| evals/quiz.eval.ts | Quiz eval (Braintrust Eval) |
| evals/coding.dataset.ts | Seeds the Coding dataset in Braintrust |
| evals/quiz.dataset.ts | Seeds the Quiz dataset in Braintrust |
Harness files are listed in the eval-library README.
Environment variables
| Variable | Default | Description |
| ------------------------- | ----------------------- | ----------------------------------------------------------------------------- |
| VIA_STORYBOOK_URL | http://127.0.0.1:6006 | Base URL of the Storybook instance |
| VIA_MCP_HOST | 127.0.0.1 | Bind address for the MCP HTTP server |
| PORT | — | Fallback port (used by Kubernetes); takes effect when VIA_MCP_PORT is unset |
| VIA_MCP_PORT | 3333 | Port for the MCP HTTP server |
| VIA_MCP_PATH | /mcp | HTTP path for the MCP endpoint |
| NODE_ENV | — | Set to production to disable interactive Storybook retry prompts |
| VIA_MCP_URL | — | MCP endpoint URL used by evals (e.g. http://127.0.0.1:3333/mcp) |
| GROVE_API_KEY | — | MongoDB Grove API key used by evals |
| GROVE_API_KEY_SECONDARY | — | Fallback for GROVE_API_KEY |
| VOYAGE_API_KEY | — | Voyage AI key used by the quiz eval's answer-correctness scorer |
| BRAINTRUST_API_KEY | — | Braintrust API key for logging eval results |
Copy .env.example to .env to configure locally.
Package structure
src/
├── server.ts # CLI entry point — starts the HTTP server
├── index.ts # Library export (createViaMCPHandler)
├── createViaMcpHandler.ts # MCP server factory — registers tools and resources
├── storybookManifestPreflight.ts # Blocks startup until Storybook manifest is reachable
└── tools/
└── get-story-ui.ts # Custom tool for interactive story previews
evals/
├── coding.eval.ts # Coding agent eval (Braintrust)
├── coding.dataset.ts # Seeds the Coding dataset in Braintrust
├── quiz.eval.ts # Quiz eval — design-guidance Q&A (Braintrust)
└── quiz.dataset.ts # Seeds the Quiz dataset in Braintrust