spoooler

spoooler

Enables local-first Instagram reel production entirely over MCP, turning raw footage, URLs, or topics into finished reels with script generation, stock media, voiceover, and captions.

Category
Visit Server

README

<div align="center"> <img src=".github/assets/spoooler-hero.png" alt="Spoooler — AI powered video clipping" width="720" />

<p><strong>Local-first Instagram reel production, driven entirely over MCP.</strong></p>

<p> <a href="https://instagram-reel-tool.vercel.app/">Website</a> · <a href="https://github.com/4nw3rprod/spoooler/releases">Download</a> · <a href="https://github.com/4nw3rprod/ReelRecon">ReelRecon (companion tool)</a> </p>

<p> <img alt="License" src="https://img.shields.io/badge/license-MIT-a78bfa?style=flat-square"> <img alt="Node" src="https://img.shields.io/badge/node-20%20%7C%2022-a78bfa?style=flat-square"> <img alt="MCP" src="https://img.shields.io/badge/interface-MCP--only-a78bfa?style=flat-square"> <img alt="Platform" src="https://img.shields.io/badge/platform-macOS-a78bfa?style=flat-square"> </p> </div>


MCP is the sole entry point. All invocations go through the MCP server (node mcp/server.mjs, or node mcp/client.mjs <tool> '<json>' from a shell). There is no web UI or HTTP API — the instagram-reel-generator.mjs engine refuses to run unless the MCP server spawns it (REEL_VIA_MCP). Start with VIDEO-DIRECTOR-SKILL.md (how to direct a reel) and FOOTAGE-MCP-SKILL.md / mcp/README.md (the tool catalog).

Spoooler turns raw footage, an Instagram URL, or a one-line topic into a finished, post-ready 1080×1920 reel — orchestrated tool-by-tool by whatever AI coding assistant you drive it with over MCP.

It can:

  • expose that workflow over MCP so Codex and other MCP hosts can drive it tool-by-tool
  • scrape real product media
  • collect stock backgrounds
  • generate voiceover with Kokoro or your own cloned pocket-tts/TADA voices
  • align captions with whisper.cpp
  • render the final MP4 with Remotion

What works out of the box vs. what's bring-your-own

Capability Requires
Topic/transcript → scripted reel, stock media, captions, render API keys only (see below)
Instagram URL / uploaded video → transcript your own MCP-compatible transcriber (IG_TRANSCRIBER_ROOT) — not included
Cloned-voice narration (Pocket-TTS / TADA) your own voice embeddings — not included
Product/brand media scraping Scrapling + Playwright installed locally

None of these are required to try the tool — --skip-transcribe --transcript "..." gets you a full render with zero external transcriber or voice setup.

System requirements

  • Node.js 20 or 22
  • npm 10+
  • Python 3.11+
  • ffmpeg and ffprobe
  • Git

Optional, only if you use these features:

  • a Scrapling-capable Python venv (product/brand media scraping)
  • pocket-tts on PATH (cloned-voice narration)
  • an MLX-TADA setup on Apple Silicon (alternate cloned-voice engine)
  • an MCP-compatible transcriber (Instagram URL / video upload input)

You'll also need API keys for whichever of these you want to use: Google Gemini, NVIDIA NIM, Groq, Pexels, Unsplash, logo.dev.

Quick start

git clone <this-repo-url>
cd instagram-reel-tool
npm install
cp .env.example .env

Fill in .env with the keys you want (see "Environment variables" below — most are optional and the tool degrades gracefully without them).

Verify the main packages resolve:

node -e "require.resolve('@modelcontextprotocol/sdk')"
node -e "require.resolve('remotion')"
node -e "require.resolve('@remotion/install-whisper-cpp')"
node -e "require.resolve('zod')"

Run the offline smoke test (no Instagram download, no LLM calls, no TTS):

node instagram-reel-generator.mjs \
  --skip-transcribe \
  --skip-tts \
  --offline \
  --transcript "Stop automating random tasks. The best AI systems start by finding the workflow bottleneck. Then they remove one handoff and measure the result." \
  --topic "AI workflow automation for founders"

This writes run artifacts under runs/<slug>/.

Environment variables

