Substack MCP Server & CLI

A free, open source Substack MCP server and CLI that lets Claude Code, Codex, Cursor and other AI agents draft posts, publish Notes and read your subscribers and stats.

Navid Moazzezby Navid Moazzez·Updated Sept 30, 2026·13 min read
~/substack-mcp-cli
$ claude
Claude Code v2.1.220
>
Rate this tool

This free Substack MCP server and CLI gives your AI real access to your Substack publication. It drafts posts, publishes Notes, reads your subscribers and stats, and studies other writers.

It's one install with 2 ways in. Claude, Codex, Cursor or any other MCP app calls its 65 tools for you, and the same tools work as a CLI that agents like Claude Code, Codex and OpenCode run, or that you type yourself.

Here's what the Substack MCP server is, how to set it up in each app, and every tool it has.

What is the Substack MCP server & CLI?

The Substack MCP server & CLI is a free, open source program that lets AI agents work in your Substack for you, in 2 ways. The MCP server is what an AI app like Claude, Codex or Cursor connects to, through MCP (Model Context Protocol), the open standard AI apps use to call outside tools.

You ask in plain language. Your AI picks the right tool, and the server makes the call to Substack.

The CLI is the same program as commands. substack-cli list-drafts runs the same code your AI runs when you ask what you have in progress, whether an agent like Claude Code runs it or you do.

What can you ask it?

Once it's set up, you ask the way you'd ask an assistant. These are real prompts it handles:

Try asking
Draft this week's post from my notes, in the voice of my last 5.
Which of my posts got the most paid conversions, and what do they have in common?
How many subscribers haven't opened anything in 90 days?
Add a paywall after the third section of that draft.
Schedule this Note for 9am Tuesday.
Turn my last 3 posts into a guide, and put the YouTube version at the top.

The last one shows why this is useful. It writes the new draft in your format and embeds the video as a real player, not a blue link.

How to install the Substack MCP server

Pick your app in the box at the top of this page. You log in once in a terminal, then add the server to your app with a single command or a pasted block.

Before you start0/3
⚠️

Watch out: Use the substack.com address even if your publication has its own domain. Substack doesn't answer its API on custom domains, so the request ends in a 404.

Set up your Substack account

Substack has no public API and no app to register. The server works through your browser's session cookie, the same way the Substack tab you have open does.

Treat that cookie like a password, because it gives full access to your account. Never paste it into an issue, a chat or a shared doc.

Log in with your session cookie0/4
npx -y @thenavidm/substack-mcp-cli login

Turn off ad blockers before you look for the cookie. Some of them hide it from that panel.

Other ways to log in

login --playwriter reads the cookie from the Chrome you already have open, using the Playwriter extension. login --playwright opens a browser for you to sign in, which is slower but works on a computer without Chrome.

You can also skip the login and set SUBSTACK_PUBLICATION_URL and SUBSTACK_SESSION_TOKEN in your app's config instead.

When the session runs out

Substack sessions expire, commonly reported at around 90 days. When calls start failing with a sign-in error, run the login again, and the doctor warns you once a stored session passes 75 days.

Check that it works

Run the doctor. It checks your credentials, your settings, the connection and your byline, and names what's wrong.

npx -y @thenavidm/substack-mcp-cli doctor

When it passes, restart your app and ask for a summary of your dashboard.

Use the Substack CLI

The CLI is the same 65 tools as commands. AI agents that run commands, like Claude Code, Codex and OpenCode, use it on their own, and you can type the same commands in a terminal or a script. Every tool name becomes a command with dashes, so create_draft runs as substack-cli create-draft.

npm install -g @thenavidm/substack-mcp-cli
substack-cli
substack-cli list-drafts
substack-cli get-dashboard-summary
substack-cli rank-posts --limit 10

The bare substack-cli lists every command, and substack-cli <command> --help shows what a command takes. Publishing, deleting and posting Notes need --confirm, the terminal's version of the check your AI has to pass.

These flags work on every command:

FlagWhat it does
--jsonPrints JSON
--compactPrints the JSON on one line
--agentMachine mode: JSON, compact, no prompts and no color
--select a,b.cKeeps only those fields, and a dotted path goes deeper
--confirmLets a write that asks first go ahead

