AI → Studio: Real-Time Design Bridge
What is the AI → Studio Bridge?
The AI → Studio Bridge lets an AI agent (Cursor, Claude Code, ChatGPT, etc.) connect to your Shavin Studio canvas and compose designs in real-time — while you watch. No terminal, no dev server, no code. It's like having an AI co-designer in Figma, but one that outputs a real website, not a picture of one.
Connection Modes
:7428Dev Mode (stdio)
For developing Studio itself. MCP server runs locally via stdio, bridge daemon on localhost:7428, SSE to browser. ~40ms latency.
mcp.shavin.ccRemote Mode (HTTP)
For IDE-based AI agents (Cursor, Claude Code, VS Code, Codex). Streamable HTTP transport with Supabase OAuth. ~300ms latency.
6-char codeStudio Pairing
For browser-only AI (Claude.ai, ChatGPT). Studio generates a 6-char pairing code; AI sends blocks via REST relay + Realtime.
Mode 1: Dev Mode (Local Bridge)
The original Shavin MCP server, running locally via stdio. Best for developers working on the Studio codebase itself. The bridge daemon on localhost:7428 provides real-time DOM audit and SSE streaming.
# Cursor (.cursor/mcp.json)
{
"mcpServers": {
"shavin": {
"command": "npx",
"args": ["-y", "@shavin/mcp"]
}
}
}Tools available: 28 (all — including dev bridge + filesystem). Latency: ~40ms.
Mode 2: Remote MCP (Cloud) — for IDE Agents
For AI agents running in your IDE (Cursor, Claude Code, VS Code, Codex), connect to the remote MCP server at mcp.shavin.cc/mcp. Uses Streamable HTTP transport with Supabase OAuth (GitHub/Google).
# Cursor (.cursor/mcp.json) — Remote mode
{
"mcpServers": {
"shavin": {
"url": "https://mcp.shavin.cc/mcp",
"transport": "http"
}
}
}Running your own remote server:
# Start remote MCP server on a custom port
npx @shavin/mcp --remote --port 3099
# Hybrid mode (stdio + remote on same process)
npx @shavin/mcp --hybrid
# Environment variables needed
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=your-publishable-keyTools available: 24 (dev bridge + filesystem filtered out). Auth: Supabase JWT Bearer token. Latency: ~300ms (cloud round-trip).
Mode 3: Studio Pairing — for Browser AI
For AI agents that live in the browser (Claude.ai, ChatGPT) and can't run a local MCP server. The workflow is:
- Open
studio.shavin.ccand click "Connect AI" - Studio generates a 6-character pairing code (expires in 10 minutes)
- Share the code with your AI agent in the chat
- The AI sends composed blocks via the REST relay API
- Blocks appear on your canvas in real-time via Supabase Realtime
REST Relay API Reference
The REST relay allows browser-based AI to inject blocks into a Studio canvas without an MCP server. All endpoints are on api.shavin.cc.
POST /studio-relay/{code}
Inject blocks or change theme on the paired Studio canvas.
POST https://api.shavin.cc/studio-relay/ABC123
Content-Type: application/json
{
"event": "canvas_inject",
"payload": {
"blocks": [
{
"id": "block-1",
"type": "Container",
"props": { "padding": "5", "className": "flex flex-col gap-4" },
"children": [
{
"id": "block-2",
"type": "Heading",
"props": { "size": "2", "children": "Hello from AI" },
"children": []
}
]
}
],
"mode": "replace"
}
}mode can be "replace" (default) or "append" for incremental composition.
Supported event types:
canvas_injectInject BlockNode[] tree (replace or append mode)
canvas_themeUpdate theme: accent, gray, radius, dark, scaling, panelBackground
canvas_clearRemove all blocks from canvas
canvas_selectSelect a node by id on the canvas
GET /studio-relay/{code}/status
Check if a pairing code is valid and if an agent has connected.
GET https://api.shavin.cc/studio-relay/ABC123/status
# 200 OK
{
"code": "ABC123",
"status": "waiting",
"createdAt": "2026-09-22T10:30:00Z",
"expiresAt": "2026-09-22T10:40:00Z"
}
# 404 — code not found or expiredMCP Studio Relay Tools (7)
These 7 tools are available in both Dev Mode and Remote Mode for controlling a Studio canvas via MCP:
connect_studioToolConnect to a Studio session by 6-char pairing code. Waits for Studio confirmation.
args: pairingCode (string), agentName? (string)
compose_to_canvasToolSynthesize a full page or section via the layout pipeline and inject it as JSX.
args: prompt (string), category? (string), mode? ("replace"|"append")
inject_blocksToolInject a raw BlockNode[] tree directly into the canvas.
args: blocks (Block[]), mode? ("replace"|"append")
set_studio_themeToolUpdate the Studio canvas theme (accent, gray, radius, dark mode, scaling).
args: accent?, gray?, radius?, dark?, scaling?, panelBackground?
get_studio_stateToolRequest current canvas state (blocks + theme) from Studio. Request-response with timeout.
args: timeoutMs? (number, default 5000)
clear_studio_canvasToolRemove all blocks from the canvas.
args: none
disconnect_studioToolSend agent_disconnect, tear down the Realtime channel, clean up the session.
args: none
Transport-Aware Tool Loading
The MCP server automatically filters its tool surface based on transport mode:
stdio (Dev)
28All tools — including dev bridge + filesystem
remote (Cloud)
24Dev bridge + filesystem filtered out
rest (Pairing)
7Studio relay + knowledge + synthesis only
Safety & Rate Limits
Max 500KB per inject. Oversized payloads are rejected with a console error.
Minimum 300ms between injects. Rapid mutations are debounced to avoid canvas thrash.
Pairing codes expire in 10 minutes. Connected sessions stay alive until either side disconnects.
Agent sends heartbeat every 15s. Studio checks every 5s. 30s without heartbeat = auto-disconnect.
Unlike Figma's use_figma (arbitrary JS), Shavin injects a BlockNode[] tree — safer, no code execution on the canvas.
Every AI inject, theme change, and clear is recorded in undo history. Press ⌘Z to revert any AI composition.
Example Prompts — How to Talk to Your AI
Here are example prompts you can give your AI agent once it's connected to your Studio canvas:
Compose a full landing page:
Connect to my Studio with pairing code ABC123.
Then compose a SaaS landing page for a project management tool
called "Flowstate". Include a hero with a bold headline and CTA,
a features bento grid, a pricing section with 3 tiers, and a footer.
Use the Shavin design system tokens — accent color "grass", dark mode.
Inject it on my canvas.Scaffold a dashboard:
Connect to Studio with code ABC123.
Compose an analytics dashboard with a sidebar navigation,
a top stats row (4 metric cards), a revenue line chart placeholder,
and a recent activity table. Use high-density mode (scaling 95%).
Append it to whatever is already on my canvas.Iterate on a section:
Get the current state of my Studio canvas.
Now replace the hero section with a more minimal version —
just a headline, subheadline, and a single CTA button.
Keep the rest of the page unchanged. Use append mode.Change the theme:
Connect to my Studio with code ABC123.
Set the theme to: accent color "violet", gray color "slate",
radius "full", dark mode on, scaling 100%.Clear and start fresh:
Connect to Studio code ABC123.
Clear the canvas, then compose a pricing page with 3 tiers:
"Starter" ($0), "Pro" ($29), "Enterprise" (custom).
The Pro tier should be highlighted as the popular choice.compose_to_canvas for natural-language descriptions (it runs through the layout synthesis pipeline) and inject_blocks when you need precise control over the BlockNode tree structure.What Can the AI Compose?
The AI composes from the full @shavin/ui primitive set — 71 Radix-backed components rendered through the Studio BlockRenderer. The block registry provides 54 convenience accelerators, but the AI is not limited to them:
53 registered component types
Every @shavin/ui primitive is available in the BlockRenderer registry — Container, Heading, Button, Card, Text, Flex, Grid, Badge, Input, Select, Dialog, Popover, Menu, Tooltip, Checkbox, Switch, Radio, Avatar, Tabs, Accordion, Callout, and more.
19 native HTML tags
Raw HTML nodes for div, span, p, a, img, ul, li, table, form, input, button, and more — for when a Shavin primitive doesn't exist yet.
JSX → Tree parser
The parseTsxToBlocks() function parses ANY JSX source into a BlockNode[] tree. The AI can write raw JSX and it renders live on the canvas.
Tree → TSX export
The generateBlocksToTsx() function exports the canvas tree back to clean, deployable TSX code. What you see is what you ship.
Architecture at a Glance
┌─────────────────────────────────────────────────────────────────┐
│ Three Connection Modes │
├──────────────────┬──────────────────┬───────────────────────────┤
│ Mode 1: Dev │ Mode 2: Remote │ Mode 3: Studio Pairing │
│ (stdio → :7428) │ (HTTP → cloud) │ (REST → Realtime) │
│ │ │ │
│ Cursor/Claude │ Cursor/Claude │ Claude.ai / ChatGPT │
│ Code (local) │ Code (any IDE) │ (browser-only) │
│ │ │ │ │ │ │
│ ▼ │ ▼ │ ▼ │
│ localhost:7428 │ mcp.shavin.cc │ api.shavin.cc │
│ (bridge daemon) │ (streamable HTTP)│ (REST relay POST) │
│ │ │ │ │ │ │
│ ▼ │ ▼ │ ▼ │
│ SSE → browser │ Supabase OAuth │ Supabase Realtime │
│ │ → Realtime │ (broadcast channel) │
│ │ │ │
├──────────────────┴──────────────────┴───────────────────────────┤
│ Converge on same canvas │
│ studio.shavin.cc (BlockRenderer) │
│ │
│ canvas_inject → parseTsxToBlocks() → BlockNode[] → render │
│ canvas_theme → ThemeProvider update │
│ canvas_clear → setBlocks([]) │
│ canvas_state → broadcast back to agent │
└─────────────────────────────────────────────────────────────────┘