
Tiktok Research
Score scraped TikTok videos and surface engagement outliers so solo builders know which short-form formats to copy or test next.
Overview
TikTok Research is an agent skill for the Grow phase that scores TikTok post JSON and identifies engagement outliers for short-form content planning.
Install
npx skills add https://github.com/bradautomates/head-of-content --skill tiktok-researchWhat is this skill?
- Weighted engagement score: comments 3×, shares 2×, saves 2×, likes 1×, plays 0.05×
- Engagement rate normalized by author follower count when available
- Outlier detection against cohort baselines with configurable threshold multiplier
- CLI reads a JSON post dump and emits structured JSON for report generation
- Designed for Head-of-Content workflows comparing many videos at once
- Engagement weighting uses 3× comments, 2× shares, 2× saves, 1× likes, 0.05× plays
Adoption & trust: 839 installs on skills.sh; 111 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have a pile of TikTok export data but no consistent way to see which videos actually over-performed on meaningful engagement.
Who is it for?
Solo builders running TikTok or repurposed short-form growth with structured post exports ready to analyze.
Skip if: Teams that need live TikTok API scraping, brand safety moderation, or paid ads optimization inside the skill itself.
When should I use this skill?
You have a JSON file of TikTok videos and need outlier identification for reports or content decisions.
What do I get? / Deliverables
You get ranked outlier videos and metadata in JSON so you can prioritize remakes, hooks, and format tests in your content calendar.
- JSON output listing outlier videos and metadata for report generation
Recommended Skills
Journey fit
TikTok outlier analysis supports compounding distribution and creative iteration after you are shipping content, which maps to the Grow phase shelf. The script weights comments, shares, saves, likes, and plays to rank videos for content strategy—not generic market research in Idea.
How it compares
Use this focused engagement outlier scorer instead of manual spreadsheet sorting or generic social listening dashboards.
Common Questions / FAQ
Who is tiktok-research for?
Indie founders, marketers, and agents supporting a Head-of-Content workflow who already collect TikTok post JSON and want data-driven outlier picks.
When should I use tiktok-research?
Use it in Grow → content when reviewing weekly exports, before planning new hooks, or when comparing competitor-style videos you archived during distribution experiments.
Is tiktok-research safe to install?
It runs locally against files you provide; review the Security Audits panel on this Prism page and inspect the Python script before running on sensitive exports.
SKILL.md
READMESKILL.md - Tiktok Research
#!/usr/bin/env python3 """ Identify outlier TikTok videos based on engagement metrics. Outputs JSON with outliers and metadata for report generation. """ import json import argparse import statistics from datetime import datetime from pathlib import Path from collections import Counter import re def load_posts(input_path: str) -> list[dict]: """Load videos from JSON file.""" with open(input_path, 'r') as f: return json.load(f) def calculate_engagement_score(video: dict) -> float: """ Calculate weighted engagement score for TikTok. - Comments (3x): Active engagement, hardest to get - Shares (2x): Strong signal of value - Saves/Collects (2x): Intent to revisit - Likes/Diggs (1x): Passive approval - Views/Plays (0.05x): Weighted lower due to auto-play """ likes = video.get('diggCount', 0) or 0 comments = video.get('commentCount', 0) or 0 shares = video.get('shareCount', 0) or 0 saves = video.get('collectCount', 0) or 0 plays = video.get('playCount', 0) or 0 return likes + (3 * comments) + (2 * shares) + (2 * saves) + (0.05 * plays) def calculate_engagement_rate(video: dict) -> float: """Calculate engagement rate relative to follower count.""" followers = video.get('authorFollowers', 0) or 0 engagement = calculate_engagement_score(video) if followers == 0: return engagement return (engagement / followers) * 100 def identify_outliers(videos: list[dict], threshold_multiplier: float = 2.0) -> list[dict]: """ Identify outlier videos with engagement rate > mean + (threshold x std_dev). """ if not videos: return [] for video in videos: video['_engagement_score'] = calculate_engagement_score(video) video['_engagement_rate'] = calculate_engagement_rate(video) rates = [v['_engagement_rate'] for v in videos] if len(rates) < 2: return videos mean_rate = statistics.mean(rates) std_dev = statistics.stdev(rates) if len(rates) > 1 else 0 threshold = mean_rate + (threshold_multiplier * std_dev) outliers = [v for v in videos if v['_engagement_rate'] > threshold] outliers.sort(key=lambda x: x['_engagement_score'], reverse=True) return outliers def extract_topics(videos: list[dict]) -> dict: """Extract trending hashtags, sounds, and keywords.""" hashtags = Counter() sounds = Counter() keywords = Counter() stop_words = { 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might', 'can', 'this', 'that', 'these', 'those', 'i', 'you', 'he', 'she', 'it', 'we', 'they', 'what', 'which', 'who', 'when', 'where', 'why', 'how', 'all', 'each', 'every', 'both', 'few', 'more', 'most', 'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 'just', 'and', 'but', 'if', 'or', 'because', 'as', 'until', 'while', 'of', 'at', 'by', 'for', 'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before', 'after', 'above', 'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', 'then', 'once', 'here', 'there', 'your', 'my', 'his', 'her', 'its', 'our', 'their', 'get', 'got', 'like', 'dont', 'im', 'ive', 'youre', 'https', 'http', 'amp', 'link', 'bio', 'comment', 'follow', 'check', 'fyp', 'foryou', 'foryoupage', 'viral', 'trending', 'xyzbca' } for video in videos: text = video.get('text', '') or '' # Hashtags video_hashtags = video.get('hashtags', []) or [] if isinstance(video_hashtags, list): for h in video_hashtags: if isinstance(h, dict): tag = h.get('name', '') or h.get('title', '') else: tag = str(h)