Skip to main content
Glama
flap4fun

substack-vault

by flap4fun

Substack Vault

English · 中文

Collect Substack newsletters from Zoho Mail, archive them locally, and analyze via MCP Streamable HTTP with cross-author search.

v0.1.0 — Initial release: Zoho sync, Web UI, article library, and MCP tools.

Features

Module

Description

Mail ingestion

Zoho Mail OAuth (Self Client + Grant Code), full Substack email body

Subscriptions

Enable/disable feeds, inbox scan for new authors, link orphans by sender_email

Article library

List/card views, filter by author/date/keyword; drawer reader, copy, export Markdown

AI analysis

DeepSeek (deepseek-v4-flash): saved schemes, date range + authors + keywords, cross-author comparison

Sync engine

Manual/scheduled incremental sync, configurable lookback, sync log

Web UI

Dashboard, subscriptions, articles, AI analysis, accounts, sync log, settings; light/dark theme

MCP

Streamable HTTP endpoint for Cursor and other agents; cross-author topic search

Local-first

SQLite storage, encrypted OAuth/LLM tokens on disk, binds to 127.0.0.1 by default

Related MCP server: substack-mcp

Requirements

Quick start

git clone https://github.com/flap4fun/substack-vault.git
cd substack-vault

python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate
pip install -e ".[dev]"
# Optional: OCR for image-only Substack emails (e.g. weekly image posts)
pip install -e ".[ocr]"

cp .env.example .env               # Windows: copy .env.example .env

Optional: image OCR (Tesseract)

Some paid newsletters put the body in images. Vault OCRs those from Zoho email HTML (not the public Substack site, which may be paywalled).

  1. Install Tesseract with language packs chi_tra and eng

  2. pip install -e ".[ocr]"

  3. In 文章库, click 修复短正文 (or re-sync) to re-fetch email HTML when needed and OCR images

Start the server:

substack-vault

Open http://127.0.0.1:8765 in your browser. Use this URL directly — do not serve web/ with Live Server or another static file server.

Connect Zoho Mail

Self Client apps do not support browser OAuth redirects. You must generate a Grant Code manually.

1. Create a Self Client in Zoho API Console

  • Type: Self Client

  • Redirect URI: http://localhost:8765/oauth/zoho/callback (must match .env)

  • Scopes (paste when generating code):

ZohoMail.messages.READ,
ZohoMail.accounts.READ,
ZohoMail.folders.READ,
offline_access

offline_access is required for refresh tokens; without it you must re-authorize when tokens expire.

2. Connect in the Web UI

  1. Open 邮箱账号 (Mail accounts) → 连接 Zoho Mail

  2. Select your data center (default: Global .com)

  3. Enter Client ID, Client Secret, and Grant Code

  4. After connecting, use 手动同步 (Sync now) in the top bar

Credentials can also go in .env (see Configuration). UI-saved credentials are stored locally as well.

3. Subscriptions and sync

  1. 订阅管理 (Subscriptions) → 扫描发现 (Scan inbox) to discover Substack senders

  2. Enable subscriptions you want to sync

  3. 手动同步 or wait for the background job (default: every 30 minutes)

Web UI

Page

Purpose

Dashboard

Article/subscription stats, recent sync activity

Subscriptions

Author list, enable toggle, inbox scan, article count & last update

Articles

Filters, resizable reading drawer, copy/export Markdown; Send to AI analysis

AI analysis

Saved schemes, authors/keywords/date range → DeepSeek Markdown report

Mail accounts

Zoho connection status, read-only sync policy

Sync log

Per-run counts, duration, errors

Settings

Theme, DeepSeek API base URL + key, compact list

