---
name: seedviral
description: Make and manage SeedViral faceless short videos from an agent. Use when the user wants to set up a video series, feed it topics (RSS feed, YouTube channel, CSV list or typed topics), make a one-off video, check progress or download finished videos. Needs the SeedViral connector (seedviral-agent) and a SeedViral API key.
---

# SeedViral

SeedViral turns a topic into a narrated, captioned vertical video (30–40 or 60–70 seconds). A **series** makes videos on a
schedule from its plan; a **one-off video** costs credits. This skill drives SeedViral through its local connector: either the
MCP tools (`seedviral` server) or the `seedviral` CLI. Both use the same API and the same key.

## Setup (once)

1. In SeedViral, open **Developers → API keys → Create key**. Choose **Read only** to look around, or **Create and manage** to
   make videos (that permission spends the workspace's credits). Copy the key when it is shown: it is shown once.
2. Download the connector from SeedViral → Developers → MCP (a single file, `seedviral-agent-1.0.0.mjs`, Node 20 or newer) and
   check it against `SHA256SUMS`.
3. Give the key to the connector through the environment, never as an argument:
   - MCP client config: command `node`, args `["/path/to/seedviral-agent-1.0.0.mjs", "mcp"]`, env `{"SEEDVIRAL_API_KEY": "svk_…"}`.
   - CLI: `export SEEDVIRAL_API_KEY=svk_…` then `node seedviral-agent-1.0.0.mjs whoami`.
   - Optional: `SEEDVIRAL_DOWNLOAD_DIR` (where videos are saved; default the current folder).

## What it can do

| Need | MCP tool | CLI |
| --- | --- | --- |
| Check the key and workspace | `get_workspace` | `whoami` |
| Valid formats, voices, styles, durations, credit costs | `get_catalog` | `catalog` |
| Credits | `get_balance` | `balance` |
| Series drafts | `list_series`, `get_series`, `create_series_draft`, `update_series_draft` | `series …` |
| Topic sources | `get_topics`, `preview_topic_source`, `use_topic_source`, `add_topic`, `pause_topic_source`, `resume_topic_source`, `remove_topic_source`, `skip_topic`, `requeue_topic` | `topics …` |
| One video | `quote_video` then `create_video` | `videos quote`, `videos create` |
| Progress and files | `list_videos`, `get_video`, `list_video_versions`, `get_download_link`, `download_video` | `videos …` |
| Square / landscape copy | `request_export`, `list_exports` | `videos export`, `videos exports` |

It cannot change billing or plans, connect social accounts, post anything, or manage the account. A new series draft is saved only:
creating it starts no plan and makes no videos.

## Workflows

**Make one video (costs credits).**
1. `get_catalog` → pick `duration`, a `format` id (or "" for a story), and a style: `{"from":"series","seriesId":…}` or
   `{"from":"custom","art":…,"voice":…,"caption":…,"language":…}` using catalog values.
2. `quote_video` with `mode` `prompt` (an idea), `script` (the user's own words), `link` (an article, Reddit post or YouTube
   video; read once, now) or `remix`. Tell the user the quoted credits (10 for 30–40 s, 15 for 60–70 s), the balance and the
   quote's `settings` (voice, art, captions, music): the video is made with exactly those, even if the series changes later.
3. Only after the user agrees: `create_video` with the quote id. Retrying with the same quote never charges twice.
4. Poll `get_video` every minute or so until `stage` is `ready` (usually several minutes), then `download_video`.

**Feed a series with topics.**
1. `list_series` / `get_series` to find the series. `get_topics` shows the current source and queue.
2. RSS or YouTube: `preview_topic_source` (shows the next 5 topics; older posts are never made), then `use_topic_source` with
   `expectedSourceId` = the current source id or `null`. Replacing a source drops its queued topics; videos already made keep theirs.
3. CSV list: `preview_topic_source` with `kind` `csv` and `input` `{fileName, text}` (the whole file). Check the columns it
   used (`mapping`, `header`) and any row `errors`; to change columns pass `mapping` `{topic, notes, link, header}` and preview
   again. Then `use_topic_source` with the SAME input and the preview's `previewHash`.
4. Typed topics: `add_topic` with a title and notes. Each topic becomes one video in order, at the series' own schedule.
5. `skip_topic` / `requeue_topic` take an itemId; `pause_topic_source` / `resume_topic_source` / `remove_topic_source` take the current sourceId. Each also takes seriesId.
   Titles and descriptions are read, never the videos or posts themselves, and they are not transcripts.

**Collect finished videos.** `list_videos` (optionally by `seriesId`) → `get_video` → `download_video`. For other shapes:
`request_export` (`1:1` or `16:9`, free), then `list_exports` for the download links once ready.

## Errors and retries

Errors come back as `CODE (status): message`.
- `SCOPE_REQUIRED`: the key is read only. Ask the user for a **Create and manage** key.
- `INSUFFICIENT_CREDITS`: tell the user what it needs and what they have (the message says both). The quote stays valid for 15 minutes.
- `QUOTE_EXPIRED`: quote again.
- `PREVIEW_CHANGED`: the CSV or its columns differ from the preview; preview again and use the new `previewHash`.
- `IDEMPOTENCY_CONFLICT`: you reused an idempotency key for a different request. Use a new key.
- `RATE_LIMITED`: wait the `Retry after` seconds.
- `INVALID_API_KEY` / `KEY_EXPIRED`: the key was revoked or expired; the user creates a new one.
If a write's result is unknown (timeout), call it again with the same `idempotencyKey`; it runs at most once.

Never print, store or echo the API key. Never ask the user to paste it into chat if they can set it in the environment instead.
