PromoShot
Headless MCP · v0.2.2

Turn a screenshot into a cinematic promo.

An agent takes a screenshot or a screen recording, layers it, keys a move, captions it, and hands back a still, a GIF, or a video. Same compositor the Mac app ships. No GUI.

Rendered headless from ProductCard.promo — 1440×810 MP4, 30 fps. Still at 3 seconds below shows a 2.5D device slab. An agent validated the project, then called promo_render_video and promo_render_still.

Still at 3 seconds: spaceBlack 2.5D device slab over a palette ground, caption Meet the new dashboard
1920×1080 still at 3s. Layers, motion, a 2.5D slab, a title.
Ken Burns push-in over a screen recording with a lower caption
Screen recording, pushed in. Footage-first recipe →

The job

  1. Point an agent at a product screenshot or a screen recording — not at a blank timeline.
  2. It authors a .promo folder: layers, motion, caption. A 2.5D device slab is optional — since 0.2.2 headless CLI/MCP bakes bezel, extruded depth, optional tilt, and contact shadow at stage time. Validate before render.ok means it will render.
  3. It writes a still to look, then a GIF or video to share. Paths come back, never bytes. Outputs land in the project's Exports/.

Agents do not discover the GitHub repo by themselves. Install the skill, then the tools. Recipes that already ran:

Install the binaries

Latest release is v0.2.2. Each tarball is promo plus promoshot-mcp — put both on PATH or keep them side by side (--promo is optional when the CLI sits next to the server). Video needs ffmpeg / ffprobe. Linux also wants a Vulkan ICD (mesa-vulkan-drivers is enough).

# Linux x64
curl -fsSL -o promoshot.tar.gz \
  https://github.com/GarAlex/promoshot/releases/download/v0.2.2/promoshot-v0.2.2-linux-x64.tar.gz
tar -xzf promoshot.tar.gz
install -m 0755 promo promoshot-mcp ~/.local/bin/

# macOS Apple silicon
curl -fsSL -o promoshot.tar.gz \
  https://github.com/GarAlex/promoshot/releases/download/v0.2.2/promoshot-v0.2.2-macos-arm64.tar.gz
tar -xzf promoshot.tar.gz
install -m 0755 promo promoshot-mcp ~/.local/bin/

Source and image: github.com/GarAlex/promoshot. Releases: github.com/GarAlex/promoshot/releases. Docker and a GPU-less Linux box: Linux & CI →

mcp.json

--workspace is where new projects go. --root fences which folders the server will touch. Pointing both at one directory is the tidy setup.

{
  "mcpServers": {
    "promoshot": {
      "command": "~/.local/bin/promoshot-mcp",
      "args": [
        "--workspace", "/ABS/PATH/Promo",
        "--root", "/ABS/PATH/Promo"
      ]
    }
  }
}
# Claude Code
claude mcp add promoshot ~/.local/bin/promoshot-mcp

# Grok Build
grok mcp add promoshot -- ~/.local/bin/promoshot-mcp \
  --workspace /ABS/PATH/Promo --root /ABS/PATH/Promo
grok inspect

Handshake that actually ran — validate, then a still:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": { "protocolVersion": "2025-06-18" }
}
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "promo_validate",
    "arguments": { "project": "/ABS/PATH/Promo/ProductCard.promo" }
  }
}
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "promo_render_still",
    "arguments": { "project": "/ABS/PATH/Promo/ProductCard.promo", "time": 3.0 }
  }
}

Replies: ok — nothing the renderer would quietly correct, then a path under Exports/. Inspect lists layer ids (promo inspect /ABS/PATH/Project.promo --json — flag after the path).

Skill — agents will not find this alone

Same file everywhere: skill/SKILL.md in GarAlex/promoshot. Drift-tested against the server's tool list.

REPO=https://github.com/GarAlex/promoshot
git clone --depth 1 $REPO /tmp/promoshot

mkdir -p ~/.claude/skills/promoshot
cp /tmp/promoshot/skill/SKILL.md ~/.claude/skills/promoshot/SKILL.md

mkdir -p ~/.grok/skills/promoshot
cp /tmp/promoshot/skill/SKILL.md ~/.grok/skills/promoshot/SKILL.md

mkdir -p ~/.agents/skills/promoshot
cp /tmp/promoshot/skill/SKILL.md ~/.agents/skills/promoshot/SKILL.md

# Cursor: in the repo the person is editing, not the engine repo
mkdir -p .cursor/rules
cp /tmp/promoshot/skill/SKILL.md .cursor/rules/promoshot.md

stdio vs the Mac app

Headless promoshot-mcp is stdio JSON-RPC only — the client spawns the process; no port, no token. The Mac app is a separate HTTP MCP (Settings → Automation) that shares the core names and adds app-only abilities.

Headless promoshot-mcpMac app MCP
Transportstdio JSON-RPCHTTP from Settings → Automation
Tools18 — schema, validate, inspect, render, workspace, media, init, upsert, speakSame core names plus promo_open (and app speech / Keychain)
WatermarkNone. CLI overlay is None — the CLI is the oracle and renders cleanFree-tier renders through the app carry the PromoShot watermark
Fence--root refuses projects outside the treePer-folder access; access_required until the person approves
Workspace--workspace / $PROMOSHOT_WORKSPACE / XDGpromo_workspace is a pre-approved folder

Want the GUI on this Mac? Download PromoShot. Want CI? Headless Linux →

Eighteen tools

Measured tools/list on v0.2.2 = 18. No MCP resources. The server owns no renderer — every validate / inspect / still / GIF / video shells out to promo.

ToolWhat it does
promo_schemaAuthoring subset + four validated recipes. Read once before authoring.
promo_schema_fullWhole .promo format (same compiled-in file as the parser).
promo_schema_typesTypes-only JSON Schema generated from the parser structs.
promo_validateRenderer's own parser. ok means it will render. Optional preview → Exports/preview.png.
promo_inspectCanvas, duration, layers with ids, undefined colours, missing media.
promo_render_stillOne PNG at a time. Returns the path. Default Exports/still-<time>s.png.
promo_render_framesPNG per frame over a range — a contact sheet before a full render.
promo_render_videomp4, audio mixed. Needs ffmpeg. Default Exports/export.mp4.
promo_render_gifLooping GIF, no ffmpeg. Default 12 fps, Exports/export.gif.
promo_workspaceFolder for new assistant-authored projects.
promo_media_probeDistilled ffprobe: container, duration, streams.
promo_media_filmstripContact sheet of a source clip; sampled times per cell. Default 12 frames, max 48.
promo_media_silencesSilence spans and their inverse (sound spans). Default −35 dB, min 0.35 s.
promo_media_scenesScene-change cuts and the shots between them. Default threshold 0.4. Use this when a clip has no silence gaps.
promo_initCreate a .promo folder (canvas, palette, bg layer). Never overwrites.
promo_upsert_layerScaffold image / video / caption with placement, fadeIn, device frame. Since 0.2.2, headless bakes the 2.5D slab (bezel, extruded depth, optional tilt, contact shadow) at stage time.
promo_upsert_keyframeCreate or merge one keyframe — a second placement is a push-in, viewport is a Ken Burns ride.
promo_speakTTS for speech.text using the person's own key. Without a key, drop a voice file into Resources/.

App-only (not in this binary): promo_open.

Mac GUI, or headless from here.

The app is the editor. This MCP is how an agent ships the same pixels.