关于 substack-ops
substack-ops 是用于管理 Substack 帖子、笔记、评论及相关活动的 Python 命令行工具和 MCP 服务。它支持 IDE 协助起草回复,并提供审核与去重控制,且无需 AI API 密钥。
主要功能
- 01读取和管理帖子、笔记及评论
- 02起草并审核回复
- 03配置定期自动化任务
- 04记录写入并防止重复操作
- 05Textual 终端界面
适用场景
- 01查找未回复评论并准备回复
- 02发送前审核已批准的草稿
- 03按规则处理回应或新笔记
- 04查看出版物动态和活动
MCP 相关
stdio MCP 服务提供 26 个工具,可安装到支持的主机或手动配置。提议并确认回复的工具可让主机 LLM 起草回复,无需单独的 AI API 密钥。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx substack-opsSUBSTACK_PUBLICATION_URLYour Substack publication URL (e.g. https://you.substack.com/). Optional if set in ~/.cursor/mcp.json's mcpServers.substack-api.env.SUBSTACK_USER_IDYour Substack numeric user id. Optional if set in ~/.cursor/mcp.json.SUBSTACK_SESSION_TOKEN密钥Your Substack session cookie value (the s%3A... string). Required for authenticated calls. Easier path: run `substack-ops auth login --browser chrome` and the cookie is auto-grabbed.SUBSTACK_OPS_MCP_PATHOverride path to the mcp.json file the auth layer reads. Defaults to ~/.cursor/mcp.json.SUBSTACK_OPS_LLM_CMDOptional: override the host CLI used by the unattended daemon path (default: auto-detect claude / cursor-agent / codex on PATH). Use {prompt} placeholder if your CLI takes the prompt as an arg.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
substack-ops
独立的 Substack CLI + 26 工具 MCP 服务,适用于 Cursor MCP、Claude MCP、OpenCode MCP,以及任何 stdio MCP 主机。由你的 IDE 起草回复。无需 AI API 密钥。
网站 → substack-ops.chavan.in · 源码 → 06ketan/substack-ops · Glama → mcp/servers/06ketan/substack-ops
文章、笔记、评论、回复、反应、转发、推荐、搜索、 个人资料、信息流、自动化、MCP 服务、Textual TUI。一次 Python 安装,一个 二进制文件,采用 MIT 许可证。
简而言之 — MCP 原生(无需 API 密钥,只需一条命令)
uvx substack-ops mcp install cursor # or claude-desktop, claude-code, opencode, print
# Restart your host. Then in chat:
# "list unanswered comments on post 193866852"
# "draft a warm reply to comment 12345"
# "post that draft"
由主机的大模型(Cursor 的、Claude 的)通过
propose_reply / confirm_reply 工具起草内容。无需 ANTHROPIC_API_KEY /
OPENAI_API_KEY。
安装方式不对?
本项目在 PyPI 上的名称是 substack-ops——请使用 uv / uvx 安装,而不是搜索“Substack MCP”时出现的无关 npx 包。权威列表:Glama — 06ketan/substack-ops。
兼容的 MCP 主机
以下条目可帮助发现项目(搜索关键词);升级前请确认每个主机当前的 MCP 文档。
面向开源的主机
| 主机 | 文档 | 常见接入方式 |
|---|---|---|
| OpenCode | OpenCode MCP 服务 | uvx substack-ops mcp install opencode |
| Continue | Continue | uvx substack-ops mcp install print — 将代码片段粘贴到 Continue 的 MCP 设置中 |
| Zed | Zed | 按照 Zed 文档配置 stdio MCP |
| Cline | Cline | 按照扩展程序 / 插件市场文档设置 MCP |
| Goose | Goose | 按照 Goose 文档使用 MCP 扩展 |
大型商业技术栈
| 宿主 | 文档 | 典型接入方式 |
|---|---|---|
| Cursor | Cursor MCP | uvx substack-ops mcp install cursor |
| Claude(Desktop / Code) | Claude Desktop,Claude Code | mcp install claude-desktop / claude-code |
| GitHub Copilot | Copilot | 在支持的 VS Code / Copilot 中使用 MCP — 使用 print + 宿主文档 |
| ChatGPT | OpenAI | 开发者 / 连接器流程 — 对不支持 MCP 的工具,通常使用 REST(Slideshot API) |
| Google Gemini | Gemini | 根据 Google 文档使用 Gemini CLI / IDE 功能 — 在支持的情况下使用 stdio |
OpenCode(复制粘贴)
自动安装:
uvx substack-ops mcp install opencode
手动安装(~/.config/opencode/opencode.json):
{
"mcp": {
"substack-ops": {
"type": "local",
"command": ["uvx", "substack-ops", "mcp", "serve"],
"enabled": true
}
}
}
可选的版本固定:使用 ["uvx", "substack-ops==0.3.5", "mcp", "serve"](替换为当前的 PyPI 版本)。
设置(开发 / 从源码构建)
git clone https://github.com/06ketan/substack-ops && cd substack-ops
uv sync
uv sync --extra mcp # mcp SDK for the MCP server (recommended)
uv sync --extra tui # textual for the TUI
uv sync --extra chrome # pycryptodome + keyring for Chrome cookie auto-grab
身份验证默认使用 ~/.cursor/mcp.json 中的 mcpServers.substack-api.env。可通过环境变量或 .env 覆盖。也可以使用 auth login / auth setup 中的一种身份验证流程。
uv run substack-ops auth verify
uv run substack-ops quickstart # 20-step tour
命令概览
按用途分组。所有写入操作默认使用 --dry-run;使用 --no-dry-run 切换(不可逆操作还需使用 --yes-i-mean-it)。所有写入内容都会记录到 .cache/audit.jsonl,并通过 .cache/actions.db 进行重复检查。
身份验证(4)
| 命令 | 功能 |
|---|---|
auth verify | 确认 Cookie 有效;打印已验证身份的用户 / publication。 |
auth test | 与 verify 相同,失败时返回非零退出码(适合 CI)。 |
auth login --browser chrome|brave | 通过 macOS Keychain 自动从本地 Chromium 浏览器获取 Cookie。 |
auth login --email [email protected] | 通过电子邮件发送魔法链接 → 粘贴链接的交互流程。 |
auth setup | 交互式粘贴 connect.sid Cookie。 |
读取 — 帖子(8)
| 命令 | 功能 |
|---|---|
posts list [--pub] [--limit] [--sort new|top] | 列出某个 publication 的帖子(默认列出你自己的)。 |
posts show <id|slug> [--pub] | 帖子元数据(标题、日期、反应数、评论数)。 |
posts get --slug <slug> [--pub] | 与 show 相同,但仅使用 slug。 |
posts content <id> [--md] [--pub] | HTML 正文(可根据身份验证访问付费内容)。--md 会转换为 Markdown。 |
posts stats <id> | 互动数据 — 反应数、评论数。 |
posts search <query> [--pub] [--limit] | Substack 端全文搜索。 |
posts paywalled <id> [--pub] | 布尔值:此帖子是否为付费内容? |
posts react <id> [--off] [--pub] | 添加反应(使用 --off 移除)。默认使用 ❤。 |
posts restack <id> [--off] | 转发帖子(Substack 不支持取消转发)。 |
读取 — Notes(5)
| 命令 | 功能 |
|---|---|
notes list [--limit] | 你发布的 Notes。 |
notes show <id> | 一条 Note 及其回复树。 |
notes publish <body> [--no-dry-run] | 发布一条顶层 Note。 |
notes react <id> [--off] | 对任意 Note 添加反应。 |
notes restack <id> [--off] | 转发一条 Note。 |
读取 + 写入 — 评论(5)
| 命令 | 功能 |
|---|---|
comments tree <post_id> [--pub] | 以表格形式显示完整的嵌套评论树。 |
comments export <post_id> --out file.json [--pub] | 将同一评论树导出为 JSON。 |
comments add <post_id> <body> [--pub] [--no-dry-run] | 添加新的顶层评论。 |
comments react <id> --kind post|note [--off] | 对评论添加反应。 |
comments delete <id> --kind post|note [--no-dry-run] | 具有破坏性 — 只能删除你自己的评论。 |
回复引擎(6)
| 命令 | 功能说明 |
|---|---|
reply template <post_id> --template thanks | 基于规则回复(不使用大模型)。 |
reply review <post_id> | 大模型为每条评论起草回复,你可以选择 [a]ccept / [e]dit / [s]kip / [q]uit。 |
reply bulk <post_id> --out drafts.json | 将每条评论的回复草稿保存到文件。编辑文件,并设置 action: "approved"。 |
reply note-bulk <note_id> --out drafts.json | 对 Note 下的回复执行相同操作。 |
reply bulk-send drafts.json [--no-dry-run] | 仅发布标记为 approved 的条目。发送前会检查重复项。 |
reply auto <post_id> --no-dry-run --yes-i-mean-it | 起草并立即发布。速率限制为 30s。 |
阅读 — 发现(8)
| 命令 | 功能说明 |
|---|---|
feed list --tab for-you|subscribed|category-{slug} | 阅读动态流(Substack 应用的动态流)。 |
profile me / profile get <handle> | 查看个人资料。 |
users get <handle> / users subscriptions <handle> | 查看公开用户信息及其订阅内容。 |
podcasts list [--pub] | 音频文章。 |
recommendations list [--pub] | 查看出版物推荐的出版物。 |
authors list [--pub] | 查看出版物的投稿人列表。 |
categories list / categories get --name <X> | 查看 Substack 的分类体系。 |
自动化(3)
| 命令 | 功能说明 |
|---|---|
auto presets | 列出内置 YAML 规则。 |
auto run <name> | 一次性运行预设。 |
auto daemon <name> --interval 60 | 无限循环运行;日志写入审计记录。 |
运维与安全(3)
| 命令 | 功能说明 |
|---|---|
audit search [--kind] [--target] [--status] [--since 7d] | 查询 JSONL 审计日志。 |
audit dedup-status | 查看去重 SQLite 数据库中的计数。 |
quickstart | 20 步交互式导览。 |
MCP 服务(3)
| 命令 | 功能说明 |
|---|---|
mcp install <cursor|claude-desktop|claude-code|opencode|print> [--dry-run] | 自动将配置合并到你的宿主应用中。 |
mcp serve | stdio MCP 服务(26 个工具)。 |
mcp list-tools | 打印工具注册表。 |
其他(1)
| 命令 | 功能说明 |
|---|---|
tui | Textual TUI — 6 个选项卡(Notes、Posts、Comments、Feed、Auto、Profile)。 |
多出版物
每个读取命令都接受 --pub <subdomain|domain>。默认使用你自己的
出版物。
substack-ops posts list --pub stratechery --limit 5
substack-ops posts search "ai" --pub stratechery
substack-ops recommendations list --pub stratechery
回复模式
| 模式 | 功能说明 | 安全性 |
|---|---|---|
template | src/substack_ops/templates/*.yaml 下的 YAML 关键词/正则规则 | 默认试运行 |
review | 大模型为每条回复起草内容,你可以选择 [a]ccept / [e]dit / [s]kip / [q]uit | 默认试运行 + 对每条评论进行人工确认 |
bulk | 大模型为每条评论起草回复,并保存到 drafts.json。编辑文件,并设置 action: "approved" | 离线审核;发送时检查重复项 |
bulk-send | 仅发布 action: "approved" 的条目 | 默认试运行;去重数据库可防止 M2 中 31 条重复回复的回归问题 |
auto | 大模型起草回复并立即发布 | 需要 --no-dry-run --yes-i-mean-it,速率限制为 30s |
每次实时回复 Note 后,引擎都会重新获取新评论,并断言
ancestor_path 非空。如果为空,审计记录中的 result_status 会
被改为 "orphaned"(这能捕获 M2 中 parent_comment_id 被悄然
丢弃的问题)。
自动化
内置预设(auto presets):
- like-back — 有人对你的 Note 作出回应时,对其最新 Note 作出回应。
- auto-reply — 触发条件相同,但会发布模板化的感谢回复。
- auto-restack — 关注列表中的用户发布新 Note 时,将其 restack。
- follow-back — 有人关注你时,回关对方。
自定义 YAML 规则位于 ~/.config/substack-ops/auto/*.yaml。使用
auto daemon <name> --interval 60 循环运行。
MCP 服务
substack-ops mcp install opencode # auto-add to ~/.config/opencode/opencode.json
substack-ops mcp install cursor # auto-add to ~/.cursor/mcp.json
substack-ops mcp install claude-desktop # auto-add to claude_desktop_config.json
substack-ops mcp install claude-code # uses `claude mcp add` under the hood
substack-ops mcp install print # print the snippet only
substack-ops mcp install cursor --dry-run # preview without writing
substack-ops mcp serve # stdio server
substack-ops mcp list-tools # 26 tools
手动配置片段(如果你更喜欢手动配置):
{
"mcpServers": {
"substack-ops": {
"command": "substack-ops",
"args": ["mcp", "serve"]
}
}
}
如果未安装 mcp SDK,服务会回退到精简的
stdin/stdout JSON 行分发器,仍可用于脚本编写:
echo '{"tool":"list_posts","args":{"limit":3}}' | substack-ops mcp serve
MCP 原生回复草拟循环(无需 API 密钥)
3 个工具专为让你的宿主大模型替你草拟回复而设计:
| 工具 | 功能 |
|---|---|
get_unanswered_comments | 返回待办列表:你尚未回复的评论(不限层级)。 |
propose_reply | 仅试运行。返回 token 和载荷预览。不会写入。 |
confirm_reply | 通过 token 发布之前提议的回复。通过去重数据库保证幂等性。Token 有效期为 5 分钟。 |
特色工具(让无人值守模式安全运行的安全与草拟工具栈):bulk_draft_replies、send_approved_drafts、audit_search、dedup_status、get_unanswered_comments、propose_reply、confirm_reply。
大模型策略
两个层级,均免费:
- MCP 原生(默认)。 宿主大模型通过
propose_reply/confirm_reply草拟回复。无需环境变量或 API 密钥。适用于交互式回复。 - 子进程 CLI(守护进程路径)。 用于
reply auto/auto daemon,适用于没有人工参与的情况。自动检测 PATH 中的claude(Claude Code)、cursor-agent或codex。可通过SUBSTACK_OPS_LLM_CMD覆盖。
不提供付费 API 密钥方案。如果需要,请自行从 substack-ops v0.2.0 移植旧版 _anthropic / _openai 方法。
Textual TUI
substack-ops tui
6 个标签页:笔记 / 文章 / 评论 / 动态 / 自动化 / 个人资料。 子标签页:1=我的,2=关注中,3=综合。 按键:tab、1-3、↑/↓、enter、r、l、s、o、q/esc。
认证方式
substack-ops auth verify # uses mcp.json or env
substack-ops auth login # auto-grab cookies from Chrome (macOS Keychain)
substack-ops auth login --browser brave
substack-ops auth login --email [email protected] # email magic-link, paste-the-link mode
substack-ops auth setup # interactive paste cookies
架构
mcp.json | env | Chrome | OTP → auth.py / auth_chrome.py / auth_otp.py
│
.cache/cookies.json
│
SubstackClient (httpx)
│
┌──────┬──────┬───────┬───────┬───────┬──────┬──────┬─────┬──────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
posts notes comments feed profile users recs cats ... reply_engine
│
┌───────────────┼────────────┐
▼ ▼ ▼
template ai_review ai_bulk + ai_auto
└───────────────┬────────────┘
▼
base.post_reply / post_note_reply
│
┌────────┼────────┐
▼ ▼ ▼
dedup audit ancestor_path
(SQLite) (jsonl) guardrail
auto/engine.py ────────────────┐
mcp/server.py ──── 23 tools ──┼─── all share SubstackClient
tui/app.py ──── 6 tabs ──┘
使用的端点
| 操作 | 方法 + URL |
|---|---|
| 认证检查 | GET https://substack.com/api/v1/subscriptions |
| 列出文章 | GET {pub}/api/v1/archive |
| 按 ID 获取文章 | GET {pub}/api/v1/posts/by-id/{id} |
| 按 slug 获取文章 | GET {pub}/api/v1/posts/{slug} |
| 文章内容 | 与上方相同;body_html 字段 |
| 搜索文章 | GET {pub}/api/v1/archive?search= |
| 评论 | GET {pub}/api/v1/post/{id}/comments?all_comments=true |
| 回复评论 | POST {pub}/api/v1/post/{id}/comment,请求体 {body, parent_id} |
| 添加顶级评论 | 与上方相同,使用 parent_id: null |
| 对文章作出回应 | POST {pub}/api/v1/post/{id}/reaction,请求体 {reaction} |
| 转发文章 | POST https://substack.com/api/v1/restack,请求体 {post_id} |
| 转发笔记 | POST https://substack.com/api/v1/restack,请求体 {comment_id} |
| 删除文章评论 | DELETE {pub}/api/v1/comment/{id}(PUB 主机) |
| 删除笔记 | DELETE https://substack.com/api/v1/comment/{id}(裸主机) |
| 我的笔记 | GET https://substack.com/api/v1/reader/feed/profile/{user_id} |
| 笔记讨论串 | GET https://substack.com/api/v1/reader/comment/{note_id} |
| 笔记回复 | GET https://substack.com/api/v1/reader/comment/{note_id}/replies |
| 发布笔记 | POST https://substack.com/api/v1/comment/feed,请求体 {bodyJson} |
| 回复笔记 | 与上方相同,使用 {bodyJson, parent_id}(不要使用 parent_comment_id——已知的 M2 错误) |
| 对评论作出回应 | POST {host}/api/v1/comment/{id}/reaction(文章评论的 host 为 pub,笔记的 host 为 substack.com) |
| 推荐内容 | GET {pub}/api/v1/recommendations/from/{publication_id} |
| 作者 | GET {pub}/api/v1/publication/users/ranked?public=true |
| 类别 | GET https://substack.com/api/v1/categories |
| 用户个人资料 | GET https://substack.com/api/v1/user/{handle}/public_profile(404 时自动重定向) |
| 阅读器动态 | GET https://substack.com/api/v1/reader/feed/{recommended|subscribed|category/{slug}} |
相关 MCP
- slideshot — HTML → 幻灯片(PNG / PDF / PPTX);npm 包
slideshot-mcp。 - medium-ops — Medium 故事、回复及 MCP(PyPI 包
medium-ops)。
测试
uv run pytest -q # 43 tests, ~0.6s, no live network
当前覆盖范围:认证、客户端(读取 + 写入 + 互动 + 删除)、回复引擎、去重数据库、审计日志搜索、MCP 工具注册表与分发器、自动化引擎预设加载器、M2 parent_id 回归测试、M2 主机不匹配回归测试。
GSD 工作流
为 Get Shit Done 在
~/.claude/skills/gsd-* 下搭建 .planning/ 框架。路线图位于 .planning/ROADMAP.md,
各阶段的计划位于 .planning/phases/M*/PHASE.md。
已知不足
- 完整的邮件统计数据(打开、点击、查看)——需要仪表板 CSRF 流程。备用方案:使用 Playwright MCP 抓取。
- 尚未通过实时探测确认 POST/DELETE 的反应端点数据结构;当前结构是根据上游工具目录推测的最佳方案。
- Auto-engine 的
new_follower/new_note_from触发器目前是空桩(返回note: "trigger not yet implemented")。 - TUI 子标签页(1/2/3)以及回复/点赞/转发快捷键已搭好框架,但尚未接入客户端。
- Chrome Cookie 自动获取功能仅在 macOS Chrome 上测试过;包含 Brave 路径;不支持 Linux/Windows。
许可证
MIT。请参阅 LICENSE。
src/substack_ops/_substack/ 下 vendored 的 httpx-port 辅助代码源自 MIT 许可的
NHagar/substack_api 包——将其保留在此处,是为了让此仓库在运行时不依赖任何第三方 Substack 库。每个文件的模块文档字符串中均保留了署名信息。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。