Short-Form Video Creator for Social Media

Transform text scripts or ideas into fully produced, platform-optimized 9:16 short-form videos with voiceover, captions, music, and export-ready MP4 files.

MIT-0 · Free to use, modify, and redistribute. No attribution required.
0 · 388 · 1 current installs · 1 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Suspicious
medium confidence
!
Purpose & Capability
The SKILL.md consistently describes using the InVideo API (including an Authorization Bearer token) to generate and download videos, which matches the skill's stated purpose. However, the registry metadata lists no required environment variable or primary credential even though the instructions explicitly instruct the user to set INVIDEO_API_KEY. That metadata omission is an incoherence that could hide required secrets or setup steps.
!
Instruction Scope
The instructions direct the agent (and user) to install npm packages, call InVideo endpoints, poll for status, and write MP4 files to disk — all reasonable for video generation. But the SKILL.md explicitly reads process.env.INVIDEO_API_KEY while the skill manifest did not declare that env var. The instructions therefore access an undeclared secret, which is a scope/visibility mismatch that should be resolved.
Install Mechanism
There is no install spec in the registry (instruction-only), which is lower risk for automatic installs. The SKILL.md tells the user to run `npm install axios form-data fs-extra` locally; that is reasonable and standard for the provided JavaScript examples. Because nothing is automatically downloaded or extracted by the skill itself, install risk is limited — but users should vet npm packages they install and the code they paste or run.
!
Credentials
Runtime instructions require a single API key (INVDEO_API_KEY) for the external service, which is proportionate to the skill's function. However, the skill manifest declares no required env vars or primary credential. The SKILL.md also directs users to a referral signup link (invideo.sjv.io/TBB), which is unrelated to security but worth noting. The primary concern is the undeclared environment secret in the manifest.
Persistence & Privilege
The skill does not request always:true and is not trying to persist or modify other skills or system-wide settings. It runs as an instruction-only skill and would rely on explicit API calls to InVideo. Autonomous invocation is allowed by default but is not combined here with additional broad privileges.
What to consider before installing
Before installing or using this skill: (1) confirm with the publisher why the registry metadata does not list INVIDEO_API_KEY — the SKILL.md expects you to provide that secret but the manifest omits it; this could be sloppy metadata or an attempt to hide required credentials. (2) Only provide an API key you control; avoid pasting long-lived production keys into untrusted environments and consider creating a scoped/limited test key if InVideo supports it. (3) Review any code you run locally (the JS snippets) and only install the listed npm packages from npmjs.org; scan them for recent issues. (4) Be aware the sign-up link is an affiliate/referral URL — that is not a security vulnerability, but it indicates the publisher may earn referrals. (5) If you need stronger assurance, ask the skill author for an updated manifest that declares INVIDEO_API_KEY (and any other required configs) or for a signed/verified source before proceeding.

Like a lobster shell, security has layers — review code before you run it.

Current versionv1.0.0
Download zip
latestvk973f2sybga2c49s01vybny47981tshh

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

SKILL.md

Short-Form Video Creation for Social Media Skill

Overview

This skill enables Claude to transform a text script or idea into a fully produced short-form video — ready to publish as an Instagram Reel, YouTube Short, or TikTok — using the InVideo AI platform and its API.

No video editing experience required. Just provide a script or topic, and Claude handles the rest.

🔗 Sign up for InVideo here: https://invideo.sjv.io/TBB


What This Skill Does

  • Convert a raw script into a complete short-form video with visuals and voiceover
  • Generate videos optimized for Instagram Reels, YouTube Shorts, and TikTok
  • Automatically match stock footage, music, and transitions to the script content
  • Add subtitles, captions, and text overlays for better engagement
  • Produce videos in the correct 9:16 vertical format for all short-form platforms
  • Export in MP4 ready to upload directly to any platform

Step 1 — Get Your InVideo API Access

  1. Go to https://invideo.sjv.io/TBB and create an account
  2. Choose a plan that includes API access (Business plan or above)
  3. Navigate to Settings → API or Developer Settings
  4. Copy your API Key: iv_api_xxxxxxxxxxxxxxxx
  5. Store it safely:
    export INVIDEO_API_KEY=iv_api_xxxxxxxxxxxxxxxx
    

