substack-mcp
Syncs recent posts from Substack publications, caches metadata and markdown locally, and provides tools for listing, fetching post chunks, and marking posts as summarized for daily summary generation. Supports paid subscriptions the user has access to.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@substack-mcp fetch recent Substack posts and list unsummarized ones"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-substack
Local MCP server for giving Copilot access to Substack posts that your own reader account is allowed to view, including paid posts from your subscriptions.
The main workflow is daily summary generation:
Sync recent posts from priority Substack publications.
Cache metadata and markdown locally.
Let Copilot list unsummarized posts.
Let Copilot fetch long posts in chunks.
Mark summarized posts so they do not repeat tomorrow.
Safety Boundary
This server uses only your own authenticated Substack session.
It does not:
read your normal Chrome profile
read Chrome Keychain-backed cookie storage
store your Substack password
bypass paywalls
share paid content outside your machine
Authentication is handled through a dedicated Playwright browser profile:
~/Library/Application Support/mcp-substack/browser-profile/Cached article data is stored locally:
~/Library/Application Support/mcp-substack/substack.dbLocal config is stored at:
~/Library/Application Support/mcp-substack/config.jsonRelated MCP server: Substack MCP
Requirements
macOS
Node.js 26 or newer recommended, because this project uses Node's built-in
node:sqlitenpm
Install
cd ~/path/to/substack-mcp
npm install
npx playwright install chromium
npm run buildFirst Login
Open the dedicated Substack browser profile and log in once:
npm run spike -- login 300If you are already logged in, the browser may open briefly and close.
Check login status:
npm run spike -- statusExpected result:
{
"loggedIn": true
}Priority Publications
You can optionally configure a small set of priority publications for daily summary runs. This is useful when you subscribe to many publications but only want a subset in the default summary.
Set or reset priority publications with your own publication URLs:
npm run spike -- config-priority \
https://example-newsletter.substack.com \
https://example.comShow current config:
npm run spike -- config-showLocal Sync Commands
Sync only priority publications:
npm run spike -- sync-priority 3 5This means:
last 3 days
up to 5 recent posts per priority publication
fetch full article bodies into the local cache
List cached unsummarized posts:
npm run spike -- cache-list 20Useful diagnostics:
npm run spike -- discover
npm run spike -- list-posts https://example-newsletter.substack.com 5MCP Server
Build and run the MCP server over stdio:
npm run build
npm startExample MCP client config:
{
"servers": {
"substack": {
"command": "node",
"args": [
"/absolute/path/to/substack-mcp/dist/server.js"
]
}
}
}Daily Copilot Workflow
Recommended tool sequence:
substack_sync_recent{ "days": 3, "limitPerPublication": 5, "priorityOnly": true, "fetchContent": true }substack_list_posts{ "summarized": false, "limit": 20 }For each post to summarize, call
substack_get_post_chunks.{ "postKeyOrUrl": "<postKey from substack_list_posts>", "maxChars": 8000 }After generating the daily summary, call
substack_mark_summarized.{ "postKeyOrUrls": ["<postKey>", "<postKey>"], "summaryDate": "2026-06-30" }
MCP Tools
substack_loginOpens the dedicated browser profile and waits for Substack login.
substack_sync_statusShows app paths, config, and login status.
substack_config_showShows local config.
substack_config_set_priority_publicationsSets priority publication URLs.
substack_config_set_defaultsSets default sync window and per-publication limit.
substack_discover_subscriptionsDiscovers publications from the authenticated reader account.
substack_sync_recentSyncs recent posts into SQLite.
substack_list_postsLists cached post metadata. This does not return full bodies.
substack_get_cached_postReturns one cached post with markdown.
substack_get_post_chunksReturns one cached post split into bounded markdown chunks.
substack_mark_summarizedMarks posts as included in a daily summary.
substack_list_recent_postsDiagnostic tool for listing recent posts from one publication.
substack_get_postDiagnostic tool for live-fetching one post as markdown.
Verification Status
Current verified behavior:
dedicated browser profile login works
subscription discovery works
paid full text works for authorized subscriptions
priority-only sync works
SQLite cache stores metadata and markdown
chunking works for long articles
npm run typecheckpassesnpm run buildpasses
Troubleshooting
Browser Opens and Closes Quickly
This usually means the dedicated profile is already logged in and the login check succeeded.
Run:
npm run spike -- statusPlaywright Browser Missing
Run:
npx playwright install chromiumSubstack Returns 429
Substack may rate-limit repeated sync attempts. Wait a few minutes and retry with a smaller window:
npm run spike -- sync-priority 3 2Paid Post Shows Preview Only
Check that the dedicated profile is logged into the account with the paid subscription:
npm run spike -- statusThen test the publication directly:
npm run spike -- list-posts https://example-newsletter.substack.com 5Reset Local State
The local data lives outside the repository:
~/Library/Application Support/mcp-substack/Remove only the files you intend to reset. Deleting browser-profile/ requires
logging into Substack again. Deleting substack.db removes cached articles and
summary state.
Available Tools
13 toolssubstack_config_set_defaultsSet Substack Sync DefaultsC
Set default sync window and per-publication post limit.
Inputs: defaultSyncDays (required), defaultLimitPerPublication (required), defaultFetchContent.
substack_config_set_priority_publicationsSet Priority Substack PublicationsB
Set publication URLs that should be synced first or exclusively for daily summaries.
Inputs: publicationUrls (required).
substack_config_showShow Substack MCP ConfigB
Show local mcp-substack configuration.
Inputs: no named parameters.
substack_discover_subscriptionsDiscover Substack SubscriptionsB
Use the authenticated dedicated browser profile to discover subscribed publications.
Inputs: no named parameters.
substack_get_cached_postGet Cached Substack PostC
Return one cached post with markdown content.
Inputs: postKeyOrUrl (required).
substack_get_postGet Substack PostB
Fetch one Substack post through the authenticated browser profile and return markdown.
Inputs: url (required).
substack_get_post_chunksGet Cached Substack Post ChunksC
Return bounded markdown chunks for one cached post.
Inputs: postKeyOrUrl (required), maxChars.
substack_list_postsList Cached Substack PostsB
List cached posts, optionally filtered to unsummarized posts and a date range.
Inputs: limit, since, until, summarized.
substack_list_recent_postsList Recent Substack PostsB
List recent posts for a publication URL. This is the spike path before cache-backed sync.
Inputs: publication (required), limit.
substack_loginSubstack LoginB
Open a dedicated local browser profile and wait for the user to log into Substack.
Inputs: timeoutSeconds.
substack_mark_summarizedMark Substack Posts SummarizedC
Mark cached posts as included in a daily summary.
Inputs: postKeyOrUrls (required), summaryDate.
substack_sync_recentSync Recent Substack PostsC
Discover subscriptions, sync recent posts, fetch bodies, and save them in the local cache.
Inputs: days, fetchContent, priorityOnly, maxPublications, +3 more.
substack_sync_statusSubstack Sync StatusA
Check the dedicated Substack browser profile path and current login status.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 13 tools
All tools have clearly distinct purposes. Even the post retrieval tools (get_cached_post, get_post, get_post_chunks) are well-separated by cache vs live vs chunked output. No overlapping functionality.
All tools follow a consistent verb_noun pattern with the 'substack_' prefix. Verbs are imperative and clear (set, show, discover, get, list, login, mark, sync), and nouns are specific and descriptive.
13 tools cover the core domain of Substack configuration, authentication, subscription discovery, post retrieval, listing, syncing, and summarization. The count is well-scoped without being overwhelming or sparse.
The tool set covers the primary workflows for syncing and summarizing Substack content. Minor gaps exist, such as no tools for individual subscription management (unsubscribe) or content deletion, but the core operations are fully supported.
Maintenance
Related MCP Connectors
Substack MCP server for ChatGPT, Claude and any AI agent: create post, schedule post, publish Note, reply to Notes, send direct message, moderate comments, list subscribers and get post stats in your own Substack account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Substack yourself; Cotlet does not store your password and you need no Substack API key. About the official Substack API: Substack has only a limited API (checked 11 Oct 2026). Its Developer API looks up public creator profiles after approval, and there is no public API to write posts or Notes, manage subscribers or send email. Setup and FAQ: https://cotlet.dev/integrations/substack-api-mcp-server
Hosted X (Twitter) MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Related MCP Servers
- FlicenseBqualityDmaintenanceA Model Context Protocol server that enables downloading and parsing Substack posts directly through the Claude desktop app, allowing users to access and summarize Substack content.124-
- AlicenseNot gradedqualityNot gradedmaintenanceAn MCP server that enables AI assistants like Claude to interact with Substack newsletters, allowing for post retrieval, content searching, and author information access through a standardized interface.MIT
- AlicenseAqualityCmaintenanceMCP server for Substack that lets Claude Code create drafts, upload images, set cover thumbnails, schedule, and publish posts on your Substack publication.1116MIT
- AlicenseAqualityBmaintenanceMCP server for Substack's official Publisher API that enables querying post analytics, subscriber counts, and publication data through natural language from MCP clients.76MIT