TW

twitter-reader

Fetch content from X/Twitter posts and articles into structured Markdown files with embedded media.

Install

mkdir -p .claude/skills/twitter-reader && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/1287" && unzip -o skill.zip -d .claude/skills/twitter-reader && rm skill.zip

Installs to .claude/skills/twitter-reader

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Fetch Twitter/X post content including long-form Articles with full images and metadata. Use when Claude needs to retrieve tweet/article content, author info, engagement metrics, and embedded media. Supports individual posts and X Articles (long-form content). Automatically downloads all images to local attachments folder and generates complete Markdown with proper image references. Preferred over Jina for X Articles with images.
433 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Beginner

Key capabilities

  • →Fetch Twitter/X posts and articles
  • →Download embedded media automatically
  • →Generate Markdown with YAML frontmatter
  • →Support batch fetching via shell scripts

How it works

Uses a Python script to fetch structured data and the Jina.ai API to retrieve content, then saves images locally and formats the output as Markdown.

Inputs & outputs

You give it
Twitter/X URL
You get back
Markdown file with local image attachments

When to use twitter-reader

  • →Archiving technical Twitter threads as notes
  • →Downloading long-form X articles for offline reading
  • →Saving media from social posts into documentation
  • →Analyzing engagement metrics for a set of posts

About this skill

Twitter Reader

Fetch Twitter/X post and article content with full media support.

Reading a single post's text: fxtwitter first (2026-08-30)

For plain post text, prefer the fxtwitter mirror API — login-free, key-free, works direct, and returns the full note_tweet body in tweet.text (the full_text key does not exist; a 2,324-char long-form announcement came back complete):

curl -sS --max-time 20 "https://api.fxtwitter.com/<user>/status/<id>" \
  | python3 -c "import json,sys; t=json.load(sys.stdin)['tweet']; print(t['created_at']); print(t['text'])"

replies is a count, not the reply thread. For X Articles with images, use fetch_article.py below — fxtwitter does not carry article bodies.

X Articles with images: fetch_article.py

uv run --with pyyaml python scripts/fetch_article.py <article_url> [output_dir]

Example:

uv run --with pyyaml python scripts/fetch_article.py \
  https://x.com/HiTw93/status/2040047268221608281 \
  ./Clippings

This will:

  • Fetch structured data via twitter-cli (likes, retweets, bookmarks)
  • Fetch content with images via jina.ai API
  • Download all images to attachments/YYYY-MM-DD-AUTHOR-TITLE/
  • Generate complete Markdown with embedded image references
  • Include YAML frontmatter with metadata

Metadata and plain article text come from twitter-cli; the image URLs ride in the markdown Jina's reader returns. When Jina refuses (see the section below), the script warns on stderr, keeps the twitter-cli text, and reports Images: 0. The Markdown is still correct; it simply has no pictures. Images: 0 on an article that visibly contains images is the signature of a Jina refusal.

Example Output

Fetching: https://x.com/HiTw93/status/2040047268221608281
--------------------------------------------------
Getting metadata...
Title: 你不知道的大模型训练:原理、路径与新实践
Author: Tw93
Likes: 1648

Getting content and images...
Images: 15

Downloading 15 images...
  ✓ 01-image.jpg
  ✓ 02-image.jpg
  ...

✓ Saved: ./Clippings/2026-04-03-文章标题.md
✓ Images: ./Clippings/attachments/2026-04-03-HiTw93-.../ (15 downloaded)

Jina's reader is intermittent, and its refusals look like success

Anonymous r.jina.ai access to x.com gets blocked for hours at a time when third-party callers abuse the domain. The block hits every anonymous caller and then expires on its own. Both states showed up minutes apart on 2026-09-12.

A refusal does not look like a failure. curl exits 0 and the body is a JSON envelope:

{"data":null,"code":403,"name":"AbuseAlleviationError","status":40305,
 "message":"Anonymous access to domain x.com blocked until <date> ..."}

