Documentation

ViralTwin MCP server

Reference for the remote MCP server at https://mcp.viraltwin.app/mcp. Streamable HTTP transport, OAuth 2.1 with PKCE, ten tools.

Overview

The ViralTwin MCP server exposes ViralTwin's video remix pipeline as MCP tools that Claude — or any MCP client — can call. The flagship tool, remix_youtube, takes a YouTube URL and returns a finished 9:16 short. Lower-level tools let you orchestrate each step yourself.

EndpointURL
MCP server (resource)https://mcp.viraltwin.app/mcp
Resource metadata (RFC 9728)https://mcp.viraltwin.app/.well-known/oauth-protected-resource
OAuth metadata (RFC 8414)https://viraltwin.app/.well-known/oauth-authorization-server
DCR endpointhttps://viraltwin.app/oauth/register
Authorizehttps://viraltwin.app/oauth/authorize
Tokenhttps://viraltwin.app/oauth/token

Authentication

Authentication uses OAuth 2.1 with Dynamic Client Registration (RFC 7591) and PKCE (RFC 7636). Compliant MCP clients (Claude Desktop, claude.ai, Claude Code, Cursor, Windsurf) handle the entire flow automatically — paste the URL, click Connect, sign in, click Allow.

What happens under the hood

  • Client fetches /.well-known/oauth-protected-resource from the MCP endpoint to discover the auth server.
  • Client registers itself via POST /oauth/register (DCR) and gets a public client_id.
  • Client opens /oauth/authorize with PKCE; ViralTwin shows the consent screen and (after Clerk sign-in) issues an auth code.
  • Client exchanges the code at /oauth/token for an access token (60 min) and refresh token (30 days, sliding).
  • Every MCP call uses Authorization: Bearer <token>.
We never store tokens in plaintext — only SHA-256 hashes. Refresh tokens rotate on every use, so a leaked refresh token can't be replayed.

Scopes

ScopeGrants
viraltwin.readView canvases, credit balance, generated video URLs
viraltwin.generateRun analyze, prompt, scene generation, render, remix tools
viraltwin.canvasCreate / edit / delete canvases (Stage 3 — not yet wired)

Tools

All tools accept structured inputs (JSON Schema, validated server- side with Zod) and return MCP content arrays — typically a human-readable summary line plus a full JSON payload Claude can chain into the next call.

analyze_videoauth: authenticatedcost: 3 free per account, then subscriber-only

Scene-by-scene Gemini 2.5 Pro analysis. Same 3-analysis lifetime free quota as the web app — subscribers are unlimited.

Arguments
nametypenotes
urlstring (URL)YouTube watch / shorts / youtu.be
Returns

videoId, url, analysis { title, summary, style, characters[], scenes[] }, freeAnalysesRemaining

generate_scene_promptsauth: authenticatedcost: free (cheap GPT-5-mini call)

Sanitization is automatic — banned cinematography phrases get auto-substituted. Warnings list anything we couldn't fix.

Arguments
nametypenotes
analysisobjectPass the analyze_video result
userPromptstring?How to remix the video
preferredModelstring?Default seedance-2.0
characterConsistencyboolean?Lock identity across scenes
Returns

scenes[] with prompt + negativePrompt + purpose, plus optional characterBrief

generate_scene_videoauth: authenticated · subscriber or credit-positivecost: varies — see list_models for per-model price ranges

Submits to Kie. Seedance 2.0 / 2.0 Fast auto-fallback to Seedance 1.5 Pro on photoreal-face filter rejections (refunds + re-charges automatically).

Arguments
nametypenotes
promptstringRequired
negativePromptstring?
imageUrlsstring[]?Reference images (1-9)
modelstring?Default seedance-2.0
aspectRatio9:16 | 16:9 | 1:1?
durationnumber?Snapped to model's nearest
resolution480p | 720p | 1080p | 4K?
generateAudioboolean?
Returns

jobId, pollingUrl, ledgerRef, model, config, charged, fallbackUsed

