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 |
| Sync engine | Manual/scheduled incremental sync, configurable lookback, sync log |
| Web UI | Dashboard, subscriptions, articles, 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 tokens on disk, binds to 127.0.0.1 by default |
Requirements
- Python 3.11+
- Zoho Mail account (accounts.zoho.com)
- A Self Client app in Zoho API Console
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]"
cp .env.example .env # Windows: copy .env.example .env
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_accessis required for refresh tokens; without it you must re-authorize when tokens expire.
2. Connect in the Web UI
- Open 邮箱账号 (Mail accounts) → 连接 Zoho Mail
- Select your data center (default: Global
.com) - Enter Client ID, Client Secret, and Grant Code
- 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
- 订阅管理 (Subscriptions) → 扫描发现 (Scan inbox) to discover Substack senders
- Enable subscriptions you want to sync
- 手动同步 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 |
| Mail accounts | Zoho connection status, read-only sync policy |
| Sync log | Per-run counts, duration, errors |
| Settings | Theme, compact list, UI preferences |
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
- 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
- MCP endpoint has no authentication — do not expose to the public internet
License
MIT © 2026 flap4fun