Copy .env.example to .env. Key variables:

  • GOOGLE_API_KEY, GEMINI_MODEL — script generation (primary)
  • NVIDIA_API_KEY, NVIDIA_MODEL — script generation (tried before Gemini)
  • GROQ_API_KEY, GROQ_MODEL — script generation (final fallback)
  • KOKORO_API_URL, KOKORO_API_KEY, KOKORO_MODEL, KOKORO_VOICE, KOKORO_SPEED — Kokoro TTS
  • PEXELS_API_KEY, UNSPLASH_ACCESS_KEY — stock media
  • LOGO_DEV_PUBLIC_KEY, LOGO_DEV_TOKEN — brand logo fetching
  • IG_TRANSCRIBER_ROOToptional, absolute path to your own MCP-compatible transcriber (see below)
  • SCRAPLING_PYTHON — path to a Python interpreter with Scrapling installed
  • FFMPEG_PATH, WHISPER_MODEL — rendering/captions
  • POCKET_TTS_VOICE, POCKET_TTS_TONE, POCKET_TTS_QUALITY — cloned-voice narration
  • TADA_* — alternate cloned-voice engine (see below)

None of these are required just to install and run the offline smoke test above.

Optional: Instagram URL / video transcription — pairs with ReelRecon

Transcribing an Instagram reel URL or an uploaded video file requires a separate MCP-compatible transcriber that this repo does not include. It must expose a run_mcp_server.sh script and a transcribe_input tool (input URL/path → transcript text).

ReelRecon — a companion tool, also by this author — is a drop-in fit: it transcribes Instagram profiles, direct video URLs, or uploaded audio/video with Whisper, and ships its own run_mcp_server.sh + transcribe_input MCP tool with exactly this interface. Typical pairing:

git clone https://github.com/4nw3rprod/ReelRecon.git
IG_TRANSCRIBER_ROOT=/absolute/path/to/ReelRecon

Feed a raw Instagram reel into ReelRecon for a clean transcript, then hand that transcript to Spoooler (via transcribe_source / --transcript) to script, voice, caption, and render the derivative reel — two focused tools instead of one that tries to do both.

Without it, Spoooler still works fully via --transcript or a plain --topic — you just skip the "give me a URL" step and provide the script input directly.

Optional: cloned-voice narration

The tool supports two cloned-voice backends. Neither ships with any voice data — bring your own.

Pocket-TTS (Kyutai)

  1. Install the pocket-tts CLI and verify pocket-tts --help works.
  2. Create a voice embedding (.safetensors) with whatever tooling you use to produce Kyutai-compatible embeddings.
  3. Place it under audio/pocket-tts/voices/ (sibling to this repo, i.e. ../audio/pocket-tts/voices/) along with a voices.json index:
[
  {"id": "my-voice", "name": "My Voice", "embeddingFile": "my-voice.safetensors"}
]
  1. Set POCKET_TTS_VOICE=audio/pocket-tts/voices/my-voice.safetensors in .env, or pass --voice-file per run.

If voices.json is missing or malformed, the MCP list_voices tool simply returns no cloned voices — Kokoro presets still work.

TADA (Hume MLX, Apple Silicon)

Optional alternate voice-cloning engine, clones from a short reference audio clip + its transcript instead of a pre-trained embedding.

python3 -m venv .venv-tada
source .venv-tada/bin/activate
python -m pip install --upgrade pip setuptools wheel
pip install mlx-tada
TADA_PYTHON=/absolute/path/to/.venv-tada/bin/python3
TADA_MODEL=HumeAI/mlx-tada-1b
TADA_PROMPT_AUDIO=/absolute/path/to/your/reference.wav
TADA_PROMPT_TEXT=
TADA_REFERENCE_CACHE=/absolute/path/to/instagram-reel-tool/.cache/tada/default-reference.npz

Notes:

  • Apple Silicon only; follows Hume's apple/ implementation.
  • Depends on the gated Meta Llama 3.2 base models on Hugging Face for the tokenizer.
  • TADA_PROMPT_AUDIO (your own reference clip) is required; TADA_PROMPT_TEXT is optional.
  • Use TADA_MODEL=HumeAI/mlx-tada-1b (English) or HumeAI/mlx-tada-3b (multilingual).
  • Set TADA_WEIGHTS/TADA_TOKENIZER to force local weights/tokenizer instead of Hub downloads.
  • Trigger via voiceEngine=tada in the MCP synthesize_voice tool, or --voice-engine tada on the CLI.
  • Wrapper script: scripts/tada-tts.py.

Optional: product/brand media scraping (Scrapling)

The media-scraping pipeline uses Python and Scrapling.

python3 -m venv .venv-scrapling
source .venv-scrapling/bin/activate
python -m pip install --upgrade pip setuptools wheel
pip install "scrapling>=0.4,<0.5"
python -m playwright install
SCRAPLING_PYTHON=/absolute/path/to/instagram-reel-tool/.venv-scrapling/bin/python3