A script can branch on the exit code:

Exit codeWhat it means
0It worked
2The command was typed wrong, or a write needed --confirm
3It wasn't found
4Substack rejected the session
5Substack's API failed
7You hit a rate limit, so wait and try again
10Nothing is set up yet

MCP server or CLI: which one?

Both are the same program with the same 65 tools. The difference is when your AI pays for them, in the tokens it reads.

Every message, in an app that loads every tool
MCP server
25,200 tokens
CLI
Nothing
Every message, in Claude Code
MCP server
1,200 tokens
CLI
Nothing
When Substack comes up
MCP server
Nothing more, or in Claude Code the tools it picks
CLI
2,300 tokens, once
20 messages with Substack in 1, every tool loaded
MCP server
504,000 tokens
CLI
2,300 tokens
Works in Claude Desktop's chat
MCP server
Yes
CLI
No, there's no terminal there
Works in a script, a cron job or CI
MCP server
No
CLI
Yes

An app that loads every tool up front sends the full list with every message, whether you mention Substack or not. Claude Code doesn't by default: its tool search sends only the tool names and the server's instructions, and loads a tool's full definition when your AI reaches for it.

The CLI costs nothing until Substack comes up. Then your agent reads its skill file once and runs the commands it needs. With the skill added, Claude Code also lists its one-line description with every message, about 140 tokens.

When the whole conversation is about Substack, the gap closes. Then the MCP server is the better experience, because you ask in plain language and your AI never has to look up a command.

Where the MCP server's tokens go

Part of the tool listShare
JSON Schema structure, like types, required lists and nesting47%
Argument descriptions36%
Tool descriptions17%

47% of it is MCP writing every tool out as JSON Schema, which any server with this many tools pays. The rest is the wording that lets your AI use each tool without guessing.

How to spend less

In Claude Code, leave tool search on, which it is unless you've set ENABLE_TOOL_SEARCH=false.

Turn the server off when you aren't using Substack. In Claude Code that's the /mcp panel, and every AI app has its own switch. SUBSTACK_READ_ONLY=1 cuts it to the 41 reading tools.

Or install the CLI and connect the server later, on the days it earns its place. Every tool stays in reach, and the standing cost drops to nothing.

Every number here was measured on September 27, 2026 in Claude Code 2.1.257 with Claude Opus 5. It's the same one-line prompt with and without the server connected, once with tool search off so every tool loads, and once with Claude Code's default. The skill was measured the same way, and other apps and models count tokens a little differently.

How it writes posts

Substack stores a post as its own document format, not HTML. The server turns your AI's markdown into that format, so a draft looks like one you made by hand.

A line with only a YouTube, X, Spotify or Vimeo link becomes a real embedded player. Write <paywall> on its own line to mark where the paid part starts.

The free part everyone reads.

https://youtu.be/VIDEO_ID

<paywall>

The part only paying subscribers get.

Substack's format has no tables, so a table in your draft is kept as a code block you can reformat in the editor. preview_draft_body shows what a body will turn into, embeds and paywall included, without changing anything.

Every Substack tool

All 65 tools, grouped the way the repo groups them. 41 only read, and 24 change something in your publication.

Drafts and publishing

create_draft
What it does
Create a new draft post.
Kind
Writes
update_draft
What it does
Change any part of an existing draft.
Kind
Writes
get_draft
What it does
Read one draft in full.
Kind
Reads
list_drafts
What it does
List unpublished drafts, most recently edited first.
Kind
Reads
delete_draft
What it does
Permanently delete an unpublished draft.
Kind
Asks first
publish_draft
What it does
Publish a draft immediately.
Kind
Asks first
schedule_draft
What it does
Schedule a draft to publish at a future time.
Kind
Writes
unschedule_draft
What it does
Cancel a scheduled publication and return the post to being a plain draft.
Kind
Writes
list_scheduled_posts
What it does
List posts queued to publish later, soonest first.
Kind
Reads
set_draft_body
What it does
Replace a draft's body with a Substack document you build node by node.
Kind
Writes
preview_draft_body
What it does
Convert a body to Substack's document format and show what it produced, without creating or touching anything.
Kind
Reads
get_sections
What it does
List the publication's sections, which are the categories a post can be filed under.
Kind
Reads

Published posts

list_posts
What it does
List published posts, newest first.
Kind
Reads
get_post
What it does
Read a published post in full by its slug.
Kind
Reads
get_post_by_id
What it does
Read a published post by its numeric id rather than its slug.
Kind
Reads
search_posts
What it does
Search your own published posts by keyword, across title and body.
Kind
Reads
get_post_stats
What it does
Full performance detail for one published post: opens, clicks, views, signups driven, reactions, restacks and comments.
Kind
Reads
rank_posts
What it does
Rank published posts by a performance metric, to find what actually worked.
Kind
Reads

Notes

publish_note
What it does
Publish a Substack Note.
Kind
Asks first
publish_note_with_link
What it does
Publish a Note with a link attached, which renders as a preview card rather than a bare URL.
Kind
Asks first
schedule_note
What it does
Queue a Note to publish later.
Kind
Writes
list_scheduled_notes
What it does
List Notes queued by schedule_note, soonest first.
Kind
Reads
cancel_scheduled_note
What it does
Cancel a queued Note before it publishes.
Kind
Writes
list_notes
What it does
List Notes you have published, newest first.
Kind
Reads
delete_note
What it does
Delete one of your published Notes.
Kind
Asks first

Subscribers

list_subscribers
What it does
List subscribers, with the same filtering the Subscribers dashboard offers: 48 columns, free-text search, sorting and paging.
Kind
Reads
export_subscribers
What it does
Export subscribers as full records, which is the only way to actually read the engagement metrics list_subscribers can only filter on: opens over 7d/30d/6mo, unique emails seen, post views, comments, shares, links clicked, days active and activity rating.
Kind
Reads
get_subscriber_count
What it does
Total subscribers, split by free and paid.
Kind
Reads
add_subscriber
What it does
Add an email address to your subscriber list.
Kind
Writes

Analytics

get_analytics
What it does
Read one of the publication-level reports behind the dashboard's Stats tabs.
Kind
Reads
get_dashboard_summary
What it does
The headline numbers from the publishing dashboard: subscribers at the start and end of the window, paid subscribers, ARR and recent activity.
Kind
Reads
get_email_stats
What it does
Overall email performance: delivery, open rate and click rate across the publication.
Kind
Reads
get_growth_sources
What it does
Where new subscribers came from in a window, ranked by how many each source brought.
Kind
Reads
get_revenue_summary
What it does
Revenue and subscription plans: what each tier costs, how many are on it, and what it brings in.
Kind
Reads

Comments

get_post_comments
What it does
Read the comments on one of your posts, newest first.
Kind
Reads
comment_on_post
What it does
Post a comment on one of your posts.
Kind
Asks first
delete_comment
What it does
Delete a comment by id.
Kind
Asks first

Tags

list_publication_tags
What it does
List every tag defined on the publication, with the ids that add_tag_to_post takes.
Kind
Reads
create_tag
What it does
Create a new tag on the publication.
Kind
Writes
get_post_tags
What it does
List the tags currently on one post.
Kind
Reads
add_tag_to_post
What it does
Put an existing tag on a post.
Kind
Writes
remove_tag_from_post
What it does
Take a tag off a post.
Kind
Asks first

Templates

list_templates
What it does
List your saved post templates, with the ids create_draft_from_template takes.
Kind
Reads
create_template
What it does
Save a reusable post template.
Kind
Writes
delete_template
What it does
Delete a saved template.
Kind
Asks first
create_draft_from_template
What it does
Create a new draft pre-filled with a saved template's body.
Kind
Writes

Your reader feed

list_subscriptions
What it does
List the publications this account subscribes to, free and paid.
Kind
Reads
list_reader_posts
What it does
The posts in your Substack inbox, from the publications you subscribe to, newest first.
Kind
Reads
get_reader_post
What it does
Read the full text of any post you have access to, including paid posts from publications you pay for.
Kind
Reads
get_reader_feed
What it does
The Notes feed, which is Substack's timeline.
Kind
Reads
get_profile_feed
What it does
Everything one account has published to Notes, newest first.
Kind
Reads
get_comment_thread
What it does
Read one Note together with the replies under it.
Kind
Reads
restack_note
What it does
Restack a Note, which republishes it to your own followers under your name.
Kind
Asks first

