@trendtech33566: [Saved Version] For those who want to turn URLs or PDFs into clean Markdown PullMD, about 400. Here's what it can do ・C…

X AI KOLs Timeline Tools

Summary

PullMD is an open-source, self-hostable service that converts web pages, PDFs, Office documents, EPUBs, images, audio, and YouTube videos into clean Markdown, with a REST API, MCP server, and PWA frontend.

[Saved Version] For those who want to turn URLs or PDFs into clean Markdown PullMD, about 400. Here's what it can do - Convert web pages to Markdown without ads or decorations - Supports PDF/Office/EPUB/images/audio/YouTube and more - Includes REST API / MCP server / PWA - Self-hostable, and easy to integrate with AI agents An OSS that instantly takes care of "standardizing information in Markdown." It'll resonate with people building RAG preprocessing or AI workflows.
Original Article
View Cached Full Text

Cached at: 08/05/26, 12:23 PM

[Saved Version] For those who want to turn URLs or PDFs into clean Markdown: PullMD, about 400 (stars). Here’s what it can do:

  • Convert web pages to Markdown without ads or decorations
  • Supports PDF/Office/EPUB/images/audio/YouTube and more
  • Includes REST API / MCP server / PWA
  • Self-hostable, and easy to integrate with AI agents

An open-source project that instantly takes care of “standardizing information in Markdown.” It’ll resonate with people building RAG preprocessing or AI workflows.

What’s new in v3

PullMD v3 grows from a web-page reader into a general anything-to-Markdown service for agents, with a leaner default output. Everything beyond plain web extraction is opt-in and degrades gracefully - left unconfigured, v3 handles web pages exactly like v2, just with a cleaner body by default.

  • Clean body by default - the Markdown body is now just # Title + content. The source URL, fetch date, and all metadata moved into the YAML frontmatter, so nothing is duplicated and you spend fewer tokens. Reddit posts follow the same rule: subreddit, author, upvotes, and publish date live in the frontmatter (subreddit, author, upvotes, published), not the body. This is the one breaking change: set PULLMD_SOURCE_HEADER=true to restore the old inline header, and use PULLMD_FRONTMATTER_FIELDS to trim which fields are emitted. See MIGRATION.md.
  • Documents → Markdown - PDF, Word, PowerPoint, Excel, EPUB and more, by URL or upload (POST /api/file, drag-and-drop in the PWA).
  • High-quality PDF tables (OCR) - an opt-in, vendor-neutral OCR tier (?pdf=ocr) for table-grade PDF conversion, with automatic fallback to the free path.
  • Images & audio → Markdown - opt-in captioning and transcription via any OpenAI-compatible or local model; runs inside pullmd, no extra container required.
  • YouTube transcripts - title, description and transcript with clickable timecodes, no API key required.
  • Richer frontmatter - extraction source, quality, and (for media/OCR) model + token/page usage for cost tracking, plus a configurable field allowlist.

Self-hosters upgrading from v2.x: the clean-body change is the only breaking one - MIGRATION.md has the one-line opt-out. Everything else is additive.

Added in the 3.x line since then:

  • Hacker News pipeline (3.1) - items, comment permalinks and listings through a purpose-built converter, plus Web Share and an instant frontmatter toggle in the PWA.
  • X-Transcript-Status (3.2) - tells a transient YouTube rate-limit apart from a genuinely missing transcript.
  • SSRF protection (3.3) - private, loopback, link-local, CGNAT and cloud-metadata targets are rejected by default, on every fetch path and every redirect hop.
  • Query-scoped extraction (3.4) - ?query= returns only the sections relevant to a question, with a max_tokens budget.
  • Site recipes opened up (3.5/3.6) - JSON-LD-to-frontmatter, a contributor guide, and select.content so a recipe can name the article body outright.
  • Coverage guard (3.7) - recovers pages where extraction kept only a sliver of the body; see PULLMD_COVERAGE_GUARD.
  • Account controls (3.8) - a non-admin can clear entries from their own history, self-registration can be closed with PULLMD_ALLOW_SIGNUP, and scripts/admin.js create-user creates accounts from the shell.
  • Download button (3.9) - the PWA saves a result as a .md file, named by the server via X-Suggested-Filename and optionally date-prefixed.

Configuration

All variables go in .env (copy from .env.example):

v3.0.0 output format change: the markdown body is clean by default - just # Title followed by content. The source URL, fetch date, and all extraction metadata remain in the YAML frontmatter unchanged - the body no longer duplicates them. Set PULLMD_SOURCE_HEADER=true to restore the old inline header. Use PULLMD_FRONTMATTER_FIELDS to pick which frontmatter fields are emitted (handy for trimming tokens in agent pipelines).

