| name | birdy |
| description | X/Twitter CLI for reading, searching, posting, and engagement via cookies, with multi-account rotation. |
birdy
Fast X/Twitter CLI using GraphQL + cookie auth. One static Go binary — no
Node runtime.
Replaced the Node bird CLI (@steipete/bird), retired 2026-08-08. birdy
began as a rotation proxy in front of bird and has served all 24 commands
natively since v1.0.0. Command and flag names are unchanged, so bird X is
birdy X. npm reports @steipete/bird as "no longer supported" — do not
reinstall it. Note that birdy still falls back to bird when its native
path errors, so a bird CLI not found message means the native call failed
(usually a rate limit), not that you need to install bird.
Install
brew tap guzus/tap && brew trust guzus/tap && brew install birdy
Authentication
birdy uses cookie-based auth, and can rotate several accounts to spread
rate-limit pressure.
Use --auth-token / --ct0 to pass cookies directly, or --cookie-source for browser cookies.
Run birdy check to see which source is active. For Arc/Brave, use --chrome-profile-dir <path>.
Multi-account rotation
birdy account add main
birdy account list
birdy account disable <name>
birdy status
birdy budget
birdy -a main read <id>
birdy -s quota-aware search "ai"
Rotation strategies (-s): round-robin (default), least-recently-used,
least-used, random.
Commands
Account & Auth
birdy whoami
birdy check
birdy query-ids --fresh
Reading Tweets
birdy read <url-or-id>
birdy <url-or-id>
birdy thread <url-or-id>
birdy replies <url-or-id>
Timelines
birdy home
birdy home --following
birdy user-tweets @handle -n 20
birdy mentions
birdy mentions --user @handle
Search
birdy search "query" -n 10
birdy search "from:steipete" --all --max-pages 3
News & Trending
birdy news -n 10
birdy news --ai-only
birdy news --sports
birdy news --with-tweets
birdy trending
Lists
birdy lists
birdy lists --member-of
birdy list-timeline <id> -n 20
Bookmarks & Likes
birdy bookmarks -n 10
birdy bookmarks --folder-id <id>
birdy unbookmark <url-or-id>
birdy likes -n 10
Social Graph
birdy following -n 20
birdy followers -n 20
birdy following --user <id>
birdy about @handle
Engagement Actions
birdy follow @handle
birdy unfollow @handle
Posting
birdy tweet "hello world"
birdy reply <url-or-id> "nice thread!"
birdy tweet "check this out" --media image.png --alt "description"
Warning: Posting is more likely to be rate limited; if blocked, use the browser tool instead.
In automation, set BIRDY_READ_ONLY=1 so these can never fire.
Media Uploads
birdy tweet "hi" --media img.png --alt "description"
birdy tweet "pics" --media a.jpg --media b.jpg
birdy tweet "video" --media clip.mp4
Pagination
Commands supporting pagination: replies, thread, search, bookmarks, likes, list-timeline, following, followers, user-tweets
birdy bookmarks --all
birdy bookmarks --max-pages 3
birdy bookmarks --cursor <cursor>
birdy replies <id> --all --delay 1000
Output Options
--json
--json-full
--plain
--no-emoji
--no-color
--quote-depth n
Global Options
--auth-token <token>
--ct0 <token>
--cookie-source <source>
--chrome-profile <name>
--chrome-profile-dir <path>
--firefox-profile <name>
--timeout <ms>
--cookie-timeout <ms>
Batch fetching
multi-fetch runs a manifest of operations concurrently and writes each result
to <output-dir>/<id>.json — one process instead of N, which is how ARA's
Twitter lane fetches ~70 sources per run.
birdy multi-fetch --manifest manifest.json --output-dir /tmp/bird
{
"operations": [
{"id": "OpenAI", "args": ["user-tweets", "@OpenAI", "-n", "20", "--json", "--plain"]},
{"id": "search-ai", "args": ["search", "AI announcement", "-n", "50", "--json", "--plain"]}
],
"concurrency": 8
}
A failed operation still writes [], so downstream readers never crash on a
missing file.
State
~/.config/birdy/ holds accounts.json (credentials + per-account use and
429 counters), state.json (rotation position), and the query-id cache.
Environment variables: AUTH_TOKEN, CT0, BIRDY_READ_ONLY=1 (blocks every
write command — set it in any automated context), BIRDY_ACCOUNTS (JSON
account list, for CI where there is no config dir).
Troubleshooting
bird CLI not found, and --bird requires it: birdy's native call failed
and it tried to fall back to the retired Node CLI. The real cause is
upstream — usually a rate limit. Check birdy budget; do not install bird.
- Query IDs stale (404 errors): Run
birdy query-ids --fresh
- Cookie extraction fails: Check browser is logged into X, try different
--cookie-source
- Arc/Brave: Use
--chrome-profile-dir to point at the correct profile
- Verbose:
-v prints which account and which engine (native (go)) served the call