InVideo offers a free trial — sign up at https://invideo.sjv.io/TBB to explore the platform before committing to a paid plan.


Step 2 — Install Dependencies

npm install axios form-data fs-extra

InVideo API — Core Endpoints

Base URL: https://api.invideo.io/v1

All requests require:

Authorization: Bearer YOUR_INVIDEO_API_KEY
Content-Type: application/json

Generate a Video from Script

POST https://api.invideo.io/v1/videos/generate

Get Video Generation Status

GET https://api.invideo.io/v1/videos/{videoId}/status

Download / Export Video

GET https://api.invideo.io/v1/videos/{videoId}/export

Examples

Generate a TikTok / Reel from a Script

import axios from 'axios';

const client = axios.create({
  baseURL: 'https://api.invideo.io/v1',
  headers: {
    'Authorization': `Bearer ${process.env.INVIDEO_API_KEY}`,
    'Content-Type': 'application/json'
  }
});

const script = `
  Did you know that 90% of startups fail in their first year?
  Here are 3 things the successful 10% do differently.
  Number 1: They talk to customers before building anything.
  Number 2: They launch ugly and iterate fast.
  Number 3: They obsess over retention, not acquisition.
  Follow for more startup insights every day.
`;

const response = await client.post('/videos/generate', {
  script: script,
  format: "9:16",           // vertical for Reels / TikTok / Shorts
  duration: "short",        // 15–60 seconds
  style: "dynamic",         // energetic cuts and transitions
  voiceover: {
    enabled: true,
    voice: "en-US-male-1",  // choose from available voices
    speed: 1.1              // slightly faster for short-form
  },
  captions: {
    enabled: true,
    style: "bold-bottom",   // TikTok-style captions
    highlight: true         // highlight word as it's spoken
  },
  music: {
    enabled: true,
    mood: "upbeat",
    volume: 0.3             // background music volume (0–1)
  },
  branding: {
    watermark: false
  }
});

const videoId = response.data.videoId;
console.log("Video generation started. ID:", videoId);

Poll for Completion and Get Download URL

async function waitForVideo(videoId, maxWaitMs = 120000) {
  const start = Date.now();

  while (Date.now() - start < maxWaitMs) {
    await new Promise(r => setTimeout(r, 5000)); // poll every 5s

    const status = await client.get(`/videos/${videoId}/status`);
    const { state, progress, exportUrl } = status.data;

    console.log(`Status: ${state} — ${progress}% complete`);

    if (state === "completed") {
      console.log("Video ready:", exportUrl);
      return exportUrl;
    }

    if (state === "failed") {
      throw new Error("Video generation failed — check your script and settings");
    }
  }

  throw new Error("Timeout — video took too long to generate");
}

const downloadUrl = await waitForVideo(videoId);

Full Pipeline: Script → Video → Download

import axios from 'axios';
import { writeFileSync } from 'fs';

async function scriptToShortVideo(script, outputPath = './output.mp4') {
  const client = axios.create({
    baseURL: 'https://api.invideo.io/v1',
    headers: { Authorization: `Bearer ${process.env.INVIDEO_API_KEY}` }
  });

  // 1 — Start generation
  const { data } = await client.post('/videos/generate', {
    script,
    format: "9:16",
    duration: "short",
    style: "dynamic",
    voiceover: { enabled: true, voice: "en-US-female-1", speed: 1.05 },
    captions: { enabled: true, style: "bold-bottom", highlight: true },
    music: { enabled: true, mood: "upbeat", volume: 0.25 }
  });

  const videoId = data.videoId;
  console.log(`Generation started — ID: ${videoId}`);

  // 2 — Wait for completion
  let exportUrl = null;
  while (!exportUrl) {
    await new Promise(r => setTimeout(r, 6000));
    const status = await client.get(`/videos/${videoId}/status`);
    if (status.data.state === "completed") exportUrl = status.data.exportUrl;
    if (status.data.state === "failed") throw new Error("Generation failed");
    console.log(`Progress: ${status.data.progress}%`);
  }

  // 3 — Download the video
  const videoStream = await axios.get(exportUrl, { responseType: 'arraybuffer' });
  writeFileSync(outputPath, videoStream.data);
  console.log(`Video saved to ${outputPath}`);

  return { videoId, exportUrl, localPath: outputPath };
}

