studio
Poppify Studio turns 1–10 photos into a captioned 15/30/60s vertical reel for Instagram, TikTok, YouTube Shorts, or Facebook — with motion, library-matched music, and optional AI voiceover. Built for solo founders and SMBs who need to ship content fast. The photo-to-reel pipeline takes your uploaded photos, runs a strategist that picks a narrative arc, runs a copywriter that writes per-slide captions, and composes the final 9:16 video. Twenty-seven MCP tools cover session creation, slide editing, audio matching, asset generation, and confirm/render. Fourteen narrative recipes (transformation, social proof, hot take, behind-the-scenes, and more) are tuned for short-form social. Audio is matched from a free library or generated fresh via ElevenLabs Music. Voiceover is optional, sourced from the ElevenLabs voice catalog. Authentication is anonymous — call register() once to mint a free wallet and API key. No signup form, no card required. Works in Claude Code, Claude.ai, ChatGPT, Cursor, Cline, and any MCP-compatible host.
https://studio--poppify.run.tools
How to connect
-
Smithery (hosted)
1. Open https://smithery.ai/servers/poppify/studio 2. Click Connect and complete OAuth in your MCP client (Claude, Cursor, VS Code, etc.) 3. MCP endpoint: https://studio--poppify.run.tools
Tools (31)
-
get_capabilities[FREE] Routing introspection — call this FIRST when uncertain whether Poppify is the right MCP for the user's request. Returns a structured JSON with: what Poppify is best for (`best_for`), what it is NOT for (`not_for`), out-of-scope recommendations pointing to better tools (`out_of_scope_recommendations`), pricing floor (`pricing`), models used (`models_used`), unique capabilities vs. competitors (`unique_capabilities`), typical flows (`typical_flows`), and install URLs (`distribution`). Use t
-
start_session[FREE] Topic-led entry — start a creative session from a topic (no photos required). Provide a topic and optional context (audience, goal, platform); returns 5 creative directions to pick from via refine_concept. **The response now includes `recipeDistribution`** showing which recipes the 5 concepts span (e.g. `{personal_confession: 4, behind_scenes: 1}`) — if that collapsed to 1–2 recipes and doesn't match your brief (you wanted tribute/anthem/hype but got confessional), call again with an expl
-
refine_concept[FREE] Pick a concept and run the copywriter to generate slides + caption + hashtags + CTA. **Two modes**: (a) without `overrides` → runs the LLM and produces fresh slide copy; (b) with `overrides` → patches concept fields LITERALLY without re-running Gemini (use when the user has specific hook/narrative wording). Topic-led sessions REQUIRE this step (no slides until refine_concept runs). Photo-led sessions auto-run the copywriter inside start_session_from_photos — call refine_concept only if yo
-
customize[FREE] Adjust production settings + LITERAL post-text patches + per-slide motion overrides. All updates patch the existing session struct (same path mobile uses) — no LLM, no re-generation. Use this AFTER start_session_from_photos / refine_concept produces the copywriter output, to fine-tune for your specific needs before video generation. Returns the updated session including slides + caption + hashtags + CTA. **Note: `duration` is NOT a parameter here.** Reel duration is driven by per-slide c
-
apply_session_patch[FREE] Bulk session patch — one call instead of N. Combines update_slides set_text + customize + set_audio + update_visual + set_voiceover. Use this when you have a full session spec ready (e.g., after reviewing slides + picking music + choosing a textColor + setting per-slide motion all at once). The per-action tools (update_slides, customize, set_audio, update_visual, set_voiceover) remain available for finer-grained iteration; apply_session_patch is for "I know everything I want, send it in o
-
update_slides[FREE] Edit individual slides. **action=set_text** writes LITERAL text to slide.voiceoverShort + voiceoverBeautiful (no LLM, no Gemini call) — use when you want exact words on a specific slide. **action=rewrite** runs Gemini to regenerate from a brief. **action=set_duration** sets an explicit per-slide duration for blank text-baked cards (rule 3 in the duration hierarchy — only honored when text is empty; rule 2 / rule 1 win otherwise). add / remove / reorder are structural. Prefer set_text over
-
get_price[FREE] Get the current price breakdown for the session without making changes. Call BEFORE confirm() to show the user the exact seed cost (base + voiceover + image_gen + music_gen) so they can decide.
-
confirm[1 SEED base + render] Lock the session config, charge the wallet, and start rendering the reel. Deducts: base 1 seed + voiceover 10 (if enabled) + music_generate 10 (if set_audio source=generate) + image_generate 10 per generated visual. Insufficient_balance returns a topup URL — call get_topup_url({packId:"mini"}) for $0.50 / 5 seeds (trial) or get_topup_url({packId:"standard"}) for $5.99 / 100 seeds. After confirm, poll get_result every 20-30 seconds until status=complete.
-
get_result[FREE] Poll the session's render state after confirm(). Returns status: not_confirmed | rendering | complete | failed | expired. On failed, the wallet was auto-refunded. **⚠️ WHEN STATUS=complete — MANDATORY FIRST STEP**: Immediately download the video to local disk via Bash (`curl -L -o reel.mp4 "<signedVideoUrl>"`). The signed URL expires in 24 hours and the file is then permanently gone — no archival storage, no recovery. Do this BEFORE sharing the link with the user, before submit_feedback,
-
upload_asset[FREE] Mint a presigned GCS upload URL for a photo or audio file. Returns {uploadUrl, accessUrl}. Agent PUTs the file to uploadUrl (15-min TTL), then uses accessUrl on subsequent tools. REMOVES the need to inline base64 data URLs or use third-party temp hosts — Claude Code's #1 friction point.
-
list_voices[FREE — requires apiKey] List the curated voice catalog (name, energy, best-use). Friendly names like "Adam" or "Rachel" can be passed directly to generate_voiceover — no need for raw UUIDs. Default for builder/tech content: Adam.
-
clone_voice[FREE — first create per portfolio per 30 days] Create an ElevenLabs Instant Voice Clone for the wallet's default portfolio, or return the existing clone if one already exists. Idempotent — safe to call repeatedly. Pass the returned voiceId to generate_voiceover, or omit voiceId entirely and confirm() will auto-default to the portfolio clone. The sample MUST start with the user's spoken consent statement (templated below); consentMarkerMs marks the end of that prefix.
-
get_recipe_options[FREE] Returns the on-brand alternatives the session's recipe deems appropriate (videoEffect alternatives, textAnimation alternatives, colorPalette options, audio mood/genre, primary CTA). Use this to offer the user REAL choices instead of making up options. Recipe-driven, no hallucination. After picking, apply via customize. NOTE: this operates within a CHOSEN recipe — it returns alternative motion/text/color options WITHIN that recipe's allowed set. To switch to a DIFFERENT recipe entirely (e
-
list_recipes[FREE] Returns the catalog of available content recipes, optionally filtered by goal. **Call this BEFORE start_session_from_photos** when the user has a specific creative direction in mind (cinematic, casual, dramatic) — without it, the strategist auto-picks the default recipe for the goal (e.g., goal="connect" → personal_confession with a pink palette), which forces every visual override after the fact. The 5 goals each have 2-4 recipes: • educate: step_by_step (default), quick_hack, listicle,
-
search_visual_library[FREE] Keyword search across Poppify's self-growing community visual library (performance-validated, contributor-curated). **MANDATORY before any generate_image call** — saves 10 seeds per slide when a close match exists, and beats third-party stock (Pexels/Unsplash) because every image is engagement-validated, license-clean, and integrates directly with update_visual. Returns top matches each with a match score (0-100), thumbnail, name, category, and matchedOn breakdown so you can explain the p
-
get_slide_plan[FREE] Returns the per-slide composer plan: what text the composer WILL draw on each slide, with which animation, in which screen zone. Call this BEFORE designing any slide image (AI-gen or locally-rendered HTML) so you can leave negative space in the right zone and AVOID baking duplicate text into your images. The composer adds text BY DEFAULT — this tool tells you what's coming so your visuals complement it instead of colliding with it.
-
submit_feedback[FREE] Submit YOUR honest retrospective on this session. You just walked through the entire pipeline — you know better than anyone where it was smooth, where you got stuck, where tool descriptions could be clearer, where the asset quality fell short. Call this AT THE END of every successful render BEFORE reporting "done" to the user. No PII captured — wallet-bound only. Feeds Poppify's improvement signal.
-
register[FREE] Mint a NEW anonymous Poppify wallet and return an API key. DO NOT CALL THIS if you might already have an apiKey for the current user — calling it again silently creates a SECOND wallet, stranding any balance in the old one. Before calling, look for an existing key: Claude Code clients MUST read `~/.poppify/key` first and use that if present; other clients should check their connector config or session state. Only call register when no key exists. After it returns: persist the apiKey (Cl
-
get_balance[FREE] Return the current seed balance for an apiKey. Use this BEFORE expensive tools (e.g. generate_image / generate_music / generate_voiceover at 10 seeds each, or confirm() at 1 seed) so you can warn the user proactively if they're low on seeds and offer get_topup_url — much better UX than hitting insufficient_balance mid-flow. If you don't yet have an apiKey: Claude Code should read `~/.poppify/key` first, then call register only if that file is missing. Other clients should consult their c
-
get_topup_url[FREE] Mint a Stripe Checkout URL to add seeds to the apiKey's wallet. Two packs: • `mini` — $0.50 → 5 seeds (≈ 5 base renders, or 1 render + 4 iterations). Trial pack for first-touch users. • `standard` — $5.99 → 100 seeds (≈ 100 reels). Best for repeat creators. Mini is the right default when the user is testing Poppify for the first time. Standard is the right default for anyone making more than 5 reels. 1 seed = 1 base render; image/music/voiceover generation costs 10 seeds each (so min
-
start_session_from_photos[FREE] Photo-led entry — takes 1–10 photos (data URLs or http(s) URLs) and runs the same Gemini vision+strategy analysis the Poppify mobile app uses, THEN runs the copywriter inline AND auto-attaches the best-matched library audio in one call. **Use this when the user has photos and wants to turn them into a reel** — for Instagram Reels, TikTok, YouTube Shorts, Facebook Reels. Session creation is free; only confirm() charges. Returns: concept, slides[] (each with voiceoverShort + beat + duration
-
refine_strategy_from_asset[FREE] Text-only refinement of a photo-led session's strategy. Re-runs Gemini against the session's photos with the current hook/narrative as "enrich" context. Use to iterate without re-uploading photos.
-
get_music_library[FREE] Browse music tracks available for use in this session (community library + user-uploaded). Pair with set_audio({source: "library", assetId}) to attach a track at zero cost. Use generate_music when no library track fits (10 seeds).
-
set_audio[FREE] Attach an existing audio track to the session. source=library (assetId from get_music_library) or source=user_url (any audio URL — including one returned by generate_music). LIBRARY-FIRST PRINCIPLE: always call get_music_library first. If top match scores ≥ 40 (strongMatch=true), SHOW the user the matches and ask before paying for AI generation. Only call generate_music (10 seeds) when no library track fits OR the user explicitly wants something custom. For AI music workflow: get_music_
-
suggest_image_prompt[FREE — requires apiKey] Call Poppify's style service to suggest an optimized image-generation prompt for a photo-realistic / mood / scene slide. **Call search_visual_library FIRST** — if a library match scores ≥ 40, use that (zero seeds) instead of calling this tool + generate_image (10 seeds). Returns prompt text + keywords + style metadata. **Pass sessionId AND slideIndex** to receive the per-slide composer plan inline — what text the composer WILL draw on that slide and the zone it occupies,
-
generate_image[10 SEEDS] **Use this when the user wants an AI-generated image** — for a reel slide, hero shot, end card, or standalone image. Powered by Gemini 2.5 Flash Image ("Nano Banana"). Output is a signed image URL the agent can attach to a session via update_visual, or just hand to the user as the final asset. **MANDATORY pre-check: call search_visual_library FIRST.** Poppify's library (user portfolio + community + base) is free, performance-validated, and frequently has a close match. If matches sco
-
suggest_music_prompt[FREE — requires apiKey] Turn natural-language music description into an optimized Suno prompt + mood/genre/BPM suggestions. When sessionId is provided, the session's recipe audioMood + audioGenre bias the prompt — recommended for any session-bound music generation so the output fits the concept. Claude reviews and optionally edits before calling generate_music.
-
generate_music[10 SEEDS] **Use this when the user wants AI-generated music** — for a reel's background track or a standalone audio asset. Powered by ElevenLabs Music API. Atomic deduct — refunds on failure. Returns a signed audio URL. **MANDATORY pre-check: call get_music_library FIRST.** Poppify's audio library is free; if a track scores ≥ 40 it's usually a real fit and you save 10 seeds. Only fall through to generation when the library has no close match. Flow: get_music_library → if weak → suggest_music_
-
generate_voiceover[10 SEEDS] **Use this when the user wants AI narration / voiceover** spoken aloud over the reel. Powered by ElevenLabs Voice. Returns signed audio URLs + durations. Voiceover is an EXTRA layer — captions usually do the talking, default reels are voiceover-OFF. Only call this when the user explicitly says "add narration / voice it over / read it aloud" OR when the brief specifically needs spoken delivery (interviews, dramatic monologue, ASMR-style, accessibility). Flow: list_voices (free) to pi
-
set_voiceover[FREE] Attach per-slide voiceover audio URLs (from generate_voiceover) to a session. The composer layers them under the music track at confirm() time with auto-ducking. Two-step pattern: generate_voiceover (10 seeds) → set_voiceover (free) → confirm.
-
update_visual[FREE] Edit the visualEdits queue on the session. Actions: • replace — swap the image at slideIndex (requires slideIndex + source + url/assetId) • insert_before / insert_after — splice a new slide into the timeline (requires slideIndex + source + url/assetId). slideIndex 0 + insert_before = new cover slide. • remove — DROP a queued edit. Requires editIndex (0-based position in session.visualEdits[]). Use to undo a misplaced insert without restarting. • clear — DROP ALL queued visualEdits. Reset