mcpField
S
Substack MCP Server

Substack MCP Server

ローカル
github.comソーシャルメディア441 日前に更新

Substack MCP Server について

Substack MCP Serverは、AIアシスタントやターミナルからニュースレターのコンテンツとアカウントデータを管理するサーバーです。長文記事は手動で確認・公開する下書きにとどまり、Notesは即時公開されます。

主な機能

  1. 01長文記事の下書き作成・更新
  2. 02投稿の検索とエクスポート
  3. 03短文Notesの公開
  4. 04アナリティクスの確認
  5. 05同意済み無料購読者の管理

活用シーン

  1. 01Substackで確認用の記事を準備
  2. 02アーカイブ記事の検索とエクスポート
  3. 03Noteの公開
  4. 04ニュースレター分析の確認や購読者の管理

MCP 対応

ローカルstdioまたはセルフホスト型HTTPを通じて、MCPクライアントにSubstack操作を提供します。長文記事ツールは下書きの作成・編集のみで、Noteツールは即時に公開します。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"conorbronsdon-substack": {
"command": "npx",
"args": [
"-y",
"@conorbronsdon/substack-mcp"
],
"env": {
"SUBSTACK_PUBLICATION_URL": "<SUBSTACK_PUBLICATION_URL>",
"SUBSTACK_SESSION_TOKEN": "<SUBSTACK_SESSION_TOKEN>",
"SUBSTACK_USER_ID": "<SUBSTACK_USER_ID>"
}
}
}
}
起動コマンドnpx -y @conorbronsdon/substack-mcp
設定が必要な環境変数
SUBSTACK_PUBLICATION_URLYour Substack publication URL (e.g., https://yourblog.substack.com)
SUBSTACK_SESSION_TOKENシークレットconnect.sid cookie value from your Substack session
SUBSTACK_USER_IDYour Substack user ID

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npm@conorbronsdon/substack-mcp1.3.0

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

substack-mcp

AI アシスタントまたはターミナルから、Substack ニュースレターを作成・管理できます。リッチな下書きを準備し、アーカイブを検索し、Notes を公開し、分析データを確認して、複数の出版物にわたる、明示的な同意を得た無料購読者を管理できます。Substack で長文記事を確認して公開します。

ライセンス:MIT 言語:TypeScript npm バージョン MCP HOL プラグインセキュリティスキャン ポッドキャスト X


substack-mcp で下書きを作成、検索、エクスポート、計画、確認

デモでは、オフラインのサンプルデータに対して実際の MCP ハンドラーを実行します。ライブ API の呼び出しや出版は行われません。投稿の作成、検索、エクスポート、確認には、下書きのワークフローに従ってください。

長文記事は下書きのみ。公開操作は明示的に実施: このサーバーでは、長文記事の公開や削除はできません。投稿ツールは下書きの作成と編集のみを行い、Substack のエディターから手動で確認して公開します。公開されるコミュニティのコメントや再投稿は、別途実験的機能であり、同意が必要です。Substack Notes も公開されます。Substack には Notes の下書き状態がないため、create_note と create_note_with_link は短文の Notes をすぐに公開します。Notes のツールは公開操作として扱ってください。プレビュー手順はなく、このサーバーから取り消すこともできません。この分け方は、エージェントにとってこのサーバーが最も重視する信頼性の基盤である、相応の確認プロセスです。重大な操作には人間の確認を必須にし、例外は明確に伝えます。

このサーバーは、ベストセラーのステータス確認を必須としていません。出版物を管理する権限のある認証済みアカウントを使用してください。個々の操作は、Substack でのアクセス権に応じて異なります。ローカル stdio またはセルフホスト型 HTTP で接続できます。

substack-mcp MCP サーバー

1.0 のセットアップ範囲とアカウントの利用条件については、互換性を参照してください。substack-mcp compatibility report を実行すると、オフラインで共有可能な診断レポートを生成できます。レポートガイド。メンテナーはリリースチェックリストと配布情報一覧を利用できます。

目次: クイックスタート · セットアップ · ツール · 運用者向け CLI · 下書きのワークフロー · 分析から下書きへ · エクスポート · Markdown · 複数の出版物 · トランスポート · 互換性

クイックスタート

  1. インストールしてサインインします。 ブラウザログインには、オプションの Playwright 依存関係が必要です。

    npm install @conorbronsdon/substack-mcp playwright
    npx playwright install chromium
    npx substack-mcp login https://yourblog.substack.com --user-id 12345
    

    ご自身のアカウントのユーザー ID を使用してください(確認方法)。セッションは、認証済みの読み取りが上限内で正常に完了した後にのみ保存されます。認証情報を貼り付ける場合は、オプション Bをご覧ください。

  2. 読み取りを確認します。 npx substack-mcp doctor --json --check-auth は、各パブリケーションに対して上限内で 1 回読み取りを実行します。読み取りアクセスを確認しますが、ユーザー ID や書き込み権限は確認しません。

  3. MCP クライアントに接続します。 Claude Desktop または Claude Codeにサーバーを追加するか、Codex プラグインを使用します。環境変数が優先されます。環境変数を省略すると、保存済みのブラウザログインセッションが使用されます。その後、アシスタントに「Substack の購読者は何人いますか?」と尋ねます。

  4. レビュー用の下書きを準備します。 下書きワークフローに従ってください。create_draft、search_posts、export_draft、preflight_draft、続いてplan_draft_updateとupdate_draftを実行します。長文の投稿は、Substack のエディターで公開するまで未公開の下書きとして保存されます。create_noteとcreate_note_with_linkは即時公開します。

コミュニティによる解説

Jonathan Price によるCodex を使って ChatGPT を Substack に接続しました。すると、投稿の下書きが作成されました。では、Codex を使った MCP のローカルインストール、OpenAI の Secure MCP Tunnel を介した ChatGPT の接続、手動で公開するための非公開の下書き作成について解説しています。彼はこの接続を使って、このガイド自体の下書きを作成しました。

このガイドでは、バージョン 1.2.0 を使用した 2026 年 9 月 18 日時点の設定を説明しています。報告されていたget_postの 404 は、1.2.1 で修正されています。クライアントのインターフェースやアクセス要件は変更される場合があります。このパッケージの現在の設定については、以下のセットアップ手順をご利用ください。これはコミュニティによる解説であり、このプロジェクトが提供するホステッドサービスではありません。

セットアップ

Node.js 22 以降が必要です(CI では Node 22 と 24 を対象としています)。ブラウザログインには、さらに Playwright が必要です。

認証情報は 2 通りの方法で指定できます。環境変数として貼り付ける方法(以下を参照)か、オプションのブラウザログインを実行して認証情報を取得・保存する方法です。

オプション A — ブラウザーでログイン(任意、Cookie の手動コピーは不要)

サーバーとオプションの Playwright 依存関係をローカルのツールディレクトリにまとめてインストールし、ログインします:

npm install @conorbronsdon/substack-mcp playwright
npx playwright install chromium
npx substack-mcp login https://yourblog.substack.com --user-id 12345

substack-mcp-login は引き続きサポートされるエイリアスです。出版物の URL とユーザー ID が未指定の場合は、入力を求められます。ご自身のアカウントのユーザー ID を指定してください(手順はこちら)。投稿者の署名欄に表示される名前は、本人確認にはなりません。CAPTCHA を含め、ブラウザーが開いてログイン画面が表示されます。ログイン後、<publication>/publish/home が開き、出版物のセッション Cookie が取得されるまで待機します。カスタムドメインでは、カスタムドメイン上の connect.sid が対象です。保存前に、認証済みの読み取りを上限付きで実行し、成功する必要があります。デフォルトのフローで確認するのは読み取りアクセスであり、設定されたユーザー ID や書き込み権限ではありません。

手動で入力する代わりに、選択した出版物の認証済みセッションから ID を取得するには、次を使用します:

npx substack-mcp login https://yourblog.substack.com --verify-identity --profile work

--verify-identity は、そのホストの Cookie を使って出版物ホストの /api/v1/user/profile/self を読み取り、トップレベルの ID が正の安全な整数であることを要求したうえで、保存前に既存の認証済み下書き一覧チェックを実行します。--user-id も指定すると、指定値は照合対象になります。不一致の場合、--force を指定していても、保存やプロフィールの置き換えは行わずに処理を停止します。代替手段として、公開プロフィール、投稿の署名欄、別ホストの Cookie、別ホストのエンドポイントを使用することはありません。検証モードの JSON 結果では、user_identity: "verified" と identity_source: "authenticated_publication_self_profile" が報告され、ID は出力されません。これはログイン時点での確認であり、永続的な本人確認の証明でも、書き込み権限の証明でもありません。通常の doctor では、引き続き本人確認が未検証として報告されます。

出版物ホストでのセルフプロフィールのサポートは、すべての Substack/カスタムドメイン構成で実際に検証されているわけではありません。エンドポイントが利用できない場合、期限切れの場合、リダイレクトされた場合、または形式が不正な場合、検証モードは安全側に倒して失敗し、何も保存しません。ユーザー ID を手動で設定する既存のフローも引き続き利用でき、本人確認が未検証であることが明示されます。#150 の確認には、実際のブラウザーでの実行が必要です。フィクスチャーを使ったテストは、現在のサインイン画面についての根拠にはなりません。

--profile を指定しない場合、ログイン情報は ~/.substack-mcp/session.json に保存されます(ディレクトリのオーバーライドには SUBSTACK_MCP_HOME を使用します)。出版物の認証情報に関する環境変数と SUBSTACK_PROFILES が設定されていない場合、サーバーはこの従来のセッションを使用します。

デフォルトの保存方式(SUBSTACK_CREDENTIAL_STORE=file): セッションは、OS アカウントとマシンから導出した鍵を使い、AES-256-GCM で暗号化されます。ファイルのアクセス権は 0600 が要求されます。Windows では、ディレクトリの ACL にも左右されます。これはマシンに紐付いたファイルであり、OS のキーチェーンやシークレット保管庫ではありません。ご自身の OS ユーザーとして実行されるコードは、この鍵を導出できます。MCP クライアントがシークレットを管理する場合は、環境変数の認証情報を使用してください。

任意の OS キーチェーン: ログインプロセスと MCP クライアントの環境の両方で SUBSTACK_CREDENTIAL_STORE=keychain を設定します。macOS では /usr/bin/security を介して Keychain を使用します。Linux では libsecret と secret-tool、およびロック解除済みの Secret Service が必要です。Windows では、PowerShell の PasswordVault を介して Credential Manager を使用します。3 つの環境すべてで、GitHub ホストランナー上の keychain CI ワークフローにより、合成認証情報を使ったテストが実行されています(ロック解除済みの一時的な macOS キーチェーンと、Linux 上の gnome-keyring セッション)。キーチェーンがロックされたデスクトップ環境では、引き続き入力を求められる場合があります。ログインすると、選択したアカウントがキーチェーンに書き込まれ、サーバーはそこから読み取ります。キーチェーンを明示的に選択した場合、暗号化ファイルを代替手段として読み取ることはありません。キーチェーンは、他の OS ユーザー、コピーされたディスク、ファイルアクセスに制限された一部のマルウェアに対する保護に役立ちます。ご自身のユーザーとして実行されるコードは、通常、キーチェーンを照会できます。OS アカウントと実行中のコードは、信頼できる状態に保ってください。 Linux では、エントリーがない場合も、キーリングがロックされている場合も、secret-tool lookup はエラーメッセージを出さずに終了コード 1 を返すことがあります。名前付きの書き込みでは、--force を指定しない限り、事前に検索してロックを解除し、エントリーが見つかった場合は上書きを拒否します。

名前付きプロファイルと移行
npx substack-mcp login https://yourblog.substack.com --user-id 12345 --profile work
npx substack-mcp profiles list
# Copy an existing legacy session without changing its file:
npx substack-mcp profiles migrate --name personal
# Copy a file session or named file profile into the keychain; source remains:
npx substack-mcp profiles migrate --to keychain
npx substack-mcp profiles migrate --to keychain --name work

キーは小文字の ASCII 文字で始まり、小文字、数字、ハイフンのみを含む最大 64 文字です。既存のプロファイルを置き換えるには、明示的に --force を指定する必要があります。一覧には、キー、読み取り可能かどうか、公開元、ファイルの保存時刻が表示されます。Cookie とユーザー ID は含まれません。読み取り不能なプロファイルも表示されますが、選択できません。保存時刻は、移行を含むローカルへの保存時刻を示すものであり、トークンの発行時刻や有効期限ではありません。一覧表示の対象は最大 32 件です。

プロファイルの保存には、ハードリンクに対応したローカルファイルシステム(NTFS や一般的な Linux ファイルシステムなど)が必要です。これにより、既存の名前を上書きせずに、暗号化済みファイル全体を作成できます。FAT/exFAT や一部のネットワークマウントには対応していません。SUBSTACK_MCP_HOME に適切なローカルディレクトリを設定してください。対応していないファイルシステムを回避するために --force を使用しないでください。

MCP クライアントの環境変数に SUBSTACK_PROFILES=work,personal を設定すると、最大 32 件の異なるプロファイルを選択できます。公開情報の認証情報に関する変数はすべて、先に削除してください。プロファイルの選択と、従来の認証情報変数または名前付き認証情報変数を併用すると、変数が空でもエラーになります。選択したプロファイルが存在しない、破損している、または無効な場合、起動は停止します。別のアカウントにフォールバックすることはありません。ディスク上のプロファイルが、検出によって有効になることはありません。複数のプロファイルがある場合、ツールには公開キーの明示的な指定が必要で、CLI での読み取りには --publication が必要です。

ロールバックするには、SUBSTACK_PROFILES の設定を解除し、以前の環境設定を復元してください。移行では、従来のセッションがバイト単位でそのまま保持されます。これらのファイルには、既存の暗号化形式が使用されます。profiles list はファイルプロファイルを一覧表示します。移行後またはログイン後に、SUBSTACK_PROFILES でキーチェーンのプロファイルを明示的に選択してください。オフラインで設定を診断するには substack-mcp status --json を、選択した各アカウントについて範囲を限定して読み取りを行うには substack-mcp doctor --check-auth --json を実行してください。

オプション B — 認証情報を手動で取得する

ブラウザーで Substack を開き、次の手順を実行してください。

  1. セッショントークン: カスタムドメインの場合は、DevTools → アプリケーション → Cookie → https://your-custom-domain を開き、公開先独自のドメインにある connect.sid をコピーします(s%3A で始まる URL エンコード文字列)。substack.com の substack.sid はコピーしないでください。これは別のセッションであり、カスタムドメインの管理 API では拒否され、403 エラーになります。*.substack.com の公開先では、そのホストの connect.sid または .substack.com の substack.sid を使用してください。トークンは SUBSTACK_PUBLICATION_URL のホストと一致する必要があります。ただし、Substack ホストの公開先に限り、.substack.com へのフォールバックが使われます。
  2. ユーザー ID: アカウントのユーザー ID を確認するの手順に従ってください。公開記事の署名欄にある ID は使用しないでください。公開先には複数の著者がいる場合があります。このサーバーは、指定された ID を独自に検証しません。
  3. 公開先の URL: カスタムドメインがある場合は、それを含む Substack の URL(例:https://newsletter.yourdomain.com または https://yourblog.substack.com)
アカウントのユーザー ID を確認する
  1. Substack で自分のアカウントプロフィールを開き、ハンドルをコピーします(https://substack.com/@your-handle の @ の後の部分)。公開先の URL や他の著者のプロフィールは、自分のアカウントのハンドルではありません。
  2. your-handle を自分のハンドルに置き換えて、https://substack.com/api/v1/user/your-handle/public_profile を開きます。JSON レスポンスのトップレベルにある数値の id を確認してください。公開先や記事の署名欄にネストされた ID は使用しないでください。このパブリックプロフィールのエンドポイントは、このサーバーの匿名プロフィール検索にも使用されます。
  3. レスポンスの handle と名前が、ログインするアカウントと一致することを確認してください。トップレベルの id を login --user-id または SUBSTACK_USER_ID に指定します。パブリックプロフィールの検索で特定されるのは、入力したハンドルです。ブラウザーログイン時の読み取りチェックでは、Cookie がその ID に属することは証明されません。書き込み操作を行う前に、アカウントを再確認してください。
2. MCP クライアントを設定する
Claude Desktop

claude_desktop_config.json に追加します:

{
  "mcpServers": {
    "substack": {
      "command": "npx",
      "args": ["-y", "@conorbronsdon/substack-mcp"],
      "env": {
        "SUBSTACK_PUBLICATION_URL": "https://yourblog.substack.com",
        "SUBSTACK_SESSION_TOKEN": "your-session-token",
        "SUBSTACK_USER_ID": "your-user-id"
      }
    }
  }
}

手動での MCP 設定に加えて、Claude Code と Codex のプラグイン設定も利用できます。リポジトリのマーケットプレイスとローカルプラグインは、審査済みディレクトリへの掲載やホスト型 ChatGPT のサポートとは別のものです。

Claude Code

.mcp.json に追加します:

{
  "mcpServers": {
    "substack": {
      "command": "npx",
      "args": ["-y", "@conorbronsdon/substack-mcp"],
      "env": {
        "SUBSTACK_PUBLICATION_URL": "https://yourblog.substack.com",
        "SUBSTACK_SESSION_TOKEN": "your-session-token",
        "SUBSTACK_USER_ID": "your-user-id"
      }
    }
  }
}
3. 確認

AI アシスタントに「Substack の購読者は何人いますか?」と尋ねます。

ツール出力の互換性、応答の上限、バージョン管理については、 ツールの仕様に記載されています。

オペレーター向け診断

CLI では、サーバーと同じ MCP ハンドラーおよび認証情報の解決を通じて、オペレーター向けのコマンドと設定チェックを実行できます。drafts create は非公開の下書きを1件作成し、それ以外のオペレーター向けコマンドは次を読み取ります:

substack-mcp status --json
substack-mcp doctor --json --check-auth
substack-mcp drafts list --limit 10

コマンド、JSON エンベロープ、終了コード、リクエストの期限、応答の上限については、オペレーター向け CLI と診断に記載されています。

ツール

すべてのツールで、MCP の副作用に関する注釈が明示的に宣言されています。詳しくはツールの注釈を参照してください。ツールの説明が正式な表現となります。

読み取り
ツール説明
get_subscriber_countパブリケーションの現在の購読者数を取得します
list_subscribers非公開の購読者レコードを、指定範囲のページで読み取ります
search_subscribers非公開の購読者レコードを絞り込んでページ表示します。アクティビティ、日付、フラグ、収益フィールドを任意で指定できます
get_subscriber完全一致するメールアドレスでメンバーシップを検索します。保留中の追加を照合します
list_published_posts公開済みの投稿をページネーション付きで一覧表示します
get_publicationパブリケーションの予測される識別情報と設定を読み取り、設定済みのホストを検証して、不足しているフィールドを報告します。アカウントの識別情報やロールは検証しません
list_publication_tagsタグの定義を読み取ります。デフォルトでは非表示のタグも含み、ローカルで範囲を指定したページネーションに対応します
get_post_tags投稿に紐づくタグを解決します。解決できないIDを保持し、結果が空の場合は識別情報が不確かなことを報告します。下書きの網羅性は現在、空の応答についてのみライブ検証されています
search_postsクエリとステータスでパブリケーションのアーカイブを検索します。継続情報付きの範囲指定ページに対応します
plan_draft_update変更案を確認し、事前チェックと、古い情報をベストエフォートで検出するためのレシートを作成します。書き込みは行いません
export_draft編集可能なMarkdown、元の本文そのもの、変換診断、事前チェック、エディターへのリンクを出力します
preflight_draftタイトル、対象読者、本文の構成、画像、有料コンテンツに関する読み取り専用のチェックを行い、エディターへのリンクを表示します
list_drafts下書きの投稿を一覧表示します
get_postIDを指定して、公開済みの投稿の全文を取得します
get_draftIDを指定して、下書きの全文を取得します
get_post_comments公開済みの投稿へのコメントを取得します
get_sectionsパブリケーションのセクション(カテゴリ)をIDとともに一覧表示します
get_post_analyticsIDを指定して、公開済み投稿の統計情報(閲覧数、開封数、登録数、購読数、リアクション数)を取得します
rank_posts閲覧数、開封数、送信数、率、登録数、購読数、推定価値または日付で投稿をランキング表示します。null値と欠損値は区別して扱います
get_publication_statsダッシュボードの概要と期間指定のパブリケーション指標を読み取り、欠損状態と利用不可状態を示します
get_growth_sources範囲を指定した成長ソースのアトリビューションと、任意のイベントを読み取ります
list_incoming_recommendationsあなたのパブリケーションを推薦しているパブリケーションを一覧表示します。開始日、アクティブ状態、ダッシュボードでアトリビューションされた購読者を含みます
list_outgoing_recommendationsあなたのパブリケーションが推薦している相手を一覧表示します(不完全な場合があります)。これはあなたを推薦している相手ではありません。そちらは list_incoming_recommendations を使用してください
list_outgoing_recommendation_statsあなたのパブリケーションが、推薦先のパブリケーションに送った購読者を一覧表示します
list_scheduled_posts将来公開予定の投稿を一覧表示します(読み取り専用です。スケジュール設定はSubstackのエディターで行います)
get_user_profileハンドル名で、公開ユーザープロフィールの最小限の情報を匿名で読み取ります
get_profile_feedカーソルによる継続に対応した、公開プロフィールのフィードページを1ページ匿名で読み取ります
get_note_thread公開Note、先祖の投稿、および返信の1ページを匿名で読み取ります
list_public_posts範囲を指定した公開アーカイブのページを匿名で読み取ります
get_public_post本文の状態と切り捨てフラグを含め、URLで指定した公開投稿を匿名で読み取ります
公開コンテンツの読み取り

これら5つのツールでは、別の匿名リーダーを使用します。このリーダーが送信するのは User-Agent と Accept のみで、設定された出版物の Cookie やその他の認証情報は送信しません。設定された出版物は、 デフォルトのアーカイブのオリジンを選択します。呼び出し元は、許可リストに登録された HTTPS の出版物 オリジンを指定できます。許可されるホストは、substack.com、1階層の *.substack.com、設定された出版物のオリジン、および SUBSTACK_PUBLIC_READ_ORIGINS に指定された完全一致のオリジンです(カンマ区切りの HTTPS オリジンで、 ポート、パス、ユーザー情報は含めません)。リダイレクトは拒否されます。*.substack.com の出版物は カスタムドメインにリダイレクトされる場合があります(例:lenny.substack.com)。JSON の読み取りでは そのリダイレクトをたどりません。カスタム HTTPS オリジンを SUBSTACK_PUBLIC_READ_ORIGINS に追加し、そのオリジン経由で読み取ってください。複数の出版物を設定している 場合、すべての出版物ツールで引き続き publication キーが必要です。

プロフィールのフィードページのサイズは上流の設定に従います。has_more: null は、上流で継続に関する メタデータが省略されたことを意味します。スレッドのページでは、more_branches または next_cursor が ある場合に返信が省略されることがあります。completeness: "unknown" は、継続に関するメタデータが 省略されたことを意味します。 アーカイブの全件ページでは、合計件数が返されないため has_more: null になります。公開投稿の body_status は、公開対象と本文の有無に基づく推定値であり、完全なアクセスを示すものではありません。 匿名リーダーは購読権限を使用しません。リーダーの購読機能と受信トレイには対応していません。設定された 出版物のセッションで substack.com のリーダーアカウント用ルートにアクセスすると 401 が返されました。 これらのルートには別のリーダーセッションが必要ですが、このサーバーでは管理していません。

アーカイブ検索と下書きのレビュー

search_posts は query(1~500文字)、status(published、drafts、 または scheduled。デフォルトは published)、offset(デフォルトは 0)、および limit(1~50、 デフォルトは 25)を受け付けます。認証済みのアーカイブリクエストを1回実行し、投影されたメタデータ、 returned、total、has_more、next_offset を返します。次のページには next_offset と同じ query/status を使用してください。Substack で合計件数が省略され、ページが満杯の場合、 has_more は null(不明)になります。次のページが空の場合もあります。検索対象とインデックスの制御は Substack が行うため、全文を網羅的にスキャンできる保証はありません。完全な内容を取得するには、 get_post または get_draft を使用してください。ページネーションはスナップショットではありません。 同時に編集が行われると、結果がページ間で移動することがあります。

preflight_draft は draft_id を受け取り、下書きを1回読み込み、checks_passed、重大度・コード・ メッセージを含む検出結果、コンテンツの件数、およびエディターへのリンクを返します。タイトル、公開対象、 JSON/本文の構造、画像ラッパーと HTTPS ソース、ペイウォールの数と端への配置を確認します。不明なノードと 外部画像については、レビュー警告が出ます。本文が200万文字、10,000ノード、または深さ100を超える場合は、 完全には確認されません。counts.complete は false になり、スキャン上限に達した後は集計チェックが スキップされます。不明なノードに関する警告には、エディターで確認するための最大5種類のタイプ名が記載されます。 これは対象を絞った静的チェックであり、完全な ProseMirror 検証や公開の承認ではありません。リンクや画像の 取得、アクセス設定の確認、最終的な表示の保証は行いません。Substack で下書きを確認してください。 コンテンツは変更されません。

複数の出版物を設定している場合、両方のツールで publication が必要です。

書き込み(非公開の下書き。画像のアップロードでは公開 URL が返されます)
ツール説明
create_draftMarkdown から新しい下書きを作成します(非公開)
update_draftレビュー済みの変更レシートを適用します。未公開状態を再確認し、読み戻しの結果を報告します
update_draft_tags下書きのタグを計画または変更します。デフォルトではドライランで、下書きのみを対象とし、書き込み後に1回読み戻します
upload_imageファイル、データ URI、または公開 HTTPS URLから画像を Substack の CDN にアップロードします — 公開取得可能な(限定公開の)URL を返します
下書きの変更前に確認する

0.9 では、まず plan_draft_update を呼び出して出力を確認し、その後、同じフィールドと返されたレシートを使って update_draft を呼び出してください。公開済みの下書きや、古いことが確認されている下書きは拒否されます。読み取りと書き込みの競合は引き続き発生するため、読み戻しの結果を確認し、Substack でも内容を確認してください。CLI でも drafts plan と drafts apply を通じて同じフローを利用できます。例と制限については、下書きの変更と移行を参照してください。

コミュニティへの公開書き込み(実験的機能)
ツール説明
create_post_comment設定済みの出版物にコメントします。デフォルトではプレビューを表示し、ライブ実行時は即時に公開します
restack別の読者アカウントとして投稿または Note を再スタックします。デフォルトではプレビューを表示し、ライブ実行時は即時に公開します

ライブ実行には、SUBSTACK_EXPERIMENTAL_COMMUNITY_WRITES=1、dry_run=false、confirm_publish=true に加え、対象アカウント、対象、テキストの正確な内容に対する明示的な承認が必要です。再スタックには、別の読者セッションも必要です。どちらのツールも書き込み前に認証済みのユーザーを確認し、POST を 1 回だけ試行して、自動再試行を行わずに範囲を限定した読み戻し結果を報告します。エンドポイントには根拠となる情報がありますが、ライブ検証は未完了です。セットアップ、認証情報のルーティング、同意、制限を参照してください。

公開(Notes — 即時に公開)
ツール説明
create_noteSubstack Note を公開します(短文形式、即時に公開)
create_note_with_linkリンクカードを添付した Note を公開します(即時に公開)

Substack には Notes の下書き状態がないため、これら 2 つのツールには下書きを先に作成するオプションはありません。

購読者の管理

add_free_subscriber は、同意を得た読者 1 人を無料ニュースレターに追加します。これは配信先の変更です。その読者には今後のニュースレターのメールが届く場合があります。send_welcome_email: true を指定すると、ウェルカムメールを送信できます(デフォルトではオフです)。有料アクセスを付与することはなく、過去に購読を解除したアドレスに対する Substack の配信抑止を上書きすることもありません。この MCP のアノテーションでは、外部への書き込みとして識別されます(readOnlyHint: false、openWorldHint: true)。

{"email":"[email protected]","consent_confirmed":true,"consent_evidence":{"source":"booking:message-id","recorded_at":"2026-09-01T00:00:00Z"},"dry_run":true}

デフォルトではドライランです。実際のニュースレター購読への同意を確認した後、実行するには dry_run: false を設定してください。ライブ実行での追加には、consent_evidence に情報源の参照先とタイムスタンプが必要です。この証明情報は監査用に出版物キーとともに返されますが、基となる同意記録の確認に代わるものではありません。複数の出版物を設定している場合は、ほかのすべてのツールと同様に publication セレクターも必要です。

結果は existing、dry_run、verified、blocked、unverified、busy、retryable を区別します。busy の場合、書き込みは行われません。ほかの処理が終わるまで待ってください。retryable は、認証またはレート制限によってリクエストが拒否されたことを意味します。明示的に再試行する前に、その状況を解消してください。API から空の確認応答が返っても、追加が行われた証拠にはなりません。 verified は、リクエスト後に完全一致する購読者の照会に成功したことを意味します。このリクエストが最初にその購読を作成した証拠にはなりません。ダッシュボードのデータ反映は遅れる場合があります。該当する読者が以前に購読を解除していた可能性もあります。

unverified の場合は get_subscriber で再確認し、追加を自動的に繰り返さないでください。blocked の場合は、配信抑止を回避せずに Substack で確認してください。自動化された呼び出し元は、ライブリクエストを送信する前に、各試行を記録する台帳を永続化する必要があります。クライアントのメモリ内重複防止機能は、再起動や別々の HTTP セッションをまたいで保持されません。購読者の識別情報と同意の証明情報を、共有リポジトリ、未承認の公開サービスへのプロンプト、通常のログに含めないでください。

実装とライブ検証に関する注意事項:購読者 API。

Google Calendar の予約オプトインには、カレンダー同期ヘルパーが、範囲を限定した Gmail のスキャン、最新の回答の選択、非公開で永続化される試行台帳、不確実な書き込み後の読み取り専用照合を提供します。スケジュール設定は明示的なローカルセットアップ手順です。MCP をインストールしてもバックグラウンドジョブは開始されません。

意図的に対象外とした機能
  • 投稿の公開 — 長文投稿の公開は、人間が意図的に行うべき操作です(上記で説明したノートは例外です)。
  • 削除 — AI ツールには破壊的すぎます。
  • スケジュール設定 — スケジュール設定には Substack のエディターを使用してください。(list_scheduled_posts はそこでキューに追加した内容を読み取りますが、このサーバーがスケジュールを作成、編集、キャンセルすることはありません。)

永続的なクラウド状態と週次メールレポートを備えた常時稼働のスケジューラーについては、Cloud Calendar sync を参照してください。

複数の出版物

1 つのサーバーで複数の出版物を運用していますか? 通常の SUBSTACK_* 変数の代わりに、出版物ごとに SUBSTACK_PUB_<KEY>_* の3点セットを設定してください。<KEY> には任意の名前(英字、数字、アンダースコア)を指定できます。これは出版物の小文字・ハイフン区切りのキーになります。たとえば、KEVIN_MULDOON → kevin-muldoon です。

"env": {
  "SUBSTACK_PUB_KEVIN_MULDOON_PUBLICATION_URL": "https://kevinmuldoon.substack.com",
  "SUBSTACK_PUB_KEVIN_MULDOON_SESSION_TOKEN": "token-1",
  "SUBSTACK_PUB_KEVIN_MULDOON_USER_ID": "111",
  "SUBSTACK_PUB_SAPERE_PUBLICATION_URL": "https://sapere.substack.com",
  "SUBSTACK_PUB_SAPERE_SESSION_TOKEN": "token-2",
  "SUBSTACK_PUB_SAPERE_USER_ID": "222"
}

各3点セットは独立しており、SUBSTACK_PUB_<KEY>_* 変数を1つでも設定すると、その出版物が宣言されます。3点セットが不完全な場合(変数がない、値が空、または空白のみ)は、その出版物を黙って除外するのではなく、キーを示すエラーで起動に失敗します。これは、出版物が除外されても単に「出版物が1つ減る」わけではないため重要です。唯一の出版物が除外されると、サーバーは保存済みのブラウザーログインセッションにフォールバックします。2つのうち1つが除外されると、すべてのツールから publication パラメーターがなくなり、除外された出版物を対象とする呼び出しが、残った出版物に黙ってルーティングされます。

キーの比較では大文字と小文字を区別せず、_ は - として扱われます。同じキーに解決される2つの名前(SUBSTACK_PUB_ALPHA_* と SUBSTACK_PUB_Alpha_*)も起動エラーになります。これらを黙って統合すると、一方の出版物の URL がもう一方のセッショントークンと組み合わされる可能性があるためです。

<KEY> に指定できるのは ASCII の英字、数字、アンダースコアです。3つのサフィックスは大文字でなければならず、名前全体に余分な空白を含めることはできません。SUBSTACK_PUB_ で始まっていてもこの形式に合わないもの(キー内のハイフン、小文字のサフィックス、アクセント付き文字、末尾の空白など)は、その変数を黙って無視するのではなく、変数名を示す起動エラーになります。前述と同じ理由で、出版物を無視しても単に出版物が1つ減るのではなく、別の出版物へのサイレントな振り分けが起きるためです。

2つ以上の出版物を設定すると、すべての出版物ツールに必須の publication パラメーターが追加されます。指定できるのは設定したキーのいずれかです(上記の kevin-muldoon、sapere など)。呼び出しモデルはすべての出版物呼び出しでキーを指定する必要があります。不明な値は Substack API の呼び出し前に拒否されるため、誤った書き込みが別の出版物に行われることはありません。出版物をちょうど1つだけ設定している場合(通常の SUBSTACK_* 変数でも、単一の SUBSTACK_PUB_<KEY>_* 3点セットでも)、publication パラメーターは追加されません。すべてのツールのスキーマは、単一出版物モードから変更されません。

2つの形式を混在させないでください。SUBSTACK_PUB_<KEY>_* 変数が1つでも設定されている場合、通常の SUBSTACK_* 変数は名前のない追加の出版物として扱われず、起動時の警告とともに無視されます。

アカウント全体を対象とする restack ツールでは、publication パラメーターの代わりに、リーダーの account_user_id を明示的に指定します。リーダーの認証情報は別途設定され、出版物のセッションは使用されません。

SUBSTACK_USER_AGENT と SUBSTACK_REQUEST_TIMEOUT_MS は、設定済みのすべての出版物に適用され、出版物ごとの設定ではありません。ブラウザーログインでは、名前付きプロファイルもサポートされています。名前付きプロファイルと移行を参照してください。

トークンの有効期限

Substack のセッショントークンは定期的に期限切れになります(通常は約 90 日です)。認証エラーが発生した場合は、substack-mcp login を再実行して保存済みのセッションを更新するか、該当する公開サイトのホストで DevTools から新しい Cookie をコピーし、環境変数を更新してください。カスタムドメインでは、独自の connect.sid が必要です。substack.com の別のセッションである substack.sid はカスタムドメインで拒否され、403 エラーになります。*.substack.com の公開サイトでは、そのホストの connect.sid または .substack.com の substack.sid を使用してください。その後、substack-mcp doctor --check-auth を実行してアクセスを確認してください。

カスタムドメインと Cloudflare

このセクションでは、認証が必要なクリエイター API 呼び出しについて説明します。匿名での公開記事の閲覧では、上記の公開記事の閲覧にあるオリジンのルールを使用します。

カスタムドメイン(例:blog.example.com)で配信される Substack の公開サイトは Cloudflare の背後にあり、ブラウザー以外からのリクエストが 403 error code: 1010 で拒否されることがあります。これを避けるため、サーバーはデフォルトでブラウザーの User-Agent と Referer を送信し、設定された公開サイトの URL を使用します。

  • ホストと Cookie を一致させます。 正規の *.substack.com URL を使用する場合は、そのホストのセッションまたは .substack.com のフォールバックを使用してください。カスタムドメインの connect.sid は、カスタムドメインの SUBSTACK_PUBLICATION_URL と組み合わせてください。
  • 別のブラウザーの識別情報が必要な場合は、SUBSTACK_USER_AGENT で User-Agent を上書きできます(任意)。
"env": {
  "SUBSTACK_PUBLICATION_URL": "https://yourblog.substack.com",
  "SUBSTACK_SESSION_TOKEN": "your-session-token",
  "SUBSTACK_USER_ID": "your-user-id",
  "SUBSTACK_USER_AGENT": "Mozilla/5.0 ..."
}

リクエストのタイムアウト

Substack へのすべてのリクエストには 30 秒の期限が設定されています。Node は独自のリクエストタイムアウトを適用せず、10 秒の 接続タイムアウトのみを適用します。そのため、接続を受け付けた後に応答しなくなるホスト(接続を拒否するのではなく、パケットを破棄するプロキシなど)に対しては、何もしなければツール呼び出しが無期限に停止する可能性があります。期限に達したリクエストは、エンドポイントと制限時間を示す TimeoutError で失敗します。

SUBSTACK_REQUEST_TIMEOUT_MS(ミリ秒)でタイムアウトを延長または短縮できます(数値以外または 0 以下の値は警告とともに無視され、デフォルト値が使用されます)。

"env": {
  "SUBSTACK_REQUEST_TIMEOUT_MS": "60000"
}

トランスポート

デフォルトでは、サーバーは stdio 経由で MCP を通信します。上記のクライアント設定はこれを前提としています。永続的なセルフホスト型デプロイでステートレスな Streamable HTTP サーバー(POST /mcp、GET /health)を使用するには、MCP_TRANSPORT=http を設定してください。セットアップ、リスナーの環境変数、セキュリティモデルについては、HTTP トランスポートを参照してください。

このリスナーが受け付けるリクエスト

HTTP リスナーは、デフォルトで閉じた状態で起動します。ループバックの Host と Origin の許可リスト、任意のベアラートークン(MCP_HTTP_TOKEN)、10 MiB の本文サイズ上限が設定されています。Host と Origin の確認は認証ではありません。他のプロセスからポートにアクセスできる場合は、トークンを設定してください。リスナーポリシーを参照してください。

バージョン管理された GHCR イメージとトランスポートの検証については、コンテナーの配布を参照してください。

型付きエラー

API の失敗は型付きエラー(AuthenticationError、RateLimitError、 ValidationError、NotFoundError、ServerError、TimeoutError、および基底クラスの SubstackAPIError)に対応付けられます。ステータスの対応付けとエラー本文の解析については、 型付きエラーに記載されています。

下書きのエクスポート

読み取り専用の Markdown/JSON バンドルには export_draft を使用するか、次を実行してください。

substack-mcp export 42 --output draft-export.json
substack-mcp export 42 --format markdown --output draft.md

Markdown エクスポートでは、元の本文が変更されずに .source.json サイドカーファイルに保持されます。再利用する前に unsupported_nodes を確認してください。既存のファイルがある場合は --force が必要です。公開サイトの選択、制限、部分エクスポート、ファイルの復元については、エクスポートと CLI の動作を参照してください。

Markdown のサポート

下書きでは、見出し、太字・斜体・取り消し線の入れ子、リンクと参照リンク、キャプションとリンク先を含む画像、開始番号を指定した入れ子のリスト、コード、引用、水平線、強制改行などの CommonMark/GFM Markdown を使用できます。独立した `` ブロックを追加すると、長文形式の下書きにペイウォールが 1 つ追加されます。

サポート対象外のコンテンツがある場合、書き込み前に unsupported_nodes が返されます。診断結果を確認した後、下書きを呼び出す側は allow_unsupported: true を明示的に設定して、リテラルなフォールバックを保持できます。表はコードブロック内の Markdown として扱われます。ネイティブの表、コールアウト、任意の埋め込みは、サポート対象として案内していません。トップレベルの段落にある脚注は、長文形式の下書きではエディターのネイティブ脚注に変換されます。ノートでは、公開または添付ファイルの作成前に、サポート対象外の変換を拒否します。フォールバックを許可する設定はありません。

変換マッピング、制限、互換性に関する変更、オフラインのフィクスチャとライブエディターのチェックの違いについては、Markdown の記述方法をご覧ください。

重要な注意事項

  • このサーバーは Substack の非公式 APIを使用しています。Substack がエンドポイントを変更すると、動作しなくなる可能性があります。
  • セッショントークンは Cookie として送信されます。SUBSTACK_SESSION_TOKEN は安全に保管してください。
  • サーバーは MCP ハンドシェイクの完了後、起動時に認証情報を確認し、警告のみを表示します。ネットワーク呼び出しによって起動がブロックされることはありません。トークンの有効期限が切れている場合、各ツールは個別にエラーを返します。この場合はエラーから原因を特定できます。
  • SIGTERM と SIGINT は処理されます。サーバーはトランスポートを閉じて 0 で終了するため、docker stop は猶予期間が終わるのを待たずに速やかに戻ります。

開発

任意で実行できるライブ読み取りチェックについては、ライブ契約の証拠をご覧ください。 このプローブは通常の CI では無効で、公開や書き込みを行うことはありません。

リリース前に npm run test:package を実行してください。ビルド済み tarball を、本番用依存関係とともにクリーンな一時ディレクトリへインストールし、両方の実行可能なエントリーポイントをチェックして、実際の認証情報を使わずに MCP のバージョンと登録済みツールのカタログ全体を検証します。

git clone https://github.com/conorbronsdon/substack-mcp.git
cd substack-mcp
npm install
npm run build

ローカルで実行するには:

SUBSTACK_PUBLICATION_URL=https://yourblog.substack.com \
SUBSTACK_SESSION_TOKEN=your-token \
SUBSTACK_USER_ID=your-id \
npm start

貢献

Issue やプルリクエストを歓迎します。このサーバーは Substack の非公式 API を使用しているため、エンドポイントが変更された際の修正が最も役立つ貢献です。ツールが動作しなくなった場合は、ツール名とエラーを添えて Issue を作成してください。安全性を重視した設計方針は変わりません。長文形式の投稿は公開、削除、予約投稿を行いません。ノートは設計上すぐに公開されるため、そのことを説明文で明確に示し続ける必要があります。

概要

Conor Bronsdon が、Chain of Thought ポッドキャストの制作ワークフロー向けに構築・保守しています。このワークフローでは、人間が公開ボタンを押す前に、ニュースレターの投稿を下書きしてレビューします。Conor は、AI インフラストラクチャと、実務者が実際にそれをどのように構築しているかを扱う番組、Chain of Thought のホストです。クリエイター向けのその他のツールは、ai-tools-for-creators にあります。X では @ConorBronsdon をフォローしてください。

関連ツール:

  • Transistor MCP:Transistor.fm の公式 MCP サーバーです。エピソード、公開、分析に対応しています。
  • podcastindex-mcp:Podcast Index を検索し、ゲスト出演を追跡します
  • op3-mcp:OP3 のダウンロード数、リスナーの地域、アプリをレポートします
  • apple-podcasts-mcp:Apple Podcasts Connect から再生数、フォロワー数、エピソードごとのリスニング数を取得します
  • gsc-mcp:Google Search Console で検索パフォーマンス、キーワード、サイトマップを照会します
  • podcast-benchmark:公開データのみを使って、番組を同業番組と比較します

免責事項

これは個人による独立したプロジェクトであり、いかなる企業とも提携、協賛、承認関係にありません。ここに記載された見解はすべて個人のものです。

Codex プラグイン

このリポジトリには、.codex-plugin/plugin.json の Codex マニフェストと .mcp.json の MCP 設定が含まれています。npx を使用して、公開済みの npm パッケージを stdio 経由で実行します。 Node.js と npm が利用可能である必要があります。パッケージのバージョンは .mcp.json で固定されているため、プラグインのサーバーのアップグレードは明示的な変更となります。

Substack の認証情報は、上記で説明した環境変数またはブラウザーログインセッションを使用して、プラグインの外部で設定してください。 セッショントークンは決してコミットしないでください。インストールしても、アカウントの認証や投稿の承認が行われることはありません。 長文の投稿は下書きのままですが、Notes はすぐに公開されます。

ライセンス

MIT

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。