Author a video as JSON, render it anywhere. Rust video engine behind PromoShot — CLI + MCP server for AI agents, wgpu + ffmpeg, runs headless on Linux.
- ✓Open-source license (Apache-2.0)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/GarAlex/promoshot{
"mcpServers": {
"promoshot": {
"command": "promoshot"
}
}
}MCP Servers overview
# promoshot
**See it work:** [demo.md](demo.md) — twenty-four prompts, each given to a
fresh agent with only the skill and the MCP, its result beside the
hand-built reference. The suite is in [demos/](demos/README.md).
<p align="center">
<img src="docs/rendered-on-linux.png" width="720"
alt="A frame rendered by the engine on Linux: a bordered video card over a themed background, with a stroked, shadowed caption reading 'Rendered on Linux'.">
</p>
The rendering engine behind [PromoShot](https://promoshot.app)
([App Store](https://apps.apple.com/us/app/promoshot-app/id6770157576)),
and an open implementation of its project format. A `.promo` project is a
folder — `metadata.json` plus its media — and this workspace is everything
needed to validate, inspect, and render one to stills, image sequences, or
mp4 with mixed audio: no app attached, byte-for-byte the same compositor the
apps ship.
The design bet is that **the format is the interface**. An assistant, a
script, or a person writes `metadata.json`; the engine renders it the same
everywhere — the Mac and iOS apps (Metal + VideoToolbox), this repo's CLI,
or a headless Linux box with no GPU at all (wgpu on lavapipe, ffmpeg as a
subprocess). The format has three faces behind one truth: an authoring
subset with four validated recipes (`promo schema`), the full document
(`--full`), and a types-only JSON Schema generated from the parser's own
structs (`--types`) — and the parser the validator runs is the parser the
renderers use, so "validates" means "renders".
## Crates
| Crate | What it owns |
|---|---|
| `promo-model` | The format: wire structs, migrations, palette roles, `schema.md` |
| `promo-timeline` | Timeline math: keyframes, trims, attachments, waits, validation |
| `promo-gpu` | wgpu compositing: quads, borders, letterbox, vectors, color conversion |
| `promo-text` | Caption shaping and effects (cosmic-text) |
| `promo-engine` | Preview/export orchestration, frame cache, memory governor, PCM mixer |
| `promo-media` | Decoder/encoder trait registry; ffmpeg-subprocess backend + conformance suite |
| `promo-editor` | The document's edit vocabulary: commands with undo, the wizard's arrangement, theme rules — what `promo_apply` and `promo_slideshow` are built on |
| `promo-cli` | `promo` — render a project from the command line |
| `promoshot-mcp` | MCP server over stdio, for agents |
## Build and verify
```
./check-all.sh # fmt, clippy -D warnings, all tests, release build
```
Rendering video needs `ffmpeg` (and `ffprobe`) on PATH — frames are composited
on the GPU and piped to it raw; ffmpeg only decodes and encodes. On a headless
Linux machine, `mesa-vulkan-drivers` (lavapipe) is enough of a GPU.
## The CLI
```
cargo build --release -p promo-cli # -> target/release/promo
promo schema # authoring subset + recipes; --full, --types
promo validate <project> # exit 0 == this will render
promo inspect <project> # canvas, layers, missing media, undefined colours
promo still <project> --out f.png --time 2.5
promo frames <project> --out frames/ --fps 30 --from 0 --to 4
promo video <project> --out out.mp4 --fps 30
```
Add `--json` to any project command for machine output — one object on
stdout, errors included, exit codes unchanged.
`promo video` mixes the soundtrack the apps would: trims and media cuts,
held frames, speed with pitch preserved, keyframed volume, a focused
narration ducking everything under it, and only the audio tracks the
project keeps.
Headless renders are CLEAN — no watermark, and no license, serial or key
will ever be asked for. (The Mac and iOS apps watermark free-tier renders;
that is their App Store Pro line, and it stays on their side of the fence.)
## The MCP server
`promoshot-mcp` speaks Model Context Protocol over stdio, so any MCP client
can author, inspect and render projects. It owns no rendering code — every
render shells to `promo` (found next to the executable, or on PATH, or via
`--promo`), so the CLI stays the single contract.
### Connect an agent
Two pieces: the MCP server (tools) and the skill (workflow).
Neither is vendor-specific. Agents do not find this repo by themselves.
**1. Build — or don't**
```bash
cargo build --release -p promo-cli -p promoshot-mcp
# binaries: target/release/promo target/release/promoshot-mcp
scripts/install-local.sh # …and on PATH, linked from target/release,
# so every later build is what runs
```
No Rust toolchain? Grab the prebuilt pair from
[Releases](https://github.com/GarAlex/promoshot/releases) (linux-x64,
macos-arm64; each asset's sha256 is on the release), or pull the image:
`docker pull ghcr.io/garalex/promoshot-mcp` — both carry `promo` and
`promoshot-mcp` together.
Put both on PATH, or pass `--promo` to the server. Rendering video also
wants `ffmpeg`/`ffprobe` on PATH. `promo skill install` then puts the
agent skill where every agent tool on the machine reads it — the shared
`~/.agents/skills` (Codex, Gemini CLI, Cursor, GitHub Copilot, Grok
Build) and the own folder of each tool found that reads only its own
(Claude Code, Antigravity); `promo skill` prints it.
**2. MCP (required for tools)**
Claude Code / Cursor / any `mcp.json`:
```json
{
"mcpServers": {
"promoshot": {
"command": "/ABS/PATH/target/release/promoshot-mcp",
"args": ["--workspace", "/ABS/PATH/Promo", "--root", "/ABS/PATH/Promo"]
}
}
}
```
`--workspace` is where new projects go; `--root` fences which projects the
server will touch — pointing both at one folder is the tidy setup. Both
optional. `--log <file>` appends one line per tool call — when,
which tool, how many milliseconds, how it went — for a session's own
accounting; the demo pages are built from it.
Client one-liners:
```bash
# Claude Code
claude mcp add promoshot /ABS/PATH/target/release/promoshot-mcp
# Grok Build
grok mcp add promoshot -- /ABS/PATH/target/release/promoshot-mcp \
--workspace /ABS/PATH/Promo --root /ABS/PATH/Promo
grok inspect # confirms the server registered
# Docker — the host needs nothing but docker (details below)
docker build -t promoshot-mcp .
# then command: docker, args: ["run","-i","--rm","-v","/ABS/PATH/Promo:/projects","promoshot-mcp"]
```
**3. Skill (the workflow)**
Same file everywhere: [skill/SKILL.md](skill/SKILL.md).
```bash
REPO=https://github.com/GarAlex/promoshot
git clone --depth 1 $REPO /tmp/promoshot
# Claude Code (Grok Build also scans this folder)
mkdir -p ~/.claude/skills/promoshot
cp /tmp/promoshot/skill/SKILL.md ~/.claude/skills/promoshot/SKILL.md
# Grok Build explicit path
mkdir -p ~/.grok/skills/promoshot
cp /tmp/promoshot/skill/SKILL.md ~/.grok/skills/promoshot/SKILL.md
# OpenAI Codex / many others
mkdir -p ~/.agents/skills/promoshot
cp /tmp/promoshot/skill/SKILL.md ~/.agents/skills/promoshot/SKILL.md
# Cursor project (in the repo the user is editing, not this engine repo)
mkdir -p .cursor/rules
cp /tmp/promoshot/skill/SKILL.md .cursor/rules/promoshot.md
# or: mkdir -p .agents/skills/promoshot && cp SKILL.md there
```
Any agent that reads instructions can be handed the file directly; it
assumes only these tools (or the CLI).
**4. Verify** — ask the agent for a render:
> Render examples/ProductCard.promo to a still at 3s.
One `promo_validate`, one `promo_render_still`, and a device-framed app
demo comes back as a path. From there, "make me a promo for <my app>" is
the loop the skill teaches.
### The tools
Tools: `promo_schema` (authoring subset + four validated recipes;
`promo_schema_full` is the whole format; `promo_schema_types` is the format
as a generated, types-only JSON Schema — also checked in at
[docs/promo.schema.json](docs/promo.schema.json) for `$schema` editor
autocomplete), `promo_validate`, `promo_inspect` (each layer listed with
its id — the handle the editing tools take),
`promo_render_still`, `promo_render_frames`, `promo_render_video`,
`promo_render_gif`, `promo_workspace`; the senses — `promo_media_probe`,
`promo_media_filmstrip` (a contact sheet of a SOURCE clip, times per cell),
`promo_media_silences` (silence spans and their inverse) and
`promo_media_scenes` (scene cuts and the shots between them), so an agent
knows what footage holds before composing with it; the editor trio,
`promo_init`, `promo_upsert_layer` and `promo_upsert_keyframe`: create a
project, add image/video/caption layers with placements, then animate —
a second placement keyframe is a push-in, viewport keyframes a Ken Burns;
your short ids are used verbatim, unnamed ones get canonical UUIDs, pixel
sizes are stamped, and the composition keeps covering its layers. Device
frames bake headless too — the same slab the apps draw. `promo_slideshow`
is the wizard: pictures and clips in, a complete classic, carousel or
store-listing show out, a caption on any slide becoming a layer that
lives with its picture. `promo_voices`
lists a provider's voices and `promo_speak` synthesizes narration with the
person's own provider key, reusing unchanged text by receipt. The authoring tools answer
with an inline thumbnail of the composition, so a misplaced layer is caught
at the moment it happens. The tools write ordinary `metadata.json`
through the format's own parser — the schema stays the source of truth, and
hand-editing remains first-class. Renders default their output into the
project's `Exports/` folder and return the path written, never the bytes.
Flags, all optional: `--workspace <dir>` (where `promo_workspace` points;
else `$PROMOSHOT_WORKSPACE`, else the XDG data dir), `--root <dir>` (refuse
projects outside this tree), `--promo <path>`.
### Narration keys
Narration spends the person's own provider account, and the key never
passes through the agent: no tool takes one, none shows one. Register it
once in the OS keyring — macOS Keychain, the Secret Service on Linux
(GNOME Keyring, KWallet), the Credential Manager on Windows:
```bash
promoshot-mcp key What people ask about promoshot
What is GarAlex/promoshot?
+
GarAlex/promoshot is mcp servers for the Claude AI ecosystem. Author a video as JSON, render it anywhere. Rust video engine behind PromoShot — CLI + MCP server for AI agents, wgpu + ffmpeg, runs headless on Linux. It has 0 GitHub stars and its last recorded update is dated 2026-09-10.
How do I install promoshot?
+
You can install promoshot by cloning the repository (https://github.com/GarAlex/promoshot) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is GarAlex/promoshot safe to use?
+
Our security agent has analyzed GarAlex/promoshot and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains GarAlex/promoshot?
+
GarAlex/promoshot is maintained by GarAlex. The last recorded GitHub activity is dated 2026-09-10, with 2 open issues.
Are there alternatives to promoshot?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy promoshot to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/garalex-promoshot)<a href="https://claudewave.com/repo/garalex-promoshot"><img src="https://claudewave.com/api/badge/garalex-promoshot" alt="Featured on ClaudeWave: GarAlex/promoshot" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!