check_video_statusauth: authenticatedcost: free (poll)

On terminal failure, the original credit reservation auto-refunds idempotently.

Arguments
nametypenotes
pollingUrlstring (URL)From generate_scene_video
ledgerRefstring?From generate_scene_video
Returns

status (queued | generating | completed | failed), videoUrl, error, refunded

render_canvasauth: authenticatedcost: free (just CPU)

Single-scene calls skip ffmpeg and just mirror to R2. Multi-scene runs the concat demuxer (fast path) with re-encode fallback.

Arguments
nametypenotes
sceneUrlsstring[] (URLs)Generated scene videos in order
aspectRatio9:16 | 16:9 | 1:1?Default 9:16
Returns

id, key, url (final MP4 on R2 CDN), sceneCount, bytes

remix_youtubeauth: authenticated · subscriber or credit-positivecost: N × generate_scene_video (one per detected scene, max 5)

Blocks until done (typically 2-4 min). Submits all scenes in parallel. If any scene fails, the whole call returns an error; partial successes still count against credits.

Arguments
nametypenotes
urlstring (URL)YouTube URL
instructionsstring?How to transform
modelstring?Default seedance-2.0
aspectRatio9:16 | 16:9 | 1:1?Default 9:16
characterConsistencyboolean?
Returns

videoUrl, sceneUrls, sourceVideo, model

list_modelsauth: authenticatedcost: free

14 video models across Seedance, Wan, Kling (incl. 3.0), Sora 2, Veo 3.1.

Returns

defaultModelId, models[] with vendor, supported config, price ranges

get_creditsauth: authenticatedcost: free

Reflects the same balance as the web app — credits are shared.

Returns

balance, planTier, status, hasActiveSubscription, currentPeriodEnd

list_canvasesauth: authenticatedcost: free

Newest first. Pair with get_canvas for the full graph.

Arguments
nametypenotes
limitnumber?1-100, default 20
Returns

canvases[] with id, title, updatedAt, nodeCount

get_canvasauth: authenticatedcost: free

Returns 'not found' if the canvas isn't owned by the connected user.

Arguments
nametypenotes
idstring10-char nanoid
Returns

full DTO: id, title, description, thumbnail, graph (nodes + edges)

Error handling

Tools return MCP error results (isError: true) with a human-readable message. The most common failures are:

ReasonTool message
Missing or invalid token401 with WWW-Authenticate header — Claude re-runs the connect flow
Free quota exhaustedUsed all 3 free analyses → subscribe to continue
Out of credits"You need N credits but only have M..."
Invalid YouTube URL"That doesn't look like a valid YouTube URL..."
Generation failedProvider error surfaced verbatim
Timeoutremix_youtube hit max wait — job is still running on Kie

Every MCP request requires a valid bearer token. Unauthenticated requests return a 401 with the OAuth challenge header, which triggers Claude's connect flow.

Rate limits

  • Free account: 3 analyses lifetime (not rolling) — same quota as the web app
  • Subscriber: unlimited analyses, generation gated by credit balance
  • Auth tokens: 60 min access, 30 day refresh (sliding)

Troubleshooting

Connector won't connect

  • Make sure you pasted the full URL: https://mcp.viraltwin.app/mcp (with /mcp at the end).
  • If your MCP client errors on the OAuth round-trip, check that it supports Dynamic Client Registration (RFC 7591). All Anthropic clients do; some third-party clients don't.

Auth screen loops

The consent screen requires you to be signed in to ViralTwin in the same browser. If sign-in keeps redirecting, clear cookies for viraltwin.app and retry.

"Out of credits" on a paid plan

Auto top-up may be off — check billing settings. Failed jobs auto-refund within ~30 seconds; if your balance looks short right after a failure, give it a minute.

Changelog

DateChange
2026-05-08v0.1.0 — initial release: 10 tools, OAuth 2.1 + DCR

Found a bug or want a tool we don't expose yet? Email us.