AI analysis (DeepSeek)

  1. Open SettingsAI / DeepSeek, set API Key (default base URL https://api.deepseek.com)

  2. Open AI analysis, pick or edit a scheme (seeded: “跨作者观点对比”)

  3. Choose date range, 1–N authors, 1–N keywords (e.g. tickers), then Run

  4. Or from Articles, set filters and click Send to AI analysis

Model is fixed to deepseek-v4-flash. The API key is Fernet-encrypted locally (same as Zoho secrets).

Display timezone defaults to Asia/Shanghai (UTC+8); the database stores UTC.

Cursor MCP

With substack-vault running, add to Cursor MCP settings:

{
  "mcpServers": {
    "substack-vault": {
      "url": "http://127.0.0.1:8765/mcp"
    }
  }
}

Tools

Tool

Description

list_subscriptions

List all Substack subscriptions

list_articles

List articles by author slug or keyword

get_article

Full text and metadata by ID

search_articles

Search titles and bodies

find_topic_across_authors

Same topic across authors for viewpoint comparison

get_sync_status

Sync state and recent logs

Example: ask an agent to compare how different authors cover a topic, or summarize the past week’s posts.

Configuration

.env example (VAULT_ prefix):

# Zoho OAuth
VAULT_ZOHO_CLIENT_ID=
VAULT_ZOHO_CLIENT_SECRET=
VAULT_ZOHO_REDIRECT_URI=http://localhost:8765/oauth/zoho/callback

# Server
VAULT_HOST=127.0.0.1
VAULT_PORT=8765

# Sync (optional)
VAULT_SYNC_INTERVAL_MINUTES=30
VAULT_SYNC_LOOKBACK_DAYS=90
VAULT_SYNC_SUBSCRIBED_ONLY=true

Variable

Default

Description

VAULT_HOST

127.0.0.1

Bind address

VAULT_PORT

8765

Port

VAULT_SYNC_INTERVAL_MINUTES

30

Background sync interval (minutes)

VAULT_SYNC_LOOKBACK_DAYS

90

Initial / lookback window (days)

VAULT_SYNC_SUBSCRIBED_ONLY

true

Sync only enabled subscriptions

Data directory

Platform

Path

Windows

%USERPROFILE%\.substack-vault\

macOS / Linux

~/.substack-vault/

Contains vault.db (SQLite), encryption key, and OAuth credentials. Do not commit this directory.

Development

pip install -e ".[dev]"
pytest

Layout:

src/substack_vault/
  api/          FastAPI REST + static Web
  connectors/   Zoho Mail connector
  parsers/      Substack email parser
  sync/         Sync engine
  storage/      SQLAlchemy models & DB
  mcp/          MCP Streamable HTTP
web/            Frontend static assets
tests/          Unit & API tests
openspec/       Specs & change history (OpenSpec)

Roadmap

  • Outlook and other mail providers

  • RSS body enrichment

  • Article tags and advanced filters

  • Analysis run history / streaming UI / more LLM providers

  • Multi-user / remote deployment

Limitations

  • Zoho Mail only (international and regional data centers)

  • Single-machine local deployment; no multi-tenant or cloud sync

  • Substack HTML parsing depends on email templates; unusual layouts may lose formatting

  • Image-body posts need local Tesseract (chi_tra+eng); OCR is best-effort

  • Paid full text is taken from Zoho email, not the public Substack site

  • In-app AI supports DeepSeek official only; model fixed to deepseek-v4-flash

  • MCP endpoint has no authentication — do not expose to the public internet

License

MIT © 2026 flap4fun

A
license - permissive license
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    An MCP server that gives Copilot access to Substack posts from your authenticated reader account, including paid subscriptions, enabling daily summary generation by syncing, caching, and summarizing posts.
    13
    MIT
  • F
    license
    -
    quality
    B
    maintenance
    A private, single-user MCP server that unifies Gmail, Microsoft 365/Outlook, and IMAP mailboxes for LLMs to search and read emails live, without storing or caching mailbox contents.
  • 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.
    10
    MIT

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/flap4fun/substack-vault'

If you have feedback or need assistance with the MCP directory API, please join our Discord server