# Substack MCP Server (npm · @conorbronsdon/substack-mcp)

Substack MCP server: posts are draft-only by design; short-form Notes publish immediately.

- Trust score: 89/100 (high trust)
- Change this week: +8
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-11

## Components

- npm · `@conorbronsdon/substack-mcp`: 89/100 (this document), [markdown](https://verifymcp.io/servers/conorbronsdon-substack-mcp/conorbronsdon-substack-mcp.md), [page](https://verifymcp.io/servers/conorbronsdon-substack-mcp/conorbronsdon-substack-mcp)

## Channel facts

- Registry: `npm`
- Package: `@conorbronsdon/substack-mcp`
- Version: `0.6.2`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-11.

- **Supply Chain Security**: 98/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - No install/post-install scripts declared.
  - 30 of 96 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 100/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to conorbronsdon/substack-mcp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 7 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 81/100
  - AI-judged instruction clarity (excellent).
  - Tool/resource definitions use about 1087 tokens (~77/item across 14 items; 14 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 53/100
  - Stability observed for 16 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add conorbronsdon-substack-mcp -- npx -y @conorbronsdon/substack-mcp
```

### Codex

```bash
codex mcp add conorbronsdon-substack-mcp -- npx -y @conorbronsdon/substack-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "conorbronsdon-substack-mcp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@conorbronsdon/substack-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add conorbronsdon-substack-mcp --command npx --arg -y --arg @conorbronsdon/substack-mcp
```

### Hermes

```yaml
mcp_servers:
  conorbronsdon-substack-mcp:
    command: "npx"
    args: ["-y", "@conorbronsdon/substack-mcp"]
```

### Other

```json
{
  "mcpServers": {
    "conorbronsdon-substack-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@conorbronsdon/substack-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-11 (score 89, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-08-09 (score 88, +1)

No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-08 (score 87, +1)

- [functional improvement] Security disclosure: fail → pass

### 2026-08-07 (score 86, +4)

- [security improvement] Known CVEs: partial → pass
- [functional] Dependency health: partial → 0.85

### 2026-08-05 (score 82, +1)

No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-04 (score 81, +35)

- [functional regression] Schema quality: 69 → 77
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Stability: unverified → 0.30
- [functional improvement] Tool coverage: unverified → 100
- [functional] Package version: 0.6.0 → 0.6.2

### 2026-08-03 (score 46, −33)

- [security regression] Stability: 0.23 → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Capabilities: pass → unverified
- [functional] Package version: 0.6.0 → 0.6.2
- [functional] Package version: 0.6.0 → 0.6.1

### 2026-08-02 (score 79, +59)

- [security improvement] Install scripts: unverified → pass
- [security improvement] Provenance: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security] The attested source repository moved: conorbronsdon/substack-mcp
- [functional regression] Schema quality: 58 → 69
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Schema quality: unverified → excellent
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] Stability: unverified → 0.23
- [functional improvement] Tool coverage: unverified → 100
- [functional] Licence: MIT
- [functional] Package version: 0.3.0 → 0.6.0

## MCP tools (14)

### `get_subscriber_count` (~90 tokens)

Get the current subscriber count for your Substack publication. Returns `precision`: 'exact' when the API reports a true count, 'approximate' when only Substack's rounded value is available (the real number is that or higher — render it hedged, e.g. '1,000+'), or 'unavailable' with count -1. Never treat an approximate value as exact.

### `list_published_posts` (~69 tokens)

List published posts with pagination. Returns title, date, slug, and URL for each post.

Input parameters:

- `limit` (number): Max posts to return (1-50; Substack rejects anything higher, so larger values are clamped)
- `offset` (number): Number of posts to skip

### `list_drafts` (~65 tokens)

List draft posts. Returns title, creation date, and audience for each draft.

Input parameters:

- `limit` (number): Max drafts to return (1-50; Substack rejects anything higher, so larger values are clamped)
- `offset` (number): Number of drafts to skip

### `get_post` (~40 tokens)

Get the full content of a published post by ID. Returns title, body HTML, metadata.

Input parameters:

- `post_id` (number, required): The post ID to retrieve

### `get_draft` (~40 tokens)

Get the full content of a draft post by ID. Returns title, body, metadata.

Input parameters:

- `draft_id` (number, required): The draft ID to retrieve

### `get_post_comments` (~59 tokens)

Get comments on a published post. Returns commenter name, comment body, date, and reaction counts.

Input parameters:

- `limit` (number): Max comments to return (default 20)
- `post_id` (number, required): The post ID to get comments for

### `get_sections` (~46 tokens)

List your publication's sections (categories). Returns each section's id and name. Use a section id as `section_id` when creating or updating a draft to file it under that section.

### `get_post_analytics` (~94 tokens)

Get performance stats (views, emails sent/delivered/opened, signups, subscribes, estimated value, comments, reactions) for a published post by ID. Substack has no per-post stats endpoint, so this searches your 500 most recent published posts for the ID; returns a not-found note if it isn't among them.

Input parameters:

- `post_id` (number, required): The published post ID to get stats for

### `list_scheduled_posts` (~107 tokens)

List posts scheduled for future publication, soonest first. Read-only visibility into what's queued — scheduling itself is done in Substack's editor (this server does not schedule, publish, or delete long-form posts). Returns id, title, audience, and scheduled time (`trigger_at`).

Input parameters:

- `limit` (number): Max posts to return (1-50; Substack rejects anything higher, so larger values are clamped)
- `offset` (number): Number of posts to skip

### `create_draft` (~79 tokens)

Create a new draft post. Accepts markdown body which is converted to Substack's format. Does NOT publish — creates a draft only.

Input parameters:

- `audience` (string): Who can see this post
- `body` (string): Post body in markdown format
- `subtitle` (string): Post subtitle
- `title` (string, required): Post title

### `update_draft` (~81 tokens)

Update an existing draft post. Only works on unpublished drafts. Accepts markdown body.

Input parameters:

- `audience` (string): Who can see this post
- `body` (string): New body in markdown format
- `draft_id` (number, required): The draft ID to update
- `subtitle` (string): New subtitle
- `title` (string): New title

### `upload_image` (~156 tokens)

Upload an image to Substack's CDN. Provide exactly one of `image_base64` (a base64 data URI) or `image_path` (a local file path). Returns a hosted image URL that is publicly fetchable by anyone with the link (an unlisted asset — not attributed to you or added to your feed).

Input parameters:

- `image_base64` (string): Base64-encoded image with data URI prefix (e.g., "data:image/png;base64,..."). Mutually exclusive with image_path.
- `image_path` (string): Absolute path to a local image file (e.g., "/Users/me/pic.png"). Read and encoded automatically; MIME type inferred from the extension. Mutually exclusive with image_base64.

### `create_note` (~74 tokens)

Create a Substack Note (short-form content). Accepts markdown text. PUBLISHES IMMEDIATELY to your public Notes feed — Notes have no draft state on Substack, and this server has no delete tools, so there is no undo from here.

Input parameters:

- `body` (string, required): Note content in markdown format

### `create_note_with_link` (~87 tokens)

Create a Substack Note with a link attachment, displayed as a rich card below the note text. PUBLISHES IMMEDIATELY to your public Notes feed — same caveats as create_note: no draft state, no undo from this server.

Input parameters:

- `body` (string, required): Note content in markdown format
- `url` (string, required): URL to attach as a link card

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/conorbronsdon-substack-mcp/conorbronsdon-substack-mcp#diagnostics

## Score history

- 2026-08-11: 89
- 2026-08-10: 88
- 2026-08-09: 88
- 2026-08-08: 87
- 2026-08-07: 86
- 2026-08-06: 82
- 2026-08-05: 82
- 2026-08-04: 81
- 2026-08-03: 46
- 2026-08-02: 79
- 2026-08-01: 20
- 2026-07-31: 21
- 2026-07-30: 28
- 2026-07-28: 46
- 2026-07-27: 46

## Links

- npm package: https://www.npmjs.com/package/@conorbronsdon/substack-mcp
- Socket report: https://socket.dev/npm/package/@conorbronsdon/substack-mcp
- Repository: https://github.com/conorbronsdon/substack-mcp
- Changelog RSS feed: https://verifymcp.io/servers/conorbronsdon-substack-mcp/conorbronsdon-substack-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/conorbronsdon-substack-mcp/conorbronsdon-substack-mcp.json
- HTML version of this page: https://verifymcp.io/servers/conorbronsdon-substack-mcp/conorbronsdon-substack-mcp