Verify:

source .venv-scrapling/bin/activate
python - <<'PY'
from scrapling.fetchers import Fetcher, DynamicFetcher, StealthyFetcher
print("scrapling fetchers ok")
PY

If Scrapling isn't set up, product scraping degrades to stock-media-only rather than failing the run.

MCP server

This repository includes an MCP server at mcp/server.mjs.

Local smoke tests

node mcp/test-client.mjs
node mcp/test-strategy.mjs

These confirm the server starts, tools register, and the strategy fast path works without an LLM script-generation step.

MCP host configuration

Most MCP hosts use a JSON mcpServers config, e.g. for a generic host settings file:

{
  "mcpServers": {
    "instagram-reel-tool": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/instagram-reel-tool/mcp/server.mjs"]
    }
  }
}

Codex configuration

Add to ~/.codex/config.toml:

[mcp.instagram-reel-tool]
command = "node"
args = ["/ABSOLUTE/PATH/TO/instagram-reel-tool/mcp/server.mjs"]

See mcp/README.md for the full tool catalog and more host examples.

Full render check

Once keys and (optionally) voices are configured:

node instagram-reel-generator.mjs \
  --skip-transcribe \
  --transcript "This is a short test reel about AI workflow automation." \
  --topic "AI workflow automation" \
  --render

Notes:

  • the first whisper.cpp alignment run can take a while because the model installs into .cache/whisper-align
  • the first cloned-voice run can take longer while pocket-tts loads
  • if no media APIs are configured, renders complete but with empty or degraded media layers

Troubleshooting

list_voices returns no cloned voices

Check ../audio/pocket-tts/voices/voices.json and the referenced .safetensors files exist.

Scraping returns nothing

Check SCRAPLING_PYTHON points to a working venv, Scrapling imports successfully, Playwright's browsers are installed, and you have network access.

Video upload fails to transcribe

Check IG_TRANSCRIBER_ROOT points to a working transcriber exposing run_mcp_server.sh + transcribe_input, ffmpeg works, and the uploaded file is under 200 MB.

Cloned voice generation fails

Check pocket-tts is on PATH, the selected .safetensors file exists, and voices.json references the correct embedding filename.

Captions do not align

Check ffmpeg is installed, npm install completed successfully, @remotion/install-whisper-cpp resolves, and the first whisper model install was allowed to complete.

Render succeeds but visuals are empty

Check PEXELS_API_KEY/UNSPLASH_ACCESS_KEY are set and stock/scraped media actually downloaded into the run folder.

Files worth reading

Related project

Roadmap: a closed-loop, autonomous content pipeline

Spoooler and ReelRecon already cover transcribe → script → produce end to end over MCP. The next integration closes the loop from raw footage to a published post, with no manual handoff in between:

Stage Tool Role
Discover / transcribe ReelRecon Pull and transcribe source content (Instagram, video, audio)
Route the LLM calls OmniRoute Single gateway across providers — smart fallback and cost-aware routing for every scripting/vision call in the pipeline
Script, produce, render Spoooler (this repo) Hook, scenes, voiceover, captions, brand media, final MP4 — driven tool-by-tool over MCP
Publish Postiz Schedule and post the finished reel across platforms, agent-driven via its tool-call CLI

The goal: point the pipeline at a source once, and let it run end to end — discovery through publishing — as a single MCP-orchestrated workflow. No manual export/upload step, no juggling separate scheduling tools, no re-planning content by hand. Set it up once, then stop thinking about posting and go back to thinking about what's worth making.

This is planned, not yet wired up — tracking here so the shape of the integration is public before the code is.

Built with

Spoooler is a thin orchestration layer over a handful of open-source projects doing the real work:

Project Role
Remotion React-based video composition and MP4 rendering
Model Context Protocol SDK the MCP server/client this tool is entirely driven through
whisper.cpp (via @remotion/install-whisper-cpp) word-level caption alignment
Scrapling + Playwright product/brand media discovery and scraping
Kokoro default text-to-speech voices
Kyutai's Pocket-TTS optional bring-your-own cloned-voice narration
Hume's TADA (MLX) optional alternate bring-your-own voice-cloning engine, Apple Silicon
Next.js the landing page / marketing surface
Zod MCP tool input schema validation

Full dependency list in package.json.

License

MIT — see LICENSE.

<div align="center"> <sub>Built locally, rendered with Remotion.</sub> </div>

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured