Substack to clean Markdown.
Bulk-export Substack posts as Obsidian-friendly Markdown using your authenticated browser session — no passwords, no copy-paste.
Substack does not let you bulk-export your reading list or subscriptions in any useful format. substack2md uses your logged-in browser via the Chrome DevTools Protocol to convert posts to clean Markdown with YAML frontmatter, image-and-embed-as-link rewriting, and [[YYYY-MM-DD-slug]] wikilinks for Obsidian.
What it does
Run substack2md against a single post URL or a text file of URLs. It opens a Chrome tab against your local browser, reads the rendered post HTML, and writes Markdown to disk organized by publication. Your Substack session cookie never leaves your machine, and no Substack credentials are ever handled by the tool.
Browser-session auth
Uses your existing Chrome via the Chrome DevTools Protocol. No passwords stored, no Substack credentials handled by the tool.
Obsidian-friendly output
YAML frontmatter, [[YYYY-MM-DD-slug]] wikilinks for cross-references, images and embeds rewritten as plain links so your vault stays portable.
Polite and configurable
Sequential requests with configurable sleep, publication-slug-to-folder mapping, transcript cleaning, and optional paywall tagging via Substack's public API.
Designed for
| You want to | substack2md does |
|---|---|
| Archive your own newsletter | Walks your archive page, exports every post with paywall status preserved. |
| Read newsletters offline in Obsidian | Outputs Markdown with frontmatter and wikilinks ready to drop into a vault. |
| Build a personal corpus for search or LLM context | Plain Markdown, one file per post, structured filenames you can grep. |
| Stop accidentally sharing paid content | Optional paywall detection tags posts as free or subscriber-only in frontmatter. |
Install
Requires Python 3.10+ and a Chrome / Chromium browser. Start Chrome with the remote debugging port, log in to Substack, then run substack2md.
Install
git clone https://github.com/snapsynapse/substack2md.git cd substack2md pip install .
Start Chrome with CDP
# macOS
./launch-browser.sh
# or manually
chrome --remote-debugging-port=9222 \
--user-data-dir=/tmp/substack2md
Convert a single post
substack2md https://example.substack.com/p/some-post
Batch from a URL list
substack2md urls.txt # one URL per line, blank lines and # comments OK
See urls.txt.example in the repo for the expected format.
AI-assisted install
substack2md ships a GuideCheck human-verifiable assistant guide (profile 0.3.0) that currently verifies at Level 3, so an AI assistant can install and run it locally under explicit human approval. Verify the guide with a conformant verifier before letting the assistant execute any [action] block.
- · Canonical:
https://substack2md.space/.well-known/assistant-guide.txt - · Repo path:
.well-known/assistant-guide.txt - · Manifest:
.well-known/assistant-guide-manifest.txt
Output shape
Each post becomes a single Markdown file with YAML frontmatter Obsidian and most static-site generators can read directly.