Generative UI for data visualization. This lab explores how MCP Apps and web components can give LLM chat applications first-class data visualization tools. The goal is to prove a white-label approach: a baseline chart library that can be branded and embedded into chat experiences.
MCPJam Inspector: https://app.mcpjam.com/shared/edu-mcp-app-live/1CD8UxW3lT1FwVFXcGZM_
- MCP App patterns for data visualization in LLM chat
- Web component chart primitives built with Plot
- A white-label design system driven by host CSS variables
- Composition between web components and visualization vocabularies
- Build web component charts with Plot
- Expose UI tools to LLMs for controlling and interacting with charts
- Create a design system that adapts to host interfaces
- Provide chart tools for:
- Line chart
- Bar chart
- Scatterplot
- Bonus: publish components as a package or registry
- Bar chart MCP App widget
- Line chart MCP App widget
- Scatterplot MCP App widget
- MCP server wiring to serve MCP Apps to chat clients
- Expand the chart catalog (compositional layouts, multi-series, annotations)
- Theming system based on host CSS variables
- Connect to a real data source (Postgres-backed reporting dashboard)
- Explore web component composition patterns for chart vocabularies
- Build a separate MCP server for the reporting dashboard and connect it to chat
- Prove a host-injected theming system for MCP Apps
- Test composition patterns with Plot/D3 and vocabulary primitives
# Install dependencies
bun install
# Start development
bun dev
# Build for production
bun run buildFormat and lint the codebase using Biome:
# Format code
bun format
# Lint code
bun lint
# Type check
bun type-checkRun tests across the monorepo:
# Run all unit tests
bun run test
# Run tests for specific apps
bun run test --filter=client
bun run test --filter=server
# Run E2E and visual regression tests
bun run test:e2e
# Update visual regression baselines
bun run test:e2e -- --update-snapshots- Client: Vitest 4.x with Browser Mode (Playwright), vitest-browser-react
- Server: Vitest 4.x with Node environment, @effect/vitest
- E2E: Playwright with visual regression testing
| Workflow | Trigger | Purpose |
|---|---|---|
check-client |
PR + main | Fast: lint, types, unit tests |
check-server |
PR + main | Fast: lint, types, unit tests |
post-merge |
main only | Slow: E2E, visual regression |
Visual regression baselines are stored in e2e/smoke.spec.ts-snapshots/ and
should be committed to git. Update them when UI changes are intentional.
.
├── apps/
│ ├── client/ # React frontend (Vite + React)
│ ├── server/ # Bun + Effect backend API
│ └── server-mcp/ # Model Context Protocol server
├── e2e/ # Playwright end-to-end tests
├── packages/
│ ├── ai/ # AI services and toolkits
│ ├── config-typescript/ # TypeScript configurations
│ ├── domain/ # Shared Schema definitions
│ ├── observability/ # OpenTelemetry setup
│ ├── presence/ # Presence tracking service
│ ├── widget-bar-chart/ # MCP App bar chart widget
│ ├── widget-line-chart/ # MCP App line chart widget
│ └── widget-scatterplot/ # MCP App scatterplot widget
├── docker-compose.yaml # Docker Compose configuration for deployment
├── package.json # Root package.json with workspaces
└── turbo.json # Turborepo configuration| App | Description |
|---|---|
client |
A React app built with Vite |
server |
A Effect Platform backend API |
server-mcp |
A Model Context Protocol server built with Effect |
| Package | Description |
|---|---|
@repo/config-typescript |
TypeScript configurations used throughout the monorepo |
@repo/domain |
Shared Schema definitions using Effect Schema used by both client and server |
@repo/ai |
AI tooling and service layers built on @effect/ai |
@repo/observability |
Shared OpenTelemetry setup |
@repo/presence |
Presence tracking service for WebSocket clients |
widget-bar-chart |
MCP App bar chart widget |
widget-line-chart |
MCP App line chart widget |
widget-scatterplot |
MCP App scatterplot widget |
# Start development server
bun dev
# Run specific app
bun dev --filter=client
bun dev --filter=server
bun dev --filter=server-mcp
# Build all apps
bun run build
# Test MCP server functionality (MCPJam Inspector)
bun --filter=server-mcp run inspectorTo run the application using Docker, you can use the provided
docker-compose.yaml file.
First, ensure you have Docker and Docker Compose installed on your system.
Then, run the following command to build and start the services in the background:
docker-compose up -d --buildThis will start all three services: client, server, and server-mcp.
You can configure the deployment using environment variables:
# Example .env file
CLIENT_PORT=3000
SERVER_PORT=9000
MCP_PORT=9009Import shared types from the domain package:
import { ApiResponse } from "@repo/domain/Api";