xfetch
xfetch
Fetch public data from X (Twitter) — profiles, tweets, threads, search, followers — using the user's own login cookies instead of the paid developer API. This skill ships a single self-contained CLI, scripts/xfetch.py, that calls X's GraphQL API directly and emits structured data an agent can parse.
How it stays working (the architecture that matters): the hard part of X scraping is that X constantly changes its site — it rotates GraphQL query IDs every few weeks, migrates endpoints between GET and POST, and reshapes response JSON. This CLI splits those concerns so a break in one place doesn't take everything down:
- It reuses the current query IDs and feature flags shipped by the twikit package (kept fresh with
pip install -U twikit) — so you don't hand-maintain the fastest-rotating values. - It does its own HTTP requests and JSON parsing, which sidesteps the two things most likely to be broken in twikit at any moment: (1) its homepage-scraped anti-bot transaction ID — this CLI sends a harmless placeholder
x-client-transaction-id, which X accepts for read endpoints; and (2) its response-model layer — this CLI parses the raw JSON itself. It also auto-falls-back GET↔POST on a 404, so an endpoint X migrates keeps working.
Net: if a command suddenly errors for everyone, the first fix is still pip install -U twikit (refreshes query IDs). If that doesn't help, X changed a response shape — check the parser in scripts/xfetch.py.
The agent-native contract
scripts/xfetch.py is built so you can drive it in a loop without surprises. Rely on these three channels rather than scraping prose:
stdoutcarries the data payload only (JSON by default). Redirect or pipe it — nothing else is written there.stderrcarries human status (✓ Saved…) and errors. Read it to diagnose; ignore it when parsing.- exit code is the truth signal:
0= success,1= error,2= not authenticated,3= rate limited (stderr carriesrate_limit_reset=<epoch>),64= usage error (bad flag or argument — fix the command, don't re-auth). Branch on the exit code, not on stderr text.