Loading...
Loading...
Fast X CLI for tweeting, replying, and reading via X/Twitter GraphQL (cookie auth). Supports: read tweets, search, thread/replies, bookmarks, likes, news/trending, user timelines, following/followers, lists. Can be used as a library. Note: Recommended for reading only. Writing will hit blocks quickly.
npx skill4agent add ninehills/skills birdbirdnpm install -g @steipete/bird
# or
pnpm add -g @steipete/bird
# or
bun add -g @steipete/bird
# one-shot (no install)
bunx @steipete/bird whoamibrew install steipete/tap/bird# Show the logged-in account
bird whoami
# Discover command help
bird help whoami
# Read a tweet (URL or ID)
bird read https://x.com/user/status/1234567890123456789
bird 1234567890123456789 --json
# Thread + replies
bird thread https://x.com/user/status/1234567890123456789
bird replies 1234567890123456789
bird replies 1234567890123456789 --max-pages 3 --json
bird thread 1234567890123456789 --max-pages 3 --json
# Search + mentions
bird search "from:steipete" -n 5
bird mentions -n 5
bird mentions --user @steipete -n 5
# User tweets (profile timeline)
bird user-tweets @steipete -n 20
bird user-tweets @steipete -n 50 --json
# Bookmarks
bird bookmarks -n 5
bird bookmarks --folder-id 123456789123456789 -n 5 # https://x.com/i/bookmarks/<folder-id>
bird bookmarks --all --json
bird bookmarks --all --max-pages 2 --json
bird bookmarks --include-parent --json
bird unbookmark 1234567890123456789
bird unbookmark https://x.com/user/status/1234567890123456789
# Likes
bird likes -n 5
# News and trending topics (AI-curated from Explore tabs)
bird news --ai-only -n 10
bird news --sports -n 5
# Lists
bird list-timeline 1234567890 -n 20
bird list-timeline https://x.com/i/lists/1234567890 --all --json
bird list-timeline 1234567890 --max-pages 3 --json
# Following (who you follow)
bird following -n 20
bird following --user 12345678 -n 10 # by user ID
# Followers (who follows you)
bird followers -n 20
bird followers --user 12345678 -n 10 # by user ID
# Refresh GraphQL query IDs cache (no rebuild)
bird query-ids --fresh# Fetch 10 news items from all tabs (default: For You, News, Sports, Entertainment)
bird news -n 10
# Fetch only AI-curated news (filters out regular trends)
bird news --ai-only -n 20
# Fetch from specific tabs
bird news --news-only --ai-only -n 10
bird news --sports -n 15
bird news --entertainment --ai-only -n 5
# Include related tweets for each news item
bird news --with-tweets --tweets-per-item 3 -n 10
# Combine multiple tab filters
bird news --sports --entertainment -n 20
# JSON output
bird news --json -n 5
bird news --json-full --ai-only -n 10 # includes raw API response--for-you--news-only--sports--entertainment--trending-onlybirdimport { TwitterClient, resolveCredentials } from '@steipete/bird';
const { cookies } = await resolveCredentials({ cookieSource: 'safari' });
const client = new TwitterClient({ cookies });
// Search for tweets
const searchResult = await client.search('from:steipete', 50);
// Fetch news and trending topics from all tabs (default: For You, News, Sports, Entertainment)
const newsResult = await client.getNews(10, { aiOnly: true });
// Fetch from specific tabs with related tweets
const sportsNews = await client.getNews(10, {
aiOnly: true,
withTweets: true,
tabs: ['sports', 'entertainment']
});const aboutResult = await client.getUserAboutAccount('steipete');
if (aboutResult.success && aboutResult.aboutProfile) {
console.log(aboutResult.aboutProfile.accountBasedIn);
}accountBasedInsourcecreatedCountryAccuratelocationAccuratelearnMoreUrlbird tweet "<text>"bird reply <tweet-id-or-url> "<text>"bird help [command]bird query-ids [--fresh] [--json]bird home [-n count] [--following] [--json] [--json-full]bird read <tweet-id-or-url> [--json]bird <tweet-id-or-url> [--json]readbird replies <tweet-id-or-url> [--all] [--max-pages n] [--cursor string] [--delay ms] [--json]bird thread <tweet-id-or-url> [--all] [--max-pages n] [--cursor string] [--delay ms] [--json]bird search "<query>" [-n count] [--all] [--max-pages n] [--cursor string] [--json]--max-pages--all--cursorbird mentions [-n count] [--user @handle] [--json]bird user-tweets <@handle> [-n count] [--cursor string] [--max-pages n] [--delay ms] [--json]bird bookmarks [-n count] [--folder-id id] [--all] [--max-pages n] [--cursor string] [--expand-root-only] [--author-chain] [--author-only] [--full-chain-only] [--include-ancestor-branches] [--include-parent] [--thread-meta] [--sort-chronological] [--json]--max-pages--all--cursorbird unbookmark <tweet-id-or-url...>bird likes [-n count] [--all] [--max-pages n] [--cursor string] [--json] [--json-full]--max-pages--all--cursorbird news [-n count] [--ai-only] [--with-tweets] [--tweets-per-item n] [--for-you] [--news-only] [--sports] [--entertainment] [--trending-only] [--json]bird trendingnewsbird lists [--member-of] [-n count] [--json]bird list-timeline <list-id-or-url> [-n count] [--all] [--max-pages n] [--cursor string] [--json]--max-pages--allbird following [--user <userId>] [-n count] [--cursor string] [--all] [--max-pages n] [--json]--max-pages--allbird followers [--user <userId>] [-n count] [--cursor string] [--all] [--max-pages n] [--json]--max-pages--allbird about <@handle> [--json]bird whoamibird check--expand-root-only--author-chain--author-only--full-chain-only--include-ancestor-branches--full-chain-only--include-parent--thread-meta--sort-chronological--auth-token <token>auth_token--ct0 <token>ct0--cookie-source <safari|chrome|firefox>--chrome-profile <name>DefaultProfile 2--chrome-profile-dir <path>--firefox-profile <name>--cookie-timeout <ms>--timeout <ms>--quote-depth <n>--plain--no-emoji--no-colorNO_COLOR=1--media <path>--alt <text>--mediaauth_tokenct0tweetreplyCreateTweet226birdstatuses/update.jsonbird--auth-token--ct0AUTH_TOKENCT0TWITTER_AUTH_TOKENTWITTER_CT0@steipete/sweet-cookie--cookie-source~/Library/Cookies/Cookies.binarycookies~/Library/Containers/com.apple.Safari/Data/Library/Cookies/Cookies.binarycookies~/Library/Application Support/Google/Chrome/<Profile>/Cookies~/Library/Application Support/Firefox/Profiles/<profile>/cookies.sqlite--chrome-profile-dir~/.config/bird/config.json5./.birdrc.json5~/.config/bird/config.json5{
// Cookie source order for browser extraction (string or array)
cookieSource: ["firefox", "safari"],
chromeProfileDir: "/path/to/Chromium/Profile",
firefoxProfile: "default-release",
cookieTimeoutMs: 30000,
timeoutMs: 20000,
quoteDepth: 1
}BIRD_TIMEOUT_MSBIRD_COOKIE_TIMEOUT_MSBIRD_QUOTE_DEPTH--json--json--all--cursor--max-pagesuser-tweets-n > 20{ tweets, nextCursor }read--plain--json| Field | Type | Description |
|---|---|---|
| string | Tweet ID |
| string | Full tweet text (includes Note/Article content when present) |
| object | |
| string? | Author's user ID |
| string | Timestamp |
| number | Number of replies |
| number | Number of retweets |
| number | Number of likes |
| string | Thread conversation ID |
| string? | Parent tweet ID (present if this is a reply) |
| object? | Embedded quote tweet (same schema; depth controlled by |
--jsonfollowingfollowers| Field | Type | Description |
|---|---|---|
| string | User ID |
| string | Username/handle |
| string | Display name |
| string? | User bio |
| number? | Followers count |
| number? | Following count |
| boolean? | Blue verified flag |
| string? | Profile image URL |
| string? | Account creation timestamp |
--jsonnewstrending| Field | Type | Description |
|---|---|---|
| string | Unique identifier for the news item |
| string | News headline or trend title |
| string? | Category (e.g., "AI · Technology", "Trending", "News") |
| string? | Relative time (e.g., "2h ago") |
| number? | Number of posts |
| string? | Item description |
| string? | URL to the trend or news article |
| array? | Related tweets (only when |
| object? | Raw API response (only when |
operationNameTweetDetailCreateTweetqueryIdbirdsrc/lib/query-ids.jsondist/~/.config/bird/query-ids-cache.jsonBIRD_QUERY_IDS_CACHE=/path/to/file.json404birdTweetDetailSearchTimelinebirdbird query-ids --fresh012--userbird --versionpackage.json0.3.0 (3df7969b)--media--altbird tweet "hi" --media img.png --alt "desc"