Research other writers

research_creator_posts
What it does
Pull another publication's recent posts with their engagement numbers: likes, comments and restacks.
Kind
Reads
research_creator_notes
What it does
Pull another writer's recent Notes with likes, replies and restacks.
Kind
Reads
compare_publications
What it does
Pull recent posts from several publications at once and rank them together by engagement, so you can see which topics and formats are working across a whole niche rather than one writer at a time.
Kind
Reads
scrape_post
What it does
Fetch a public Substack post by URL and pull out the title, subtitle, author and body text.
Kind
Reads

Publication settings

get_publication_settings
What it does
Read the publication's full settings: name, hero text, logo, cover, sender name, theme colours, sections, welcome email, podcast feed and everything else on the settings page.
Kind
Reads
update_publication_settings
What it does
Change publication settings.
Kind
Writes
get_user_profile
What it does
Read the account behind the session: name, handle, user id, bio and which publications it owns.
Kind
Reads
list_contributors
What it does
List the people attached to the publication, with their role and their numeric user id.
Kind
Reads
get_import_status
What it does
Read the result of the most recent subscriber import: when it ran, how many addresses were in it, how many were added, and how many were skipped.
Kind
Reads
search_publications
What it does
Search Substack for publications by name or topic.
Kind
Reads
get_publication_info
What it does
Read the public details of any Substack publication from its homepage: name, description, author and cover image.
Kind
Reads

Images

upload_image
What it does
Upload an image to Substack's CDN and get back a URL you can use in a post body or as a cover image.
Kind
Writes

Is the Substack MCP server safe?

Publishing a draft with the email on sends it to every subscriber, and there's no unsend. Deleting a draft has no undo, and a Note or a comment is public the moment it runs. So 10 tools refuse to run until your AI passes confirm: true. They're the ones marked Asks first in the tool tables above.

A careless call stops at that check, and one you meant clears it in a single retry. Drafting and editing don't ask, because nothing there is public or permanent.

Make it read-only

Set SUBSTACK_READ_ONLY=1 and every write disappears from the tool list, leaving 41 reading tools. Your AI can't call a tool it can't see.

SUBSTACK_ALLOW_DESTRUCTIVE=0 is the middle setting. Drafting and tagging still work, and publishing and deleting don't.

Keep a log of every write

Set SUBSTACK_AUDIT_LOG to a file path. The server writes one line per attempted write, allowed or blocked.

⚠️

Watch out: Comments, your reader feed and other writers' posts are text other people wrote, and a comment can try to give your AI orders. The server tells your AI to treat it as data, but SUBSTACK_READ_ONLY=1 is the real defense for an agent working on its own.

Your data

Nothing goes anywhere but Substack. There's no tracking, no analytics and no other service in between.

If you use the login, your session is stored in ~/.substack-mcp, encrypted with a key tied to your computer and your user account. Your posts, drafts and subscribers are never copied to your computer, and every read goes to Substack live.

Substack MCP server settings

Every setting is an environment variable, in your app's config or your shell.

SUBSTACK_PUBLICATION_URL
Default
none
What it does
Sets your publication, like example.substack.com
SUBSTACK_SESSION_TOKEN
Default
none
What it does
Holds the connect.sid cookie value when you skip the login
SUBSTACK_USER_ID
Default
looked up
What it does
Sets your numeric user ID for the byline
SUBSTACK_PUBLICATIONS
Default
none
What it does
Lists several publications, as JSON
SUBSTACK_READ_ONLY
Default
0
What it does
1 hides every write
SUBSTACK_ALLOW_DESTRUCTIVE
Default
1
What it does
0 blocks publishing and deleting
SUBSTACK_AUDIT_LOG
Default
none
What it does
Logs every attempted write to a file
SUBSTACK_REQUEST_TIMEOUT_MS
Default
30000
What it does
Sets how long a request can take
SUBSTACK_MIN_REQUEST_INTERVAL_MS
Default
350
What it does
Spaces out requests, so your account isn't rate limited
SUBSTACK_MCP_HOME
Default
~/.substack-mcp
What it does
Sets where the session and the Notes queue live