// Usage
await scriptToShortVideo(
  "3 productivity hacks that changed my life. Number 1: Time blocking...",
  "./my-reel.mp4"
);

Batch Generate Multiple Videos

const scripts = [
  { topic: "morning routine tips",     voice: "en-US-female-1", mood: "calm" },
  { topic: "5 foods to boost energy",  voice: "en-US-male-1",   mood: "upbeat" },
  { topic: "how to learn faster",      voice: "en-US-female-2", mood: "inspiring" }
];

const jobs = await Promise.all(
  scripts.map(s =>
    client.post('/videos/generate', {
      script: s.topic,
      format: "9:16",
      duration: "short",
      style: "dynamic",
      voiceover: { enabled: true, voice: s.voice },
      music: { enabled: true, mood: s.mood, volume: 0.3 },
      captions: { enabled: true, style: "bold-bottom" }
    })
  )
);

const videoIds = jobs.map(j => j.data.videoId);
console.log("All jobs started:", videoIds);

Video Creation Workflow

When asked to create a short-form video, Claude will:

  1. Analyze the script or topic provided by the user
  2. Optimize the script for short-form pacing (hook in first 3 seconds)
  3. Select the right style, voice, music mood, and caption style
  4. Call the InVideo API to generate the video
  5. Poll the status endpoint until the video is ready
  6. Return the download URL or save the MP4 locally
  7. Suggest platform-specific tweaks (TikTok vs Reels vs Shorts)

Platform-Specific Settings

PlatformFormatDurationCaption StyleMusic
TikTok9:1615–60sBold bottom, word highlightUpbeat / trending
Instagram Reels9:1615–90sBold bottom or centeredUpbeat / chill
YouTube Shorts9:1615–60sClean bottomOptional
LinkedIn Video16:9 or 1:130–90sProfessional, top-alignedSubtle / none

Script Optimization Tips (Claude Will Apply These)

  • Hook in 3 seconds — start with a bold claim, question, or shocking stat
  • One idea per video — don't try to cover too much ground
  • Short sentences — 8–12 words max per caption line
  • Call to action at the end — "Follow for more", "Comment below", "Save this"
  • Conversational tone — write how people talk, not how they write
  • Numbers perform — "3 tips", "5 mistakes", "1 rule" always outperform vague titles

Normalized Output Schema

{
  "videoId": "iv_7f3k29xm",
  "title": "3 Startup Lessons Nobody Tells You",
  "platform": "tiktok",
  "format": "9:16",
  "durationSeconds": 42,
  "exportUrl": "https://cdn.invideo.io/exports/iv_7f3k29xm.mp4",
  "captions": true,
  "voiceover": "en-US-male-1",
  "musicMood": "upbeat",
  "createdAt": "2025-02-25T10:00:00Z",
  "status": "completed"
}

Best Practices

  • Always start with a strong hook — the first 2–3 seconds determine if users keep watching
  • Keep scripts between 120–200 words for a 30–60 second video
  • Use bold captions with word highlighting — it significantly increases watch time
  • Set music volume to 0.2–0.3 so it never overpowers the voiceover
  • Generate 3–5 variations of the same script with different styles to A/B test
  • For TikTok, use a slightly faster voiceover speed (1.1x) to match platform energy
  • Always review the video before publishing — AI generations may need minor tweaks

Error Handling

try {
  const response = await client.post('/videos/generate', payload);
  return response.data.videoId;
} catch (error) {
  if (error.response?.status === 401) throw new Error("Invalid InVideo API key");
  if (error.response?.status === 429) throw new Error("Rate limit hit — wait before retrying");
  if (error.response?.status === 400) throw new Error(`Bad request: ${error.response.data.message}`);
  throw error;
}

Requirements

  • An InVideo account → https://invideo.sjv.io/TBB
  • A plan with API access enabled (Business plan or above)
  • A valid API Key from your InVideo settings
  • Node.js 18+ and axios for API calls
  • Optional: ffmpeg locally if you need to post-process or compress the exported MP4

Files

1 total
Select a file
Select a file to preview.

Comments

Loading comments…