Xtracticle

Official registry Productivity

Read public X (Twitter) posts, threads and X Articles as clean Markdown. Read-only, no auth.

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

Remote (streamable-http)
Claude Code
claude mcp add --transport http xtracticle 'https://xtracticle.com/mcp'
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "xtracticle": {
            "type": "http",
            "url": "https://xtracticle.com/mcp"
        }
    }
}

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. Xtracticle
  2. Features
  3. Getting Started
  4. Deployment
  5. Architecture
  6. SEO & AI Discoverability
  7. API
  8. Weekly “Best X Articles”
  9. Contributing
  10. License

Xtracticle

Download X (Twitter) Articles, threads & posts as PDF, Markdown, EPUB/Kindle, text or a ZIP with images.

Free, open source, no login required.

Features • Getting Started • Architecture • SEO & AI • API • Contributing


Live: xtracticle.com — or just change x.com to xtracticle.com in any post URL.

Features

Export formats
FormatWhat you get
PDFA4, print-ready; title/author/date/source header, images, page numbers, clickable source link. Rendered page by page so long articles never produce blank PDFs and lines are never cut.
MarkdownHeadings, bold/italic/strikethrough, links, nested lists, quotes, code, dividers, images, video thumbnails. Optional YAML front-matter (Obsidian properties, Hugo/Jekyll/Astro).
EPUB 3Reflowable e-book with embedded images and metadata — Kindle (Send to Kindle), Kobo, Apple Books.
ZIP + imagesMarkdown + every image stored locally — an offline archive that survives deleted posts.
TextClean .txt.
ObsidianCopies the Markdown and opens a new note via obsidian://new.
Content
  • 📝 X Articles — full Draft.js conversion: cover, inline images, videos, captions, embedded posts
  • 🧵 Threads from any post — paste the first, a middle or the last post; the whole self-thread is assembled (other people's replies are excluded)
  • 💬 Posts — line breaks, photos, videos and quoted posts
  • 🔗 Flexible input — x.com, twitter.com, mobile, fxtwitter/vxtwitter/fixupx, nitter/xcancel links, /i/web/status/, bare IDs, links inside shared text
Workflow
  • 🔁 URL swap — xtracticle.com/{user}/status/{id} opens a post directly, with rich link previews (Open Graph) when shared
  • 📚 Batch mode — up to 20 links → one ZIP of Markdown files
  • 🔖 Bookmarklet and PWA share target (share from the X app on Android)
  • 🔊 Listen — read aloud with the browser's text-to-speech
  • 📱 iPhone/iPad Shortcut — share a post from the X app straight to Xtracticle (public/shortcuts/)
  • 🤖 MCP server + Markdown API — AI assistants read X posts as Markdown (/mcp, /api/markdown/:id)
  • 📜 History, 🌙 dark mode, 🌍 English, Español, Português, 日本語, 简体中文, العربية, Türkçe (Arabic is right-to-left)
  • 📈 Analytics events — extract, download (format), copy, share, listen, batch_extract, errors — in GA4

Getting Started

git clone https://github.com/ahmetdeveci3112-crypto/Xtracticle.git
cd Xtracticle
npm install
npm run dev

The dev server runs at http://localhost:5173. /api/* is served by the same handler as the Worker (src/shared/api.ts), and every landing page is rendered on the fly — no wrangler needed.

ScriptDescription
npm run devVite dev server with the API
npm run buildProduction build → dist/ (all landing pages, 404, sitemap)
npm run preview:workerBuild and run the real Worker locally with wrangler dev (SSR status pages, 404s, _headers)
npm run lintType-check the app and the Worker

Deployment

Cloudflare Workers + Static Assets, deployed automatically on push to main (build: npm run build, deploy: npx wrangler deploy). No environment variables.

wrangler.json:

  • run_worker_first — only /api/*, /mcp, /video/* and /*/status/* hit the Worker; everything else is served straight from the CDN
  • not_found_handling: "404-page" — unknown URLs return a real 404 (no soft-404s)
  • public/_headers — security headers, Link: </llms.txt>, download headers for the iOS Shortcut

Architecture

Browser ──► Cloudflare
             ├─ Static assets (dist/)          /, /x-article-to-pdf, /tr/, … , 404.html, sitemap.xml
             └─ Worker (src/worker.ts)
                 ├─ /api/thread/:id, /api/tweet/:id ──► src/shared/api.ts ──► FxTwitter API
                 │                                        (edge cache, 5 min)
                 └─ /{user}/status/{id} ──► app shell + per-post OG tags + preloaded JSON (noindex)
src/
├── App.tsx              UI: extraction, exports, batch mode, deep links
├── i18n.ts              UI strings (en, tr, es, pt, ja, zh)
├── lib/export.ts        PDF (jsPDF + html2canvas-pro), EPUB, ZIP (fflate), Obsidian
├── lib/url.ts           Input + path parsing
├── lib/analytics.ts     GA4 event helper
├── shared/fx.ts         FxTwitter client (v2 thread endpoint + v1 fallback), shared by Worker & dev server
├── shared/api.ts        JSON API handler with edge caching
├── shared/convert.ts    Posts / threads / Draft.js articles → Markdown + text + metadata (app + Worker)
├── shared/markdown.ts   GET /api/markdown/:id
├── shared/mcp.ts        Remote MCP server (POST /mcp)
├── shared/text.ts       Title extraction
└── worker.ts            Cloudflare Worker (API + status-page SSR)
site/
├── blocks.ts            Types + localized shared blocks (shortcuts, privacy)
├── pages.ts             English pages (one per search intent) + page registry
├── pages-{es,pt,ja,zh,ar,tr}.ts  The same pages, localized (linked by `group`)
├── curated.ts           Weekly “Best X Articles” pages from site/curated/*.json
├── guides.ts            /guides — informational guides
├── mcp-page.ts          /mcp-server — MCP setup docs
├── render.ts            Head/meta/JSON-LD/content/footer rendering
└── plugin.ts            Vite plugin: emits every page, 404.html and sitemap.xml

Heavy export libraries are dynamically imported, so the initial page only loads React + the app.

SEO & AI Discoverability

LayerImplementation
Intent pages/x-article-to-pdf, /x-article-to-markdown, /x-thread-to-pdf, /x-article-to-epub, /save-x-articles-to-obsidian, /thread-reader-app-alternative — each with unique, visible HTML content and FAQ
LanguagesEvery page in 7 languages (/, /es/…, /pt/…, /ja/…, /zh/…, /ar/…, /tr/…) + UI in 7 languages; first-visit language banner, remembered choice redirects (never for crawlers)
Crawlable contentContent is static HTML outside the React root — no JS needed to index it
Structured dataWebApplication, FAQPage (matches visible FAQ), BreadcrumbList
i18nReciprocal hreflang for every translation group + x-default
Share pages/{user}/status/{id} get post-specific OG/Twitter tags; noindex, follow
Sitemap / 404Generated at build; real 404 status for unknown URLs
AI/llms.txt, /llms-full.txt, AI crawlers allowed in robots.txt

API

GET /api/thread/:id  → { tweets: Tweet[], count, isThread }   # self-thread containing :id
GET /api/tweet/:id   → Tweet
GET /api/markdown/:id → text/markdown  # ?format=markdown|text&thread=0|1&front_matter=0|1
POST /mcp            → MCP (Streamable HTTP, stateless), tool read_x_post

Tweet mirrors the FxTwitter status object (text, author, media, quote, article, …). Responses are edge-cached for 5 minutes — please be gentle.

Weekly “Best X Articles”

/best-x-articles is a hand-reviewed weekly selection built from site/curated/*.json (title, author and a one-sentence summary in our own words — never the article text).

npm run curate -- 2026-W41 https://x.com/user/status/123 https://x.com/other/status/456
# → site/curated/2026-w41.json with title/author/lang filled in; write "intro", "topic" and "summary"
npm run build   # issues with an empty summary are skipped automatically

The newest issue is shown on /best-x-articles (its /best-x-articles/<week> page canonicals to the hub until the next issue); older issues stay at /best-x-articles/<week>.

Contributing

  1. Fork the repo
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes
  4. Open a Pull Request

Notes:

  • Landing page copy lives in site/pages.ts; run npm run build to see the generated HTML
  • Keep src/shared/* free of DOM/Node-only APIs — it runs in both the Worker and the dev server
  • Test Worker-only behavior (SSR, 404, headers) with npm run preview:worker

License

MIT

Frequently asked questions

What is Xtracticle?

Read public X (Twitter) posts, threads and X Articles as clean Markdown. Read-only, no auth.

How do I install Xtracticle?

It runs as a remote server. In Claude Code: claude mcp add --transport http xtracticle 'https://xtracticle.com/mcp'. For other clients, paste the JSON configuration from this page into their MCP settings.

Does Xtracticle need an API key?

Its registry entry lists no required key or secret. Some features may still need an account with the service it connects to.

Is Xtracticle open source?

Its code is public on GitHub, but the repository does not declare a standard license.

Who maintains Xtracticle?

It is published by ahmetdeveci3112-crypto. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.