Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
DATA_DIRNoDirectory for show data: catalog, transcripts, templates, playbook, and backups.
XURL_APPNoOptional xurl app name for X posting.
SITE_MODENoWebsite mode: none or astro.
XURL_PATHNoOptional path to the xurl executable or configuration.
X_USERNAMENoOptional X username for posting.
DEFAULT_TAGSNoOptional default tags for episodes.
PODCAST_GUIDNoOptional Podcasting 2.0 podcast GUID.
PODCAST_LINKYesPodcast website link.
WEBSITE_PATHNoPath to the website repository when SITE_MODE=astro.
DEVTO_API_KEYNoOptional dev.to API key for creating companion drafts.
OP3_API_TOKENNoOptional OP3 API token for download analytics.
PODCAST_TITLEYesPodcast title.
R2_ACCOUNT_IDYesCloudflare R2 account ID.
HF_BACKUP_REPONoOptional private Hugging Face dataset repository for backups.
PODCAST_AUTHORYesPodcast author.
R2_BUCKET_NAMEYesCloudflare R2 bucket name.
USE_OP3_PREFIXNoOptional flag to enable the OP3 analytics prefix.
WEBSITE_BRANCHNoGit branch used for website deploys.
X_BEARER_TOKENNoOptional X bearer token for X metrics.
FEED_OBJECT_KEYNoR2 object key for the RSS feed.
METRICS_SOURCESNoOptional list of enabled metrics sources.
THUMBNAIL_STYLENoOptional thumbnail style setting.
X_LOOKBACK_DAYSNoOptional number of days to look back for X metrics.
PODCAST_FEED_URLYesPublic RSS feed URL.
R2_ACCESS_KEY_IDYesCloudflare R2 access key ID.
R2_PUBLIC_DOMAINYesPublic R2 custom domain for audio and feed URLs.
WEBSITE_BLOG_DIRNoDirectory for generated blog pages in the website repository.
WEBSITE_RSS_FILENoPath to the RSS feed file in the website repository.
BLOG_URL_TEMPLATENoOptional blog post URL template containing {slug}.
PODCAST_IMAGE_URLYesPublic cover art URL.
CLOUDFLARE_ZONE_IDNoOptional Cloudflare zone ID for analytics.
YOUTUBE_TOKEN_PATHNoOptional path to YouTube OAuth credentials.
DESCRIPT_API_BEARERNoOptional Descript API bearer token for staging episodes.
EPISODE_GUID_PREFIXYesPrefix used to generate permanent episode GUIDs.
PODCAST_DESCRIPTIONYesPodcast description.
PODCAST_OWNER_EMAILYesPodcast owner email.
CLOUDFLARE_API_TOKENNoOptional Cloudflare analytics API token.
R2_SECRET_ACCESS_KEYYesCloudflare R2 secret access key.
WEBSITE_EPISODES_DIRNoDirectory for generated episode pages in the website repository.
METRICS_BACKFILL_DAYSNoOptional number of days to backfill metrics.
SUBSTACK_COOKIES_PATHNoOptional path to the Substack session cookie file.
PODCAST_SERVER_ENV_FILENoOptional path to an alternate show .env file.
METRICS_EXTRA_COLLECTORSNoOptional additional metrics collectors.
SUBSTACK_PUBLICATION_URLNoOptional Substack publication URL.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": true
}
resources
{
  "subscribe": false,
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
post_draft_from_markdownA

Create or update a Substack draft from Markdown.

This tool builds a Substack `Post` from markdown content and posts a draft.
It supports optional tag assignment, prepublish (setup check), and publishing.

Args:
    title: Draft title.
    markdown: Markdown body content.
    subtitle: Optional subtitle text.
    audience: One of `everyone`, `only_paid`, `founding`, `only_free`.
    write_comment_permissions: One of `none`, `only_paid`, `everyone`.
    search_engine_title: Optional title for search engine optimization.
    search_engine_description: Optional description for search engine optimization.
    slug: Optional URL slug for the post.
    draft_section_id: Optional section ID for the draft.
    tags: Tag or list of tags to attach to the post.
    prepublish: If true, calls `prepublish_draft` after creation.
    publish: If true, calls `publish_draft` after creation (and optionally prepublish).
    send: Passed to `publish_draft` for newsletter delivery.
    share_automatically: Passed to `publish_draft`.

Returns:
    dict containing drafted post (`draft`), optional `tags`, `prepublish`, `publish` results.

Examples:
    With the YAML structure from the README, a caller can map fields like:

    ```yaml
    title: "My Post Title"
    subtitle: "My Post Subtitle"
    audience: "everyone"
    write_comment_permissions: "everyone"
    markdown: |
      # Hello

      This is the body.

    tags:
      - python
      - substack
    prepublish: true
    publish: true
    send: false
    share_automatically: true
    ```

    Then invoke via MCP directly:

    ```python
    from substack_mcp.mcp_server import post_draft_from_markdown

    result = await post_draft_from_markdown(
        title='My Post Title',
        markdown='# Hello

This is the body.', subtitle='My Post Subtitle', audience='everyone', write_comment_permissions='everyone', tags=['python', 'substack'], prepublish=True, publish=False, # set true when ready ) print(result) ```

    A longer process with manual prepublish/publish calls:

    ```python
    from substack_mcp.mcp_server import (
        post_draft_from_markdown,
        prepublish_draft,
        publish_draft,
        add_tags,
    )

    d = await post_draft_from_markdown(
        title='Long flow',
        markdown='Content',
        tags=['a','b'],
        publish=False,
    )
    draft_id = d['draft']['id']

    await add_tags(draft_id, ['post-tag', 'news'])
    await prepublish_draft(draft_id)
    await publish_draft(draft_id, send=True, share_automatically=True)
    ```

    This docstring example is meant to mirror the YAML-driven workflow and show how to decompose the same operations into explicit tool calls.
put_draftC

Update an existing draft by draft ID.

add_tagsB

Add tags to a specific draft/post.

prepublish_draftC

Invoke prepublish checks for a draft.

publish_draftA

Publish a draft to live post state. (Legacy compatibility interface).

This tool remains for backward compatibility. It is recommended to use publish_draft_checked instead, which provides a safer publishing path with explicit confirmation and prepublish validation.

publish_draft_checkedB

A safer publishing path that requires confirmation and runs prepublish checks.

get_statusA

Get the authentication status and basic user information.

list_publicationsB

List all publications available to the authenticated user.

list_draftsC

List drafts for the current publication.

get_draftC

Get a specific draft by its ID.

schedule_draftC

Schedule a draft for release.

unschedule_draftC

Unschedule a previously scheduled draft.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

B3.1/5.0

Scored across 12 tools

Disambiguation3/5

Several tools overlap: post_draft_from_markdown bundles create/update plus prepublish/publish/tags, duplicating add_tags, prepublish_draft, and publish_draft, and put_draft also updates drafts, muddying create-vs-update boundaries. publish_draft and publish_draft_checked are near-duplicates, though the descriptions explicitly flag the legacy/safer distinction. Descriptions help but an agent must still reason about which of several paths to use.

Naming Consistency4/5

Most tools follow a clean verb_noun pattern (add_tags, prepublish_draft, publish_draft, get_status, list_drafts, get_draft, schedule_draft, unschedule_draft). Minor deviations: put_draft uses 'put' instead of 'update', and post_draft_from_markdown is a longer, less uniform form. Overall consistent and readable.

Tool Count4/5

Twelve tools is well-scoped for a publishing workflow and each maps to a recognizable operation. Slight redundancy from the legacy publish_draft alongside publish_draft_checked, but count is reasonable.

Completeness3/5

Draft lifecycle is mostly covered (create, get, list, update, publish, schedule/unschedule, add tags), but there is no delete_draft and no way to remove tags. Publication listing exists without a corresponding get/select-publication operation, leaving a few dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues