Xitter — X/Twitter via x-cli
Use x-cli for official X/Twitter API interactions from the terminal.
This skill is for:
- posting tweets, replies, and quote tweets
- searching tweets and reading timelines
- looking up users, followers, and following
- liking and retweeting
- checking mentions and bookmarks
This skill intentionally does not vendor a separate CLI implementation into Hermes. Install and use upstream x-cli instead.
Important Cost / Access Note
X API access is not meaningfully free for most real usage. Expect to need paid or prepaid X developer access. If commands fail with permissions or quota errors, check your X developer plan first.
Install
Install upstream x-cli with uv:
uv tool install git+https://github.com/Infatoshi/x-cli.git
Upgrade later with:
uv tool upgrade x-cli
Verify:
x-cli --help
Credentials
You need these five values from the X Developer Portal:
X_API_KEYX_API_SECRETX_BEARER_TOKENX_ACCESS_TOKENX_ACCESS_TOKEN_SECRET
Get them from:
Why does X need 5 secrets?
Unfortunately, the official X API splits auth across both app-level and user-level credentials:
X_API_KEY+X_API_SECRETidentify your appX_BEARER_TOKENis used for app-level read accessX_ACCESS_TOKEN+X_ACCESS_TOKEN_SECRETlet the CLI act as your user account for writes and authenticated actions
So yes — it is a lot of secrets for one integration, but this is the stable official API path and is still preferable to cookie/session scraping.
Setup requirements in the portal:
- Create or open your app
- In user authentication settings, set permissions to
Read and write - Generate or regenerate the access token + access token secret after enabling write permissions
- Save all five values carefully — missing any one of them will usually produce confusing auth or permission errors
Note: upstream x-cli expects the full credential set to be present, so even if you mostly care about read-only commands, it is simplest to configure all five.
Cost / Friction Reality Check
If this setup feels heavier than it should be, that is because it is. X’s official developer flow is high-friction and often paid. This skill chooses the official API path because it is more stable and maintainable than browser-cookie/session approaches.
If the user wants the least brittle long-term setup, use this skill. If they want a zero-setup or unofficial path, that is a different trade-off and not what this skill is for.
Where to Store Credentials
x-cli looks for credentials in ~/.config/x-cli/.env.
If you already keep your X credentials in ~/.hermes/.env, the cleanest setup is:
mkdir -p ~/.config/x-cli
ln -sf ~/.hermes/.env ~/.config/x-cli/.env
Or create a dedicated file:
mkdir -p ~/.config/x-cli
cat > ~/.config/x-cli/.env <<'EOF'
X_API_KEY=your_consumer_key
X_API_SECRET=your_secret_key
X_BEARER_TOKEN=your_bearer_token
X_ACCESS_TOKEN=your_access_token
X_ACCESS_TOKEN_SECRET=your_access_token_secret
EOF
chmod 600 ~/.config/x-cli/.env
Quick Verification
x-cli user get openai
x-cli tweet search "from:NousResearch" --max 3
x-cli me mentions --max 5
If reads work but writes fail, regenerate the access token after confirming Read and write permissions.
Common Commands
Tweets
x-cli tweet post "hello world"
x-cli tweet get https://x.com/user/status/1234567890
x-cli tweet delete 1234567890
x-cli tweet reply 1234567890 "nice post"
x-cli tweet quote 1234567890 "worth reading"
x-cli tweet search "AI agents" --max 20
x-cli tweet metrics 1234567890
Users
x-cli user get openai
x-cli user timeline openai --max 10
x-cli user followers openai --max 50
x-cli user following openai --max 50
Self / Authenticated User
x-cli me mentions --max 20
x-cli me bookmarks --max 20
x-cli me bookmark 1234567890
x-cli me unbookmark 1234567890
Quick Actions
x-cli like 1234567890
x-cli retweet 1234567890
Output Modes
Use structured output when the agent needs to inspect fields programmatically:
x-cli -j tweet search "AI agents" --max 5
x-cli -p user get openai
x-cli -md tweet get 1234567890
x-cli -v -j tweet get 1234567890
Recommended defaults:
-jfor machine-readable output-vwhen you need timestamps, metrics, or metadata- plain/default mode for quick human inspection
Agent Workflow
- Confirm
x-cliis installed - Confirm credentials are present
- Start with a read command (
user get,tweet search,me mentions) - Use
-jwhen extracting fields for later steps - Only perform write actions after confirming the target tweet/user and the user's intent
Pitfalls
- Paid API access: many failures are plan/permission problems, not code problems.
- 403 oauth1-permissions: regenerate the access token after enabling
Read and write. - Reply restrictions: X restricts many programmatic replies.
tweet quoteis often more reliable thantweet reply. - Rate limits: expect per-endpoint limits and cooldown windows.
- Credential drift: if you rotate tokens in
~/.hermes/.env, make sure~/.config/x-cli/.envstill points at the current file.
Fallback Extraction (No x-cli Credentials)
When x-cli is unavailable (no API keys), these fallback methods extract tweet content with decreasing reliability:
1. Twitter Syndication API (BEST — no auth needed)
Returns full JSON with tweet text, media, quoted tweets, article metadata:
curl -sL "https://cdn.syndication.twimg.com/tweet-result?id=TWEET_ID&token=x" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d, indent=2))"
- Extracts:
text,mediaDetails,photos,quoted_tweet,article(title + preview_text + cover media) - Works for: regular tweets, quote tweets, tweets with images, tweets linking X articles
- Limitation: Does NOT return article body text — only
title,preview_text, andcover_media
2. Twitter oEmbed API (partial — no auth needed)
Returns HTML embed block with tweet text:
curl -sL "https://publish.twitter.com/oembed?url=https://x.com/USER/status/TWEET_ID" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('html',''))"
- Extracts: tweet text (truncated for long tweets), author, date
- Limitation: Single tweet only — no thread expansion, no images, no article content
3. Scrapling (for tweet pages)
python3 ~/clawd/skills/scrapling/scripts/scrape.py "https://x.com/USER/status/TWEET_ID"
- Works sometimes via syndication fallback inside scrapling
- Fails on X articles (
x.com/i/article/...) — JS-rendered, no static content
X Articles (x.com/i/article/...) — UNEXTRACTABLE
X articles are fully JS-rendered single-page apps. No known method extracts the body text without a real browser session (Playwright/Selenium with auth cookies). The syndication API returns only title, preview_text, and cover image URL. If you need the full article, ask the user to paste it or use a logged-in browser.
Fallback Decision Tree
- Try syndication API first (fastest, most data)
- If you need article body → tell user it's unreachable, ask them to paste
- If syndication fails → try oEmbed (partial text)
- If oEmbed fails → try scrapling (may or may not work)
Notes
- Prefer official API workflows over cookie/session scraping.
- Use tweet URLs or IDs interchangeably —
x-cliaccepts both. - If bookmark behavior changes upstream, check the upstream README first: https://github.com/Infatoshi/x-cli