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.

Three connection modes — pick the one that matches your workflow. All three converge on the same Studio canvas via Supabase Realtime.

Connection Modes

Local:7428

Dev Mode (stdio)

For developing Studio itself. MCP server runs locally via stdio, bridge daemon on localhost:7428, SSE to browser. ~40ms latency.

Remotemcp.shavin.cc

Remote Mode (HTTP)

For IDE-based AI agents (Cursor, Claude Code, VS Code, Codex). Streamable HTTP transport with Supabase OAuth. ~300ms latency.

Pairing6-char code

Studio 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-key

Tools available: 24 (dev bridge + filesystem filtered out). Auth: Supabase JWT Bearer token. Latency: ~300ms (cloud round-trip).

Auth auto-disabled in dev: If Supabase env vars are not set, the remote server skips token validation — useful for local testing.

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:

  1. Open studio.shavin.cc and click "Connect AI"
  2. Studio generates a 6-character pairing code (expires in 10 minutes)
  3. Share the code with your AI agent in the chat
  4. The AI sends composed blocks via the REST relay API
  5. Blocks appear on your canvas in real-time via Supabase Realtime
No MCP server needed: The browser AI just needs to POST to the relay endpoint. The pairing code is the session link.

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_inject

Inject BlockNode[] tree (replace or append mode)

canvas_theme

Update theme: accent, gray, radius, dark, scaling, panelBackground

canvas_clear

Remove all blocks from canvas

canvas_select

Select 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 expired

MCP Studio Relay Tools (7)

These 7 tools are available in both Dev Mode and Remote Mode for controlling a Studio canvas via MCP:

connect_studioTool

Connect to a Studio session by 6-char pairing code. Waits for Studio confirmation.

args: pairingCode (string), agentName? (string)

compose_to_canvasTool

Synthesize a full page or section via the layout pipeline and inject it as JSX.

args: prompt (string), category? (string), mode? ("replace"|"append")

inject_blocksTool

Inject a raw BlockNode[] tree directly into the canvas.

args: blocks (Block[]), mode? ("replace"|"append")

set_studio_themeTool

Update the Studio canvas theme (accent, gray, radius, dark mode, scaling).

args: accent?, gray?, radius?, dark?, scaling?, panelBackground?

get_studio_stateTool

Request current canvas state (blocks + theme) from Studio. Request-response with timeout.

args: timeoutMs? (number, default 5000)

clear_studio_canvasTool

Remove all blocks from the canvas.

args: none

disconnect_studioTool

Send 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)

28

All tools — including dev bridge + filesystem

remote (Cloud)

24

Dev bridge + filesystem filtered out

rest (Pairing)

7

Studio relay + knowledge + synthesis only

Safety & Rate Limits

Payload

Max 500KB per inject. Oversized payloads are rejected with a console error.

Rate

Minimum 300ms between injects. Rapid mutations are debounced to avoid canvas thrash.

TTL

Pairing codes expire in 10 minutes. Connected sessions stay alive until either side disconnects.

Heartbeat

Agent sends heartbeat every 15s. Studio checks every 5s. 30s without heartbeat = auto-disconnect.

No JS execution

Unlike Figma's use_figma (arbitrary JS), Shavin injects a BlockNode[] tree — safer, no code execution on the canvas.

Undo

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.
Tip: Use 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.

Figma comparison: Both Figma and Shavin compose from scratch using their component libraries. But only Shavin outputs a real website — Figma outputs a picture of one. The AI doesn't need a "Code Connect" layer because the canvas IS the code.

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                        │
└─────────────────────────────────────────────────────────────────┘

Related

Configure Theme
Theme
Accent Color
Custom
Gray Family
Appearance
Radius
Scaling
Panel Style
Heading Font
Body Font