Hey, I'm Marco and welcome to my newsletter!
In this episode, I'm going to introduce you to the MCP server that I made for Substack.
You can download all the code shown directly from my Github repository: https://github.com/marcomoauro/substack-mcp
🔒 Substack lacks public APIs
Substack lacks public APIs, so I reverse-engineered the platform to understand the data exchanged between the platform's UI and backend.
This allowed me to use the same mechanism to request operations.
I've discovered that the session is managed through a cookie, which is exchanged in all calls between the client and the backend. This cookie is used to verify if the user is authenticated and authorized for the operations they're requesting.
Using the same mechanism, I created an e-mail sequence platform for Substack that allows for creating customized workflows to send e-mails every day.
You can find the post here:
🖥️ What is an MCP Server?
as well explained by modelcontextprotocol.io:
MCP is an open protocol that standardizes how applications provide context to LLMs. It provides a standardized way to connect AI models to different data sources and tools.
MCP follows a client-server architecture where a host application can connect to multiple servers:
MCP Hosts: Programs like Claude Desktop, IDEs, or AI tools that want to access data through MCP
MCP Clients: Protocol clients that maintain 1:1 connections with servers
MCP Servers: Lightweight programs that each expose specific capabilities through the standardized Model Context Protocol
Local Data Sources: Your computer’s files, databases, and services that MCP servers can securely access
Remote Services: External systems available over the internet (e.g., through APIs) that MCP servers can connect to
🔑 Retrieve your Substack credentials
To use the server, you need to retrieve 3 parameters:
Session token
Publication URL
User ID
Session token
This information is exchanged in all authenticated calls between the UI and the backend. You can retrieve it using your browser's devtools, such as Chrome in my case.
Go to Network, filter the calls by Fetch/XHR and look for the call drafts?offset=.....
Among the request headers, look for Cookie, which contains a list of information in the “key=value;” format. From these, retrieve the session token found in the substack.sid or connect.sid key. Only one of these will be present, so simply retrieve the value you find!
In my case, I have the substack.sid cookie. Please note the value we'll need later for the MCP Server.
Publication URL
This is the domain of your newsletter, which you can find in the address bar. In my case, it's https://implementing.substack.com
User ID
Just like the Session token process, open the network and search for the publication_user call.
Go to the response, Preview section, and retrieve the id from the user key. If you have multiple users in your newsletter, retrieve the id associated with the user with your name.
📘 How to start the MCP server
You can use the MCP server in two ways, via NPX (Node.js) or via Docker.
NPX (Node.js)
Keep reading with a 7-day free trial
Subscribe to Implementing to keep reading this post and get 7 days of free access to the full post archives.