Content
# substack-mcp
A Model Context Protocol (MCP) server for Substack. Lets Claude Code create
drafts, upload images, set cover thumbnails, schedule, and publish posts on
your Substack publication.
> Built on top of [`python-substack`](https://github.com/ma2za/python-substack).
> Uses Substack's internal API (no public posting API exists). Not affiliated
> with Substack Inc.
## Tools
**Required**
- `create_draft(title, content_markdown, subtitle?, audience?)` — Create a new draft from Markdown.
- `update_draft(post_id, title?, subtitle?, content_markdown?, audience?)` — Edit an existing draft.
- `upload_image(image_path)` — Upload a local file or remote URL to Substack's CDN, returning the URL.
- `publish_draft(post_id, send_email?, share_automatically?)` — Publish immediately. `send_email` toggles email delivery.
**Recommended**
- `schedule_draft(post_id, iso_datetime)` — Schedule a publish for a future date/time (ISO 8601).
- `unschedule_draft(post_id)` — Cancel a scheduled publish.
- `set_cover_image(post_id, image_url)` — Set the cover thumbnail (from `upload_image` URL).
**Utility**
- `list_drafts(limit?)` — List recent drafts.
- `get_draft(post_id)` — Get a draft's full body.
- `delete_draft(post_id)` — Permanent deletion.
## Setup
```bash
# 1. Install dependencies
uv pip install -e .
# 2. Make sure you're logged in to Substack in Chrome (or Brave/Edge) — that's it.
# 3. Save credentials — auto-detects your existing browser session
substack-mcp-setup
# 4. Register with Claude Code
claude mcp add substack-mcp --scope user -- /Users/$USER/substack/.venv/bin/substack-mcp
```
Restart Claude Code, then `/mcp` should show `substack-mcp` as `connected`.
### (Optional) Install the `substack-article` skill
This repo also ships a [Vercel Skills](https://skills.sh/)-compatible **agent skill**
that uses the MCP above to plan, draft, generate a thumbnail, and publish a
Substack article in one flow.
```bash
# Globally for all projects
npx skills add nanameru/substack-mcp -g -a claude-code -y
# Or scoped to the current project
npx skills add nanameru/substack-mcp -a claude-code
```
Restart Claude Code. The skill is automatically invoked when you say things like
「Substack 記事を書いて」 / 「Substack に投稿して」 / 「短文ポストして」.
`npx skills` works with Claude Code, Cursor, Codex, OpenCode, GitHub Copilot,
and 50+ other agents. See [skills.sh](https://skills.sh/) for details.
The skill expects:
- `substack-mcp` registered as an MCP (above)
- `codex` MCP registered (for thumbnail generation; optional if you skip thumbnails)
- macOS with Hiragino fonts installed (default on macOS for Japanese text overlay)
See `skills/substack-article/SKILL.md` for the full flow and guardrails.
### How auth works
By default `substack-mcp-setup` reads the `substack.sid` cookie directly from
your existing Chrome session via [pycookiecheat](https://pypi.org/project/pycookiecheat/).
Substack can't tell anything was automated because **nothing was**: it's the
same session you're already using.
macOS will prompt once for Keychain access ("Chrome Safe Storage"). Click
"Always Allow" so it doesn't ask again next time.
Supports: Chrome, Brave, Edge, Chromium, Vivaldi, Opera.
### Fallback modes
```bash
# Specific browser
substack-mcp-setup --from-browser brave
# Playwright-based (often blocked by Substack — use --chrome instead)
substack-mcp-setup --browser
# Manual paste from DevTools
substack-mcp-setup --manual
```
Tokens are stored at `~/Library/Application Support/substack-mcp/config.json`
with `0600` permissions.
## Security
The `substack.sid` cookie is **equivalent to a password** — anyone with it has
full account access (publish posts, edit billing, etc.). Treat it as such.
### Where the token lives
- macOS: `~/Library/Application Support/substack-mcp/config.json` (mode `0600`)
- Linux: `~/.config/substack-mcp/config.json` (mode `0600`)
- Or via env vars: `SUBSTACK_PUBLICATION_URL` + `SUBSTACK_SESSION_TOKEN` (env
vars are inherited by child processes — be aware when spawning subprocesses)
The `.gitignore` excludes `config.json`; never commit it. The MCP also writes
a temporary cookie file via `tempfile.mkstemp` (mode `0600`) and deletes it in
a `finally` block — see `auth.py:write_cookie_file`.
### If a token leaks
1. **Sign out of all sessions**: Substack → Settings → Security → "Sign out of
all sessions". This invalidates every existing `substack.sid` immediately.
2. Log back in to Substack in your browser.
3. Re-run `substack-mcp-setup` to capture the new cookie.
### Image upload safety
`upload_image` only accepts:
- HTTP(S) URLs, or
- Local files with image extensions (`.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`,
`.heic`, `.heif`) that are **not** under sensitive system paths
(`/etc`, `/System`, `~/.ssh`, `~/.aws`, `~/Library/Keychains`, etc.)
This guards against an assistant being tricked (via prompt injection in
fetched content) into uploading e.g. an SSH private key to Substack's CDN.
**Known limitation**: Markdown image syntax `` inside `create_draft`
is processed by `python-substack` and bypasses this validation. If you pass
untrusted Markdown, sanitize image paths first.
### Dependencies
Versions are pinned with `~=` (compatible release, no major bumps). Bumping
`python-substack` in particular should be reviewed — it talks to Substack's
private API and lives outside Substack's official surface.
## Notes
- `audience` accepts: `everyone` (default), `only_paid`, `founding`, `only_free`.
- Markdown image syntax `` auto-uploads local files when you call `create_draft`.
- The cover image (set via `set_cover_image`) is what appears on your publication
homepage and in social shares. If you don't set one explicitly, Substack
typically uses the first image in the body.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
markitdown
Python tool for converting files and office documents to Markdown.
OpenAI Whisper
OpenAI Whisper MCP Server - 基于本地 Whisper CLI 的离线语音识别与翻译,无需 API Key,支持...
oh-my-opencode
Background agents · Curated agents like oracle, librarians, frontend...
comsol-mcp
Unofficial COMSOL MCP learning project: Controlling an opened COMSOL Desktop...
pump-fun-sdk
Token creation launching, bonding curve trading, AMM migration, tiered fees,...
spectral
Browse any app normally. Spectral captures the traffic, understands what...