Skip to content

Latest commit

 

History

41 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

scry

Turn TikTok videos and Instagram posts (reels, photos, carousels) into LLM-readable intel: audio transcripts (STT), post metadata, top comments with a transparent community-consensus score, and local media file paths (so a vision-capable agent can look at the media directly). Visual understanding by a small local VLM (image description + on-screen text) is an optional extra ([vision], -v flag) for agents and models without their own vision.

STT and scraping run CPU-only; the optional VLM runs on your GPU when the installed build supports it (CPU otherwise — and a failed GPU attempt falls back to CPU automatically). A lightweight anti-detect browser (Camoufox) is launched only for Instagram when the fast HTTP path is not enough.

Personal-use tool. This project is for occasional, personal research on a few links at a time — not for mass scraping, not for building datasets, not for automation at scale. See Responsible use.

Install

For humans

If you want to use scry as a normal CLI tool:

Requirements: Linux with ffmpeg/ffprobe (e.g. apt install ffmpeg) and Python ≥ 3.10.

pip install scry-social          # or: uv tool install scry-social
scry setup                       # one-time: Camoufox browser (~200MB)

That's it: scry is on your PATH and the base pipeline (download, STT, metadata, comments, media file paths) works.

Optional local VLM — only if the model consuming the output has no vision of its own (if it does, pass the Media files to it instead):

scry setup --vision                # one-time: Qwen3.5-0.8B Q8_0 (~1GB)

scry setup --vision detects your accelerator (NVIDIA CUDA, AMD ROCm, Apple Metal, or CPU) and installs the matching precompiled llama.cpp wheel, then downloads the model. On supported GPUs there is no compilation: no C compiler needed. Force a backend with --backend:

scry setup --vision --backend rocm   # force ROCm (also: cuda, metal, cpu)

The CPU backend builds llama-cpp-python from source (tuned for the machine; needs a C compiler, build-essential); if no compiler is present it automatically falls back to a prebuilt basic-CPU wheel, so a compiler is not strictly required. Equivalently, pip install "scry-social[vision]" (or uv tool install "scry-social[vision]") installs the vision dependencies up front — note that plain pip compiles the CPU build from source, and scry setup --vision then replaces it with the precompiled wheel if you have a supported GPU. In the pipeline the VLM is opt-in too: without -v no VLM runs. With -v it tries the GPU first (all layers offloaded, n_gpu_layers=-1) and, if the GPU attempt crashes (e.g. not enough free VRAM), retries the image on CPU automatically; --cpu (or SCRY_VLM_GPU=0) skips the GPU attempt entirely.

From source: git clone <this-repo> && cd scry && pip install -e . (add [vision] if you want the VLM).

Models (Whisper ~600MB, VLM ~1GB) download on demand and are cached persistently in ~/.cache/scry/models/.

For agents (you are an LLM reading this)

If you are an AI agent and the user asked you to set up scry (or you scraped this page to install it): install the CLI exactly as above, then install the bundled agent skill so future sessions automatically know how to use the tool — you don't need to remember anything else:

scry setup                    # one-time: Camoufox browser
scry setup --vision           # only if you want the local VLM (-v): installs
                              # the precompiled llama-cpp-python wheel for your
                              # GPU (CUDA/ROCm/Metal) + the Qwen3.5-0.8B model
scry setup --vision --backend rocm        # force a backend (auto|cuda|rocm|metal|cpu)
scry skill --path ~/.agents/skills        # cross-harness standard location

or into your harness's skills directory:

scry skill --path ~/.claude/skills        # Claude Code
scry skill --path ~/.codex/skills         # OpenAI Codex
scry skill --path ~/.pi/agent/skills      # pi

The skill is the package's SKILL.md (Agent Skills standard); scry skill (no args) prints its location and these options. Once it is in a scanned skills directory, your harness presents it on demand — the skill contains the full usage guide, output-reading procedure, cookie handling, and reliability checks.

Uninstall (removing scry from your machine)

Everything scry ever writes to your disk is listed below — it touches nothing else. Quick removal (default install, Linux/macOS):

uv tool uninstall scry-social      # or: pip uninstall scry-social
rm -rf ~/.cache/camoufox           # anti-detect browser (~200MB)
rm -rf ~/.cache/scry               # STT + VLM models (~1.6GB)
rm -rf ~/.config/scry              # cookie files (your sessions!)
rm -rf /tmp/scry                   # per-run data (gone on reboot anyway)

Where each piece lives

