substack-mcp
Allows creating, editing, scheduling, and publishing drafts on a Substack publication, including uploading images and setting cover thumbnails.
Click on "Install 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-mcpcreate a draft called 'My First Post' and schedule it for tomorrow"
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.
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. 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_emailtoggles 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 (fromupload_imageURL).
Utility
list_drafts(limit?)— List recent drafts.get_draft(post_id)— Get a draft's full body.delete_draft(post_id)— Permanent deletion.
Related MCP server: Substack MCP Server
Setup
# 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-mcpRestart Claude Code, then /mcp should show substack-mcp as connected.
(Optional) Install the substack-article skill
This repo also ships a Vercel Skills-compatible agent skill that uses the MCP above to plan, draft, generate a thumbnail, and publish a Substack article in one flow.
# 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-codeRestart 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 for details.
The skill expects:
substack-mcpregistered as an MCP (above)codexMCP 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.
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
# 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 --manualTokens 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(mode0600)Linux:
~/.config/substack-mcp/config.json(mode0600)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
Sign out of all sessions: Substack → Settings → Security → "Sign out of all sessions". This invalidates every existing
substack.sidimmediately.Log back in to Substack in your browser.
Re-run
substack-mcp-setupto 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
audienceaccepts:everyone(default),only_paid,founding,only_free.Markdown image syntax
auto-uploads local files when you callcreate_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.
Available Tools
11 toolscreate_draftA
Create a new Substack draft post from Markdown.
Args:
title: Post title (max 280 chars).
content_markdown: Body in Markdown. Supports headings, bold/italic, links,
bullet lists, blockquotes, code blocks, and images ( - local
paths are auto-uploaded to Substack CDN).
subtitle: Optional subtitle (max 280 chars).
audience: Who can read it: 'everyone' (default), 'only_paid', 'founding',
or 'only_free'.
Returns: Summary including post_id, title, edit_url.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| content_markdown | Yes | ||
| subtitle | No | ||
| audience | No | everyone |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses important behavior: auto-uploading local image paths to Substack CDN. However, it omits permissions, reversibility, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with Args and Returns, and each sentence provides value. It is somewhat lengthy but not verbose; front-loaded purpose and parameter details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema and no annotations, the description covers purpose, parameters with constraints, and return summary. It lacks some behavioral details like authentication needs, but is reasonably complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description must compensate. It adds max char limits for 'title' and 'subtitle', allowed values for 'audience', and explains Markdown support and image handling for 'content_markdown'.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Create a new Substack draft post from Markdown,' making the verb and resource clear. It differentiates from sibling tools like 'delete_draft' and 'publish_draft' by focusing on creation from Markdown.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what the tool does but does not explicitly say when to use it versus alternatives like 'update_draft' or 'schedule_draft.' It provides no exclusions or context for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_draftA
Permanently delete a draft. This cannot be undone.
Args: post_id: Draft ID.
Returns: {post_id, deleted: true}
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description notes the operation is permanent and cannot be undone, and states the return format. However, it lacks details on side effects, authorization needs, or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise: two sentences plus an Args/Returns block. No fluff, immediately conveys the action and key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple delete operation with one parameter and no output schema, the description adequately covers purpose, effect, parameter, and return. It is nearly complete, though missing error handling or precondition details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It adds 'Draft ID' for post_id, but provides no further context like where to find the ID or expected format. Minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it permanently deletes a draft, with a strong verb ('delete') and specific resource ('draft'). Among siblings like create_draft, get_draft, list_drafts, etc., it is uniquely identified.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like unschedule_draft or update_draft. The description does not mention prerequisites or scenarios where deletion is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_draftA
Get full details of a specific draft, including the body content.
Args: post_id: Draft ID.
Returns: Full draft data including draft_body (ProseMirror JSON).
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries burden. It mentions the return includes 'full draft data including draft_body (ProseMirror JSON),' which is helpful. However, it doesn't disclose error handling (e.g., if draft not found) or permissions needed, leaving some gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise with clear sections (Args, Returns). Each sentence adds value, no redundancy. Front-loaded purpose, followed by parameter and return details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, description partially explains returns ('full draft data including draft_body') but lacks specifics on other fields or structure. For a simple get operation, it's adequate but not exhaustive. No annotations to supplement.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has one required param (post_id) with no description. Description adds 'post_id: Draft ID,' which is minimal and largely restates the schema title. With 0% schema coverage, description should provide more context (e.g., format, constraints).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get full details of a specific draft, including the body content.' This specifies a read operation for a single draft, distinguishing it from siblings like list_drafts (multiple) and create_draft/update_draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description implies use for retrieving a single draft by ID, but lacks explicit guidance on when to use this vs siblings. No mention of when not to use or alternatives beyond the implied context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_draftsA
List recent drafts (unpublished posts).
Args: limit: Max number of drafts to return (1-50). Default 10.
Returns: List of draft summaries with post_id, title, edit_url, etc.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It indicates read-only behavior by saying 'List' and mentions return fields. It doesn't hide any destructive aspects, and the behavior is straightforward. A perfect score would need to explicitly state non-destructiveness, but it's clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: two sentences in the main body, plus a structured Args/Returns section. Every sentence adds value, no fluff. The purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low complexity (1 parameter, no required), the presence of an output schema (described in Returns), and no annotations missing critical info, the description is complete. It covers purpose, parameter, and return format sufficiently for an agent to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only 'limit' with type and default. The description adds semantics: 'Max number of drafts to return (1-50). Default 10.' This explains constraints (1-50) and default behavior, compensating fully for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List recent drafts (unpublished posts)', specifying the verb 'list' and resource 'drafts', with a clarifying parenthetical. It distinguishes from siblings like get_draft (single) and create_draft (creation).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies it lists recent drafts with an optional limit. It doesn't explicitly say when to use it over other tools, but given the sibling list, it's the only list tool, so context is clear. A small gap is not mentioning that it only returns recent ones, but that's inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_noteA
Post a Note (Substack's short-form, X/Threads-like post) to the public feed.
Notes are different from Posts:
No title or subtitle.
No email delivery to subscribers.
Not added to the publication's article archive.
Visible in the Substack Notes feed (cross-publication discovery surface).
Use Notes for:
Quick thoughts, links, restacks, questions to your audience
Daily presence between long-form posts
Networking with other Substackers (replies, mutual follows)
Args: text: Plain text body. Use \n\n to separate paragraphs and \n for soft line breaks. Max 4000 chars (Substack's practical Notes limit).
Returns: {note_id, url, raw}
| Name | Required | Description | Default |
|---|---|---|---|
| text | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description bears full burden. Describes the operation (post to public feed) and key behavioral traits (no email delivery, not archived). Lacks details on authentication or rate limits, but sufficient for a simple create tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with bullet points and clear sections. Slightly verbose but all information is relevant. Front-loaded with main purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 1-parameter tool with no output schema and no annotations, the description is fully complete: explains return value (note_id, url, raw), differentiates from sibling tools, and covers usage guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 0% coverage ('text' is just 'string'), but description fully compensates: explains format (plain text), paragraph separation (\n\n), soft line breaks (\n), and max length (4000 chars).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it posts a Note (Substack's short-form post) to the public feed. Distinguishes Notes from Posts by listing specific differences (no title, no email, no archive). The verb 'Post' matches the tool name and resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly specifies when to use Notes vs Posts, and provides concrete use cases: quick thoughts, links, restacks, questions, daily presence, networking. Also states what Notes are not, which helps avoid misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_draftA
Publish a draft immediately.
Args: post_id: Draft ID. send_email: If True (default), send the post as an email to subscribers. If False, publish to web only without emailing. share_automatically: If True, auto-share to Substack social channels.
Returns: {post_id, title, public_url, post_date, send_email}
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| send_email | No | ||
| share_automatically | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries burden. It explains the effect of boolean parameters (send_email, share_automatically) and returns a dict. But it doesn't disclose potential irreversibility, permission requirements, or side effects beyond those stated.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise and well-structured: a brief purpose statement followed by a clean bulleted list of parameters and return. Every sentence adds value with no repetition or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description includes return fields (post_id, title, public_url, etc.). It covers the tool's behavior adequately for a simple publish operation. Lacks error handling info but within acceptable bounds.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Description adds meaningful context: 'send_email' and 'share_automatically' each have conditional behavior explained. 'post_id' is simply 'Draft ID', lacking detail. With 0% schema coverage, the description compensates well for most parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Publish a draft immediately.' with a specific verb and resource. It distinguishes from siblings like 'schedule_draft' (scheduling) and 'delete_draft' (deletion) by focusing on immediate publication.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies immediate publishing, and sibling tool 'schedule_draft' suggests alternative for future scheduling. However, no explicit when-not-to-use or exclusion criteria are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
schedule_draftA
Schedule a draft to publish at a future datetime.
Args: post_id: Draft ID. iso_datetime: ISO 8601 datetime, e.g., '2026-05-15T09:00:00+09:00' for JST or '2026-05-15T00:00:00Z' for UTC.
Returns: {post_id, scheduled_for}
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| iso_datetime | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, and the description does not disclose behavioral traits such as whether scheduling overwrites existing schedule, permission requirements, or side effects. The description is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with a clear structure (what, args, returns), though the Args/Returns format adds minor verbosity; it is front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description includes return value details. However, it lacks behavioral context and usage guidance, leaving some gaps for a complete understanding.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description adds full meaning to both parameters beyond the schema: explains post_id as Draft ID and provides explicit ISO 8601 datetime format examples, compensating for 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool schedules a draft to publish at a future datetime, distinguishing it from siblings like publish_draft (immediate) and unschedule_draft (cancel).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives; it only describes the action without context of when to choose it over similar tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_cover_imageA
Set the cover (thumbnail) image for a draft.
The cover image is shown on the publication homepage, in social shares, and as the email header. Use upload_image first to get a CDN URL.
Args: post_id: Draft ID. image_url: Substack CDN URL from upload_image, or any public image URL.
Returns: Updated draft summary.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| image_url | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It explains where the cover image is used (homepage, social shares, email header) and notes the return type (updated draft summary). It does not mention side effects like overwriting, but the behavior is largely implied.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, front-loaded with purpose, followed by context, argument details, and return. No redundant information. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simplicity (2 params, no output schema), the description covers essential usage: purpose, prerequisite (upload_image), parameter semantics, and return value. It lacks info on idempotency or error handling, but completeness is adequate for this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 0% coverage, but the description adds meaning beyond property names. It specifies 'post_id: Draft ID' and 'image_url: Substack CDN URL from upload_image, or any public image URL.' This clarifies valid values and origin requirements.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: 'Set the cover (thumbnail) image for a draft.' The verb 'set' and resource 'cover image' are specific and distinct from sibling tools like upload_image or update_draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance: 'Use upload_image first to get a CDN URL.' It also clarifies that image_url can be 'any public image URL', not just from upload_image. This helps the agent understand prerequisites and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unschedule_draftB
Cancel a scheduled publish, keeping the post as a draft.
Args: post_id: Draft ID.
Returns: {post_id}
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears the full burden. It states the tool cancels a scheduled publish and keeps the post as a draft, but does not disclose potential side effects, required permissions, or whether the post must be in scheduled state. The return value is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is brief with only two sentences, front-loaded with the purpose. Every word carries meaning, though it could be slightly expanded without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity (one parameter, no output schema, no annotations), the description covers the basic action and argument. However, it lacks behavioral details that would complete the context for an agent, such as whether the tool can be called on non-scheduled posts or if it's idempotent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description only reiterates 'Draft ID', adding little beyond the parameter name. No format, constraints, or additional context is given for the post_id parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: cancel a scheduled publish, keeping the post as a draft. The verb 'cancel' and resource 'scheduled publish' are specific and contrast with sibling tools like schedule_draft and publish_draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (when a post is scheduled and you want to unschedule it) but provides no explicit guidance on prerequisites, when not to use, or alternatives. The context of sibling tools helps but the description itself lacks directive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_draftA
Update an existing draft. Provide only the fields you want to change.
Args: post_id: Draft ID returned by create_draft or list_drafts. title: New title (optional). subtitle: New subtitle (optional). content_markdown: New body in Markdown (optional, replaces full body). audience: New audience setting (optional).
Returns: Updated draft summary.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | ||
| title | No | ||
| subtitle | No | ||
| content_markdown | No | ||
| audience | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It explains partial update behavior and return of a draft summary. It does not disclose permissions or side effects, but given the simplicity, it's adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, structured with an Args and Returns section, and contains no redundant information. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters, no output schema, and no annotations, the description covers the core functionality well. It could optionally list possible audience values, but overall it's sufficient for correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description fully compensates by explaining each parameter, including the source of post_id and the effect of content_markdown replacing the full body.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Update an existing draft' and lists the modifiable fields, clearly distinguishing from siblings like create_draft and delete_draft.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It advises 'Provide only the fields you want to change,' indicating partial updates, and implies usage when an existing draft needs modification. However, it does not specify when not to use or provide alternative tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upload_imageA
Upload an image to Substack's CDN and return its public URL.
Args: image_path: Local file path (e.g., /Users/foo/cover.png) or remote URL.
Returns:
{url, id, width, height} — pass url to set_cover_image or embed in
Markdown as .
| Name | Required | Description | Default |
|---|---|---|---|
| image_path | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries full burden. It discloses input (local/remote), return structure, and usage of result. However, it does not mention side effects, idempotency, file size limits, or permanence of URL, leaving gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with Args and Returns sections, each sentence is relevant. It could be slightly more concise, but it's clear and well-organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one parameter and no output schema, the description covers input format, output fields, and usage context. Missing file format/size constraints, but overall complete for a straightforward upload tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The sole parameter image_path has 0% schema description coverage, but the description adds critical semantics: it accepts both local file paths and remote URLs with examples. This goes beyond the bare string type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool uploads an image to Substack's CDN and returns a public URL, specifying the verb and resource. It distinguishes from sibling set_cover_image by indicating the URL can be passed there.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage before set_cover_image or Markdown embedding, but lacks explicit when-not or alternative tools beyond set_cover_image. No exclusions or context signals for when to avoid.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
11 tool updates
v0.1.0- First observed
create_draft - First observed
delete_draft - First observed
get_draft - First observed
list_drafts - First observed
post_note - First observed
publish_draft - First observed
schedule_draft - First observed
set_cover_image - First observed
unschedule_draft - First observed
update_draft - First observed
upload_image
TDQS
Each tool has a clearly distinct purpose: draft CRUD, publishing, scheduling, notes, and image operations. No two tools overlap in functionality.
All tools follow a consistent verb_noun pattern with underscores (e.g., create_draft, publish_draft, upload_image), making the API predictable.
11 tools is well-scoped for a Substack server, covering drafting, publishing, scheduling, notes, and images without being excessive.
The tool set covers core drafting and publishing workflows comprehensively, but lacks tools for managing published posts, subscribers, or analytics, which are minor gaps for a content creation MCP.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for QPost — lets AI agents publish video and image posts to YouTube, TikTok, Instagram.
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
WordPress MCP server: generate SEO posts, AI images, autoblog & WooCommerce on your self-hosted site
WordPress MCP server: publish posts, AI images, SEO and full site management, self-hosted
Related MCP Servers
- -licenseNot 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.-
- AlicenseAqualityAmaintenanceMCP server for Substack — read posts, manage drafts, and upload images. Safe by design: cannot publish or delete.1411824MIT
- 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.7721MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/nanameru/substack-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server