
Substack MCP Server
io.github.conorbronsdon由 GitHub 帳號 conorbronsdon 發布v1.3.0更新於 Oct 24, 2026
Substack drafts, Notes, analytics and consented subscribers. Long-form posts stay draft-only.
概覽
讓 AI 助理管理 Substack 電子報:撰寫與審閱草稿、檢索文章庫、查看數據與訂閱者,並發布 Notes。
- 可以做什麼
- 讀取出版品資料:訂閱者數量與紀錄、已發布與草稿文章、分區、標籤、留言、分析數據、成長來源與推薦關係
- 依關鍵字與狀態檢索文章庫,匯出草稿並做發布前檢查,附編輯器連結
- 以 Markdown 建立與更新私有草稿,先規劃再套用變更,並上傳圖片到 Substack CDN
- 立即發布短篇 Notes,可附上連結卡片
- 加入已同意的免費訂閱者,並以實驗性社群寫入方式留言或 restack
- 匿名讀取公開個人頁、動態、Notes 與文章,不帶出版品 Cookie
- 適用情境
- 適合希望讓助理準備與檢查草稿、查找歷史文章、查看訂閱者與分析數據,或直接在對話中發布 Notes 的電子報作者。長篇發布、刪除與排程仍需在 Substack 編輯器中完成。
- 執行需求
- 透過 npx 在本機執行,需要 Node.js 22 或更新版本。需要 SUBSTACK_PUBLICATION_URL、SUBSTACK_USER_ID 以及密鑰 SUBSTACK_SESSION_TOKEN(對應主機的 connect.sid Cookie),也可選用 Playwright 瀏覽器登入來儲存工作階段。另有選用的 SUBSTACK_PROFILES、SUBSTACK_CREDENTIAL_STORE 與 SUBSTACK_PUBLIC_READ_ORIGINS 設定。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Substack MCP Server,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
substack-mcp
Create and manage your Substack newsletter from your AI assistant or terminal. Prepare rich drafts, search your archive, publish Notes, inspect analytics, and manage explicitly consented free subscribers across publications. Review and publish long-form posts in Substack.
[License: MIT] [Language: TypeScript] [npm version] [MCP] [HOL Plugin Security Scan] [Podcast] [X]
[Create, search, export, plan and review a draft with substack-mcp]
The demo runs actual MCP handlers against offline sample data. No live API calls or publication occur. Follow the draft workflow to create, find, export and review a post.
Draft-only long-form posts; explicit public actions: This server cannot publish or delete long-form posts. Post tools create and edit drafts only; you review and publish manually through Substack's editor. Public community comments/restacks are separately experimental and consent-gated. Substack Notes also publish publicly: create_note and create_note_with_link publish short-form Notes immediately, because Notes have no draft state on Substack. Treat the Note tools as public-publish actions — there is no preview step and no undo from this server. The split is proportionate review, the piece of trust infrastructure for agents this server cares most about: the high-stakes surface gets a human gate, and the exception is stated loudly.
This server imposes no Bestseller-status check. Use an authenticated account with permission to manage the publication; individual operations depend on your Substack access. Connect through local stdio or self-hosted HTTP.
[substack-mcp MCP server]For 1.0 setup coverage and account eligibility, see compatibility. Run substack-mcp compatibility report for an offline, shareable diagnostic report; reporting guide. Maintainers can use the release checklist and distribution inventory.
Contents: Quick start · Setup · Tools · Operator CLI · Draft workflow · Analytics to draft · Export · Markdown · Multiple publications · Transports · Compatibility
Quick start
-
Install and sign in. Browser login needs the optional Playwright dependency:
Use your own account's user ID (how to find it). The session is saved only after a bounded authenticated read succeeds. To paste credentials instead, see Option B.
-
Verify a read.
npx substack-mcp doctor --json --check-authmakes one bounded read per publication. It confirms read access, not your user ID or write permission. -
Connect your MCP client. Add the server to Claude Desktop or Claude Code, or use the Codex plugin. Environment variables take precedence; omit them to use the stored browser-login session. Then ask your assistant: "How many Substack subscribers do I have?"
-
Prepare a draft for review. Follow the draft workflow:
create_draft,search_posts,export_draft,preflight_draft, thenplan_draft_updateandupdate_draft. Long-form posts stay unpublished drafts until you publish them in Substack's editor.create_noteandcreate_note_with_linkpublish immediately.
Community walkthrough
Jonathan Price's I used Codex to connect ChatGPT to Substack. Then it drafted this post. walks through using Codex to install the MCP locally, connecting ChatGPT through OpenAI's Secure MCP Tunnel, and creating a private draft for manual publication. He used the connection to create the draft of the guide itself.
The guide documents his September 18, 2026 setup with version 1.2.0. Its reported
get_post 404 is fixed in 1.2.1. Client interfaces and access requirements can
change; use the setup instructions below for this package's current
configuration. This is a community walkthrough, not a hosted service provided
by this project.
Setup
Requires Node.js 22 or newer (CI covers Node 22 and 24). Browser login additionally requires Playwright.
You can supply credentials two ways: paste them as env vars (below), or run the optional browser login which captures and stores them for you.
Option A — Browser login (optional, no manual cookie copying)
Install the server and optional Playwright dependency together in a local tools directory, then sign in:
substack-mcp-login remains a supported alias. Missing publication URL and user
ID are prompted. Supply your own account's user ID (steps below); a post author's byline does
not verify your identity. The browser opens for sign-in, including any CAPTCHA.
Login then opens <publication>/publish/home and waits for the publication
session cookie; on custom domains this is connect.sid on the custom domain.
A bounded authenticated read must succeed before saving. The default flow verifies
read access, not the configured user ID or permission to write.
To derive your ID from the selected publication's authenticated session instead of entering it manually, use:
--verify-identity reads the publication-host /api/v1/user/profile/self with
that host's cookie, requires a positive safe integer top-level ID, and then
performs the existing authenticated draft-list check before saving. Supplying
--user-id as well turns it into an assertion: a mismatch stops without saving
or replacing a profile, even with --force. No public profile, post byline,
other-host cookie or other-host endpoint is used as a fallback. The verified
mode's JSON result reports user_identity: "verified" and
identity_source: "authenticated_publication_self_profile"; it prints no ID.
This is an observation at login time, not a persisted identity attestation or
proof of write permission. Ordinary doctor continues to report identity as
unverified.
Self-profile support on publication hosts has not been live-verified for every Substack/custom-domain configuration. If the endpoint is unavailable, expired, redirected or malformed, verified mode fails closed and saves nothing. The existing manually configured-ID flow remains available and explicitly unverified. A real browser run is still needed for #150; fixture tests are not evidence about the current sign-in UI.
Without --profile, login saves ~/.substack-mcp/session.json (directory override:
SUBSTACK_MCP_HOME). The server uses this legacy session when publication
credential environment variables and SUBSTACK_PROFILES are unset.
Default storage (SUBSTACK_CREDENTIAL_STORE=file): sessions use AES-256-GCM with a key derived from the OS account and
machine. File permissions request 0600; Windows access also depends on directory
ACLs. This is a machine-bound file, not an OS keychain or secret vault. Code
running as your OS user can derive the key. Use environment credentials if your
MCP client manages secrets for you.
Optional OS keychain: set SUBSTACK_CREDENTIAL_STORE=keychain in both the
login process and the MCP client's environment. macOS uses Keychain via
/usr/bin/security; Linux needs libsecret and secret-tool plus an unlocked Secret
Service; Windows uses Credential Manager through PowerShell's PasswordVault. All
three are exercised with synthetic credentials by the keychain CI workflow on
GitHub-hosted runners (an unlocked temporary macOS keychain and a gnome-keyring
session on Linux); desktop setups with locked keychains may still prompt. Login writes the selected account to the keychain, and the
server reads it there. Explicit keychain selection never reads the encrypted
file as a fallback. The keychain helps against other OS users, copied disks,
and some malware limited to file access. Code running as your user can usually
query the keychain. Keep the OS account and running code trusted.
On Linux, secret-tool lookup can exit 1 without an error message for either
an absent entry or a locked keyring. Named writes without --force search and
unlock first, and refuse overwrites when an entry is found.
Named profiles and migration
Keys start with a lowercase ASCII letter and contain only lowercase letters,
digits and hyphens, up to 64 characters. Existing profiles require explicit
--force to replace. List output contains keys, readability status, publication origins and file save
times; it excludes cookies and user IDs. Unreadable profiles remain visible but
cannot be selected. Save time records local persistence, including migration; it
is not token issuance or expiration time. Listing is bounded to 32 profiles.
Profile storage requires a local filesystem supporting hard links (such as NTFS
or a typical Linux filesystem), so creation can install a complete encrypted file
without overwriting an existing name. FAT/exFAT and some network mounts are not
supported: set SUBSTACK_MCP_HOME to a suitable local directory. Do not use
--force to work around an unsupported filesystem.
Set SUBSTACK_PROFILES=work,personal in your MCP client's environment to select
up to 32 distinct profiles. Remove all publication credential variables first:
combining profile selection with legacy or named credential variables is an
error, including empty variables. Missing, corrupt or invalid selected profiles
stop startup; they never fall back to another account. Profiles on disk are
never activated by discovery. With multiple profiles, tools require an explicit
publication key and CLI reads require --publication.
To roll back, unset SUBSTACK_PROFILES and restore your previous environment
configuration. Migration preserves the legacy session byte-for-byte. These files
use the existing encryption format. profiles list lists file profiles; select
keychain profiles explicitly with SUBSTACK_PROFILES after migration or login.
Run substack-mcp status --json for offline configuration diagnostics or
substack-mcp doctor --check-auth --json for a bounded read per selected account.
Option B — Get your credentials manually
Open your Substack in a browser, then:
- Session token: For custom domains, open DevTools → Application → Cookies →
https://your-custom-domainand copyconnect.sidfrom the publication's own domain (URL-encoded string starting withs%3A). Do not copysubstack.sidfrom substack.com: it is a different session that the custom domain's admin API rejects with 403. For*.substack.compublications, useconnect.sidon that host orsubstack.sidon.substack.com. The token must match the host ofSUBSTACK_PUBLICATION_URL, with the.substack.comfallback only for Substack-hosted publications. - User ID: Follow Find your account user ID. Do not use a publication post's byline ID: publications can have multiple authors. This server does not independently verify the supplied ID.
- Publication URL: Your Substack URL, including custom domain if you have one (e.g.,
https://newsletter.yourdomain.comorhttps://yourblog.substack.com)
Find your account user ID
- In Substack, open your own account profile and copy its handle (the part after
@inhttps://substack.com/@your-handle). A publication URL or another author's profile is not your account handle. - Open
https://substack.com/api/v1/user/your-handle/public_profilewith that handle substituted. Read the top-level numericidin the JSON response; do not use an ID nested under a publication or post byline. This public profile endpoint is also used by this server's anonymous profile lookup. - Confirm that the response's
handleand name match the account you will sign in with. Supply the top-levelidtologin --user-idorSUBSTACK_USER_ID. A public profile lookup identifies the handle you entered; the browser-login read check does not prove that the cookie belongs to that ID. Recheck the account before any write operation.
2. Configure your MCP client
Claude Desktop
Add to your claude_desktop_config.json:
Claude Code and Codex plugin setup is available alongside manual MCP configuration. The repository marketplace and local plugin are separate from curated-directory acceptance or hosted ChatGPT support.
Claude Code
Add to your .mcp.json:
3. Verify
Ask your AI assistant: "How many Substack subscribers do I have?"
Tool output compatibility, response limits and versioning are documented in the tool contract.
Operator diagnostics
The CLI exposes operator commands and configuration checks through the same MCP
handlers and credential resolution as the server. drafts create writes one
private draft; the other operator commands read:
Commands, the JSON envelope, exit codes, request deadlines and response limits are documented in operator CLI and diagnostics.
Tools
Every tool declares explicit MCP side-effect annotations; see tool annotations. Tool descriptions carry the authoritative wording.
Read
Public reading
These five tools use a separate anonymous reader. It sends only User-Agent and
Accept, never the configured publication cookie or other credentials. The
configured publication selects the default archive origin; callers may supply an
allowlisted HTTPS publication origin. Allowed hosts are substack.com, one-label
*.substack.com, configured publication origins, and exact origins in
SUBSTACK_PUBLIC_READ_ORIGINS (comma-separated HTTPS origins without ports,
paths or userinfo). Redirects are rejected. A *.substack.com publication may
redirect to its custom domain (for example, lenny.substack.com); JSON reads do
not follow that redirect. Add the custom HTTPS origin to
SUBSTACK_PUBLIC_READ_ORIGINS and read through that origin. With multiple
publications, the publication key remains required for every publication tool.
Profile feed pages are upstream-sized; has_more: null means the upstream omitted
continuation metadata. Thread pages can omit replies when more_branches or
next_cursor is present; completeness: "unknown" means continuation metadata
was omitted.
Archive full pages have has_more: null because no total is returned. Public
post body_status is a heuristic based on audience and body presence; it does
not establish full access. The anonymous reader does not use subscription
entitlements. Reader subscriptions and inbox are unsupported: the configured
publication session received 401 on the substack.com reader-account routes,
which require a separate reader session this server does not manage.
Archive search and draft review
search_posts accepts query (1–500 characters), status (published, drafts,
or scheduled, default published), offset (default 0), and limit (1–50,
default 25). It makes one authenticated archive request and returns projected
metadata, returned, total, has_more, and next_offset. Continue with
next_offset and the same query/status. When Substack omits the total and a
page is full, has_more is null (unknown); another page may be empty. Substack
controls matching and indexing: this is not a guaranteed full-text scan. Use
get_post or get_draft to retrieve full content. Pagination is not a snapshot;
concurrent edits can move results between pages.
preflight_draft accepts draft_id, reads it once, and returns checks_passed,
findings with severity/code/message, content counts and an editor link. It checks title,
audience, JSON/body shape, image wrappers and HTTPS sources, and paywall count
and edge placement. Unknown nodes and external images produce review warnings.
Bodies over two million characters, 10,000 nodes, or depth 100 are not fully
checked; counts.complete is false and aggregate checks are skipped after a
scan limit. Unknown-node warnings name up to five types for editor review.
This is a focused static check, not full ProseMirror validation or
publish approval. It does not fetch links/images, verify access settings, or
prove final rendering. Review the draft in Substack; no content is modified.
Both tools require publication when multiple publications are configured.
Write (private drafts; image upload returns a public URL)
Review before changing a draft
In 0.9, call plan_draft_update, review its output, then call update_draft with
the same fields and returned receipt. Published or known stale drafts are
rejected. The read/write race remains; check readback outcomes and review in
Substack. The CLI shares this flow through drafts plan and drafts apply.
See draft changes and migration for examples and limits.
Public community writes (experimental)
Live attempts require SUBSTACK_EXPERIMENTAL_COMMUNITY_WRITES=1,
dry_run=false, confirm_publish=true and explicit approval of the exact
account, target and text. Restacks additionally need a separate reader session.
Both tools check the authenticated identity before writing, attempt one POST,
and report bounded readback outcomes without automatic retries. The endpoints
have source evidence; live verification remains pending. See
setup, credential routing, consent and limitations.
Publish (Notes — public immediately)
Notes have no draft state on Substack, so there is no draft-first option for these two tools.
Subscriber management
add_free_subscriber adds one consenting reader to the free newsletter. It is
a distribution change: that reader may receive future newsletter emails. It
can request a welcome email with send_welcome_email: true (off by default).
It never grants paid access or overrides Substack's
suppression of previously unsubscribed addresses. Its MCP annotations identify
it as an external write (readOnlyHint: false, openWorldHint: true).
Dry-run is the default. After checking actual newsletter consent, set
dry_run: false to execute. Live adds require the source reference and timestamp
in consent_evidence; this attestation is echoed with the publication key for
auditing and does not replace checking the underlying consent record.
Multi-publication configurations also require the
publication selector, just like every other tool.
Results distinguish existing, dry_run, verified, blocked, and
unverified, busy, and retryable. busy performs no write; wait for the
other operation. retryable means authentication or rate limiting refused the
request; resolve that condition before explicitly retrying. An empty API acknowledgement is not proof of addition.
verified means an exact membership lookup succeeded after the request; it
does not prove that this request originally created the membership. Dashboard
data can lag. A missing reader may also have previously unsubscribed.
For unverified, recheck with get_subscriber; never automatically repeat the
add. For blocked, review in Substack without bypassing suppression. Automated
callers must persist an attempt ledger before sending each live request.
The client's in-memory duplicate guard does not survive restarts or separate
HTTP sessions. Keep subscriber identities and consent evidence out of shared
repositories, prompts to unapproved public services, and routine logs.
Implementation and live verification notes: subscriber API.
For Google Calendar booking opt-ins, the calendar sync helper provides a bounded Gmail scan, latest-answer selection, a private durable attempt ledger, and read-only reconciliation after uncertain writes. Scheduling is an explicit local setup step; installing the MCP does not start a background job.
Intentionally excluded
- Publish posts — Publishing long-form posts should be a deliberate human action (Notes are the documented exception above)
- Delete — Too destructive for an AI tool
- Schedule — Use Substack's editor for scheduling. (
list_scheduled_postsreads what you've queued there, but this server never creates, edits, or cancels a schedule.)
For an always-on scheduler with durable cloud state and weekly email reports, see Cloud Calendar sync.
Multiple publications
Running more than one publication behind a single server? Set a SUBSTACK_PUB_<KEY>_* triplet per publication instead of the plain SUBSTACK_* vars. <KEY> is any name you choose (letters, digits, underscores) — it becomes the publication's lowercase, hyphenated key, e.g. KEVIN_MULDOON → kevin-muldoon.
Each triplet is independent, and setting any SUBSTACK_PUB_<KEY>_* variable declares that publication. An incomplete triplet — a missing variable, an empty value, or a whitespace-only value — fails startup with an error naming the key, rather than silently dropping that publication. That matters because a dropped publication is not "one fewer publication": drop the only one and the server falls back to your stored browser-login session; drop one of two and every tool loses its publication parameter, so a call meant for the dropped publication routes silently to the surviving one.
Keys are compared case-insensitively, with _ folded to -. Two names that resolve to the same key (SUBSTACK_PUB_ALPHA_* and SUBSTACK_PUB_Alpha_*) are a startup error too — merging them silently would let one publication's URL pair with another's session token.
<KEY> accepts ASCII letters, digits, and underscores; the three suffixes must be uppercase and the whole name must have no stray whitespace. Anything that begins with SUBSTACK_PUB_ but does not fit that shape — a hyphen in the key, a lowercase suffix, an accented character, a trailing space — is a startup error naming the variable, not a variable that gets quietly ignored. For the same reason as above: an ignored publication is not one fewer publication, it is a silent reroute to a different one.
With two or more publications configured, every publication tool gains a required publication parameter — one of your configured keys (e.g. kevin-muldoon, sapere above). The calling model must specify one on every publication call; an unrecognized value is rejected before any Substack API call is made, so a stray write can't land on the wrong publication. With exactly one publication configured — the common case, whether via plain SUBSTACK_* vars or a single SUBSTACK_PUB_<KEY>_* triplet — no publication parameter is added at all; every tool's schema is unchanged from single-publication mode.
Don't mix the two styles: if any SUBSTACK_PUB_<KEY>_* var is set, the plain SUBSTACK_* vars are ignored (with a startup warning) rather than treated as an unnamed extra publication.
The account-wide restack tool uses an explicit reader account_user_id instead of a publication parameter. Its reader credential is configured separately; it never uses a publication session.
SUBSTACK_USER_AGENT and SUBSTACK_REQUEST_TIMEOUT_MS apply to every configured publication — they are not per-publication. Browser login also supports explicit named profiles; see Named profiles and migration.
Token expiration
Substack session tokens expire periodically (typically ~90 days). If you get authentication errors, re-run substack-mcp login to refresh the stored session, or copy a fresh cookie from DevTools on the matching publication host and update the env var. Custom domains require their own connect.sid, not substack.com's different substack.sid session (which the custom domain rejects with 403). For *.substack.com publications, use connect.sid on that host or substack.sid on .substack.com. Then run substack-mcp doctor --check-auth to verify access.
Custom domains & Cloudflare
This section covers authenticated creator API calls. Anonymous public reading uses the public reading origin rules above.
Substack publications served on a custom domain (e.g. blog.example.com) sit behind Cloudflare, which can reject non-browser requests with 403 error code: 1010. To avoid this, the server sends a browser User-Agent and a Referer by default, and uses the configured publication URL.
- Match the host and cookie. If using the canonical
*.substack.comURL, use its host session or the.substack.comfallback. A custom-domainconnect.sidpairs with the custom-domainSUBSTACK_PUBLICATION_URL. - Override the User-Agent (optional) via
SUBSTACK_USER_AGENTif you need a different browser signature:
Request timeout
Every request to Substack is bounded by a 30-second deadline. Node applies no request timeout of its own — only a 10-second connect timeout — so a host that accepts the connection and then goes silent (a proxy that drops packets rather than refusing them) would otherwise hang a tool call indefinitely. A request that hits the deadline fails with a TimeoutError naming the endpoint and the limit.
Raise or lower it with SUBSTACK_REQUEST_TIMEOUT_MS (milliseconds; a non-numeric or non-positive value is ignored with a warning and the default is used):
Transports
By default the server speaks MCP over stdio, which the client configurations
above assume. Set MCP_TRANSPORT=http for a stateless Streamable HTTP server
(POST /mcp, GET /health) in a persistent, self-hosted deployment. Setup,
listener variables and the security model are in HTTP transport.
What this listener will accept
The HTTP listener starts closed: loopback Host and Origin allowlists by
default, an optional bearer token (MCP_HTTP_TOKEN) and a 10 MiB body cap. Host
and Origin checks are not authentication; set a token wherever other processes
can reach the port. See the listener policy.
Versioned GHCR images and transport verification: container distribution.
Typed errors
API failures map to typed errors (AuthenticationError, RateLimitError,
ValidationError, NotFoundError, ServerError, TimeoutError, and the base
SubstackAPIError). The status mapping and error-body parsing are documented in
typed errors.
Draft export
Use export_draft for a read-only Markdown/JSON bundle, or run:
Markdown exports retain the exact original body in a .source.json sidecar.
Inspect unsupported_nodes before reuse. Existing files require --force.
See export and CLI behavior for publication selection, limits,
partial exports and file recovery.
Markdown support
Drafts accept CommonMark/GFM Markdown: headings, nested bold/italic/strikethrough,
links and reference links, images with captions and linked destinations, nested
lists with starting numbers, code, blockquotes, rules and hard breaks. A standalone
<!-- paywall --> block adds one paywall to a long-form draft.
Unsupported content returns unsupported_nodes before a write. After reviewing
those diagnostics, draft callers can explicitly set allow_unsupported: true
to retain literal fallbacks. Tables remain Markdown inside code blocks; native
tables, callouts and arbitrary embeds are not advertised as supported. Footnotes
in top-level paragraphs map to the editor's native footnotes in long-form drafts.
Notes reject unsupported conversion before either publication or attachment
creation and have no fallback override.
See Markdown authoring for mappings, limits, compatibility changes and the distinction between offline fixtures and live editor checks.
Important notes
- This server uses Substack's unofficial API. It may break if Substack changes their endpoints.
- Session tokens are sent as cookies. Keep your
SUBSTACK_SESSION_TOKENsecure. - The server checks your credentials on startup, after the MCP handshake completes, and only warns — it never blocks startup on a network call. Tools still error individually if the token is expired, which is where the failure is actionable.
SIGTERMandSIGINTare handled: the server closes its transport and exits 0, sodocker stopreturns promptly instead of waiting out the grace period.
Development
For opt-in live read checks, see live contract evidence. The probe is disabled in ordinary CI and never publishes or writes.
Before releasing, run npm run test:package. It installs the built tarball with production dependencies in a clean temporary directory, checks both executable entrypoints, and verifies the MCP version and the complete registered tool catalog without real credentials.
Run locally:
Contributing
Issues and pull requests are welcome. Because this server uses Substack's unofficial API, the most useful contributions are fixes when an endpoint changes. If a tool stops working, open an issue with the tool name and the error. The safe-by-design boundary stays: no publish, no delete, no schedule for long-form posts. Notes publish immediately by design and must keep saying so loudly in their descriptions.
About
Built and maintained by Conor Bronsdon for the Chain of Thought podcast production workflow, where it drafts and reviews newsletter posts before a human hits publish. Conor hosts Chain of Thought, a show about AI infrastructure and how practitioners actually build with it. More tools for creators live in ai-tools-for-creators. Find Conor on X at @ConorBronsdon.
Companion tools:
- Transistor MCP: Transistor.fm's official MCP server. Episodes, publishing, and analytics.
- podcastindex-mcp: search the Podcast Index and track guest appearances
- op3-mcp: report downloads, listener geography, and apps from OP3
- apple-podcasts-mcp: pull plays, followers, and per-episode listening from Apple Podcasts Connect
- gsc-mcp: query search performance, keywords, and sitemaps in Google Search Console
- podcast-benchmark: benchmark a show against its peers using only public data
Disclaimer
This is an independent personal project, not affiliated with, sponsored by, or endorsed by any company. All views expressed are my own.
Codex plugin
The repository includes a Codex manifest at .codex-plugin/plugin.json and an
MCP configuration at .mcp.json. It runs the published npm package over stdio
using npx; Node.js and npm must be available. The package version is pinned
in .mcp.json, so upgrading the plugin's server is an explicit change.
Configure your Substack credentials outside the plugin using the environment variables or browser-login session described above. Never commit a session token. Installation does not authenticate an account or grant approval to post. Long-form posts remain drafts; Notes publish immediately.
License
MIT
來源:README.md,提交 21468d9
工具
0版本歷史
3- v1.3.0最新Sep 24, 2026
- v1.2.1Sep 18, 2026
- v1.2.0Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分