Artifact Location Remove with
Python package + dependencies the environment you installed scry-social into pip uninstall scry-social or uv tool uninstall scry-social
Camoufox browser, ~200MB (only if you ran scry setup) ~/.cache/camoufox/ — macOS: ~/Library/Caches/camoufox/, Windows: %LOCALAPPDATA%\camoufox rm -rf ~/.cache/camoufox
Models: Whisper ~600MB + Qwen3.5-0.8B ~1GB (only if you used STT or -v) ~/.cache/scry/models/ ($SCRY_CACHE_DIR/models/ if overridden) rm -rf ~/.cache/scry/models
Cookie files (tiktok_cookies.txt, instagram_cookies.txt) the current directory where you installed it, or ~/.config/scry/, or wherever SCRY_COOKIES* points rm them, or rm -rf ~/.config/scry
Per-run data (media, audio, reports) /tmp/scry/ ($SCRY_DATA_DIR if overridden) rm -rf /tmp/scry — already auto-cleared on reboot
Agent skill (only if you ran scry skill --path DIR) DIR/scry/SKILL.md rm -rf DIR/scry (e.g. ~/.agents/skills/scry, ~/.claude/skills/scry)
llama-cpp-python wheel (only if you used the vision stack) the same environment as scry pip uninstall llama-cpp-python in that environment

Notes:

  • Cookies are the only sensitive item. They are a session export of your TikTok/Instagram accounts. Deleting the files removes them from your disk, but to be thorough revoke the session itself (log out and back in on the platform).
  • uv tool install keeps scry in an isolated venv (~/.local/share/uv/tools/scry-social): uv tool uninstall scry-social removes the venv and the scry executable, so the package, its dependencies, and (if you set up vision there) the llama-cpp wheel all disappear in one step.
  • For an editable install from source (pip install -e .): run pip uninstall scry-social inside that venv, then delete the venv and the clone if you made them just for this.
  • ffmpeg/ffprobe are a system requirement you installed separately (e.g. apt install ffmpeg); remove them with your package manager only if nothing else on the machine needs them.
  • A little download metadata may remain in ~/.cache/huggingface/ from the model downloads — safe to delete if you don't use other Hugging Face tools.
  • Windows: replace rm -rf X with Remove-Item -Recurse -Force X (PowerShell); ~/.cache/scry and ~/.config/scry are literal paths under C:\Users\<you>\.

Usage

# TikTok
scry tiktok "https://www.tiktok.com/@user/video/1234567890"

# Instagram (reel/video -> STT + media files; photo/carousel -> media files)
scry instagram "https://www.instagram.com/reel/XXXX/"

# Instagram with local-VLM visual analysis (needs the [vision] extra)
scry instagram "https://www.instagram.com/reel/XXXX/" -v

# Auto-detect platform
scry auto "https://www.instagram.com/reel/XXXX/"

# Options
#   --max-comments N    comments to analyze (default 30)
#   --no-comments       skip comments + consensus
#   --no-download       skip media download + STT (metadata + comments only)
#   -v, --vision        local VLM visual analysis (Instagram; needs the
#                       [vision] extra; default: off)
#   --stt-model NAME    tiny|base|small|medium|large-v3 (default small)
#   --language it       force STT language (default auto-detect)
#   --cookies FILE      Netscape cookies file for login-walled content
#   --json              print JSON only
#   Instagram extra:
#   --no-browser        force HTTP-only tier (faster, less robust)
#   --headless          run the fallback browser without a window

Use the full share URL for TikTok (@user/video/<id>), as copied from TikTok's share button — the bare /video/<id> URL may 404.

What you get

For one URL you get a Markdown report (plus raw JSON) with:

  1. Header — author, URL, ID, date, stats (plays/likes/comments/shares)
  2. Caption — the author's original text
  3. Transcript (STT) — what is said in the video, with timestamps
  4. Visual (VLM) (only with -v) — concise description of each image/frame + verbatim transcription of any on-screen text (hooks, claims, CTAs)
  5. Media files — local absolute paths of the downloaded media (video, extracted frames, carousel images): a vision-capable agent reads these directly with its own model
  6. Top comments — most-liked comments with like/reply counts (Instagram: including images/stickers attached to comments)
  7. Consensus (likes-based) — which comments the community "validated" (a meaningful share of the video's likes = readers who agree upvoted). Stance (agree/disagree) is left to the reader

The consensus is a deliberately simple, transparent like-count heuristic. It is an indicator, not truth — treat it as context, and verify factual claims independently.

Cookies

TikTok metadata has a single path — the logged-in page fetch — so TikTok needs tiktok_cookies.txt. Instagram mostly works without login (the browser tier covers it), but cookies make it more reliable, especially from a datacenter IP.

To get them: in a browser where you're logged in on tiktok.com / instagram.com, use the extension Cookie-EditorExport Netscape, and save as tiktok_cookies.txt / instagram_cookies.txt — in the current directory or in ~/.config/scry/. They are picked up automatically. A residential IP works much better than a datacenter one.

How it works (tiers)

Platform Tier 1 (fast) Tier 2 (fallback)
TikTok curl_cffi with Chrome 136 TLS impersonation → page JSON → direct CDN download → comments API — (no fallback; metadata needs a logged-in session, see Cookies)
Instagram curl_cffi → embedded page data (XDT/__additionalData) + og meta Camoufox (headed anti-detect Firefox): opens the post, reads page data, opens the comments popup, extracts comments from the DOM

Media download: direct CDN URLs first, then the browser's request context, then gallery-dl.

Instagram comments live in a popup (no dedicated URL): the browser clicks the comment icon, waits for the popup to populate, scrolls it via JS, and extracts text, usernames, like counts, timestamps, and attached images using stable structural anchors (permalinks, "Mi piace: N" spans) — no screenshot/OCR.

Data & privacy

  • All data stays local. No telemetry, no third-party calls beyond the two target platforms (and the model downloads on first run).
  • Per-run data is ephemeral by default. Downloaded media, audio, frames, comments, and reports go to /tmp/scry/ — cleared on reboot on most Linux systems. Set SCRY_CLEAN=1 to wipe stale run data on every start, or set SCRY_DATA_DIR to keep data deliberately somewhere else.
  • Comments are collected as local context only. They are gathered to give the AI agent a better understanding of how a community reacts to a post — nothing more. They are not uploaded, not sold, not aggregated, and this tool is not intended for building datasets of user content.
  • Cookie files are yours, are git-ignored, and can be revoked by regenerating your session.

Responsible use / personal use

  • This is a personal, low-volume research tool. Use it on a handful of links when you need to understand a post — not in loops, not at scale.
  • Mass scraping of TikTok/Instagram violates their Terms of Service, can put your IP/account at risk, and raises obvious privacy concerns about the people who write comments. Do not do that.
  • Collected comments belong to their authors. Use them as ephemeral context for your own research; don't republish, dataset-ize, or profile people with them.
  • Respect the platforms: no bypassing paywalls, no harvesting private content, no hammering endpoints. If a request fails, the answer is to stop, not to add more requests.

Configuration (env vars)

Variable Default Purpose
SCRY_CACHE_DIR ~/.cache/scry persistent model cache lives under models/ here
SCRY_DATA_DIR /tmp/scry where per-run data (downloads, reports) is stored
SCRY_CLEAN unset 1 = wipe stale run data on every start
SCRY_IMPERSONATE chrome136 TLS impersonation target for curl_cffi; the yt-dlp fallback derives its own spelling from it (chrome136 -> chrome-136)
SCRY_IMPERSONATE_YTDLP derived force a different --impersonate target for the yt-dlp fallback only
SCRY_COOKIES[_TIKTOK/_INSTAGRAM] <plat>_cookies.txt in cwd or ~/.config/scry/ Netscape cookies file(s)

Limitations

  • STT can miss proper nouns/slang; ambiguous transcripts are flagged in the report.
  • Vision is opt-in ([vision] extra + -v) and the VLM (0.8B) is small: descriptions are short and occasionally imperfect, and on-screen text transcription can drop or alter words. It is a signal for the agent, not a certified transcript — and if your model has vision, prefer reading the Media files with it.
  • Comments are the top-N by likes, not the full corpus — a bias toward mainstream opinions (declared in every report).
  • Instagram: top-level comments in the popup (~15–30 with one scroll); collapsed nested replies are not extracted.
  • The consensus is likes-based: comment likes say how much the community upvoted a comment, not what it means — stance is for the reader.
  • Both platforms change their page formats; when a tier fails, the report says which one and why. notes/RESEARCH.md documents the current formats.

Project layout

scry/
  __init__.py
  cli.py                CLI (tiktok|instagram|auto <url> [options], setup)
  common.py             sessions, URL parsing, paths, ffmpeg helpers, output
  stt.py                faster-whisper wrapper
  gpu.py                GPU detection + precompiled llama-cpp-python wheel install
  vision.py             Qwen3.5-0.8B VLM wrapper (GGUF via llama-cpp-python, optional)
  browser.py            Camoufox wrapper (page open, comments popup, download)
  tiktok.py             TikTok pipeline
  instagram.py          Instagram pipeline
  consensus.py          likes-based comment reliability
pyproject.toml          packaging (pip install scry-social)
notes/                  RESEARCH.md (format docs), DECISIONS.md (rationale)

scry/SKILL.md (inside the package) is the agent skill: install it with scry skill --path <skills-dir> — see For agents.

Per-run data (default, ephemeral):

/tmp/scry/downloads/<platform>-<id>/   media, audio, frames
/tmp/scry/output/<ts>-<platform>-<id>.{md,json}

License

MIT — see LICENSE.

Note on scope: the MIT license covers the code. Platform content, collected comments, and your cookies are not part of this project: keep them private, use them as ephemeral personal context, and don't build datasets or anything commercial from them. The tool is intentionally designed for personal, low-volume use only.

Publishing to PyPI

The package on PyPI is scry-social (the bare name scry is taken by an old SPARQL project); the import package and the CLI are both scry.

To publish a new version:

# 1. bump the version in pyproject.toml AND scry/__init__.py
# 2. build
uv build
# 3. upload (token from https://pypi.org/manage/account/token/)
pip install twine
twine upload dist/*

About

Turn TikTok & Instagram posts into LLM-readable intel: STT transcripts, on-screen text, consensus.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages