Substack Scraper MCP Server
Scrapes Substack publications and posts, returning publication profiles with author, subscriber counts, and plan prices, plus post details such as title, URL, date, audience, engagement metrics, tags, and optional body text. Also supports keyword search across Substack posts or the publications behind them.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Substack Scraper MCP ServerHow many subscribers does Lenny's Newsletter have and what does paid cost?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Substack Scraper MCP Server
An MCP server for the Mamba Labs Substack Scraper actor on Apify. Give it Substack publications or keywords. It returns publication profiles and posts as flat rows.
What's Inside
Related MCP server: substack-mcp
What it does
Publications: name, author, tagline, subscriber count as Substack shows it (
subscriber_count_text, andsubscriber_count_minas a number), subscriber tier text, and monthly, yearly, and founding plan prices.Posts: title, URL, date,
audience(free, paid, or founding), likes, comments, restacks, word count, bylines, and tags. Optional post text withinclude_body.Search: keyword search across Substack posts, returned as posts or as the publications behind them.
All of the work runs on Apify. This package is a thin client that starts the actor run, waits for it, and hands back the dataset rows.
Quick start
You need Node.js 18 or newer and an Apify account with an API token.
Add this to your Claude Desktop config (claude_desktop_config.json), Cursor, or any MCP client:
{
"mcpServers": {
"mamba-substack-scraper": {
"command": "npx",
"args": [
"-y",
"@mambalabsdev/mcp-substack-scraper"
],
"env": {
"APIFY_TOKEN": "your-apify-token"
}
}
}
}Restart the client. The scrape_substack tool appears.
Prerequisites
Node.js 18 or newer.
An Apify API token from console.apify.com/account/integrations, set as
APIFY_TOKEN. The server lists its tool without a token; a call needs one.
Example prompts
"How many subscribers does Lenny's Newsletter have, and what does a paid plan cost?"
"Find Substack newsletters that write about cold email and list their subscriber counts."
"What did notboring.co publish in the last 30 days, and which posts were paid only?"
Tool
scrape_substack. One tool. Example arguments:
{
"publications": [
"lenny.substack.com"
],
"search_queries": [
"cold email"
],
"max_posts_per_publication": "5",
"max_search_results": "5"
}Inputs
Every buyer facing input of the actor, unchanged. Omitted inputs take the actor's own defaults. Numbers and booleans are sent as strings.
Input | Type | Description |
| array | Substack publications, one per line, up to 100: a URL (https://www.lennysnewsletter.com), a domain (lenny.substack.com), a profile (substack.com/@lenny), or a bare Substack name (lenny). Each one returns a publication row and its newest posts |
| array | Keywords to search across Substack posts, one per line, up to 20. Each query returns matching posts, or the publications behind them when Search output is publications |
| string | What a search query returns Default posts |
| string | Newest posts returned per publication, 0 to 1000. 0 returns only the publication row Default 20 |
| string | Rows returned per search query, 1 to 1000 Default 50 |
| string | Optional. Skip posts older than this many days. 0 or empty keeps every post up to the max Default 0 |
| string | true to return one publication row per listed publication (name, author, subscribers, paid plan prices), billed as a publication row. false returns only post rows Default true |
| string | true to add the post text (up to 20,000 characters) to each post row of a listed publication. A paid post gives its free preview. Reads one more page per post; no extra charge Default false |
| string | Optional. The run stops before it would charge more than this |
| string | How pages are fetched Default auto |
Pricing
Pay per event on Apify, billed to your Apify account. Prices in USD.
Event | Free plan | Bronze | Silver | Gold |
| $0.00115 | $0.001093 | $0.001035 | $0.000977 |
| $0.002 | $0.0019 | $0.0018 | $0.0017 |
| $0.001057 | $0.001057 | $0.001057 | $0.001057 |
no_results and error rows are free, including the one row a refused input returns.
Your keys
The actor needs no key. It reads Substack's public pages and public JSON routes and holds no key of any kind. Proxy traffic adds nothing to your price: Mamba Labs pays the platform costs of the run.
Full actor documentation
apify.com/mambalabs/substack-scraper
License
MIT. See LICENSE.
Available Tools
1 toolscrape_substackScrape Substack publications, posts, and searchARead-onlyIdempotent
Read Substack publications and posts, or search Substack by keyword. Give publications as URLs, domains, substack.com profiles, or bare Substack names (for example lenny.substack.com, https://www.notboring.co, lenny). Each publication returns one publication row (name, author, subscriber count as Substack shows it, subscriber tier text, paid plan prices) and its newest posts, one row each with date, free or paid audience, likes, comments, restacks, word count, bylines, and tags. Search queries return matching posts with their publication and subscriber count, or one row per publication when search_output is publications. Input with nothing to run returns one free row whose error_reason starts with input_invalid:. A run that does not succeed is returned as an error with its run ID. Read-only; requires an APIFY_TOKEN; Apify charges per post row and per publication row.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy_mode | No | How pages are fetched. Default auto. | |
| since_days | No | Optional. Skip posts older than this many days. 0 or empty keeps every post up to the max. Default 0. | |
| include_body | No | true to add the post text (up to 20,000 characters) to each post row of a listed publication. A paid post gives its free preview. Reads one more page per post; no extra charge. Default false. | |
| publications | No | Substack publications, one per line, up to 100: a URL (https://www.lennysnewsletter.com), a domain (lenny.substack.com), a profile (substack.com/@lenny), or a bare Substack name (lenny). Each one returns a publication row and its newest posts. | |
| search_output | No | What a search query returns. Default posts. | |
| max_charge_usd | No | Optional. The run stops before it would charge more than this. | |
| search_queries | No | Keywords to search across Substack posts, one per line, up to 20. Each query returns matching posts, or the publications behind them when Search output is publications. | |
| max_search_results | No | Rows returned per search query, 1 to 1000. Default 50. | |
| include_publication_row | No | true to return one publication row per listed publication (name, author, subscribers, paid plan prices), billed as a publication row. false returns only post rows. Default true. | |
| max_posts_per_publication | No | Newest posts returned per publication, 0 to 1000. 0 returns only the publication row. Default 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the read-only annotations: it discloses that an APIFY_TOKEN is required, that Apify bills per post row and per publication row, that invalid input returns a free row whose error_reason starts with input_invalid:, and that a failed run is returned as an error with its run ID. These are exactly the operational facts an agent needs before invoking.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the two modes, then details outputs, then error/cost behavior—a sensible ordering. It is dense and somewhat run-on with many clauses in one paragraph, but nearly every sentence carries operational value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 10 parameters, no required fields, and no output schema, the description does the heavy lifting on return shape: it enumerates publication row fields and post row fields, and covers error and billing semantics. It omits how optional controls like include_body or since_days change the returned rows, a minor but real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 100%, so the schema carries the parameter burden. The description restates the accepted publication formats and the search_output behavior, which is useful reinforcement but adds little new meaning, and it never mentions include_body, since_days, proxy_mode, or max_charge_usd. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verbs and resources: reading Substack publications and posts, and searching Substack by keyword. It clearly separates the two operating modes (listed publications vs. keyword search) so an agent knows exactly what the tool does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explains that input is publications or search queries and that search_output controls whether search returns posts or publications, which effectively tells the agent which input to supply for which goal. There are no sibling tools to disambiguate against and no explicit 'when not to use' guidance, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.1.0- First observed
scrape_substack
TDQS
Scored across 1 tool
With a single tool there is no inter-tool misselection risk, and the description clearly enumerates the three modes (publication read, post read, keyword search). However, the tool internally conflates distinct operations (fetching vs. searching), and the mode is selected via a search_output parameter, which is a mild ambiguity an agent must resolve from prose.
Only one tool exists, and it follows a clean verb_noun convention (scrape_substack) that matches the server name and domain. There is no mixing of conventions to penalize.
A single tool for a domain that spans publication lookup, post retrieval, and keyword search is thin, and the overloaded parameter surface suggests it could reasonably be split into fetch_publication, fetch_posts, and search_posts. It is not egregiously wrong, but the count is borderline for the described scope.
Read-only coverage of publications, posts, and search is reasonable for a scraper, but there are notable gaps: no way to fetch an arbitrary post by URL, no comments retrieval despite comments being reported, and no explicit pagination/limit controls. Agents hitting those needs will dead-end.
Maintenance
Related MCP Connectors
Substack newsletter, posts & podcast search
Search 89,000+ Substack and beehiiv newsletters, their sponsors, topics and mentioned companies.
1Posts, Notes, messages, subscribers and stats for your publication.
Search ATProto writing, annotations, identity, agents, and forum posts. 12 read-only tools.
Related MCP Servers
- AlicenseBqualityNot gradedmaintenanceEnables interaction with Substack publications through natural conversation, allowing users to create posts with cover images, publish notes, manage content, and retrieve profile information.82 npm-
- AlicenseBqualityDmaintenanceEnables searching, filtering, and exporting Substack blog posts via MCP tools, with full-text search, caching, and citation generation.7ISC
- AlicenseNot gradedqualityFmaintenanceProvides deep, structured access to Substack publications with real-time content analysis, including sentiment analysis, readability metrics, and publishing patterns.13MIT
- FlicenseNot gradedqualityDmaintenanceEnables searching Bluesky, Substack, and Hacker News content via structured APIs with optional x402 micropayments or API key authentication.-