Skip to main content
Glama
IMPORTANT

This is an independent, unofficial project. It never signs in to Substack, accepts no Substack cookies, calls no private endpoints, and cannot publish. Use it only with a publication you own, administer, or have permission to archive.

Why this exists

An RSS feed tells you what went out. Substack's official MCP can tell you how it performed. Neither gives your assistant a durable, versioned memory that it can query next month.

Substack Insights MCP joins those pieces locally:

flowchart LR
    RSS[Public RSS archive] -->|exact HTML + text| LEDGER[(SQLite ledger)]
    OFFICIAL[Substack official MCP] -->|timestamped metric snapshot| LEDGER
    DRAFT[Local Markdown] -->|immutable versions| LEDGER
    LEDGER --> ANALYTICS[Deterministic analytics]
    ANALYTICS --> MCP[12 MCP tools]
    MCP --> CLIENT[Codex · Claude · Cursor · any MCP client]

Everything important is stored as a fact: exact content, SHA-256 digests, capture times, metric sources, and raw snapshot values. The model can interpret the results; it cannot silently invent the arithmetic.

Related MCP server: substack-mcp

What you get

Archive

Analytics

Trust boundary

Exact RSS HTML and searchable text

Open rate and normalized conversion rates

No credentials or private APIs

Immutable local Markdown versions

Post rankings on comparable metrics

SQLite stays on your machine

SHA-256 content fingerprints

Word-count, title-length, and send-hour correlations

Missing metrics remain missing

Timestamped audit trail

Full metric history instead of latest-value overwrite

No remote writes—ever

Quick start

Requirements: Node.js 22.5 or newer.

git clone https://github.com/jakewlittle-cs/substack-insights-mcp.git
cd substack-insights-mcp
npm ci
cp .env.example .env

Set your publication origin in .env:

SUBSTACK_PUBLICATION_URL=https://your-publication.substack.com
SUBSTACK_INSIGHTS_DB_PATH=./data/substack-insights.sqlite

Then build, test, and import the public archive:

npm run check
npm test
npm run build
node dist/src/cli.js sync

Add it to Codex

Use absolute paths for the executable and database:

codex mcp add substack_insights \
  --env SUBSTACK_PUBLICATION_URL=https://your-publication.substack.com \
  --env SUBSTACK_INSIGHTS_DB_PATH=/absolute/path/substack-insights.sqlite \
  -- node /absolute/path/substack-insights-mcp/dist/src/cli.js serve

For another client, configure the equivalent stdio command:

{
  "command": "node",
  "args": ["/absolute/path/substack-insights-mcp/dist/src/cli.js", "serve"],
  "env": {
    "SUBSTACK_PUBLICATION_URL": "https://your-publication.substack.com",
    "SUBSTACK_INSIGHTS_DB_PATH": "/absolute/path/substack-insights.sqlite"
  }
}

Pair it with Substack's official MCP

Substack's official MCP exposes private publication analytics through OAuth for eligible publication admins. Install it beside this server:

codex mcp add substack_official --url https://mcp.substack.com/api/v1/mcp
codex mcp login substack_official

Then ask your agent:

Using substack_official, get the latest metrics for my recent posts. Match each result to the local archive and save every observed value with substack_insights.record_metric_snapshot. Then rank posts by subscriptions per 1,000 delivered and explain the strongest content patterns.

The agent is the bridge: it reads authoritative values from the official connector and records them here with source official_mcp and a capture timestamp. This project never receives or stores the official connector's OAuth token. See the snapshot workflow.

The toolbox

Tool

Purpose

connection_status

Configuration, ledger counts, and sync freshness

sync_publication

Import the public RSS archive

list_posts

Browse canonical post records and latest digests

get_post

Retrieve exact latest content for one post

list_post_versions

Inspect immutable version history

list_audit_events

Review imports and local content changes

record_metric_snapshot

Persist values observed through the official MCP

get_post_performance

Get raw history plus derived rates

compare_posts

Rank comparable posts deterministically

analyze_content_patterns

Calculate content/performance correlations

create_local_draft

Start versioned local Markdown—without publishing

update_local_draft

Append a new immutable local version

Analytics that show their work

  • open_rate: supplied value, or opens divided by delivered when absent.

  • subscriptions_per_1000: signups—or free plus paid subscriptions—per 1,000 delivered.

  • views_per_1000: views per 1,000 delivered.

  • engagement_rate: likes plus comments plus shares, divided by views.

  • content_patterns: Pearson correlations against word count, title length, and UTC send hour, with an explicit causation warning.

Comparisons use each post's latest stored snapshot. For sound conclusions, compare similar audiences at similar measurement ages.

Design promises

  1. Local first. SQLite is the system of record and its file is restricted to the current user.

  2. Immutable history. New content creates a version; it does not rewrite what was previously observed.

  3. Provenance always. Metrics carry a source and capture time. Unknown stays null.

  4. Deterministic math. Rankings and rates are ordinary code, covered by tests.

  5. A narrow network boundary. The only Substack request is a public RSS GET.

Read the architecture, operations guide, and security model for details.

Project status

v0.1.0 is the first public release. The storage format and MCP tool contracts are intentionally small and tested, but pre-1.0 APIs may evolve with release notes and migrations.

Contributions are welcome. Start with CONTRIBUTING.md, report security issues through SECURITY.md, and see the roadmap for good first directions.


Available Tools

12 tools
analyze_content_patternsAnalyze content-performance patternsA
Read-onlyIdempotent

Calculate correlations between performance and word count, title length, and UTC send hour. Requires at least three measured posts.

ParametersJSON Schema
NameRequiredDescriptionDefault
metricYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds the data requirement (at least three measured posts), which is a useful behavioral constraint beyond annotations. No contradiction. However, it does not state what happens if the requirement is unmet or the return format, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the core action ('Calculate correlations') and includes a necessary constraint in a compact manner. No redundant wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should at least hint at the return value. It says 'Calculate correlations' but doesn't specify the output structure or behavior when the precondition is not met. However, the tool has a small parameter surface and annotations, making it moderately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one required parameter, 'metric', with an enum of four performance metrics, but schema description coverage is 0%. The description does not mention this parameter at all; it only says 'performance' generically. This fails to compensate for the lack of schema descriptions, leaving the agent to infer the mapping between the parameter and the analysis.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the verb 'Calculate' and specifies the resource as 'correlations between performance and word count, title length, and UTC send hour.' This clearly states what the tool does and distinguishes it from siblings like get_post_performance or compare_posts by focusing on multi-factor pattern analysis. It also includes a requirement, further clarifying scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear precondition ('Requires at least three measured posts') which indicates when the tool is applicable, but does not explicitly compare to siblings or mention when not to use it. This gives clear context without exclusions, so a 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_postsRank comparable post performanceA
Read-onlyIdempotent

Rank posts using normalized, deterministic rates from each post's latest stored snapshot.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
metricYes
statusNopublished

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds behavioral context beyond the readOnlyHint and idempotentHint annotations by explaining that ranking is based on 'normalized, deterministic rates' and 'latest stored snapshot,' indicating results are reproducible and based on snapshot data rather than live state. This aligns with the annotations and provides useful insight into the operation's behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly worded sentence that front-loads the primary action ('Rank posts') and immediately provides the method. It avoids unnecessary verbiage and is highly scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core concept of ranking by normalized snapshot rates, but lacks details on sort order (e.g., descending), how limit and status are applied, and what the output looks like. With no output schema, return value expectations are unaddressed, leaving gaps for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides zero descriptions for parameters (coverage 0%), and the description does not elaborate on metric, limit, or status semantics. While parameter names and enums provide some self-evident meaning, the description fails to explain how limit affects result size or how status filters the posts, leaving the agent to infer these details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action 'Rank posts' with a specific resource and adds scope via 'using normalized, deterministic rates from each post's latest stored snapshot.' This distinguishes it from sibling tools like list_posts (which lists without ranking) and get_post_performance (which likely targets a single post rather than comparing multiple).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used for comparing/ranking posts but does not explicitly state when to use it versus alternatives like get_post_performance or list_posts. There is no direct mention of when not to use it or clear context distinguishing it from similar tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connection_statusSubstack Insights connection statusA
Read-onlyIdempotent

Show publication configuration, local ledger counts, and synchronization freshness.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, covering safety traits. The description adds useful context about what the tool specifically shows (publication config, ledger counts, sync freshness), which goes beyond the annotation-only safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly-worded sentence that is front-loaded with the verb 'Show' and lists three concrete outputs. Every word contributes meaning, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the low complexity (no params, no output schema), the description fully captures what the tool does by listing its three output areas. It is sufficient for an agent to understand the tool's purpose and safely invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The description appropriately describes the tool's function without needing to explain parameter details, as none exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Show' and names three distinct resources: publication configuration, local ledger counts, and synchronization freshness. This clearly differentiates it from sibling tools like list_posts or sync_publication, which focus on specific actions or data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context by indicating what the tool reports on (status-related information), but it does not explicitly state when to use it over alternatives or exclude any scenarios. The implied use case is to assess overall connection health, which is evident from the name and description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_local_draftCreate an immutable local draft versionA

Create local Markdown content in the immutable ledger. This never contacts or publishes to Substack.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
subjectNo
markdownYes
subtitleNo
preheaderNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide basic safety signals (readOnly=false, idempotent=false, destructive=false). The description adds valuable context about the 'immutable ledger' and the lack of Substack interaction, which goes beyond the annotations and clarifies the tool's side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short, focused sentences that front-load the action and key constraint. Every word earns its place; no fluff or redundancies.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description captures the essential purpose and the key constraint (local, immutable), but with 5 parameters and no output schema, it omits details about parameter usage, required fields, and return behavior. It is adequate but leaves gaps that the schema partially fills.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description provides no information about parameters such as title, markdown, subject, etc. The schema names give minimal hints, but the description fails to compensate for the low coverage, leaving the agent to infer parameter meanings from schema names alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Create') and resource ('local Markdown content in the immutable ledger'), and the second sentence clearly distinguishes it from publishing tools by stating it never contacts or publishes to Substack. This differentiates it from siblings like update_local_draft and sync_publication.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear exclusions ('never contacts or publishes to Substack') and implies it is for local-only draft creation. It does not name specific alternatives, but the context is sufficient to infer when to use this tool over publishing or updating tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_postGet exact post content and history pointerA
Read-onlyIdempotent

Return the canonical record and latest immutable content version for a local id, remote id, slug, canonical URL, or exact title.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds valuable context beyond annotations by explaining that the tool returns both the canonical record and the latest immutable content version, and that the identifier can be one of several types. This enriches the behavioral understanding without contradicting annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with a clear verb. No unnecessary words. Every piece of information (return value and identifier types) is essential and immediately visible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema, no nested objects) and strong annotations, the description fully covers what the tool does and what it returns. It explains both the input semantics and the output content without requiring additional details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must fully explain the parameter. It does so explicitly by listing the accepted identifier forms: local id, remote id, slug, canonical URL, or exact title. This gives meaning to the single 'identifier' parameter beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Return' and the resource: the canonical record and latest immutable content version for a post. It specifies multiple identifier types (local id, remote id, slug, canonical URL, or exact title), distinguishing it from sibling tools like list_posts or list_post_versions, which focus on listing or version history.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies clear usage: use this when you need the canonical record and latest content version given a post identifier. However, it does not explicitly name alternatives or exclusions, such as when to use list_post_versions instead. The context is clear but lacks explicit when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_post_performanceGet post performanceA
Read-onlyIdempotent

Return the latest derived performance rates plus every stored raw metric snapshot for one post.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds some behavioral context about the response composition (derived rates plus raw snapshots) but does not disclose potential volume or ordering of snapshots. This is moderate value beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, 14-word sentence that front-loads the action ('Return') and precisely describes the output. No unnecessary words or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one parameter and no output schema. The description explains the return composition but lacks details about identifier semantics and response structure. Given the missing output schema, the description is adequate but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter 'identifier' has 0% schema coverage, and the description merely hints it is a post identifier ('for one post') without specifying format, type, or how to obtain it. Since the description must compensate for the lack of schema documentation, it falls short.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it returns performance data for a single post, specifying the exact output: 'latest derived performance rates plus every stored raw metric snapshot.' This verb-action structure distinguishes it from sibling tools like 'get_post' and 'record_metric_snapshot'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use this tool (need performance metrics for one post) but does not explicitly mention exclusions or alternative tools. It provides clear context without naming alternatives, so it falls 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.

list_audit_eventsList ledger audit eventsA
Read-onlyIdempotent

Return timestamped RSS imports and local content changes, optionally scoped to one post.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
identifierNo

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds the event types (RSS imports, local content changes) and optional scoping, but does not disclose behavioral details such as ordering, pagination, or result limits beyond what the schema implies. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence of 12 words, directly starting with the verb and resource. It is efficient, with no filler or redundant restatement of the title, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple two-optional-parameter tool and strong annotations, the description adequately covers the core functionality and scoping. It does not describe the return structure (no output schema), but for invocation purposes, an agent understands what the tool returns and how to optionally scope it. Missing a bit around limit semantics keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It clarifies that 'identifier' refers to scoping to one post, but does not explain the 'limit' parameter at all (though the schema provides min/max). The description adds partial meaning but not enough to fully compensate for the low coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Return') and a specific resource ('timestamped RSS imports and local content changes'), with an optional scope ('to one post'). This distinguishes it from sibling tools like list_posts (which lists posts) and list_post_versions (which lists versions), so the agent can confidently select this tool for audit events.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for retrieving audit events but does not explicitly state when to use it vs. alternatives. It mentions optional scoping to a post, which gives some context, but there is no direct mention of alternatives or exclusions (e.g., 'for version history use list_post_versions instead').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_postsList locally tracked postsA
Read-onlyIdempotent

List canonical post records and content-version digests. This omits full bodies; use get_post for exact content.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
statusNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds behavioral context beyond these by explaining that the result includes 'canonical post records and content-version digests' and that full bodies are excluded. This gives useful insight into what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, two sentences that front-load the primary purpose and immediately add a key caveat with a pointer to an alternative. Every word earns its place without wasted elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers what the tool returns (canonical post records and digests) and what it omits (full bodies), which is sufficient for a simple list operation. However, it does not address filtering or pagination behavior for the `limit`/`status` parameters, nor clarify what a 'content-version digest' is, but the schema and sibling tool names provide some context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description does not mention the `limit` or `status` parameters at all. While the parameter names are self-explanatory, the description fails to compensate for the lack of schema descriptions, providing no additional meaning or usage hints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'List canonical post records and content-version digests.' It uses a specific verb ('List') and resource ('posts'), and immediately distinguishes itself from the sibling `get_post` by noting that full bodies are omitted and directing users to `get_post` for exact content.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly provides usage guidance by stating 'This omits full bodies; use get_post for exact content.' This tells users when to use this tool versus the primary alternative, making the intended use case clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_post_versionsList immutable post versionsA
Read-onlyIdempotent

Return the stored content-version history for one post, newest first, including exact bodies and SHA-256 digests.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
identifierYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable context beyond annotations: 'newest first' indicates ordering, and 'including exact bodies and SHA-256 digests' informs about return content. The title's 'immutable' aligns with the read-only/idempotent hints, and no contradictions exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that is front-loaded with the action and resource, plus essential details. Every word is informative and no content is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the tool's core purpose, ordering, and return content, which is sufficient for a simple read operation with a well-defined schema. It omits explicit mention of the 'limit' parameter's behavior, but the schema provides range constraints, making the description mostly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It implies 'identifier' identifies the post via 'for one post', but does not explain the 'limit' parameter's meaning or how it affects results. Partial compensation, but not complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns the stored content-version history for one post, with a specific verb ('Return') and resource ('content-version history'), and is distinguishable from siblings like list_posts and get_post. The mention of 'newest first' and 'exact bodies and SHA-256 digests' adds specific scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly scopes usage to 'one post' version history, providing context that it is not for listing posts or fetching a single current post. However, it does not explicitly state when not to use it or name alternatives, so it falls 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.

record_metric_snapshotRecord an official MCP metric snapshotA

Store timestamped metrics obtained from Substack's official MCP against an existing post. Never enter estimates.

ParametersJSON Schema
NameRequiredDescriptionDefault
sentNo
likesNo
opensNo
viewsNo
sharesNo
signupsNo
commentsNo
openRateNo
deliveredNo
capturedAtNo
identifierYes
revenueCentsNo
unsubscribesNo
estimatedValueNo
freeSubscriptionsNo
paidSubscriptionsNo

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds the 'never estimates' policy and official MCP source constraint, but fails to disclose side effects like whether the operation overwrites existing snapshots, creates duplicates, or fails if the post doesn't exist. With all annotation hints false, the description carries the transparency burden and does not meet it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences convey the core action, source, and a critical constraint. No repetition of schema details, tightly front-loaded, and every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a write tool with 16 parameters, no output schema, and no nested objects, this description is too minimal. It omits identifier semantics, null-vs-zero handling, return value, and error behavior, leaving significant gaps for an agent deciding when and how to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not compensate. It barely hints at capturedAt via 'timestamped' and identifier via 'against an existing post', but ignores the 15 other parameters, the required identifier, and ambiguity around nullable fields like estimatedValue given the 'never estimates' rule.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Store timestamped metrics') and the target ('against an existing post'), with a specific source ('Substack's official MCP'). It is immediately distinguishable from sibling read/list tools and draft-writing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: use this only for metrics obtained from Substack's official MCP, and explicitly forbids entering estimates. It does not name alternative tools (e.g., get_post_performance) or mention when not to use it, but the source and the 'never estimates' rule give strong direction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sync_publicationSynchronize Substack publicationA
Idempotent

Import the publication's public RSS archive into the local immutable ledger. No credentials are used.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a non-read, idempotent, non-destructive operation. The description adds valuable context: the source is a public RSS archive, the destination is an immutable ledger, and no credentials are used. It does not contradict the annotations and provides useful behavioral details beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two short sentences. It is front-loaded with the core action and adds a meaningful qualifier about credentials. There is no wasted wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple no-parameter tool with no output schema, the description covers the essential purpose and a key operational detail (no credentials). It might benefit from noting idempotency or what happens on re-sync, but annotations already supply idempotence, making the description adequately complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema fully covers them (100% coverage trivially). The description does not need to add parameter meaning, and the baseline for zero-parameter tools is 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: importing the publication's public RSS archive into the local immutable ledger. It uses a specific verb ('Import') and resource, and is distinct from sibling tools that read or modify existing ledger entries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for syncing public content, and 'No credentials are used' suggests it is safe to run without auth. However, it does not explicitly state when to use this tool versus alternatives, nor does it mention any prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_local_draftCreate a new local draft versionA

Update selected local draft fields by appending an immutable version. Existing sent versions cannot be changed.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNo
postIdYes
subjectNo
markdownNo
subtitleNo
preheaderNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations all false, the description carries the transparency burden. It discloses that updates are implemented by appending an immutable version, and that sent versions are immutable, adding meaningful behavioral context beyond the annotation fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences deliver the core functionality and a key restriction with zero redundancy. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides the essential versioning behavior and the sent-version constraint, but for a 6-parameter mutation tool with no output schema, it lacks parameter-specific guidance and explicit alternatives, making it adequate but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description only mentions 'selected local draft fields' without enumerating parameters or explaining the role of postId. It leans on self-explanatory field names but fails to compensate for the lack of schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Update' targeting 'local draft' and clarifies that updating appends an immutable version, distinguishing it from creating a new draft. It also explicitly states that sent versions cannot be changed, making the tool's scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly establishes the tool is for modifying local drafts and provides a when-not condition ('Existing sent versions cannot be changed'). However, it does not explicitly name alternatives like create_local_draft, so it stops short of a full 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. 12 tool updatesv0.1.0
    • First observedanalyze_content_patterns
    • First observedcompare_posts
    • First observedconnection_status
    • First observedcreate_local_draft
    • First observedget_post
    • First observedget_post_performance
    • First observedlist_audit_events
    • First observedlist_post_versions
    • First observedlist_posts
    • First observedrecord_metric_snapshot
    • First observedsync_publication
    • First observedupdate_local_draft

TDQS

A4.1/5.0

Scored across 12 tools

Disambiguation5/5

Each tool targets a distinct resource and action: listing vs retrieving posts, managing versions, tracking metrics, comparing posts, analyzing patterns, and handling drafts. Even potentially similar tools like get_post and list_post_versions are clearly differentiated by latest vs full history.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern (list_posts, get_post, record_metric_snapshot, create_local_draft). The only outlier is connection_status, which is a noun phrase rather than a verb-oriented name, making it slightly inconsistent.

Tool Count5/5

12 tools is well within the ideal range for a focused server. Each tool earns its place by covering a distinct aspect of the publication insight workflow: syncing, querying, versioning, auditing, metrics, analysis, and drafts.

Completeness4/5

The toolset covers the full lifecycle for content ingestion (sync), retrieval (list/get), version history, audit, metric recording/analysis, and draft management. Minor gaps like explicit list/delete for drafts are mitigated by the immutable ledger design and list_posts coverage, but a dedicated draft listing would improve completeness.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Read-only MCP server for accessing Substack content including publications, posts, comments, author profiles, recommendations, and Notes feed using your own session token.
    239 npm
    4
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A local MCP server for managing saved Substack posts. Enables offline reading, searching, bookmarking, and unbookmarking of Substack content via CLI or MCP clients.
    17
    MIT