# Dazzle
> Cloud stages for AI agents and live streaming.
> https://dazzle.fm
## Overview
Dazzle gives you cloud stages — isolated environments that render and broadcast your content. Control everything from the `dazzle` CLI.
Primary use cases: AI agents that need a persistent visual environment, live streaming to Twitch/Kick/Restream or any custom RTMP server, and programmatic automation.
## Getting Started
### 1. Install the CLI
**macOS / Linux:**
```bash
curl -sSL https://dazzle.fm/install.sh | sh
```
**Windows (PowerShell):**
```powershell
irm https://dazzle.fm/install.ps1 | iex
```
Or `go install github.com/dazzle-labs/cli/cmd/dazzle@latest`, or download a binary from the [releases page](https://github.com/dazzle-labs/cli/releases). Source: https://github.com/dazzle-labs/cli
### 2. Authenticate
```bash
dazzle login
# Opens your browser to sign in with your Dazzle account
```
### 3. Create a stage
```bash
dazzle s new my-stage
```
If you have multiple stages, specify which one with `--stage` or `DAZZLE_STAGE`:
```bash
dazzle s ls # list all stages
dazzle s up --stage my-stage # bring up a specific stage
# Or set for your session
export DAZZLE_STAGE=my-stage
```
If you only have one stage, it's auto-selected.
### 4. Create content
Create a directory with an `index.html` entry point:
```bash
mkdir my-stage && cat > my-stage/index.html << 'EOF'
Hello, Dazzle
EOF
```
For more examples, see https://github.com/dazzle-labs/stream-examples
### 5. Push content
Sync a local directory to your stage:
```bash
dazzle s sync ./my-stage # one-time sync (auto-refreshes browser)
dazzle s sync ./my-stage --watch # watch for changes, re-sync, and auto-refresh
```
Every sync is a full snapshot — files deleted locally are automatically removed from the stage. The browser automatically reloads after every successful sync. The directory must contain an `index.html` entry point (customizable with `--entry`).
```bash
# Take a screenshot to verify
dazzle s ss -o preview.png
```
### 6. Update content live
```bash
# Push live data without rewriting code
dazzle s ev e score '{"points": 42}'
# Manual browser reload (rarely needed — sync auto-refreshes)
dazzle s refresh
```
### 7. Stream to external platforms
Every stage automatically streams to Dazzle (watch URL shown on `dazzle s up`). To also stream to Twitch, Kick, Restream, or a custom RTMP server (including YouTube via custom RTMP):
```bash
# Add a destination (interactive — opens browser for OAuth, or prompts for RTMP details)
dazzle dest add
# Attach it to your stage (broadcasting starts automatically)
dazzle dest attach my-destination
# Check status (includes broadcast info)
dazzle s status
# Detach when done (stops broadcasting to that destination)
dazzle dest detach my-destination
```
Multiple destinations can be attached simultaneously for multi-platform streaming. Destinations are user-scoped and reusable across stages.
## Pricing
Dazzle uses pay-as-you-go billing with no subscriptions.
| | Free trial | Pay-as-you-go |
|---|---|---|
| CPU stages | 24 hrs (one-time) | $0.10/hr |
| GPU stages | 2 hrs (one-time) | $0.30/hr |
| Stages | Unlimited | Unlimited |
| Watermark | Yes | No |
Free trial hours are one-time — once consumed, add a payment method to continue. Adding a payment method removes the watermark from all future streams. Existing stages keep the watermark until restarted — spin a stage down (`dazzle s down`) and back up (`dazzle s up`) to apply the change.
## MCP (Model Context Protocol)
The CLI includes a built-in MCP server for AI agent integration. Any MCP-compatible client (Claude Desktop, Claude Code, VS Code, Cursor, etc.) can control stages natively.
### Setup
Add to your MCP client config:
```json
{
"mcpServers": {
"dazzle": {
"command": "dazzle",
"args": ["mcp"]
}
}
}
```
Set `DAZZLE_STAGE` in `env` to pin a specific stage, or omit it to auto-select (works if you have one stage).
### Tools
**Core:**
- **`cli`** — Run any dazzle CLI command. Pass `["--help"]` to discover available commands. Output is JSON.
- **`screenshot`** — Capture a screenshot of the stage's current browser output. Returns a JPEG image.
- **`guide`** — Fetch the complete Dazzle reference (llms-full.txt). Read this first.
**Workspace** (files stored in `~/.dazzle/stages//` on the host):
- **`write_file`** — Write a file to the stage workspace. Creates parent directories as needed.
- **`read_file`** — Read a file from the stage workspace.
- **`edit_file`** — Edit a file by exact string replacement (old_string must match uniquely).
- **`list_files`** — List all files in the stage workspace.
- **`sync`** — Push the workspace to the live stage. Run after writing/editing files.
### Resource
- **`dazzle://llms-full`** — This complete reference document (getting started, CLI help, content guide).
### Workspace tools vs direct CLI
The workspace tools exist for **sandboxed environments** (e.g. Claude Desktop) where the agent's bash runs in an isolated container and can't share files with the `dazzle` CLI process on the host. Files written via `write_file` land in `~/.dazzle/stages//` on the host filesystem where the CLI can see them.
**Limitations:** No shell/exec capability — can't run build tools (npm, npx, tailwind, etc.) in the workspace. Content must be pre-built HTML/CSS/JS that doesn't require a build step. For anything needing a build pipeline, use an agent with direct filesystem and shell access (e.g. Claude Code) and `dazzle stage sync` directly.
**If you have full filesystem access** (Claude Code, terminal): skip the workspace tools entirely. Write files with your normal tools and run `dazzle stage sync ./your-dir`.
### Example usage
```
guide() → read the complete reference first
cli(["stage", "list"]) → list all stages (JSON)
cli(["stage", "up"]) → activate stage
write_file(stage="my-stage", path="index.html", content="Hello
")
sync(stage="my-stage") → push workspace to live stage
screenshot() → capture JPEG of current output
edit_file(stage="my-stage", path="index.html", old_string="Hello", new_string="World")
sync(stage="my-stage") → push edit
cli(["stage", "event", "emit", "score", '{"points": 42}']) → push live data
cli(["--help"]) → discover all commands
```
## CLI Reference
```
Usage: dazzle [flags]
Dazzle — cloud stages for streaming.
A stage is a cloud browser environment that renders and streams your content.
Sync a local directory (must contain an index.html) and everything visible in
the browser window is what gets streamed to viewers.
Your content runs in a real browser with full access to standard web APIs (DOM,
Canvas, WebGL, Web Audio, fetch, etc.). localStorage is persisted across stage
restarts — use it to store app state that should survive between sessions.
Workflow:
1. dazzle login # authenticate (one-time)
2. dazzle s new my-stage # create a stage
3. dazzle s up # bring it up — starts streaming to Dazzle
4. dazzle s sync ./my-app -w # sync + auto-refresh on changes
5. dazzle s ss -o preview.png # take a screenshot to verify
6. dazzle s down # stop streaming and shut down
Auth: dazzle login, or set DAZZLE_API_KEY for headless/CI use. Stage selection:
use -s , DAZZLE_STAGE env, or auto-selected if only one.
https://dazzle.fm
Flags:
-h, --help Show context-sensitive help.
-j, --json Output as JSON.
-s, --stage=STRING Stage name or ID ($DAZZLE_STAGE).
--api-url=STRING API URL ($DAZZLE_API_URL).
Commands:
version Print version information.
update Update dazzle to the latest release.
guide Show content authoring guide (rendering tips,
performance, best practices).
login Authenticate with Dazzle (opens browser).
logout Clear stored credentials.
whoami Show current user.
stage (s) list (ls) List stages.
stage (s) create (new) Create a stage.
stage (s) delete (rm) Delete a stage.
stage (s) up Activate a stage.
stage (s) down Deactivate a stage.
stage (s) status (st) Show stage status.
stage (s) stats Show live pipeline stats.
stage (s) preview Show the shareable preview URL for a running
stage.
stage (s) sync (sy) Sync a local directory to the stage. This is
the primary way to push content — use --watch
for live development.
stage (s) refresh (r) Reload the stage entry point.
stage (s) event (ev) emit (e) Push a named event with JSON data to
the running page — dispatched as a DOM
CustomEvent. Use this to send real-time data
from external processes (other agents, APIs,
etc.) without re-syncing or reloading.
stage (s) logs (l) Retrieve stage console logs.
stage (s) screenshot (ss) Capture a screenshot of the stage.
stage (s) info Get current stream title and category.
stage (s) title Set the stream title (not supported for
Restream).
stage (s) category Set the stream category or game (not
supported for Restream).
stage (s) chat send Send a message to live chat (not supported
for Restream).
destination (dest) list (ls) List broadcast destinations.
destination (dest) add (create,new)
Add a broadcast destination.
destination (dest) delete (rm)
Remove a broadcast destination.
destination (dest) attach (set)
Attach a destination to a stage.
destination (dest) detach (unset)
Detach a destination from a stage.
Run "dazzle --help" for more information on a command.
```
## Visibility
All stages are public during beta — anyone can watch your stage's rendered video stream. Viewers see only the visual output, not your source code or files. Treat your stage like a live broadcast.
## Authentication
`dazzle login` opens your browser for OAuth sign-in — no API key needed. The CLI stores credentials locally after login.
For programmatic/headless use (CI, automation), create an API key in the dashboard (Settings > API Keys) and set:
```bash
export DAZZLE_API_KEY=dzl_your_key_here
```
## Content Guide
Full reference with GPU vs CPU details: https://dazzle.fm/llms-full.txt (also via `dazzle guide`).
### Stage tiers
- **GPU stages** — NVIDIA RTX with hardware-accelerated WebGL and video encoding. Shaders, raymarching, complex post-processing — all 30 FPS.
- **CPU stages** — Software-rendered OpenGL, no hardware GPU. CSS, Canvas 2D, DOM, WebGL geometry all 30 FPS. Fragment-heavy shaders limited.
### Environment
| Setting | GPU Stage | CPU Stage |
|-------------|------------------------------------------------|------------------------------------|
| Resolution | 1280×720 (fixed) | 1280×720 (fixed) |
| Frame rate | 30 fps rendering + capture | 30 fps rendering + capture |
| Renderer | NVIDIA RTX (hardware WebGL) | Software OpenGL (no hardware GPU) |
| Encoder | Hardware video encoder, CBR 2500k | Software video encoder, CBR 2500k |
| Browser | Chrome, full viewport | Chrome, full viewport |
| Audio | Web Audio API supported, audio captured | Web Audio API supported, audio captured |
| Persistence | localStorage and IndexedDB survive restarts | Same |
### Page setup
Always use a full-viewport, no-scroll layout:
```html
```
For canvas, size to the window (`canvas.width = window.innerWidth`) — do NOT hardcode 1920×1080.
### What works well (30 fps)
- **CSS animations & transitions** — `@keyframes`, `transform`, `opacity`. Cheapest animation path.
- **Canvas 2D** — Drawing, compositing, particle effects. Efficient even with 1000+ particles.
- **DOM-heavy animation** — 200+ elements repositioned per frame via JS.
- **WebGL shaders** — GPU: unlimited (raymarching, SDF, noise, bloom — all 30 FPS). CPU: geometry-only (500K+ tris at 30 fps, fragment shaders limited).
- **Web Audio** — Oscillators, buffers, Tone.js. Audio captured to the stream.
- **CDN libraries** — Three.js, D3, GSAP, p5.js, Tone.js all work via `