Metadata-Version: 2.4
Name: zyng-mcp
Version: 0.22.0
Summary: Zyng MCP client — record your running app with an agent, seed an editable Zyng Studio project.
Author-email: Rahul Gaur <rahul.nbg@gmail.com>
License: Proprietary
Project-URL: Homepage, https://zyng.work
Project-URL: Studio, https://app.zyng.work
Keywords: mcp,zyng,playwright,video,walkthrough,agent,loom
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Environment :: Console
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Software Development :: Documentation
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp>=1.0
Requires-Dist: playwright>=1.40
Requires-Dist: requests>=2.31
Requires-Dist: pydantic>=2.5
Requires-Dist: pillow>=10
Provides-Extra: keychain
Requires-Dist: keyring>=24; extra == "keychain"
Dynamic: license-file

# zyng-mcp

Record a running app with your coding agent, get back an **editable, directed Zyng Studio project**,
without ever recording it yourself.

Point your agent (Claude Desktop, Claude Code, or any MCP client) at your localhost app. This server
captures real product proof **keyless and free**, then uses hosted Zyng Director to author the first
cut and seed a hosted, editable Studio project. That `project_url` is the deliverable: you open it in
Zyng Studio, tweak the cut, and export or publish from the UI. No TTS key ever leaves your machine, the
video engine stays managed, and the agent flow never spends credits.

Zyng produces two output kinds off the same pipeline: **`launch_film`** (the primary, a cinematic
product-proof cut from your own captured product flow, including logged-in / authenticated / localhost
footage) and **`walkthrough`** (a secondary, opt-in step-by-step tutorial / onboarding / explainer with a
teaching grammar). You pick with `compose(kind=...)`.

## Tools

| tool | what it does | needs |
|------|--------------|-------|
| `account` | your Zyng credit balance (the "do I have credits?" check) | API token |
| `direct` | read a local app's brand + route map so your agent can understand the product before capture | Chromium, no key |
| `capture_clips` | drive a running app headless, screen-record a feature into a raw clip + timeline | Chromium, no key |
| `compose` | send the URL, brief, captured proof, and `kind` into hosted Director; authors the cut and seeds an editable hosted Studio project, returns `project_url`, free (never renders, never spends) | API token |
| `review` | local review page and markdown for the exact spec and clips, free | nothing |
| `estimate` | approximate the credit cost of a cut (informational; the compose flow never charges) | API token |
| `voices` | voice catalog, and whether premium voices are unlocked for this account | API token |
| `trailer` | deprecated thin alias for `compose(kind="launch_film")`, kept for back-compat | API token |
| `publish` | deprecated headless / CI escape hatch: upload clips + a spec → a managed narrated stitch. Out of the normal flow, still spends credits. Prefer exporting from the Studio UI | API token, spends credits |

## Install

```bash
pipx install zyng-mcp            # or: pip install ./zyng_mcp-0.15.1-py3-none-any.whl
python -m playwright install chromium   # one-time browser download (~150MB)
```

`capture_clips` needs Chromium; `compose` does not (it directs on Zyng and seeds the Studio project). No
ffmpeg required.

## Get an API token

1. Sign in at **https://app.zyng.work** (Google).
2. Avatar menu → **API tokens** → **Mint**, and copy the `zyk_…` token (shown once).

A fresh account includes free credits; 1 credit = 1 second of finished video.

## Recording apps that need a login

Never put a password in a capture spec — it would land in the agent's context, the tool-call logs,
and (if typed on screen) the uploaded video. Three on-machine options instead, all resolved locally
so the credential never reaches the agent or Zyng:

**HTTP Basic Auth (the browser's `WWW-Authenticate` dialog — e.g. a staging site):**
```bash
zyng-mcp secret set staging_basic_auth   # hidden prompt; enter:  username:password
```
Then pass the secret's **name** to capture (the agent never sees the value):
```json
{ "do": "capture_clips", "http_auth": "staging_basic_auth" }
```
Playwright answers the challenge at the network layer — no dialog, nothing on screen, `authenticated:true`.


**Preferred — a saved session (nothing is typed or recorded):**
```bash
zyng-mcp login http://localhost:3000   # opens a browser; log in by hand, press Enter to save
```
This writes the authenticated session to `~/.zyng/state/<host>.json` (chmod 600). `capture_clips`
auto-detects it for that host, so recordings start already signed in — the result shows
`"authenticated": true`. No login step, no password on screen.

**If you must demonstrate the login itself — a named secret (the agent only sees the name):**
```bash
zyng-mcp secret set acme_password      # hidden prompt; stored in the OS keychain or a chmod-600 file
```
Then a step references it by name (never the value):
```json
{ "do": "fill", "selector": "#password", "secret": "acme_password" }
```
The value is resolved at capture time and never enters the spec, the tool call, a log, or the result.
Keychain storage needs `pipx install "zyng-mcp[keychain]"`; otherwise it falls back to
`~/.zyng/secrets.json` (chmod 600). You can also pass a secret as an env var, e.g.
`ZYNG_SECRET_ACME_PASSWORD`.

> Anything visible on screen during capture ends up in the uploaded MP4 — prefer the saved session
> for anything sensitive, and use a throwaway/test account where you can.

## Register with your agent

Add to `claude_desktop_config.json` (Claude Desktop) or `.mcp.json` (Claude Code):

```json
{
  "mcpServers": {
    "zyng": {
      "command": "zyng-mcp",
      "env": {
        "ZYNG_API_KEY": "zyk_your_token_here",
        "ZYNG_BASE_URL": "https://app.zyng.work"
      }
    }
  }
}
```

(If you installed with `pipx`, `zyng-mcp` is on your PATH. With a venv, use the absolute path to the
`zyng-mcp` script, or `command: "python", args: ["-m", "zyng_mcp.server"]`.)

## Use it

Tell your agent something like:

> My app is running at http://localhost:3000. Record the sign-in and the dashboard into a 30-second
> launch film. Say "this is the fastest way to onboard" over the dashboard.

The preferred flow is: ask which kind (a cinematic `launch_film` or a step-by-step `walkthrough`) and
whether it is a desktop or mobile-first cut, capture one proof clip per payoff with `capture_clips`, call
`compose(kind=...)` to let hosted Director author the cut and seed an editable Studio project, then hand
over the returned `project_url`. The user opens it in Zyng Studio, tweaks the cut, and exports or publishes
from the UI. The agent flow ends at the seeded project and never spends credits.

Director's story grounding now defaults to Zyng's approved launch-video corpus. In practice, that means
the first cut is influenced by the vetted internal benchmark set only. Public review candidates and
source-queue references do not affect live retrieval until they are promoted into the approved corpus.

The brief should sound like Director, not a form fill. Ask in plain language:

- what should this cut make unmistakable?
- who is this for?
- what product proof should it show?

If the product needs a little understanding first, use `direct` before capture. It reads the local brand
and route map so the agent can form a stronger brief before it calls `compose`.

### Spec shapes

`compose` input:
```json
{
  "url": "http://localhost:3000",
  "kind": "launch_film",
  "nudge": "Focus on onboarding speed for founders.",
  "clips": ["/abs/path/dashboard.webm", "/abs/path/report.webm"],
  "register": "cinematic",
  "audio_mode": "music_captions",
  "aspect": "16:9"
}
```

`compose` returns the cut `spec`, an `estimate`, a local `review_url`, and a hosted `project_url` that
opens the same cut in Zyng Studio. Hand `project_url` to the user; they tweak and export from the Studio UI.
`compose` never renders and never spends. Set `"kind": "walkthrough"` for a step-by-step tutorial grammar
instead of the cinematic one.

`capture_clips` spec:
```json
{ "url": "http://localhost:3000", "title": "Dashboard", "aspect": "16:9",
  "steps": [
    { "do": "wait",  "ms": 1000, "say": "Here's the dashboard." },
    { "do": "click", "selector": "text=New report", "say": "One click to a new report." }
  ] }
```

The cut `spec` returned by `compose` mixes cards and clips (clip files matched by basename to the captured
clips you pass in `clips`):
```json
{ "title": "My app", "theme": "dawn", "voice": "narrator", "aspect": "16:9",
  "segments": [
    { "card": { "layout": "title", "heading": "My app", "narration": "A quick tour." } },
    { "clip": { "file": "dashboard.webm", "audio": "narrate", "say": "This is the dashboard." } }
  ] }
```

`trailer(...)` is a deprecated alias for `compose(kind="launch_film")` kept so existing 0.15.x clients keep
working. `publish` is deprecated and out of the normal flow: it is a headless / CI escape hatch that still
spends credits, so prefer exporting from the Studio UI. Publishing now happens in Zyng Studio: open your
`project_url`, tweak, and export from the UI.

## Notes

- **Credits + voice are managed.** You never ship an ElevenLabs/OpenAI key; Zyng renders with its own
  voice and charges your balance at export time (gate-at-zero with a clear error).
- **The deliverable is `project_url`**, an editable hosted Studio project. Export or publish happens in the
  Studio UI, not from the agent. The compose flow itself is free.
- **Selectors come from your source**, not pixel-guessing — Zyng executes the steps your agent authors,
  so a recording is deterministic and re-runnable. A bad selector returns a clean error naming the step.
- Set `ZYNG_BASE_URL` to a different host to target a self-hosted or staging studio.
