Metadata-Version: 2.4
Name: zyng-mcp
Version: 0.10.0
Summary: Zyng MCP client — record your running app with an agent, publish a managed narrated pitch.
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 a **managed, narrated pitch video** — without
ever recording it yourself.

Point your agent (Claude Desktop, Claude Code, or any MCP client) at your localhost app. It authors the
steps from the source it just wrote; this server drives the app headless with Playwright, screen-records
each feature **keyless and free**, then publishes the clips + your narration context to hosted Zyng
(https://app.zyng.work), which stitches and narrates the pitch **server-side on your credits** and hands
back an MP4. No TTS key ever leaves your machine — the data→video engine stays managed.

## Tools

| tool | what it does | needs |
|------|--------------|-------|
| `account` | your Zyng credit balance (the "do I have credits?" check) | API token |
| `capture_clips` | drive a running app headless, screen-record a feature into a raw clip + timeline | Chromium, no key |
| `publish` | upload clips + a composition spec → a managed narrated stitch, downloaded as MP4 | API token, spends credits |

## Install

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

`capture_clips` needs Chromium; `publish` does not (the render happens on Zyng). 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, then publish a
> 30-second pitch. Say "this is the fastest way to onboard" over the dashboard.

The agent will, in order: check `account` for credits, call `capture_clips` once per feature (authoring
the Playwright selectors from your source), assemble a `publish` spec (title card + clip segments with
your narration), and call `publish` — blocking until Zyng returns the finished MP4 and the share link.

### Spec shapes (the agent fills these)

`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." }
  ] }
```

`publish` spec (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." } }
  ] }
```

## Notes

- **Credits + voice are managed.** You never ship an ElevenLabs/OpenAI key; Zyng renders with its own
  voice and charges your balance (gate-at-zero with a clear error).
- **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.
