Substack MCP Server and API by Cotlet
Server Details
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
- Status
- Healthy
- Uptime
- 100.0% over the last 24 hours
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
- Repository
- cotletdev/substack-api-mcp-server
- GitHub Stars
- 6
- Server Listing
- Substack MCP Server
- ChatGPT
- –
- Claude
- –
TDQS
Scored across 83 tools
The surface contains two parallel and heavily overlapping layers: native API tools (create_draft, publish_post, list_subscribers, get_post_stats) and substack_* tools that only return step-by-step browser instructions for the same tasks, plus a third near-equivalent path through cotlet_browser_*. Agents will struggle to decide between create_draft vs substack_create_post vs cotlet_browser_*, and finer pairs like delete_comment/remove_comment, like_post/like_comment, cotlet_browser_type/cotlet_browser_fill_form/cotlet_browser_select, and click vs press add friction. Descriptions are detailed and help, but the boundaries between the three layers are structural, not cosmetic.
Core Substack tools follow a clean verb_noun snake_case pattern (create_draft, list_posts, tag_subscribers), but the server mixes in a cotlet_ prefix with noun-first browser primitives (cotlet_browser_click, cotlet_browser_read) and a separate substack_ prefix family (substack_publish_note, substack_send_direct_message). All are snake_case and readable, but three competing conventions in one server reduce predictability.
83 tools is far beyond a well-scoped set, and a meaningful chunk is redundant: eight substack_* guide tools duplicate the native tools, and several cotlet_browser_* tools exist only to mirror each other. The breadth (full browser automation plus a full publication API) explains some size, but the count is heavy enough to inflate selection cost and misselection risk.
Coverage is strong: posts go through create/update/get/list/duplicate/publish/schedule/cancel/delete/unpublish, and subscribers, comments, Notes, messages, tags, sections, recommendations, feed, search and analytics all have read and write paths. Gaps exist but are workable: no way to edit a published post in place (must unpublish/update/republish), no post-tag or subscriber-tag deletion, no section management beyond listing, and no note deletion separate from delete_comment.
Publisher details
- Operator
- Cotlet.dev
- Operator website
- https://cotlet.dev
- Vendor relationship
- Independent
- Trust center
- https://cotlet.dev/security
- Restrictions
- Needs a Cotlet account (free trial, then credits). The user signs in to Substack once in their own Cotlet Cloud Browser; no Substack API key or paid Substack plan is needed.
Available Tools
83 toolsadd_subscriberAdd subscriberADestructiveInspect
Add one email to your list as a free subscriber. Adds one email as a free subscriber, the same as Add subscribers in the dashboard, and Substack sends its usual welcome email. Substack adds the email in the background, so list_subscribers may show it a minute later. Add only people who agreed to hear from you. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: email (required).
cancel_scheduled_postCancel scheduled postADestructiveInspect
Stop a scheduled post from going out; it stays as a draft. Removes the scheduled time from a post, so nothing is published or emailed then; the post stays a draft with its content. Schedule it again with schedule_post. A post with no schedule returns an error.
Inputs: post_id (required).
cotlet_app_guideCotlet: how to work in an appARead-onlyIdempotentInspect
How to work in an app by clicking in the user's Cloud Browser with Cotlet's browser tools: which browser to use for this workspace and the sign-in link, the method step by step, the app's screens, menus and actions, notes, and the app's dedicated tools when Cotlet has them. Call it before the first browser step in an app. Works for any web app; one outside Cotlet's catalog gets the general method. Free, no browser session. For Substack it covers these actions: Create post, Schedule post, Publish Note, Reply to Notes, Send direct message, Moderate comments, List subscribers, Get post stats.
Inputs: app, task.
cotlet_appsCotlet: apps I can useBRead-onlyInspect
The apps of the user's workspace and whether each works now: the app account in the user's Cloud Browser (connected, signed out, signed in but not connected), and the one step the user has to take, with the console link. Free. Needs the user's Cotlet API key or sign-in.
Inputs: app.
cotlet_browser_clickClick on the pageADestructiveInspect
Clicks element element, or point x, y of the screenshot; double double-clicks, button: right right-clicks. Answers the page after it: the elements and text in view, with the same numbers. Says when nothing changed. A link that would open a new tab opens in this one. Buttons that pay or buy, and sign-in and account pages, are refused.
Inputs: x, y, button, dialog, +3 more.
cotlet_browser_closeClose the browserAIdempotentInspect
Ends the browser session when the task is done: the browser keeps its cookies and sleeps, and the per-minute charge stops. Answers the session's minutes and credits.
Inputs: no named parameters.
cotlet_browser_downloadDownload a fileADestructiveInspect
Gets the file that clicking element (a download link or button) or opening url starts, also an image or PDF it only opens: answers its name, type, size and a link valid 15 minutes; CSV, JSON and other text files also as text.
Inputs: url, element.
cotlet_browser_dragDrag on the pageADestructiveInspect
Drags from one element or point to another: a card between columns, a piece on a board, a slider's handle. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: to (required), from (required), dialog, dialog_text.
cotlet_browser_evaluateRun a script on the pageADestructiveInspect
Runs a JavaScript function body on the page and answers what it returns, as JSON. Use it to extract data the page holds (a table, a list, attributes); act with the other tools. It cannot send requests, click, submit, or read cookies or storage; a filled field's value reads [hidden by Cotlet]. Example: return [...document.querySelectorAll('h2')].map(h => h.innerText)
Inputs: script (required).
cotlet_browser_fill_formFill in a formADestructiveInspect
Fills several fields in one step: text fields take text, drop-downs an option's label, checkboxes, radios and switches true or false. Stops at the first field that fails and names those filled. Does not send the form: click its button after. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: fields (required), dialog, dialog_text.
cotlet_browser_findFind on the pageARead-onlyIdempotentInspect
Finds text on the whole current page, frames included: the elements whose label holds it, with their numbers, and each line of text that holds it. Use it instead of reading or scrolling a long page for one thing.
Inputs: text (required), kind.
cotlet_browser_hoverPoint at the pageARead-onlyIdempotentInspect
Rests the pointer on an element or a point, to open a hover menu, a tooltip or a preview. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: x, y, element.
cotlet_browser_openOpen the browserARead-onlyInspect
Starts the user's Substack Cloud Browser (a real Chrome on Cotlet, signed in to Substack as the user; use it for what the Substack tools do not cover) and opens url. Call it first. Only Substack pages open. Answers the page after it: the elements and text in view, with the same numbers. In Substack it serves these actions: Create post, Schedule post, Publish Note, Reply to Notes, Send direct message, Moderate comments, List subscribers, Get post stats.
Inputs: url.
cotlet_browser_pressPress a keyADestructiveInspect
Presses a key on the focused element: Enter to send, Tab to the next field, Escape to close a pop-up, arrows in a list or slider, or one character (a site's shortcut). Answers the page after it: the elements and text in view, with the same numbers.
Inputs: key (required), dialog, repeat, dialog_text.
cotlet_browser_readRead the pageARead-onlyIdempotentInspect
The whole current page: its text (up to 20,000 characters) and a numbered list of its links, buttons, fields and other controls, open dialogs first. Use it on a new page or when a step's answer is not enough; element reads only inside one element (a dialog, a form, a list). Never returns field values, cookies or storage.
Inputs: element.
cotlet_browser_screenshotSee the pageARead-onlyIdempotentInspect
A JPEG of the visible part of the page. Use it for boards, canvases, maps, charts and layout that the text does not show, then click or drag by x, y of the image.
Inputs: no named parameters.
cotlet_browser_scrollScroll the pageARead-onlyIdempotentInspect
Scrolls with the mouse wheel: down or up by screens, to top or bottom, until element is in view, or inside a panel or list (inside). Content that loads on scroll appears. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: inside, element, screens, direction.
cotlet_browser_selectChoose from a listADestructiveInspect
Chooses option (its label as listed, or its value) in drop-down element. For a home-made drop-down, click it, then click the option. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: option (required), element (required), dialog, dialog_text.
cotlet_browser_typeType on the pageADestructiveInspect
Types text into field element, replacing what it held; submit presses Enter after it. For several fields use fill_form. Without element the text goes where the focus is, as a person types after clicking: for spreadsheet cells and editors that read does not number (Google Sheets, Docs), click the place first; there a tab in text presses Tab and a line break Enter, so one call fills a table. Answers the page after it: the elements and text in view, with the same numbers. Password, card and one-time code fields are refused: the user types them.
Inputs: text (required), dialog, slowly, submit, +2 more.
cotlet_browser_uploadUpload a fileADestructiveInspect
Puts files into file field or upload button element: each file is {"url": "https://..."} or {"file_id": "..."} of a file uploaded to Cotlet; up to 10 files, 20 MB each. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: files (required), element (required).
cotlet_browser_waitWait for the pageARead-onlyIdempotentInspect
Waits until text shows on the page (at most seconds, default 5, up to 20), or just seconds: for results that load slowly. Says whether the text appeared. Answers the page after it: the elements and text in view, with the same numbers.
Inputs: text, seconds.
cotlet_get_callCotlet: check a callARead-onlyInspect
Status of an earlier Cotlet call, by its call_id: pending (waits for the owner's approval in the Cotlet console), approved, running, success, rejected, expired, blocked or failed. For a call that answered with status pending or running.
Inputs: call_id (required).
cotlet_report_issueCotlet: report a bug or a missing featureAInspect
Sends a report to the Cotlet team: a tool that failed or returned wrong data, an error you could not get past, or a step the browser could not do, with the page, the step and what you saw. A missing dedicated tool is not a problem to report: do the task in the browser. A feature the user asks for goes as feature_request. A report promises nothing: tell the user it was sent, never that something will be built or fixed, or when. The report carries the error text and call_id when there is one, never passwords or tokens. Needs the user's Cotlet API key or sign-in.
Inputs: kind (required), title (required), description (required), app, +3 more.
cotlet_request_appsCotlet: request access to appsAInspect
Requests access to apps for the user's workspace, as Request access in the console: every app is granted at once. Not needed to work in an app: the user's AI works in any web app in their Web browser with cotlet_app_guide. An app with dedicated tools gets them after the user signs in to it in their Cloud Browser. Access says nothing about whether a task works there: check that in the browser. Takes app slugs as listed at https://cotlet.dev/api/v1/apps. Free. Needs the user's Cotlet API key or sign-in.
Inputs: apps (required), use_case.
cotlet_upload_fileCotlet: upload a file for a toolAInspect
Returns a one-time upload_url and a file_id for a local file (an image for a post, an attachment). The file is sent to upload_url with an HTTP PUT; an argument that takes a file accepts {"file_id": "..."}. Up to 25 MB, the URL works once. Free. Needs the user's Cotlet API key or sign-in.
Inputs: name, content_type.
cotlet_whoamiCotlet: who am IARead-onlyInspect
The Cotlet account this connection acts as: email, workspace, access status, the API key or OAuth client in use with its scope, the apps the workspace may call and its credit balance. Free. Needs the user's Cotlet API key or sign-in.
Inputs: no named parameters.
create_draftCreate draftADestructiveInspect
New draft from Markdown. Nothing is sent until you publish or schedule it. Creates a draft in your publication and returns its post_id and editor link. Markdown covers headings, paragraphs, bullet and numbered lists, quotes, code blocks, rules, images by public URL, bold, italic, strikethrough, inline code and links; local image files cannot be used. Sending is a separate step: schedule_post or publish_post. A draft reaches no one, so it runs without asking.
Inputs: title (required), body_markdown (required), audience, subtitle.
create_post_tagCreate post tagADestructiveInspect
New tag for grouping your posts. Creates a post tag on your publication; Substack makes the slug from the name. A tag with no posts shows nowhere. Put posts under it with tag_post.
Inputs: name (required).
create_subscriber_tagCreate subscriber tagADestructiveInspect
New private tag for grouping subscribers. Creates a subscriber tag on your publication. Tags are private: subscribers never see them. Put subscribers under it with tag_subscribers.
Inputs: name (required).
delete_commentDelete comment or NoteADestructiveInspect
Delete one of your own comments, Notes or Note replies. Deletes something you wrote: a comment under a post, a Note or a reply to a Note. Replies other people wrote under it stay, under a deleted placeholder. Someone else's comment returns an error; on your own posts remove it with remove_comment. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: comment_id (required).
delete_postDelete postADestructiveInspect
Delete a draft, scheduled or published post, with its comments. Deletes one post of your publication for good: a draft, a scheduled post (its send is cancelled) or a published post, which leaves the web, the archive and the app with its comments and stats. Emails already sent stay in inboxes. Substack has no undo; unpublish_post keeps the post as a draft instead. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: post_id (required).
duplicate_postDuplicate postADestructiveInspect
Copy any post into a new draft. Makes a new draft with the title, subtitle, body and settings of a draft or published post, as Duplicate in the post list does. Substack puts [COPY] in front of the title; change it with update_draft. Nothing is published or sent.
Inputs: post_id (required).
export_subscribersExport subscribersARead-onlyIdempotentInspect
The full subscriber list as a CSV download link, with the row count. Builds the same CSV as Export in the subscriber dashboard: email, name, subscription type, activity rating and start date. Substack builds the file in the background; the call waits up to about a minute and otherwise asks you to try again later. The link needs no sign-in and works until expires_at, 24 hours when we recorded it. For filtered pages use list_subscribers.
Inputs: no named parameters.
follow_userFollow userADestructiveInspect
Follow or unfollow a Substack user, so their Notes reach your feed. Follows a person on Substack, as Follow on their profile does, or unfollows them. Following is not subscribing: you get their Notes and activity in the app, not their newsletter by email. They see the follow.
Inputs: user (required), unfollow.
get_audience_insightsGet audience insightsARead-onlyIdempotentInspect
Where your subscribers live, and which publications share your readers. Returns Analytics > Statistics > Audience: subscriber counts per country (region world, ISO codes such as us, gb) or per US state (region usa, codes such as ny, ca), all subscribers or paid only, the number of countries and states with any subscriber, and the publications whose readers overlap most with yours. Substack computes these in the background; a new publication has empty lists for a while.
Inputs: region, paid_only.
get_conversationGet conversationARead-onlyIdempotentInspect
The latest messages of one direct-message conversation, oldest first. Returns who is in the conversation and its latest messages as the chat window first shows them, oldest first, with sender, text and time. Opening a conversation this way marks nothing read.
Inputs: conversation_id (required).
get_daily_statsGet daily statsARead-onlyIdempotentInspect
Day by day: total and paid subscribers, followers and views. Returns one row per day of the period, as the charts on the dashboard home and in Audience: total subscribers, paid subscribers and followers at the end of the day, and the day's views across your site and the app. Days Substack has no number for are null; a young publication starts on the day it was made.
Inputs: period.
get_feedGet feedARead-onlyIdempotentInspect
Your Substack home feed: posts and Notes, For you or Following. Returns one page of the home feed of the Substack app, split into posts and Notes in feed order. for_you is Substack's own mix; following holds only people and publications you follow or subscribe to. Suggestions of people to follow are left out. Reading marks nothing seen. Page with next_cursor; the feed is personal and changes between calls.
Inputs: tab, cursor.
get_postGet postARead-onlyIdempotentInspect
Full post: title, subtitle, body as Markdown, audience, URL and dates. Returns one post of your publication, draft, scheduled or published, with its full body as Markdown, including the paywalled part. Images come back as URLs. Buttons, embeds and footnotes come back as plain text, so writing the body back with update_draft drops them. A scheduled post also has publish_at.
Inputs: post_id (required).
get_post_engagementGet post engagementARead-onlyIdempotentInspect
Who liked and commented on a post, and the subscribers it won and lost. Returns the Engagement and Growth parts of a post's stats: like and comment counts with the people behind them (name and handle, never email), and the free signups, paid subscriptions and unsubscribes Substack credits to the post. Counts keep changing for days after a send.
Inputs: post_id (required).
get_post_statsGet post statsARead-onlyIdempotentInspect
Recipients, opens, open rate, views, likes, restacks and subscribers gained. Returns the engagement numbers of one published post, as on its stats page in the dashboard. Email numbers cover the send; views include the web; likes are reactions. A draft or scheduled post returns an error. Numbers keep growing for days after a send, so check again later.
Inputs: post_id (required).
get_post_trafficGet post trafficARead-onlyIdempotentInspect
Where a post's readers came from: sources, categories and devices. Returns the Traffic part of a post's stats: each source (app, email, a website, search) with its views, share of all views and the free and paid subscribers it brought, the share per source category and per device. A post nobody has read yet returns empty lists.
Inputs: post_id (required).
get_publication_statsGet publication statsARead-onlyIdempotentInspect
Total and paid subscribers, new subscribers, paid cancellations and estimated revenue for a period. Totals are from the publisher dashboard at the end of the period (7, 30 or 90 days). subscribers_churned counts paid cancellations only; Substack keeps no count of free unsubscribes. subscribers_new is the growth in total subscribers plus those cancellations. revenue_usd is not money received: it is the dashboard's annualized revenue at the end of the period, times the period's share of a year.
Inputs: period.
get_unread_countsGet unread countsARead-onlyIdempotentInspect
How many unread direct messages, message requests and activity notifications you have. Returns the badges of the Substack app: unread direct messages, pending message requests and unread activity (likes, replies, new followers, restacks). Reading them marks nothing read.
Inputs: no named parameters.
like_commentLike comment or NoteADestructiveInspect
Like or unlike a comment or a Note as you. Adds your heart to any Note or Note reply, or to a comment under a post of your publication, or removes it with unlike. Comments and Notes share one ID space, so a Note ID from list_notes or search_substack works too. The author sees your like in their activity.
Inputs: comment_id (required), unlike.
like_postLike postBDestructiveInspect
Like or unlike any Substack post as you. Adds your heart to a post on any publication, as the heart under a post does, or removes it with unlike. The author sees your like in their activity. Liking twice keeps one like.
Inputs: post_id (required), unlike.
list_activityList activityARead-onlyIdempotentInspect
Your Substack notifications: replies, likes, new followers, restacks, newest first. Returns the Activity tab of the Substack app, newest first. type is Substack's own name, e.g. note_reply, note_like, comment_reply, comment_like, post_like, follow, restack or mention. from lists the latest people behind a grouped item and people counts all of them. A reply or mention carries its comment_id and text; on_comment_id and on_post_id point at what it was about. Reading the list marks nothing read. Page with next_cursor.
Inputs: cursor, filter.
list_commentsList commentsARead-onlyIdempotentInspect
Comments on a post, with author, text and whether you replied. Returns all comments of one post at once, oldest first, with replies nested under their parent. Deleted comments are left out. replied is true when you answered anywhere in the thread under the comment; unanswered_only keeps only top-level comments where you did not. Pass comment_id to reply_to_comment.
Inputs: post_id (required), unanswered_only.
list_conversationsList conversationsARead-onlyIdempotentInspect
Your direct-message conversations, latest first, with the last message. Returns your Substack chat inbox: one-to-one and group direct messages with who they are with, the last message, its time, your unread count and whether it is a message request from someone you do not follow. Publication chats are left out. Reading the list does not mark anything read. Pass conversation_id to get_conversation or send_message.
Inputs: cursor, unread_only.
list_note_repliesList Note repliesARead-onlyIdempotentInspect
Replies under a Note, with author, text and likes. Returns the direct replies under one Note (yours or anyone's), in Substack's order. replies is the count under each reply; list those by passing its note_id. Substack sends no handle with replies, so author.handle is empty and url is null. Page with next_cursor.
Inputs: note_id (required), cursor.
list_notesList NotesARead-onlyIdempotentInspect
Notes posted by you or any other Substack user, newest first, with likes and replies. Returns the Notes on a profile's Notes tab, newest first: text, time, likes, restacks, reply count and link. Without user it lists yours. Posts and restacks of posts on the profile are left out. Page with next_cursor. Pass note_id to list_note_replies, like_comment or reply_to_note.
Inputs: user, cursor.
list_postsList postsARead-onlyIdempotentInspect
Posts of your publication, newest first, with status and audience. Lists posts of your publication, newest first. Filter by status to see drafts or scheduled posts. Scheduled posts include their publish time. Pages hold up to 50 posts; pass next_cursor back as cursor for the next page.
Inputs: limit, cursor, status.
list_post_tagsList post tagsARead-onlyIdempotentInspect
Tags your publication uses to group posts. Returns every post tag of your publication with its ID, name and slug; readers see tagged posts on /t/{slug}. hidden tags group posts without a public page. Pass tag_id to tag_post.
Inputs: no named parameters.
list_recommendationsList recommendationsARead-onlyIdempotentInspect
Publications you recommend, or that recommend you, with the subscribers each sent. Returns Audience > Recommendations: with direction given, the publications you recommend; with received, the ones recommending you, and whether you recommend them back (mutual). subscribers_sent counts subscribers the recommendation brought. The table is rebuilt by Substack in the background, so a recommendation made minutes ago may be missing while counts already include it; publication_id checks one recommendation of yours directly.
Inputs: direction, publication_id.
list_sectionsList sectionsARead-onlyIdempotentInspect
Sections of your publication, the separate newsletters inside it. Returns each section with its ID, name, description and slug. live is false while Substack still sets a new section up. subscribed_by_default tells whether new subscribers get its emails. A publication without sections returns an empty list.
Inputs: no named parameters.
list_subscribersList subscribersARead-onlyIdempotentInspect
Subscribers with plan, start date and activity rating. Lists subscribers, newest first, from the subscriber dashboard. Activity rating is the 0 to 5 score Substack shows there. Pages hold up to 500 rows; pass next_cursor back as cursor. The plan and since filters apply inside each page, so a filtered page can be short or empty while next_cursor still points further. Someone added a minute ago may not show yet: Substack fills the table in the background. paid includes founding members.
Inputs: plan, limit, since, cursor.
list_subscriber_tagsList subscriber tagsARead-onlyIdempotentInspect
Tags you use to group subscribers. Returns the subscriber tags of your publication with their IDs, as Audience > Subscribers > Tags shows them. Subscribers never see tags. Pass tag_id to tag_subscribers.
Inputs: no named parameters.
list_subscriptionsList subscriptionsARead-onlyIdempotentInspect
Publications you subscribe to, with your plan and whether their emails reach you. Returns every publication your account subscribes to, as Settings > Subscriptions lists them: name, link, plan (free, paid, comp, founding or gift, as Substack names the membership) and whether you get its emails. Your own publications are left out.
Inputs: no named parameters.
list_traffic_sourcesList traffic sourcesARead-onlyIdempotentInspect
Where your publication's visitors came from in a period, most views first. Returns Analytics > Traffic > Traffic sources: each source (the app, email, a website, search, social) with its category, views, unique visitors and the free and paid subscribers it brought. Sorted by views; page with next_cursor.
Inputs: limit, cursor, period.
pin_commentPin commentADestructiveInspect
Pin a comment to the top of your post's comments, or unpin it. Pins one comment on a post of your publication above all others, as Pin in the comment menu does, or unpins it. A comment on someone else's post returns an error.
Inputs: comment_id (required), unpin.
publish_notePublish NoteADestructiveInspect
Short post in Substack Notes, now or at a set time, optionally with a link card to one of your posts. Posts a Note under your name. Without publish_at it goes out now; with it, the Note waits in your scheduled Notes, status is scheduled and published_at is that time. Text is 1 to 1,000 characters. link_post_id must be a published post. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: body (required), publish_at, link_post_id.
publish_postPublish postADestructiveInspect
Publish a draft now. Publishes a draft immediately, on the web and, unless send_email is false, by email, to the audience set on the draft. Substack's own pre-publish check runs first; a missing title or an empty body stops the call. A sent email cannot be recalled. On a publication with sections the post goes to section_id, else to the section already set on the draft, else to the main publication. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: post_id (required), section_id, send_email.
recommend_publicationRecommend publicationADestructiveInspect
Recommend another publication to your readers, or stop recommending it. Adds a publication to your Recommendations, as Growth > Recommendations does: Substack suggests it to people who subscribe to you and notifies its author. blurb is the short reason readers see. With remove it takes the recommendation back. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: publication_id (required), blurb, remove.
remove_commentRemove commentADestructiveInspect
Remove someone's comment from your post as the publication's moderator. Hides a comment on a post of your publication, as Remove in the comment menu does: readers see that a moderator removed it, the text is gone, replies under it stay. Use delete_comment for your own comments. A comment on someone else's post returns an error. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: comment_id (required).
remove_subscriberRemove subscriberADestructiveInspect
Remove one email from your subscriber list. Removes a subscriber from your list, as Remove in the subscriber's menu does: they get no more emails from you and no notice. A paid subscription is cancelled and Substack refunds the unused part. An email not on your list returns an error; add_subscriber takes about a minute before the address is listed. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: email (required).
reply_to_commentReply to commentADestructiveInspect
Reply as you under a comment on your post. Posts a reply under one comment on a post of your publication, under your name, visible to everyone who can read the post. A comment elsewhere on Substack returns an error. The author gets Substack's usual reply notification. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: body (required), comment_id (required).
reply_to_noteReply to NoteADestructiveInspect
Reply as you under any Note or Note reply. Posts a reply under a Note (yours or anyone's) or under a reply to one, visible to everyone who sees the Note. Text is 1 to 1,000 characters; Markdown bold, italics and links work. The author gets Substack's usual notification. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: body (required), note_id (required).
schedule_postSchedule postADestructiveInspect
Publish a draft at a set time, on the web and by email. Schedules a draft to go live at the time you set, on the web and, unless send_email is false, by email, to the audience set on the draft. The time needs a time zone and must be in the future. Substack's own pre-publish check runs first; a missing title or an empty body stops the call. A scheduled post stays editable until it goes out. On a publication with sections the post goes to section_id, else to the section already set on the draft, else to the main publication. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: post_id (required), publish_at (required), section_id, send_email.
search_substackSearch SubstackARead-onlyIdempotentInspect
Search all of Substack for people, posts and Notes. Runs Substack's search as the search box does and splits the results into people, posts and Notes. Use the IDs with follow_user, like_post, like_comment, reply_to_note, send_message or recommend_publication. Page with next_cursor; later pages may hold only posts and Notes.
Inputs: query (required), cursor.
send_messageSend messageADestructiveInspect
Send a direct message on Substack, in a conversation or to a person. Sends a private chat message under your name. With conversation_id it replies there; with user it writes to that person, in your existing conversation with them or a new one. Someone who does not follow you gets it as a message request. Give one of conversation_id or user. A sent message cannot be recalled. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: body (required), user, conversation_id.
substack_create_postCreate post in SubstackBRead-onlyIdempotentInspect
Create post in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_get_post_statsGet post stats in SubstackBRead-onlyIdempotentInspect
Get post stats in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_list_subscribersList subscribers in SubstackBRead-onlyIdempotentInspect
List subscribers in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_moderate_commentsModerate comments in SubstackARead-onlyIdempotentInspect
Moderate comments in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_publish_notePublish Note in SubstackARead-onlyIdempotentInspect
Publish Note in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_reply_to_notesReply to Notes in SubstackARead-onlyIdempotentInspect
Reply to Notes in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_schedule_postSchedule post in SubstackARead-onlyIdempotentInspect
Schedule post in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
substack_send_direct_messageSend direct message in SubstackARead-onlyIdempotentInspect
Send direct message in the user's own Substack account from ChatGPT, Claude or any AI agent. Returns how to do it in Substack step by step (screens, buttons, fields) and opens nothing by itself; then do it with the cotlet_browser_* tools in the user's Substack Cloud Browser. Substack's official API: Substack has only a limited API (checked 11 Oct 2026).
Inputs: no named parameters.
tag_postTag postADestructiveInspect
Add a tag to a post, or take it off. Puts one of your post tags on a draft or published post, or removes it with remove. A post can have several tags. Tagging twice keeps one tag.
Inputs: tag_id (required), post_id (required), remove.
tag_subscribersTag subscribersADestructiveInspect
Put a tag on subscribers by email, or take it off. Adds one of your subscriber tags to up to 50 subscribers, or removes it with remove. Emails not on your list come back in not_found and nothing else fails. A subscriber added a minute ago may not be findable yet; try again shortly.
Inputs: emails (required), tag_id (required), remove.
unpublish_postUnpublish postADestructiveInspect
Take a published post off the web and back to drafts. Turns a published post back into a draft, as Unpublish in the editor does: it leaves your site, archive and the Substack app, and its link stops working. Comments and stats stay with the draft. Emails already sent stay in inboxes. Publish it again with publish_post. A post that is not published returns an error. By default you confirm each call; you can switch that off for this tool. Waits for the owner's approval.
Inputs: post_id (required).
update_draftUpdate draftADestructiveInspect
Change the title, subtitle, body or audience of a draft. Changes the fields you pass and leaves the others as they are. body_markdown replaces the whole body. Drafts and scheduled posts only: a published post returns an error. Nothing reaches your subscribers, so it runs without asking.
Inputs: fields (required), post_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
Related MCP Connectors
Medium MCP server for ChatGPT, Claude and any AI agent: create post, edit post, cross-post article and get post stats in your own Medium account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Medium yourself; Cotlet does not store your password and you need no Medium API key. About the official Medium API: Medium has an old REST API, but it is no longer supported and Medium does not allow new integrations (checked 11 Oct 2026). Accounts that still hold a token can only create posts, list publications and upload images, with no editing, stats or responses. Setup and FAQ: https://cotlet.dev/integrations/medium-api-mcp-server
Ghost MCP server for ChatGPT, Claude and any AI agent: list posts, create draft post, schedule post, send newsletter, list members and label members in your own Ghost account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Ghost yourself; Cotlet does not store your password and you need no Ghost API key. About the official Ghost API: Ghost has a full REST Admin API, but no official MCP server (checked 17 Oct 2026). The Admin API covers posts, pages, members, labels, newsletters, tiers and offers, and Ghost says everything Ghost Admin can do is also possible with the API. Setup and FAQ: https://cotlet.dev/integrations/ghost-api-mcp-server
Patreon MCP server for ChatGPT, Claude and any AI agent: create post, send message to patron, list members, update tier, schedule post and export earnings in your own Patreon account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Patreon yourself; Cotlet does not store your password and you need no Patreon API key. About the official Patreon API: Patreon has a public API v2, but it reads campaigns, members and posts and cannot create posts, message members or edit tiers (checked 11 Oct 2026). Its only write endpoints are for livestreams and webhooks. Setup and FAQ: https://cotlet.dev/integrations/patreon-api-mcp-server
Sprout Social MCP server for ChatGPT, Claude and any AI agent: schedule post, reply to message, tag message, assign case, get post performance and list queued posts in your own Sprout Social account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Sprout Social yourself; Cotlet does not store your password and you need no Sprout Social API key. About the official Sprout Social API: Sprout Social has a REST API, but only on the Advanced plan and above, and it reads more than it writes (checked 17 Oct 2026). It returns analytics, Smart Inbox messages, listening data and cases, and it creates posts as drafts only. Setup and FAQ: https://cotlet.dev/integrations/sprout-social-api-mcp-server
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables programmatic management of Substack content, including creating drafts, publishing posts, and uploading images. It supports specialized features like live blogging and posting to Substack Notes through MCP-compatible AI tools.MIT
- AlicenseNot gradedqualityDmaintenanceCreate, manage, and publish Substack posts with full rich text formatting directly from Claude Desktop or any MCP-compatible client.71 npm26MIT
- AlicenseAqualityCmaintenanceMCP server for Substack that lets Claude Code create drafts, upload images, set cover thumbnails, schedule, and publish posts on your Substack publication.1116MIT
- AlicenseNot gradedqualityDmaintenanceEnables managing Substack publications: publish Notes and posts, manage drafts, pull analytics, and read any publication's public feed via MCP.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.