# DemoReady for AI agents

DemoReady turns your AI coding agent into a demo director. Your agent (Claude Code, Codex, Cursor, or any MCP client whose model can read screenshots) opens your app, decides every click, and narrates as it goes. DemoReady performs each step with a smooth cursor, captions, highlights and voice-over, and records a polished 1080p MP4 into your library. It also works with **apps running on your own computer** (`localhost`).

> **AI agents:** this page is written so you can set DemoReady up for your user. Follow [Setup for AI agents](#setup-for-ai-agents). The only thing the user does by hand is enter their API key, in their own terminal.

- Plain-text version of this page: https://demoready.ai/docs.md
- Connector package: [demoready-mcp on npm](https://www.npmjs.com/package/demoready-mcp)

## Setup for AI agents

Do these steps for the user, in order.

1. **Check Node.js.** Run `node --version`. It must be 22 or newer. If it isn't, ask the user to install Node 22+ from https://nodejs.org and stop here.
2. **Add the DemoReady MCP server** to the client you are running in, using the exact command or config for that client in [Add DemoReady to your agent](#add-demoready-to-your-agent). No API key goes into the config.
3. **Have the user sign in.** Ask the user to run this in **their own terminal** (not through you), so their key is never shown in the chat:

   ```bash
   npx -y demoready-mcp login
   ```

   It asks for their API key without showing it, checks it, and saves it to `~/.demoready/credentials.json` (readable only by them). They create a key at https://demoready.ai/app/settings/api. Recording needs a DemoReady plan (MCP, MCP Plus, Pro or Studio) or a single-demo credit.

   Never ask the user to paste their API key into the chat, and never write a key into a file yourself.
4. **Reload.** Tell the user to restart the client (or reload its MCP servers) so the `demoready` tools appear.
5. **Verify.** Run `npx -y demoready-mcp status`. It should print `Signed in as … (plan)`. After the reload, the `demoready` server should list tools such as `demo_open` and `demo_record_start`.

Then record a first demo. See [Directing a demo](#directing-a-demo).

## Add DemoReady to your agent

All clients run the same connector, `npx -y demoready-mcp`. It downloads on first use and needs no other install.

### Claude Code

```bash
claude mcp add --scope user demoready -- npx -y demoready-mcp
```

Check with `claude mcp list`.

### Codex

```bash
codex mcp add demoready -- npx -y demoready-mcp
```

Then open `~/.codex/config.toml` and add the two timeout lines to the `demoready` entry. Recording and encoding can take a few minutes, longer than Codex waits by default. The entry should look like this (you can also paste it in directly instead of running the command):

```toml
[mcp_servers.demoready]
command = "npx"
args = ["-y", "demoready-mcp"]
startup_timeout_sec = 60
tool_timeout_sec = 600
```

Check with `codex mcp list`.

### Cursor

Add to `~/.cursor/mcp.json` (all projects) or `.cursor/mcp.json` (one project):

```json
{
  "mcpServers": {
    "demoready": {
      "command": "npx",
      "args": ["-y", "demoready-mcp"]
    }
  }
}
```

### Claude Desktop

Add the same `mcpServers` entry as Cursor to `claude_desktop_config.json`:

- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

Then quit and reopen Claude Desktop.

### Windsurf

Add the same `mcpServers` entry as Cursor to `~/.codeium/windsurf/mcp_config.json`.

### VS Code (GitHub Copilot agent mode)

Add to `.vscode/mcp.json` in the workspace (or run **MCP: Add Server** from the command palette):

```json
{
  "servers": {
    "demoready": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "demoready-mcp"]
    }
  }
}
```

### Any other MCP client

Run it as a stdio server: command `npx`, arguments `-y demoready-mcp`. On Windows, if the client can't find `npx`, use command `cmd` with arguments `/c npx -y demoready-mcp`.

### Passing the key as an environment variable

Instead of `demoready-mcp login`, you can set `DEMOREADY_API_KEY` in the MCP server's environment (for example `claude mcp add --scope user demoready -e DEMOREADY_API_KEY=dr_live_… -- npx -y demoready-mcp`). It takes priority over the saved login. This suits CI and shared machines, but it stores the key in the client's config file.

### No install (public apps only)

Clients that support remote MCP servers can connect straight to `https://demoready.ai/mcp` with the header `Authorization: Bearer dr_live_…`. This records public URLs only; it can't reach `localhost`.

```bash
claude mcp add --scope user --transport http demoready https://demoready.ai/mcp --header "Authorization: Bearer dr_live_YOUR_KEY"
```

## Signing in

| Command | What it does |
| --- | --- |
| `npx -y demoready-mcp login` | Asks for an API key (hidden), checks it with DemoReady and saves it to `~/.demoready/credentials.json` with owner-only permissions. |
| `npx -y demoready-mcp status` | Shows which account and plan the connector uses, and where the key comes from. |
| `npx -y demoready-mcp logout` | Deletes the saved key. Revoke the key itself under Settings → API & MCP. |

Create and revoke keys at https://demoready.ai/app/settings/api. Each key acts as your account: demos it records count toward your plan.

## Recording apps on your computer

Use a local URL like any other: `http://localhost:3000`, `http://127.0.0.1:5173`, `http://myapp.test`, `*.localhost`, `*.local` or a private IP. When the agent opens one, the connector makes an encrypted, **outbound-only** connection to DemoReady and shares that address with the recording browser.

If the app calls an API on another local address, the agent lists it in `demo_open`'s `local_hosts`, for example `local_hosts: ["localhost:8000"]`. Otherwise those calls fail.

How it stays safe:

- **Only the addresses the agent opened are shared.** The connector refuses any other request (another port, another device on your network) on your machine, and logs it.
- **Only your recordings** can use the connection. It's signed in with your key and routed only to your own sessions.
- **Only until the recording ends.** Sharing stops when the demo finishes or is discarded, and whenever the connector exits.
- **Nothing gets a public URL**, and no port is opened on your computer.
- The connector never follows redirects itself; the recording browser re-checks where they lead.

While sharing, the connector logs a line such as `[demoready] sharing http://localhost:3000 with your DemoReady recording (only this address, until the recording ends)`.

Limits: 25 MB per response and 120 seconds per request. Streamed responses (Server-Sent Events, token-by-token AI answers) arrive all at once instead of streaming. Web-app demos can't reach `localhost`; this works over MCP only.

## Directing a demo

These are the same instructions the DemoReady MCP server gives your agent:

> DemoReady records polished product-demo videos of web apps. You are the director: you decide every step, DemoReady performs it with smooth cursor motion, highlights and captions, and records 1080p video.
>
> Workflow:
> 1. demo_open(url): opens a browser (off camera) and returns a screenshot with numbered elements. Explore, log in, or set up data with demo_act; nothing is recorded yet. Return to the starting screen when ready.
> 2. demo_record_start(title, subtitle): the intro card plays and recording starts.
> 3. For each scene: demo_scene(title, caption) puts a viewer caption on screen, then use demo_act for that scene's clicks and typing. Every demo_act returns a fresh screenshot.
> 4. demo_finish(headline, cta): outro card, encode, returns the MP4 path.
>
> Local apps (localhost, 127.0.0.1, *.test): these work when DemoReady was added through its connector (npx -y demoready-mcp), which securely shares only the address you open. If the app calls other local addresses (an API on another port), list them in demo_open's local_hosts.
>
> Prefer demo_move for showing content (a row of steps, features, pricing, a call to action): one call, smooth motion paced to your narration, instead of many demo_act calls.
>
> The recording is paused while you think, so take the time you need: viewers only see actions. Keep demos tight: 3-6 scenes, a few purposeful actions each, no trial and error on camera (explore before demo_record_start if unsure). Use callouts sparingly for the key moment of a scene. Everything typed is visible in the video.
>
> Narration: pass `narration` to demo_record_start, demo_scene and demo_finish to have a voice read that line at that exact point in the video. DemoReady's built-in voice speaks it (no extra key needed) and mixes it in at demo_finish. Write it as speech, not as caption text: spell numbers out ("twenty five percent", "eight hundred sixty four thousand"), keep a scene's line to roughly 2.3 words per second of what that scene will actually take, and let the caption carry the label while the narration carries the meaning. A scene with no `narration` is simply silent, so narrate all of a demo or none of it.

### Tools

| Tool | What it does |
| --- | --- |
| `demo_open` | Opens the app off camera and returns a screenshot with numbered elements. Takes `url`, optional `pace`, `brand_color`, `camera_zoom`, and `local_hosts` for extra local addresses. |
| `demo_act` | One polished action: click, type, select, press, hover, scroll, spotlight, wait, navigate. Returns a fresh screenshot. Off camera until recording starts, so it's also for logging in and seeding data. |
| `demo_move` | A ready-made move in one call (`walk_items`, `tour_section`, `highlight`, `point_cta`, `fill_form`), paced to your narration. |
| `demo_observe` | A fresh screenshot without acting. |
| `demo_record_start` | Intro card; recording starts. Uses one demo from the plan. Optional `narration` and `voice`. |
| `demo_scene` | Puts the next scene's caption on screen, with optional narration. |
| `demo_finish` | Outro card, voice-over mix and encode. The video lands in the library. |
| `demo_close` | Discards a session without saving. |
| `list_demos`, `get_demo` | The user's library. |

### Example prompts

- *Use demoready to record a 3-scene demo of http://localhost:3000 showing how to create a project and invite a teammate. Log in off camera with demo@acme.test / demo first.*
- *Record a narrated demo of our pricing page at https://acme.com/pricing: walk through the plans, then point to Start free trial.*
- *Record the new onboarding flow on localhost:5173. The API runs on localhost:8000.*

Tips: use test accounts and demo data (everything typed appears in the video, and actions really happen in the app); keep it to 3–6 scenes; explore before recording starts.

## Plans

| Plan | Price | Demos | Where | Scenes per demo |
| --- | --- | --- | --- | --- |
| MCP | $4.99/month | 10 demos a month | MCP only | up to 15 |
| MCP Plus | $9.99/month | 30 demos a month | MCP only | up to 15 |
| Pro | $29/month | 30 demos a month | MCP and the web app | up to 8 |
| Studio | $99/month | 150 demos a month | MCP and the web app | up to 15 |
| Single demo | $4 once | 1 demo | MCP or the web app | up to 8 |

A demo is used when recording starts (`demo_record_start`). Exploring and closing a session without recording is free. Plans and billing: https://demoready.ai/app/settings/billing.

## Troubleshooting

| Problem | Fix |
| --- | --- |
| `UNABLE_TO_GET_ISSUER_CERT_LOCALLY` or `SELF_SIGNED_CERT_IN_CHAIN` (often on company laptops) | Your network inspects HTTPS with a certificate your browser trusts but Node doesn't. On macOS, export it: `security find-certificate -a -p /Library/Keychains/System.keychain > ~/.demoready-ca.pem`, then set `NODE_EXTRA_CA_CERTS=~/.demoready-ca.pem` in your shell **and** in the `env` of the DemoReady MCP server config. Node 22.19+ picks up the system certificates automatically with connector 1.1.3+. |
| "DemoReady isn't signed in yet" | Run `npx -y demoready-mcp login` in your terminal, then restart the client. |
| "didn't accept that key" / tunnel refused | The key was revoked or mistyped. Create a new one and run `login` again. |
| The `demoready` tools don't appear | Check `node --version` is 22+, restart the client, and check its MCP logs. The connector caches the tool list in `~/.demoready/tools.json`. |
| Codex says a tool timed out, but the video appears later | Add `tool_timeout_sec = 600` to the Codex entry (see [Codex](#codex)). |
| "… is on your computer, which DemoReady can't reach directly" | DemoReady was added with the no-install HTTP address. Switch to the connector (`npx -y demoready-mcp`). |
| The local page loads but data is missing | The app calls an API on another port. Ask the agent to add it to `local_hosts`. |
| "You've used all … demos" or "Buy a single demo" | Your plan's demos for the month are used up, or your account has no plan yet. Upgrade or buy a single demo at https://demoready.ai/app/settings/billing. |

Still stuck? Email hello@sundrylab.ai.