VariableRequiredPurpose
HOST_DOMAINTraefik variant onlyPublic hostname without scheme. Used by Traefik routing and as fallback for PUBLIC_URL. Unused by the default compose.
PUBLIC_URLnoFull public origin embedded in /help and the skill zip. Defaults to https://${HOST_DOMAIN}.
TRAFILATURA_URLnoURL of the Trafilatura sidecar’s /extract endpoint. Unset → skip Trafilatura, Readability only.
PLAYWRIGHT_URLnoURL of the Playwright sidecar’s /render endpoint. Unset → skip Playwright fallback for JS pages.
MARKITDOWN_URLnoURL of the MarkItDown sidecar’s /convert endpoint. Unset → document-conversion path disabled; POST /api/file returns 502.
PULLMD_VISION_API_KEY / ..._BASE_URL / ..._MODELnoImage captioning via an OpenAI-compatible vision endpoint. Enabled when the key is set. _MODEL defaults to gpt-4o-mini.
PULLMD_STT_API_KEY / ..._BASE_URL / ..._MODELnoAudio transcription via an OpenAI-compatible /audio/transcriptions endpoint. Enabled when the key is set. _MODEL defaults to whisper-1.
PULLMD_LLM_API_KEY / ..._BASE_URLnoShared fallback credentials for vision + STT when the per-modality vars are unset. Key and base URL only - there is no PULLMD_LLM_MODEL, and setting one is ignored (the server warns at startup).
PULLMD_PDF_OCR_API_KEY / ..._BASE_URL / ..._MODELnoOpt-in high-quality PDF→Markdown via an OCR provider that preserves tables (reference: Mistral OCR mistral-ocr-latest). Triggered per request with ?pdf=ocr or a recipe fetch.pdf: ocr. Default PDF handling stays the free markitdown path. _MODEL defaults to mistral-ocr-latest.
MARKITDOWN_YOUTUBEnoSet to true to route YouTube URLs through the markitdown sidecar (returns title + description + transcript). No API key required. Default: off.
MARKITDOWN_YT_TIMECODESno (sidecar)Default timecode format in transcripts: links (YouTube timestamp links, default), plain (bare [MM:SS] labels), none (transcript text only). Overridable per-request via ?yt_timecodes=.
MARKITDOWN_YT_CHUNKno (sidecar)Transcript block size in seconds (default 30). 0 keeps the original per-snippet granularity. Overridable per-request via ?yt_chunk=.
MARKITDOWN_YT_LANGSno (sidecar)Comma-separated preferred transcript languages (e.g. de,en). Falls back to the first available language if none of the preferred ones exist.
MARKITDOWN_YT_PROXYno (sidecar)HTTP(S) proxy URL for YouTube requests. Datacenter IP addresses are often rate-limited by YouTube’s transcript API; a residential or ISP proxy can help.
REDDIT_CLIENT_IDnoOAuth credentials for Reddit. Without them, PullMD uses the public JSON API (lower rate limit).
REDDIT_CLIENT_SECRETno
REDDIT_USER_AGENTnoReddit requires a unique UA. Default: PullMD/1.0 (URL-to-Markdown service).
DISABLE_PUBLIC_HISTORYnoWhen true, hides the global recent-conversions list and archive (/api/history + /api/archive return 403, frontend hides the section). /s/:id share links keep working. Default: false.
PULLMD_USER_AGENTnoPin a single outbound User-Agent for every web fetch. Disables rotation. Useful for CI or when one specific UA is known to work.
PULLMD_UA_FEED_URLnoURL of a JSON feed of current real-world UAs. Default: WinFuture23/real-world-user-agents (https://github.com/WinFuture23/real-world-user-agents). Set to an empty string to disable live refresh and rely on the built-in seed pool.
PULLMD_AUTH_MODEnodisabled (default) / single-admin / multi-user. See “Authentication” below.
PULLMD_ALLOW_SIGNUPnoSelf-registration in multi-user mode. Default: on. false / 0 / no / off closes /signup (404) and removes the “create an account” link from the login page. Accounts can still be created with node scripts/admin.js create-user .
PULLMD_ADMIN_EMAILrequired when AUTH_MODE != disabled, on first startupBootstrap email for the first admin user.
PULLMD_ADMIN_PASSWORDrequired when AUTH_MODE != disabled, on first startupBootstrap password (min 8 chars).
PULLMD_AUTH_TOKENnoLegacy bearer token compat (single-admin mode only, deprecated).
PULLMD_SOURCE_HEADERnoSet to true to restore the legacy inline source header in the body (# Title + **domain** · date + url; for Reddit the **r/sub** · u/user · N ↑ line). Default (unset): clean body - just the H1 title; source/date/post meta live in the frontmatter.
PULLMD_FRONTMATTER_FIELDSnoComma-separated allowlist of frontmatter fields to emit (e.g. title,url,source,llm_tokens). Unset = all fields. Trims tokens. Unknown names are ignored with a startup warning.
`PULLMD

Similar Articles

@GitHub_Daily: Trying to feed webpage content to AI, but ending up with a bunch of navigation bars, ads, and garbled text, wasting most of the context window, and AI still can't understand it. So I found this open-source project PullMD, which can extract any webpage content and convert it into clean Markdown files. Just provide a URL, auto-detect page type, layer by layer...

X AI KOLs Timeline

PullMD is an open-source URL to Markdown service that automatically extracts the main content of a webpage, removing navigation, ads, and other clutter. It supports headless browsers and multiple interfaces (web, REST API, MCP), making it easy for AI tools and users to obtain clean webpage text.

tweet.md

Product Hunt

tweet.md is a tool that converts X (Twitter) posts into clean Markdown format, simplifying content repurposing.