Troubleshooting

Run the doctor first. It names what's wrong and the fix.

What you seeWhat to do
"Substack rejected the session"The cookie expired. Run the login again with a fresh one
Calls fail on a custom domainSet your publication to its yourname.substack.com address
A post shows HTML tags as textSomething else wrote that draft. Check it with preview_draft_body
Making a draft fails on the bylineSet SUBSTACK_USER_ID, and the doctor tells you when you need to
A scheduled Note didn't go outThe server wasn't running at that time. It posts on the next start
Tools are missing from the listSUBSTACK_READ_ONLY is on, so the writes are hidden

Scheduled Notes go out from the computer the server runs on. A Note queued for 9am only goes out if that computer is awake.

More free tools for your newsletter

Turn a post into images for social, or tag the links you share so you can check what sent readers.

Substack MCP Server FAQs

Here are the questions people ask most about the Substack MCP server and CLI.

The Substack MCP server & CLI is a free, open source program that lets an AI app like Claude, Codex or Cursor work in your Substack publication.

It has 65 tools for drafts, publishing, Notes, subscribers, analytics, tags, comments and research on other writers, and the same tools run as a CLI that agents like Claude Code and Codex use, or that you type yourself.

An MCP server is a standard way to give an AI app real access to a tool, so it can act instead of guessing.

MCP stands for Model Context Protocol, and Claude, Codex, Cursor and many other AI apps speak it.

The Substack CLI is the same program as the Substack MCP server, run as commands.

AI agents like Claude Code, Codex and OpenCode run them for you, and you can type them in a terminal or a script.

Every tool is a command with dashes, so create_draft runs as substack-cli create-draft, and one npm package installs both.

Use the Substack MCP server in an AI app with no terminal, like Claude Desktop's chat, and the CLI in a terminal, a script or a cron job.

In an AI app that can run commands, like Claude Code, Codex or Cursor, the CLI is the lighter choice, because it costs nothing until it runs.

Yes, the Substack MCP server is free and open source under the MIT license.

The only thing you pay for is your own AI app.

No, Substack has no public API and no app to register.

The Substack MCP server works through your browser's session cookie, the same way your signed-in Substack tab does.

Your Substack session cookie stays on your computer, encrypted with a key tied to your machine, and it only ever goes to Substack.

Treat it like a password, because it gives full access to your account.

The Substack MCP server publishes when you ask it to.

Publishing, deleting and posting Notes only run once your AI passes a confirm check, and read-only mode removes every write so your AI can't see them at all.

The Substack MCP server needs your publication's yourname.substack.com address, even if readers use a custom domain.

Substack doesn't answer its API on custom domains.

The Substack MCP server works with any app that speaks MCP.

That includes Claude Code, Claude Desktop, Codex, Cursor, VS Code, GitHub Copilot CLI, Gemini CLI, OpenCode, OpenClaw, Antigravity and Hermes.

Yes, the Substack MCP server takes several publications through the SUBSTACK_PUBLICATIONS setting.

Every publication tool then takes an optional publication, and the first one acts when you don't name any.

Navid Moazzez built the Substack MCP server and maintains it.

The code is on GitHub under the MIT license, and the package is on npm.

Navid Moazzez

AI business strategist & AI OS builder

Navid Moazzez helps creators and founders master AI and build their own AI Operating System (AI OS) to automate their business and life.

Navid.me is reader-supported. When you buy through links on this site, I may earn an affiliate commission. Learn more.

More MCP servers & CLIs

Free AI newsletter

The most actionable AI newsletter for founders

Every week, get proven AI strategies, curated tools, and step-by-step systems to grow your audience, create better content, and build a profitable creator business.

No fluff, no filler, no BS. Just five minutes each week that might level up your online business and life.

P.S. Sign up now to get free access to my ultimate AI tools guide for creators.

Loved by 10,000+ readers