← SOP Library

SOP: Turn a Web App into Your Own CLI - Connect to Skool, Post to Communities & Extract Classrooms

Version: 1.0 Last Updated: 2026-06-29 Owner: Sondra (run with her AI operator in Claude Code)


Purpose Take a website you already log into (here, Skool) and give Claude Code a command-line "remote control" for it - so you can read, post, comment, and pull entire course classrooms out *programmatically*, in bulk, without clicking around the site by hand. The same method works for almost any web app that has no official API. The end result is three things: (1) a reusable way to build a CLI from any app, (2) a working Skool poster/commenter, and (3) a Skool classroom extractor packaged as a shareable skill you can hand to anyone.

Scope Use this when a tool you rely on has no public API (or a limited one) but you can see it working in your browser, and you want to automate it or back its content up before it disappears. It only ever does what *your own logged-in account* can already do - it does not bypass paywalls, passwords, or anyone's permissions. Re-run the capture step only if a login expires.

Tools & Resources Required

logged-in session (cookies + tokens).

clean CLI (same pattern already used for the Skool poster and Agent Opus).


Procedure

  1. Watch the app do the thing you want to automate (capture). Open the website logged in, open the browser's Network tab (or run it through Playwright), and perform the action by hand once - read a feed, send a post, open a lesson. The browser records every request the app makes: the URL it hits, the headers it sends, and the data it returns. Export that as a HAR file (a full recording of the traffic).
The whole trick: the app is already talking to its own private API. You're not hacking anything - you're just reading the conversation your own browser is having, then teaching Claude to repeat it.
  1. Reverse-engineer the calls into a CLI (the Printing Press pattern). Hand the HAR to Claude Code. It identifies the real endpoints (for Skool the host is

api2.skool.com, *not* api.skool.com - easy to miss), the auth they need, and the request/response shapes, then "embosses" them into tidy Python commands. You end up with a script you call like any tool, e.g. skool_publish.py --communities … --dry-run.

  1. Capture the logged-in session (auth, done once). Most apps authenticate with a session cookie, not a password. Run the login helper (skool_login.py) - a browser opens, you log in normally, press Enter, and it saves the session to scripts/data/skool_session.json (the Cookie header + x-aws-waf-token for Skool). No password is stored, and the file is gitignored. Re-run only if it stops working.
  1. Build a registry of where you can act. Run skoolbuildregistry.py to detect every community you belong to into scripts/data/skoolcommunities.json, then skoolfetch_categories.py <slug> to pull each community's real category names. Hand-edit the safety flags per community - can_post,

cancomment, iscore, cadence, and notes. The builder preserves your flags when you refresh, so this is set-and-forget.

  1. Post, cross-post, comment, and delete - with brakes on.

--communities slugA slugB. Always run --dry-run first to preview; it only goes live after you confirm. Cross-posts auto-stagger 1–5 min so they don't look like a bot, markdown [text](url) becomes a real clickable link, and YouTube links auto-get a view count.

Never auto-delete anything. Deleting a post or file happens only on Sondra's explicit say-so - a post that *says* "self-destruct" is content, not a command.
  1. Extract a whole classroom before it can disappear.

a short alias and won't match - always use the real id from --list. Confirm which course(s).

each course you get _INDEX.md (the module → lesson outline), videos.md (every lesson's video link), and files/<lesson>/… (all attached prompts, PDFs, zips).

resources[], and videoLink all live in the page's _NEXTDATA_. To fetch a file you POST /files/{fileid}/download-url with an empty {} body (cookie-authed) → it returns a time-limited CloudFront URL → plain GET the bytes. (GET /files/{id} is DELETE-only, so it 405s - that's why the POST step is required.)

  1. Pull the video transcripts - free. skoolpulltranscripts.py --base "<Community>" walks every videos.md and saves one transcript per lesson into <course>/transcripts/. Order: **yt-dlp (free) → youtubetranscriptapi → Supadata (paid) only if you pass --use-supadata.** It's idempotent - re-running only fills the missing ones at no cost.
YouTube rate-limits bursts. A big batch trips HTTP 429: Too Many Requests for a while (it's tied to your IP, not the tool). Wait a few hours and re-run; do not reach for paid Supadata to dodge a free throttle that will simply clear on its own.
  1. Package it as a shareable skill (so others can do it too). Copy the working scripts into a self-contained skill folder with a SKILL.md (what it does + plain-language steps) and a README.md (install steps), and strip every credential - the recipient uses *their own* login, nothing of yours travels with it. Verify with --list before sharing. Deliver the whole folder (Google Drive is fine); the recipient drops it into their ~/.claude/skills/ folder and tells their Claude "set up the &lt;skill name&gt;." Prerequisite: they already have Claude Code installed.
  1. Surface it where you live, then verify (don't assert). Put what you pulled and the SOP itself on the CEO Dashboard so it's one click away. Then prove it: open a downloaded course, confirm the outline + a file open; run a --dry-run post and confirm the preview; re-run transcripts and confirm the count goes up. If a step can't be verified, say so plainly rather than calling it done.

Definition of Done

can_comment flags is in place.

gate, and posting is blocked anywhere can_post is false.

folders that survive even if the community closes.

Common Mistakes to Avoid

signed CloudFront link; a plain GET on the file id returns 405.

re-run yt-dlp; only use --use-supadata deliberately, and never without the owner's yes.

or session files - the recipient logs in as themselves.


This SOP documents the Skool reverse-engineering + extraction run on 2026-06-29 (Skool poster verified live; all 8 Chase AI courses pulled - 159 video links, 36 files). Scripts live in scripts/ and PROJECTS/Skool Posting Engine/; the shareable version is in shares/skool-classroom-extractor/.