From twitter-skill
This skill should be used when the user asks to "post a tweet", "read timeline", "check twitter", "like a tweet", "retweet", "search twitter", "manage twitter lists", "twitter auth", "get twitter user", "delete tweet", "trending topics", "what's trending", "bookmarks", "bookmark a tweet", "saved tweets", or mentions Twitter/X integration. Provides full Twitter API v2 access for posting, reading, engagement, bookmarks, and list management.
npx claudepluginhub the-focus-ai/claude-marketplace --plugin twitter-skillThis skill uses the workspace's default tool permissions.
This skill provides full Twitter/X API integration through OAuth 2.0 PKCE authentication. Post tweets, read timelines, engage with content, search, view trends, and manage lists.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
This skill provides full Twitter/X API integration through OAuth 2.0 PKCE authentication. Post tweets, read timelines, engage with content, search, view trends, and manage lists.
The CLI script is located at:
${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts
Run commands using:
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts <command> [options]
Just run the auth command - no setup required:
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts auth
A browser will open for Twitter authentication. Authorize the app and you're ready to go.
If you prefer to use your own Twitter Developer credentials:
http://127.0.0.1:3000/callback (NOT localhost!)http://127.0.0.1:3000~/.config/twitter-skill/credentials.json:{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}
Tokens are looked up in this order:
.claude/twitter-skill.local.json (in current project directory)~/.config/twitter-skill/tokens.jsonThis allows different projects to use different Twitter accounts, with a global default for projects without local tokens. Project-local tokens are automatically added to .gitignore.
# Run OAuth flow (opens browser) - saves token to project-local .claude/
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts auth
# Run OAuth flow and save token globally (for use across all projects)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts auth --global
# Check authentication status
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts check
Response fields:
auth: Checks token validity and expirationcheck: Returns { authenticated: boolean, user?: string, expiresAt?: string }# Get authenticated user info
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts me
# Get authenticated user info including email
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts me --email
# Get user by username
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts user elonmusk
# Get user by ID
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts user-id 44196397
# Get multiple users by IDs (max 100, comma-separated)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts users "44196397,12,178273"
Response fields for user objects:
id: User's unique IDname: Display nameusername: @handle (without the @)created_at: Account creation datedescription: Bio textlocation: User-provided locationprofile_image_url: Avatar URLprotected: Whether tweets are protectedverified: Whether account is verifiedverified_type: Type of verification (e.g., "blue", "business", "government")url: User's website URLpublic_metrics: Object containing:
followers_count: Number of followersfollowing_count: Number followingtweet_count: Total tweetslisted_count: Times listed# Post a new tweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts post "Hello from Claude Code!"
# Delete a tweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts delete 1234567890
Important: Always confirm with the user before posting tweets.
Response fields:
post: Returns { id, text, url } - the url is the direct link to the posted tweetdelete: Returns { deleted: true } on successNote on Long-Form Content (Articles/Note Tweets):
The skill automatically requests the note_tweet field. If a tweet contains long-form content (up to 25k chars), the full text will be returned in the note_tweet object within the response.
# Get specific tweet by ID
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts tweet 1234567890
# Get my recent tweets (last 10)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts tweets
# Get home timeline (last 20 tweets from followed accounts)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts timeline
Response fields for tweet objects:
id: Tweet's unique IDtext: Tweet content (up to 280 chars, or check note_tweet for long-form)author_id: User ID of the authorcreated_at: When the tweet was postedconversation_id: Thread ID (same as first tweet in thread)source: App used to post (e.g., "Twitter Web App")lang: Detected language codepublic_metrics: Object containing:
retweet_count: Number of retweetsreply_count: Number of replieslike_count: Number of likesquote_count: Number of quote tweetsbookmark_count: Number of bookmarksimpression_count: View countentities: Object containing parsed URLs, mentions, hashtagsreferenced_tweets: Array of { type, id } for retweets, quotes, repliesnote_tweet: Object with { text, entities } for long-form content# Like a tweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts like 1234567890
# Unlike a tweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts unlike 1234567890
# Retweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts retweet 1234567890
# Undo retweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts unretweet 1234567890
# Get users who retweeted a tweet (up to 100)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts retweeters 1234567890
Response fields:
like/unlike: Returns { liked: boolean }retweet/unretweet: Returns { retweeted: boolean }retweeters: Returns array of user objects (see User Information section)# Get my bookmarked tweets
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts bookmarks
# Bookmark a tweet
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts bookmark 1234567890
# Remove a bookmark
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts unbookmark 1234567890
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts bookmarks-archive reports/bookmarks.html
**Response fields:**
- `bookmarks`: Returns `{ tweets: [...], includes: { media: [...] } }` with tweet objects and media expansions
- `bookmark`: Returns `{ bookmarked: true }` on success
- `unbookmark`: Returns `{ bookmarked: false }` on success
- `bookmarks-archive`: Returns `{ path: string, tweets: number }` — the written file path and tweet count
### Search
```bash
# Search recent tweets (last 7 days)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts search "claude ai"
Response: Returns array of tweet objects (see Reading Tweets section). Search queries support Twitter's search operators:
from:username - Tweets from a specific userto:username - Replies to a specific user#hashtag - Tweets with hashtag"exact phrase" - Exact phrase match-word - Exclude wordlang:en - Filter by language# Get personalized trending topics
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts trends
Note: This endpoint requires X Premium subscription for full data. Non-premium users may receive "Unknown" for category and post_count fields.
Response fields for trend objects:
trend_name: The trending topic or hashtagcategory: Topic category (e.g., "Sports", "Entertainment", "Technology")post_count: Approximate number of posts (e.g., "10K", "100K+")trending_since: When the topic started trending# Get my lists
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts lists
# Get list details
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list 1234567890
# Get tweets from a list (last 20)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list-tweets 1234567890
# Get list members (up to 100)
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list-members 1234567890
# Add user to list
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list-add <list-id> <user-id>
# Remove user from list
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list-remove <list-id> <user-id>
# Create a new list
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list-create "My List" --description "Description" --private
# Delete a list
pnpm tsx ${CLAUDE_PLUGIN_ROOT}/scripts/twitter.ts list-delete 1234567890
Response fields for list objects:
id: List's unique IDname: List namedescription: List descriptionprivate: Whether the list is privateowner_id: User ID of list ownermember_count: Number of membersfollower_count: Number of followerscreated_at: When the list was createdResponse fields for operations:
list-add: Returns { is_member: true } on successlist-remove: Returns { is_member: false } on successlist-delete: Returns { deleted: true } on successAll commands output JSON with a consistent structure:
{
"success": true,
"data": {
// Response data here
}
}
Error responses:
{
"success": false,
"error": "Error message here"
}
The CLI outputs rate limit info to stderr after each request:
[rate-limit] /users/me: 75/75, resets in 15m
Status indicators:
X/Y - plenty of requests remainingX/Y (low) - less than 50% remainingX/Y (CRITICAL) - less than 20% remainingpost "Tweet text"timelinetrendssearch "#trending_topic"listslist-members <id>bookmarkstweet <id>search "topic"tweet <id>user <username>tweet <id>retweeters <id> to see who shared itTwitter API v2 has rate limits. The most common:
The skill will return rate limit errors when exceeded.
http://127.0.0.1:3000/callback (NOT localhost)auth againauth to re-authenticate with updated scopes