Substack has no public API. This server calls the same JSON endpoints Substack's own web app calls, signed with your browser session cookie.
Four discovery tools work with no login at all: search_publications, get_publication_info, scrape_post and get_post against a public publication. Everything else needs your session.
Node 22 or newer. Nothing else.
claude mcp add substack -- npx -y @thenavidm/substack-mcp-cliOr in any client's MCP config:
{
"mcpServers": {
"substack": {
"command": "npx",
"args": ["-y", "@thenavidm/substack-mcp-cli"],
"env": {
"SUBSTACK_PUBLICATION_URL": "example.substack.com",
"SUBSTACK_SESSION_TOKEN": "your-connect-sid-value"
}
}
}
}Your connect.sid cookie is full access to your Substack account. Treat it like a password. Never paste it into an issue or share it.
npx @thenavidm/substack-mcp-cli loginPrompts for the publication URL and the cookie, resolves your user id, and stores it encrypted in ~/.substack-mcp/session.json. After that you can leave the env block out of your client config entirely.
npx @thenavidm/substack-mcp-cli login --playwriterReads the cookie out of your running Chrome. Needs Playwriter and its extension.
npm i -g playwright && npx playwright install chromium
npx @thenavidm/substack-mcp-cli login --playwrightSlowest by a distance. Use it on a machine with no Chrome, or in CI.
- Open your publication and sign in.
- DevTools, then Application, then Cookies.
- Copy the value of
connect.sid. It starts withs%3A.
Disable ad blockers first. Some strip the cookie from that panel.
SUBSTACK_USER_ID is optional. It is looked up automatically and cached.
npx @thenavidm/substack-mcp-cli doctorChecks credentials, configuration, connectivity and byline resolution, and names whatever is wrong.
| Variable | Effect |
|---|---|
SUBSTACK_READ_ONLY=1 |
Only the 41 read tools are exposed |
SUBSTACK_ALLOW_DESTRUCTIVE=0 |
Drafting works, publishing and deleting do not |
SUBSTACK_AUDIT_LOG=/path/to/log |
Append-only record of every attempted write, and who approved it |
SUBSTACK_CONFIRM=model |
Lets confirm: true alone approve over MCP, for an agent with no person to ask |
Publishing, deleting, Notes and comments wait for your approval whatever these settings say: Claude Code shows its own prompt for each, a client that can show forms asks with one, and elsewhere the model must pass confirm: true.
Sessions expire at around 90 days. Run login again, or paste a fresh cookie.
If you are on a custom domain and get a 403 mentioning error code: 1010, that is Cloudflare. Set SUBSTACK_PUBLICATION_URL to the canonical *.substack.com host instead.