| name | explainer |
| description | Use when the user asks for explainer or a task matching the examples below. ~60-80s explainer video for any URL — GitHub repo, product page, docs site, blog post, or launch. Canonical workflow for URL walkthroughs. Use when the user asks to "explain this URL / repo / website / product", "make a walkthrough video for [url]", "demo this site", "Loom-style explainer of [url]", "explainer for github.com/...", or "explain this product link". Drives a real browser through the URL, generates an avatar lipsync, and composites in a 1280×800 macOS Sonoma frame with a 246-pixel bottom-left avatar circle. GitHub URLs activate a repo-aware mode (README scan + live-demo detection); other URLs use a generic page-walkthrough flow. |
| argument-hint | <url> [--focus angles] [--avatar url] [--voice id] [--live-url url] [--lipsync-provider pika|kling] [--no-captions] [--preview] |
/pika:explainer
Generate a ~60–80s URL explainer video: drive a real browser through the URL along a beat-sheet timeline, generate an avatar lipsync of the narration, and composite it all in a 1280×800 macOS Sonoma frame with a 240-pixel inner avatar (246-pixel outer including 3px white stroke ring) at canvas (20, 476) and element-targeted zoom on every mid-section beat. Works on any URL — product pages, docs sites, blog posts, launches. GitHub URLs activate a repo-aware mode (README scan + live-demo detection); all other URLs use a generic page-walkthrough flow.
Usage: /pika:explainer <url> [--focus "angles"] [--avatar <url>] [--voice <id>] [--lipsync-provider pika|kling] [--preview] [--live-url <url>]
Cost transparency gate
Before any paid MCP call, call identity_balance({verbose: true}) once. Surface the current balance, recent burn rate, and remaining runway, then gate the run with this exact message:
Estimated cost: about 50-500 credits (~$0.50-$5.00) depending on lipsync provider, narration, captions, and preview mode. This can reach $5, so Reply proceed to continue or cancel to stop.
Do not call any paid MCP tool until the user replies proceed. If the user replies cancel, stop without generating. The gate runs after the URL and optional flags are known, before avatar generation, speech, lipsync, captions, or video composition.
Behavior
Defaults — fire fast, no unnecessary mid-flow confirmation
- Resolve avatar / voice silently. Never ask "should I use your avatar?" or "which voice?" before firing. Honor explicit overrides (
--avatar, --voice) when supplied; otherwise generate a presenter avatar and pick a default voice, and proceed. See Step 1 for the full resolution waterfall.
- Only the cost transparency gate asks for
proceed. Step 5 preview is normally opt-in via --preview for explicit avatars, but it becomes mandatory auto-preview when the avatar source is a generated or regenerated fallback. After the cost gate, the flow runs end-to-end except for that required fallback-avatar preview guardrail.
- Do not solicit
--focus either. Make a confident first attempt from page structure; users re-run with --focus "X" if the angle missed.
These defaults match industry standard for media-gen tools (Midjourney / Sora / Runway / HeyGen / Pika.art): submit → render → return. Account credit balance + provider failover (Step 9) are the canonical guardrails.
Local avatar images on Claude Desktop
Claude Desktop can't pass inline-pasted images to MCP tools yet (Anthropic-side limitation). If the user pastes a photo inline, or mentions a local file they want as --avatar, pause Step 1 and kindly send them this — something like:
Heads up — pasted images don't reach MCP tools on Claude Desktop yet (Anthropic limitation). Two easy options for your avatar:
- Paste a URL if it's already hosted (Imgur, S3, your site) — fastest
- Attach the image file so I can upload it before generation.
When a local file arrives, convert it to a public URL with upload_asset and use the returned public_url as --avatar <url> before Step 1. Already-hosted https://... URLs work as-is and skip this entirely. If no avatar is supplied at all, a presenter portrait is generated silently (Step 1).
Step 0 — Resolve URL (empty-args menu)
Strip flags (--focus, --avatar, --voice, --live-url, --lipsync-provider, --no-captions, --preview, --skip-preview, --yes) and key=value parameters from $ARGUMENTS. If what remains contains no https://... URL (or is empty / whitespace-only), print this menu verbatim as your full response, then stop and wait for the user's next message. Calling a tool here risks recording or explaining the wrong page. If $ARGUMENTS already carries a URL, skip this step silently and proceed to Step 1.
Which URL would you like me to walk through? Works on any of:
- A GitHub repo — e.g.
https://github.com/anthropics/claude-code (activates repo-aware mode: README scan + live-demo detection)
- A product page / launch page — e.g.
https://pika.art
- A docs site — e.g.
https://docs.anthropic.com
- A blog post / article URL
Output: 1280×800 macOS Sonoma frame with a bottom-left avatar lipsync and element-targeted zoom on every mid-section beat. Default flow runs end-to-end after the cost gate; pass --preview if you want a 3-second lipsync sanity check for an explicit avatar. Generated / regenerated fallback avatars auto-run that preview guardrail.
Reply with the URL and I'll start.
Tip: you don't need to type /pika:explainer — just say things like "walk me through ", "make a demo video of ", or "explain this repo: " and I'll fire this skill automatically.
When the user replies with a URL, treat it as the resolved input and proceed to Step 1. Do not re-prompt.
Step 1 — Parse input + detect mode
Required: url (must be https://...).
Optional: --avatar <url> (the presenter photo; if omitted, one is generated), --voice <minimax-voice-id>, --focus "..." (editorial guidance woven into vo_text), --live-url <url> (force-supply live demo URL — GitHub mode only), --lipsync-provider <pika|kling> (defaults to pika — parrot a2v, ~2-5 min wall-clock, slightly more dramatic head motion. Pass kling for tighter face-centered output at ~5-30 min wall-clock — Kling produces minimal-head-motion presenter shots but is the long-pole stage; reserve for high-stakes renders), --no-captions (skip the Step 11 caption burn — default is captions on), --preview (opt-in to the Step 5 preview gate for explicit avatars; generated and regenerated fallback avatars auto-run the preview gate before full lipsync). --skip-preview and --yes are accepted as no-ops for backward compatibility.
Mode detection:
- GitHub mode — URL host is
github.com AND path matches /{owner}/{repo} (no further path segments past the repo root). Activates the repo-aware extras: README scan, live-demo detection, GitHub-specific selectors.
- Generic-URL mode — anything else (a product page, docs site, blog post, deeper GitHub path like
/blob/HEAD/path). Skips the GitHub extras; uses generic CSS selectors and walks through the URL itself.
Avatar resolution (silent — never ask the user):
- If
--avatar <url> was passed, use it.
- Else call
generate_image once with prompt "professional presenter, friendly tech narrator, studio portrait, 1:1, natural lighting" and use the returned URL. Do not ask the user "should I generate one?" — just generate silently.
Track avatar_source as one of explicit, generated, or regenerated.
Avatar suitability gate (mandatory before any lipsync spend):
Call analyze_media(media=<avatar>, query=<gate_query>) once on the resolved avatar image before Step 4 TTS and before any generate_lipsync preview/full call. This is the one case where avatar analysis is required, because the avatar is the central presenter asset and a bad generated avatar can burn the whole render.
Gate query:
Return JSON only: {
"is_single_front_facing_coherent_human_face": boolean,
"has_visible_mouth": boolean,
"is_faceless_or_masked": boolean,
"is_mascot_illustration_or_non_human": boolean,
"face_suitability_score": 0-100,
"apparent_gender": "female" | "male" | "unclear",
"reason": string
}
Is this image suitable for talking-head lipsync: a single front-facing coherent human face with a visible mouth? Flag faceless, masked, mascot, illustration-only, non-human, or distorted avatars.
Pass only if is_single_front_facing_coherent_human_face == true, has_visible_mouth == true, is_faceless_or_masked == false, is_mascot_illustration_or_non_human == false, and face_suitability_score >= 75.
If the avatar fails and avatar_source is explicit, stop before paid lipsync and ask for --avatar <real-looking-photo-url> or permission to generate a presenter portrait. If the avatar fails and avatar_source is generated, call generate_image once with prompt "realistic professional presenter portrait, single front-facing coherent human face, visible mouth, friendly tech narrator, neutral studio background, 1:1, natural lighting"; set avatar_source = "regenerated" and re-run this suitability gate on the regenerated avatar. If the regenerated avatar also fails, abort with a clear error instead of attempting lipsync.
Set avatar_auto_preview_required = true whenever avatar_source is generated or regenerated; otherwise false unless the user passed --preview.
Voice resolution (silent — never ask the user):
-
If --voice <id> was passed, use it.
-
Else pick a casual MiniMax speech-2.8-hd preset matching the resolved avatar's apparent gender:
- Female-coded avatar →
English_PlayfulGirl (warm, casual, clearly female-voiced — verified)
- Male-coded avatar →
English_Jovialman (warm, casual male)
- Unclear / gender-neutral →
English_Jovialman (default)
Infer gender from the avatar suitability gate result (apparent_gender). Do not ask the user.
Do NOT use English_FriendlyPerson — despite being categorized under "female" in MiniMax's catalog, its display name is "Friendly Guy" and it reads as male in playback. English_PlayfulGirl is the canonical casual-female pick. Other verified-female alternates: English_Upbeat_Woman, English_LovelyGirl, English_radiant_girl.
The flow below is annotated per step: GitHub-only, Generic-only, or Both modes.
Step 2 — Read source (no MCP call)
Both modes: use Claude's WebFetch on the input URL to pull the page's main content (h1, hero section, headings, primary copy).
Build proper_noun_glossary during this source read. Include canonical spellings of product, repo, company, model, framework, and proper nouns from the URL/domain, page title, h1, README headings, repo metadata, package names, and repeated capitalized tokens. For GitHub repos, preserve exact spellings surfaced by README/source scan, e.g. Ollama, Llama, DeepSeek, Gemma. Use this glossary later when authoring narration and when burning manual captions so caption text does not phonetically drift into misspellings like "Olama" or "DeepSeq".
GitHub mode additions: also fetch top-level file tree, (best-effort) package.json / pyproject.toml, and GitHub API repo metadata via gh api repos/{owner}/{repo} for homepage, description, language, topics. Detect a candidate live_url in this priority:
- User-supplied
--live-url.
- GitHub API
meta.homepage field — set when the maintainer configured the repo's homepage in GitHub settings.
package.json "homepage" field.
- First match in README of
https?://[^\s)\"'<>]+(?:vercel\.app|netlify\.app|github\.io|fly\.dev|railway\.app|render\.com|herokuapp\.com|surge\.sh)[^\s)\"'<>]*.
- Any other URL in README that the badge area / "Live Demo" / "Project Page" / "Demo" text points at. The allowlist regex above misses arbitrary custom domains (e.g.
<project>-project-page.com); when the README explicitly designates a project page, prefer that over the github.io fallback.
- GitHub Pages convention
https://{owner}.github.io/{repo} — but only if the deep tree contains a frontend signal (one of index.html, App.tsx, App.jsx, App.vue, app.py, main.py).
If no candidate resolves, the beat sheet skips beats 6–7.
Generic-URL mode: the input URL itself is the only URL the beats walk through — no live_url inference, no extra metadata fetches. Skip Step 2.5 and Step 3.0; jump straight to Step 3.
Step 2.5 — Verify live_url reachability (GitHub mode only, no MCP call)
If a candidate live_url was selected, verify it serves real content before authoring beats 6–7. Use WebFetch on the candidate and check the response:
- If the response status is 4xx / 5xx, drop
live_url to None and skip beats 6–7. The github.io fallback in particular is reachable as a hostname but often returns 404 ("There isn't a GitHub Pages site here") for repos that haven't enabled Pages — recording that 404 page wastes ~12s of the explainer on wrong content.
- If the response renders the GitHub Pages "404 — There isn't a GitHub Pages site here." template (heuristic: response body contains
"There isn't a GitHub Pages site here"), drop live_url and skip beats 6–7.
- Otherwise, keep
live_url for beats 6–7.
This mirrors the legacy reachability gate that checked live_url with a short timeout and followed redirects.
Step 2.6 — Generic-URL pre-flight (Generic-URL mode only, no MCP call)
Before authoring beats for a non-GitHub URL, WebFetch the input URL and inspect the response. This step prevents three common Generic-URL failure modes: (a) recording a captcha / bot-block page instead of content, (b) the cookie/consent banner eating the first ~3 seconds of video, (c) generic CSS selectors missing the page's actual hero / sections.
A. Bot-block / captcha detection — abort if matched:
If the response body contains any of:
"Verify you are human" / "verify you are not a robot"
"captcha" / "CAPTCHA" / "reCAPTCHA"
"403 Forbidden" / "Access Denied"
"Just a moment" + cf-chl-bypass (Cloudflare challenge)
"We're sorry, something went wrong" (Amazon-style bot block)
- A
<title> or h1 of just "Robot Check" / "Are you a robot?"
→ ABORT with a clear error to the user: "Generic-URL mode can't render this site — the page is showing a bot-detection / captcha challenge under headless Chrome. Try a different URL, or run a real-user version of the page first to verify it loads cleanly."
B. Cookie / consent-banner detection — defuse with extra_css + optional click:
Scan the response for these patterns (case-insensitive):
- IDs / classes starting with
onetrust-, truste-, cookie-banner, cookie-consent, gdpr-, consent-, cmp-
- Buttons matching
(?i)accept (all )?cookies / (?i)agree.{0,10}cookies / (?i)i (accept|agree)
- Apple-specific banner: id
ac-gdpr-banner or class as-globalfooter-curtain
- Google consent:
[role="dialog"] with text "Before you continue"
If detected, set cookie_banner_present = true. Defense in depth — the recording uses BOTH:
- CSS injection (
extra_css) in the capture_website call to hide common banners universally — even if the click below misses, the banner is visually gone.
- A
click timed_action at at_s: 0.0 against the most likely dismissal selector (extracted from the WebFetch DOM, e.g. #onetrust-accept-btn-handler, [aria-label*="Accept all" i], button[id*="accept"]).
The extra_css payload (use this verbatim — covers ~80% of consent platforms):
#onetrust-banner-sdk, #onetrust-pc-sdk, #onetrust-consent-sdk { display: none !important; }
#truste-consent-track, #truste-consent-content, .truste_box_overlay { display: none !important; }
[id*="gdpr-cookie"], [id*="cookie-consent"], [id*="cookie-banner"] { display: none !important; }
[class*="cookie-banner"], [class*="cookie-consent"], [class*="consent-banner"] { display: none !important; }