substack-publisher
Publish newsletter articles to Substack as drafts. Use when "publish to substack", "create substack draft", "post newsletter to substack", "substack draft".
Installation
Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.
View source ↗GuidesSkill instructions
Substack Publisher
What This Does
Takes a Markdown newsletter article and creates a beautiful draft in Substack, preserving all formatting (headers, bold, tables, code blocks, links). You review the draft in Substack, add images, and publish when ready.
Prerequisites
One-Time Setup
-
Set a password on your Substack account (if using magic links):
- Go to Substack Settings → Account → Set password
-
Add environment variables to
~/.zshrc:export SUBSTACK_EMAIL="your-email@example.com" export SUBSTACK_PASSWORD="your-password" export SUBSTACK_PUBLICATION_URL="https://thelittlebluereport.substack.com" -
Reload shell:
source ~/.zshrc -
Install the library (first time only):
pip install python-substack
Verify Setup
Run the auth check before first use:
python3 ~/Documents/GitHub/powerhouse-lab/skills/substack-publisher/tools/check_auth.py
Instructions
PHASE 1: Locate the Article
When user says "publish to substack" or similar:
- If they provide a file path, use that
- If they mention an article name, search Zettelkasten:
/Users/eddale/Documents/COPYobsidian/MAGI/Zettelkasten/ - Look for files starting with "Newsletter Draft -" or matching their description
Read the file to confirm it's the right article.
PHASE 2: Extract Metadata
Parse the article for:
Title: Look for first # Heading or use filename (minus date)
Subtitle: Look for second ## Heading or first bold line after title
Body: Everything after the subtitle
If frontmatter exists (between --- markers), extract:
-
title: -
subtitle: - Any other metadata
PHASE 3: Preview (Dry Run)
Show the user what will be created:
Ready to create Substack draft:
Title: [extracted title]
Subtitle: [extracted subtitle]
Body preview: [first 150 characters]...
Word count: [X] words
Estimated read time: [X] minutes
PHASE 4: Confirm
Use AskUserQuestion to confirm before creating the draft.
Ask: "Create this draft in Substack?"
- Options: "Yes, create draft" / "Edit title/subtitle first" / "Cancel"
If they want to edit, let them provide new title/subtitle, then confirm again.
PHASE 5: Create Draft
Run the publish script:
python3 ~/Documents/GitHub/powerhouse-lab/skills/substack-publisher/tools/publish_draft.py \
--file "/path/to/article.md" \
--title "The Title" \
--subtitle "The Subtitle"
Parse the output for the draft URL.
PHASE 6: Report Success
Tell the user:
Draft created successfully!
View your draft: [URL]
Next steps:
1. Open the link above
2. Add any images
3. Preview and publish when ready
Error Handling
| Error | Solution |
|---|---|
| "Authentication failed" | Check SUBSTACK_EMAIL and SUBSTACK_PASSWORD in ~/.zshrc |
| "Publication not found" | Verify SUBSTACK_PUBLICATION_URL is correct |
| "Rate limited" | Wait 60 seconds and try again |
| "File not found" | Confirm the markdown file path exists |
Examples
User: "Hey, publish my newsletter about the 45 minutes to 45 seconds thing"
Claude:
- Searches Zettelkasten for matching file
- Finds "Newsletter Draft - 45 Minutes to 45 Seconds - 2026-01-15.md"
- Extracts title: "45 Minutes to 45 Seconds"
- Extracts subtitle: "45 Minutes of Prep Work. Done in 45 Seconds."
- Shows preview, asks for confirmation
- Creates draft, returns URL
User: "Create a substack draft from ~/Documents/article.md"
Claude:
- Reads the specified file
- Extracts metadata
- Confirms with user
- Creates draft
Roadmap
Current (MVP):
- Markdown → Substack draft
- Title/subtitle extraction
- Dry-run confirmation
Planned:
- Image uploading
- One-click publish (skip draft)
- Scheduling posts
- Audience targeting (free vs paid)
Examples
Read the usage examples in the source repository.
View source ↗Source history
- Indexed on
- 2026-01-20
- Index updated
- 2026-01-26
- Branch
- main
Index and sync dates describe this directory. View the source repository for code history.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!