v0.3.0MIT·Python 3.12+·MCP-compatible

Reply to your Substack from Cursor.
No API keys.

substack-ops is a standalone Substack CLI and a 26-tool MCP server. Your IDE's LLM does the drafting through propose_reply / confirm_reply — so you never pay an Anthropic or OpenAI bill for writing replies.

$ uvx substack-ops mcp install cursor

Writes ~/.cursor/mcp.json. Restart Cursor.

~/projects · zsh

What you get

Full Substack control surface. Zero subscription tax on the AI side.

26 MCP tools

Posts, notes, comments, replies, reactions, restacks, profiles, search, feed, audit, dedup. Full Substack surface.

Host LLM drafts

propose_reply / confirm_reply tokens let Cursor / Claude Desktop / Claude Code do the writing. No API key, ever.

Dedup + audit

SQLite-backed dedup, JSONL audit log, ancestor_path guardrail. Replays are no-ops. Mistakes leave a trail.

Auto-restack daemon

Subprocess fallback to claude / cursor-agent / codex when no human is in the loop. YAML rules, dry-run by default.

Why no API keys?

Your chat app already has an LLM. We just hand it the tools.

Most “AI” CLIs make you bring an ANTHROPIC_API_KEY. You then pay twice: once for your Cursor / Claude subscription, once for tokens your IDE could have generated for free.

MCP fixes that. Your IDE talks to substack-ops over stdio, asks for get_unanswered_comments, drafts a reply locally, then calls propose_reply → you approve → confirm_reply ships it. The CLI is just hands.

For unattended runs (cron, daemon) we shell out to claude, cursor-agent, or codex — whichever you already have on PATH. Same subscription. Still $0.

All 26 tools

· test_connection
· get_own_profile
· get_profile
· list_posts
· get_post
· get_post_by_id
· get_post_content
· search_posts
· list_notes
· list_comments
· get_feed
· publish_note
· reply_to_note
· comment_on_post
· react_to_post
· react_to_comment
· restack_post
· restack_note
· delete_comment
· bulk_draft_replies
· send_approved_drafts
· audit_search
· dedup_status
· get_unanswered_comments
· propose_reply
· confirm_reply