Skip to main content
Glama
marcomoauro

Substack MCP Server

by marcomoauro

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
SUBSTACK_USER_IDYesYour Substack user ID
SUBSTACK_SESSION_TOKENYesYour Substack session token
SUBSTACK_PUBLICATION_URLYesYour Substack publication URL

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
create_draft_postC

create a draft post on your Substack account.

set_post_bodyA

replace the body of a draft with a Substack document. This is the only way to write structured content — headings, lists, links, code blocks, images, buttons and a paywall. Create the draft first with create_draft_post, then call this with its id. The result reports how many nodes of each type were stored, so a caller can confirm that what it asked for is there. An image must already be hosted by Substack: this cannot upload one.

upload_imageA

Host an image on your Substack publication and get back a Substack URL — the one thing image2.src in set_post_body and cover_image in update_draft will actually render. The source is either an http(s) URL, which the server downloads and re-hosts, or path, an absolute path to a local file on the machine running this server, which is read straight from disk: use that for an image you generated or edited locally, with no need to publish it anywhere first. Private and loopback hosts are refused, HEIC is not accepted, max 10 MB.

list_subscribersA

List and filter the subscribers of your Substack publication. Supports the same 48 columns and operators as the Subscribers dashboard, combined with AND, plus free-text search, sorting and pagination. Returns count, the total matching the filters regardless of limit, so a call with limit 1 is a cheap way to size a segment. Engagement columns (email opens, post views, comments, shares, activity rating) can be filtered on here but are not part of the records this tool returns — use export_subscribers to read their values.

export_subscribersA

Export subscribers with their full column values, including the engagement metrics list_subscribers can filter on but not return: email opens over 7d/30d/6mo, unique emails seen, post views, unique posts seen, comments, shares, links clicked, days active and activity rating. Takes the same filters as list_subscribers and covers the whole matching set — there is no paging. Substack generates the file asynchronously, so this waits for it and returns the parsed records. Two columns cannot be exported and are reported in missing_columns rather than failing: tag_ids and group_membership.

list_postsA

List the posts of your Substack publication: drafts, published posts or scheduled posts. Supports free-text search, pagination and sort direction. Each post is returned as a summary; use get_draft for the full content of an unpublished one.

get_draftA

Read one draft post of your Substack publication in full, including its body and its audience and email settings. Take the id from list_posts or create_draft_post.

update_draftA

Change an existing draft's title, subtitle or any of its Post settings: audience, who may comment, comment order, cover image, social preview title and description, SEO title and description, and URL slug. The update is partial: only the fields you pass change, everything else — including the body — is left alone. A cover_image not already hosted by Substack is downloaded and re-hosted first. Take the id from list_posts or create_draft_post.

publish_draftA

Publish a draft. The post goes live on the web; send additionally emails it to subscribers and defaults to false, because an email cannot be recalled. Publishing cannot be undone from this server — there is no unpublish tool.

delete_draftA

Delete an unpublished draft. Refuses if the id belongs to a published post: Substack deletes both through the same endpoint, and removing a live post is irreversible, so that is left to the dashboard.

get_publicationA

Read the settings and identity of your Substack publication: name, subdomain, custom domain, hero text, copyright, sender name, logo, plans and payment state. Returns a projection by default; pass full: true for all 111 fields.

get_user_profileA

Read the account behind the session: id, handle, name, bio, and every publication you have a role on. This is how to discover which publications the session can reach, beyond the one SUBSTACK_PUBLICATION_URL points at.

list_publication_tagsA

List every tag defined on your Substack publication, with its name, slug and whether it is hidden. Tag ids are UUIDs, so this is how to find one — though add_tag_to_post takes a name and does not need it.

get_post_tagsA

List the tags on one post, by name. The underlying endpoint returns only UUIDs, so this resolves them against the publication's tag list — it is the only way to read back what add_tag_to_post did, since neither get_draft nor list_posts carries tags.

add_tag_to_postA

Add a tag to a post, by tag name, creating the tag on the publication if it does not exist yet. Works on drafts as well as published posts. Reports already_tagged rather than failing when the post already carries the tag.

get_post_commentsA

Read the comments on one of your posts, each with its author, text, reaction and reply counts, and its position in the thread. Comments withheld by Substack's automod are counted separately under automod_hidden_count rather than mixed in.

comment_on_postA

Post a public comment on one of your posts, as you. This is published under your name and this server offers no way to delete it.

list_subscriptionsA

List the Substack publications this account subscribes to, with the plan, membership state and whether emails are on. Excludes paused and expired subscriptions unless asked otherwise. This is what the account reads, not who reads it — for your own subscribers use list_subscribers.

list_reader_postsA

List recent posts from the publications this account subscribes to — the reader Inbox — with read state and reading progress. Each post is summarised; use get_reader_post to read one.

get_reader_postA

Read one post in full, from any publication — not just your own. Returns the body as HTML along with its author, stats and audience. This is the only way to read the text of someone else's post.

get_reader_feedA

Read the Substack Notes feed: Notes and posts surfaced to this account. Pick the feed with tab ('for-you' or 'subscribed'), and set include_tabs to discover the ids available.

get_profile_feedA

Read what one account has published — its Notes, its posts, or both. Defaults to your own account, so this is how to list the Notes you have written; pass user_id for anyone else.

get_comment_threadA

Read one Note or comment together with the replies beneath it, each with its author and its position in the thread. Take the id from get_reader_feed or get_profile_feed.

restack_itemA

Restack a Note to your own followers. This is public, appears on your profile, and cannot be undone from here — a restack has no id of its own, so there is nothing to delete. Notes only: restacking a post is not supported, because that endpoint 404s even on a valid post id.

get_publication_statsA

Read the headline stats of your Substack publication: total and recent subscribers, ARR, site views, and the 30-day email open rate. Takes no arguments. For anything deeper — retention, churn, growth sources, referrals — use get_analytics.

get_post_statsA

Rank the posts of your Substack publication by any of 43 per-post metrics. This is how to tell which post actually grew the list (signups, subscribes, free_to_paid_upgrades), which was worth most (estimated_value), which cost you subscribers (unsubscribes), and which people read to the end (subscribers_finished_post) — alongside delivery, opens, clicks, views and restacks. Covers the whole archive with paging. There is no date filter: the endpoint ignores one, so narrow by sorting and paging instead.

get_analyticsA

Read one publication-level analytics report, covering the dashboard's Stats tabs: cohort retention, unsubscribes and their reasons, growth sources, referrals, audience overlap with other Substacks, subscriber Notes, paid growth, and timeseries for subscribers, followers and ARR. For per-post numbers use get_post_stats instead. Pick a report with report; the ones covering a period accept from_date and to_date and otherwise default to the last 30 days.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marcomoauro/substack-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server