A lapsed or unfunded key returns the same shape with "code":402, "name":"InsufficientBalanceError". curl --fail catches neither: this endpoint answered HTTP 200 with the envelope in the body. The one signal that holds is the Markdown Content: marker that Jina's reader puts in front of the article body: no marker, no article. fetch_article.py tests for that marker before accepting a response, which keeps a refusal envelope out of the generated Markdown.

scripts/fetch_tweets.sh and scripts/fetch_tweet.py both require JINA_API_KEY and have no second source to fall back to, so they stop working whenever that key lapses. Both check the same marker and fail loudly on a refusal — the Python one raises without writing the output file, the shell one reports the URL on stderr and exits non-zero — rather than handing back an envelope dressed up as a post. No key ships with this repository.

For simple text-only fetching:

# Single tweet
curl "https://r.jina.ai/https://x.com/USER/status/TWEET_ID" \
  -H "Authorization: Bearer ${JINA_API_KEY}"

# Batch fetching
scripts/fetch_tweets.sh url1 url2 url3

Features

Full Article Mode (fetch_article.py)

  • ✅ Structured metadata (author, date, engagement metrics)
  • ✅ Automatic image download (all embedded media)
  • ✅ Complete Markdown with local image references
  • ✅ YAML frontmatter for PKM systems
  • ✅ Handles X Articles (long-form content)

Simple Mode (Jina API)

  • Text-only content
  • Intermittent availability (see the section above); both scripts require JINA_API_KEY and have no fallback
  • Usable for quick text extraction while Jina is answering

Prerequisites

For Full Article Mode

  • uv (Python package manager)
  • No additional setup (twitter-cli auto-installed)

For Simple Mode (Jina)

export JINA_API_KEY="your_api_key_here"
# Get from https://jina.ai/

Output Structure

output_dir/
├── YYYY-MM-DD-article-title.md       # Main Markdown file
└── attachments/
    └── YYYY-MM-DD-author-title/
        ├── 01-image.jpg
        ├── 02-image.jpg
        └── ...

What Gets Returned

Full Article Mode

  • YAML Frontmatter: source, author, date, likes, retweets, bookmarks
  • Markdown Content: Full article text with local image references
  • Attachments: All downloaded images in dedicated folder

Simple Mode

  • Title: Post author and content preview
  • URL Source: Original tweet link
  • Published Time: GMT timestamp
  • Markdown Content: Text with remote media URLs

URL Formats Supported

  • https://x.com/USER/status/ID (posts)
  • https://x.com/USER/article/ID (long-form articles)
  • https://twitter.com/USER/status/ID (legacy)

Scripts

fetch_article.py

Full-featured article fetcher with image download:

uv run --with pyyaml python scripts/fetch_article.py <url> [output_dir]

fetch_tweet.py

Simple text-only fetcher using Jina API:

python scripts/fetch_tweet.py <tweet_url> [output_file]

fetch_tweets.sh

Batch fetch multiple tweets (Jina API):

scripts/fetch_tweets.sh <url1> <url2> ...

twitter-cli's 500-item ceiling belongs to the tool, not to X

This skill reads metadata through twitter-cli, so the tool's own limits apply. twitter bookmarks and the other timeline commands stop at 500 items however the config is written. That ceiling is a module constant in the client: _ABSOLUTE_MAX_COUNT = 500 in twitter_cli/client.py, applied as min(maxCount, 500) when the client is constructed. Both lines read from version 0.8.5. X's own bookmark timeline goes far deeper than that.

Two consequences are easy to get wrong:

  • A run that stops at exactly 500 stopped on its own counter and never reached the point of reading the next cursor. "The platform gave no further page" and "my loop finished" are different claims, and only the first one is evidence. A round number is a reason to look closer, not a boundary.
  • maxCount has to sit under the rateLimit: section of the config. Put it under fetch: and the client ignores it without any message, falling back to 200.

Going deeper means calling the GraphQL endpoint directly: the Bookmarks operation with the client's own feature flags, parsed by twitter_cli.parser.parse_timeline_response, paging until the platform stops returning a cursor or returns the same cursor twice. Stop on the platform's signal rather than on a count.

Migration from Jina API

Old workflow:

curl "https://r.jina.ai/https://x.com/..."
# Manual image extraction and download

New workflow:

uv run --with pyyaml python scripts/fetch_article.py <url>
# Automatic image download, complete Markdown

When not to use it

  • →Real-time social media monitoring
  • →Tasks requiring authentication to private accounts

Prerequisites

uv package managerJina API key for simple mode

Limitations

  • →Requires Jina API key for text-only fetching
  • →Limited to public posts

How it compares

Automates the entire extraction and local media storage process instead of requiring manual copy-pasting.

Compared to similar skills

twitter-reader side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
twitter-reader (this skill)55moReviewBeginner
qmd264moReviewIntermediate
biorxiv-database711moReviewBeginner
read-arxiv-paper166moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

ppt-creator

daymade

Create professional slide decks from topics or documents. Generates structured content with data-driven charts, speaker notes, and complete PPTX files. Applies persuasive storytelling principles (Pyramid Principle, assertion-evidence). Supports multiple formats (Marp, PowerPoint). Use for presentations, pitches, slide decks, or keynotes.

75110

macos-cleaner

daymade

Analyze and reclaim macOS disk space through intelligent cleanup recommendations. This skill should be used when users report disk space issues, need to clean up their Mac, or want to understand what's consuming storage. Focus on safe, interactive analysis with user confirmation before any deletions.

1631

qa-expert

daymade

This skill should be used when establishing comprehensive QA testing processes for any software project. Use when creating test strategies, writing test cases following Google Testing Standards, executing test plans, tracking bugs with P0-P4 classification, calculating quality metrics, or generating progress reports. Includes autonomous execution capability via master prompts and complete documentation templates for third-party QA team handoffs. Implements OWASP security testing and achieves 90% coverage targets.

1427

repomix-unmixer

daymade

Extracts files from repomix-packed repositories, restoring original directory structures from XML/Markdown/JSON formats. Activates when users need to unmix repomix files, extract packed repositories, restore file structures from repomix output, or reverse the repomix packing process.

524

teams-channel-post-writer

daymade

Creates educational Teams channel posts for internal knowledge sharing about Claude Code features, tools, and best practices. Applies when writing posts, announcements, or documentation to teach colleagues effective Claude Code usage, announce new features, share productivity tips, or document lessons learned. Provides templates, writing guidelines, and structured approaches emphasizing concrete examples, underlying principles, and connections to best practices like context engineering. Activates for content involving Teams posts, channel announcements, feature documentation, or tip sharing.

591

ui-designer

daymade

Extract design systems from reference UI images and generate implementation-ready UI design prompts. Use when users provide UI screenshots/mockups and want to create consistent designs, generate design systems, or build MVP UIs matching reference aesthetics.

48

You might also like

qmd

tobi

Search personal markdown knowledge bases, notes, meeting transcripts, and documentation using QMD - a local hybrid search engine. Combines BM25 keyword search, vector semantic search, and LLM re-ranking. Use when users ask to search notes, find documents, look up information in their knowledge base, retrieve meeting notes, or search documentation. Triggers on "search markdown files", "search my notes", "find in docs", "look up", "what did I write about", "meeting notes about".

2669

biorxiv-database

lifangda

Efficient database search tool for bioRxiv preprint server. Use this skill when searching for life sciences preprints by keywords, authors, date ranges, or categories, retrieving paper metadata, downloading PDFs, or conducting literature reviews.

780

read-arxiv-paper

karpathy

Use this skill when when asked to read an arxiv paper given an arxiv URL

1656

notion-research-documentation

openai

Research across Notion and synthesize into structured documentation; use when gathering info from multiple Notion sources to produce briefs, comparisons, or reports with citations.

551

arxiv-to-md

solatis

Convert arXiv papers to LLM-consumable markdown. Invoke when user provides an arXiv ID or URL, or when syncing academic papers from a PDF folder to a markdown destination.

412

arxiv-viewer

actionbook

View, search, and download academic papers from arXiv. Supports API queries, web scraping via Actionbook, and HTML paper reading via ar5iv. Use when user asks about arxiv papers, academic papers, research papers, paper summaries, latest papers, or wants to search/download/read papers.

49

Search skills

Search the agent skills registry