npm package: @mise-en-scene/server
Description: Design studio MCP + HTTP server — browser preview, export, versioning, typography
Latest version: 0.1.2

# @mise-en-scene/server

Design studio MCP + HTTP server. Serves HTML designs in the browser with hot-reload, exports to SVG/PNG/JPG/PDF, manages design versions with branching, and provides typography intelligence.

## MCP Tools

### Core

| Tool | Input | Description |
|------|-------|-------------|
| `studio_preview` | `html`, `filename?` | Write HTML+CSS+SVG to preview server, triggers hot-reload |
| `studio_feedback` | — | Read user interaction feedback (click selections) |
| `studio_screenshot` | `selector?` | Capture screenshot for self-critique (returns image) |
| `studio_export` | `format`, `width?`, `height?`, `preset?`, `quality?` | Export to SVG, PNG, JPG, or PDF |

### Versioning

| Tool | Input | Description |
|------|-------|-------------|
| `studio_branch` | `name`, `from_branch?`, `from_version?` | Create a design branch |
| `studio_checkout` | `branch`, `version?` | Switch to a branch or version |
| `studio_gallery` | — | Open the version gallery in browser |

### Typography

| Tool | Input | Description |
|------|-------|-------------|
| `studio_font_suggest` | `mood`, `context?` | Get curated font pairing suggestions |
| `studio_font_analyze_url` | `url` | Extract font stack from any website |
| `studio_font_scale` | `base_size?`, `ratio?` | Generate a modular type scale |
| `studio_font_embed` | `fonts[]` | Generate @font-face CSS with base64 woff2 |

## Usage

### As an MCP Server

```json
{
  "mcpServers": {
    "mise-en-scene-server": {
      "command": "npx",
      "args": ["@mise-en-scene/server"]
    }
  }
}
```

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `MISE_PORT` | `3333` | HTTP server port |
| `MISE_DESIGN_DIR` | `mise-en-scene/main` | Directory for design files |

## Components

### HTTP Server

Zero-dependency HTTP server (no Express). Serves the newest `.html` file from the design directory with runtime injection — a `<script>` tag and `<link>` to the client-side runtime are added automatically.

Routes:

| Route | Description |
|-------|-------------|
| `GET /` | Serve newest HTML design with runtime injection |
| `GET /gallery` | Version gallery with thumbnail grid |
| `GET /mise-en-scene.js` | Client-side runtime |
| `GET /styles.css` | Selection highlight styles |

### WebSocket Server

Real-time communication between the browser and the MCP server:

- **Server → Browser**: `reload` (trigger page refresh), `highlight` (visual feedback)
- **Browser → Server**: `select` (user clicked an element — captured as feedback)

### File Watcher

Uses chokidar to watch the design directory for `.html` file changes. Triggers WebSocket `reload` broadcast on new or modified files.

### Export Pipeline

Lazy-loads Puppeteer on first use. Supports four export formats:

| Format | Engine | Notes |
|--------|--------|-------|
| SVG | SVGO | Extracts inline SVGs, optimizes with multipass |
| PNG | Puppeteer | Full-page or selector-based capture |
| JPG | Puppeteer | Configurable quality (1-100) |
| PDF | Puppeteer | Configurable dimensions, print media |

#### Dimension Presets

13 built-in presets across three categories:

**Social:**
`instagram-post` (1080x1080), `instagram-story` (1080x1920), `twitter-post` (1200x675), `twitter-header` (1500x500), `facebook-post` (1200x630), `linkedin-post` (1200x627), `og-image` (1200x630)

**Web:**
`desktop-hd` (1920x1080), `desktop` (1440x900), `tablet` (768x1024), `mobile` (375x812)

**Print:**
`a4` (2480x3508 @ 300dpi), `letter` (2550x3300 @ 300dpi)

### Screenshot

Captures the current design state as a PNG image. Used by the agent for self-critique — screenshot the design, analyze it against the taste profile, fix issues before presenting to the user.

```
studio_screenshot()           → full page capture
studio_screenshot("h1")       → capture specific element
studio_screenshot(".header")  → capture by CSS selector
```

Returns image data as base64 in the MCP response (not written to disk).

### Version Manager

Git-inspired branching for design iterations:

```
studio_preview(html)              → saves as next version on current branch
studio_branch("dark-theme")      → fork from current version
studio_checkout("main", 2)       → switch to main/v2
studio_gallery()                  → view all branches and versions
```

Versions are stored as flat HTML files (`v1.html`, `v2.html`, ...) organized by branch. Metadata is persisted in `meta.json`:

```json
{
  "branches": {
    "main": { "versions": [1, 2, 3] },
    "dark-theme": { "forkedFrom": { "branch": "main", "version": 2 }, "versions": [1] }
  },
  "stars": [{ "branch": "main", "version": 2 }],
  "current": { "branch": "main", "version": 3 }
}
```

### Typography Intelligence

#### Font Registry

35+ fonts classified by category and subtype:

| Category | Subtypes |
|----------|----------|
| Serif | old-style, transitional, modern, slab |
| Sans-serif | grotesque, neo-grotesque, geometric, humanist |
| Display | creative, bold, futuristic |
| Monospace | technical, terminal |

Each font entry includes `category`, `subtype`, `era`, and `mood` descriptors.

#### Curated Pairings

8 aesthetic presets with display + body font pairings, Google Fonts import URLs, and mood descriptions:

| Aesthetic | Display | Body | Mood |
|-----------|---------|------|------|
| dark-premium | Fraunces | Outfit | Elegant, editorial |
| clean-minimal | Satoshi | Satoshi | Confident, modern |
| neobrutalism | Space Grotesk | Space Mono | Technical, raw |
| editorial | Instrument Serif | Instrument Sans | Refined, readable |
| y2k-cyber | Orbitron | JetBrains Mono | Sci-fi, technical |
| warm-scandinavian | DM Serif Display | DM Sans | Approachable, refined |
| creative-playful | Bricolage Grotesque | Bricolage Grotesque | Expressive, bold |
| luxury | Playfair Display | Source Sans 3 | Classic, timeless |

#### Font Suggestion Engine

`studio_font_suggest(mood)` scores pairings against the mood query using token-based text similarity, filters out avoided fonts, and returns the top 3 matches.

#### Type Scale Generator

`studio_font_scale(base_size, ratio)` generates CSS custom properties for a modular type scale:

| Ratio | Name | Use Case |
|-------|------|----------|
| 1.2 | Minor Third | Body-heavy, readability |
| 1.25 | Major Third | General purpose |
| 1.333 | Perfect Fourth | Balanced drama |
| 1.618 | Golden Ratio | Posters, maximum drama |

Produces 11 named steps (xs through 7xl) with size, line-height, and letter-spacing. Headlines get tighter line-height and tracking automatically.

#### URL Font Analyzer

`studio_font_analyze_url(url)` launches Puppeteer, navigates to the URL, and extracts computed font families, weights, and styles from common HTML elements.

#### Font Embedder

`studio_font_embed(fonts)` fetches woff2 files from URLs and returns `@font-face` CSS with base64-inlined font data — for self-contained SVG exports.

## Feedback System

User interactions in the browser are captured as JSON Lines in a `.feedback` file:

```jsonl
{"type":"select","element":{"tag":"h1","classes":["title"],"text":"Hello"},"timestamp":1710...}
```

The agent reads feedback via `studio_feedback`, interprets selections, and records design decisions in taste memory.

## Client Runtime

The browser runtime (`mise-en-scene.js`) provides:

- **WebSocket connection** with auto-reconnect (2s backoff)
- **Live reload** on design file changes
- **Click-to-select** — clicking any element sends a `select` event to the server
- **Visual feedback** — selected elements get a `.mise-selected` outline

## Development

```bash
npm test                # Run tests (42 unit + 3 integration + 6 Puppeteer)
npm run build           # Compile TypeScript
npm run test:watch      # Watch mode
```