An MCP server and CLI tool for ENS DAO editorial workflows
The ENS Editorial System automates monitoring, scoring, and content generation for the ENS DAO Newsletter. It provides two interfaces:
- MCP Server (Primary) - Natural language interaction via Claude Code
- CLI Tool - Direct command-line access for scripting
What it does:
- Monitors ENS ecosystem sources (Discourse forum, GitHub repositories, X/Twitter)
- Scores and ranks content using heuristics + LLM analysis
- Generates editorial reports for content review
- Produces newsletters and social media posts from curated items
- Outputs timestamped markdown + JSON artifacts
Time savings: 15-30 minutes vs continuous week-long manual monitoring across X, Discourse, GitHub, and Farcaster.
The MCP server enables natural language editorial workflows through Claude Code.
-
Install dependencies:
Option A: Using
uv(recommended, faster):uv venv source .venv/bin/activate # or: . .venv/bin/activate uv pip install -e .
Option B: Using standard
venv:python -m venv .venv source .venv/bin/activate pip install -e .
-
Configure environment:
cp .env.example .env # Edit .env with your API credentials -
Configure MCP server:
cp .mcp.json.example .mcp.json # Edit .mcp.json with your absolute pathsExample
.mcp.json:{ "mcpServers": { "editor": { "command": "/path/to/your/project/.venv/bin/python", "args": ["/path/to/your/project/src/mcp/run_servers.py", "editor"], "cwd": "/path/to/your/project" } } } -
Restart Claude Code to load the MCP server.
| Tool | Description |
|---|---|
run_editorial_pipeline |
Run full pipeline (fetch, score, synthesize) |
generate_editorial_report |
Generate unified signal table with categories |
cull_items |
Select items for newsletter using natural language |
generate_newsletter |
Generate newsletter from culled items |
generate_social_posts |
Create social posts from signals |
get_ranked_signals |
Get scored signals from a run |
get_pipeline_status |
Check pipeline run status |
list_sources |
List configured content sources |
fetch_discourse |
Fetch from ENS Forum |
fetch_github |
Fetch from GitHub repos |
fetch_x |
Fetch from X/Twitter |
test_source |
Test source connectivity |
refine_newsletter_section |
Improve newsletter section |
check_style_compliance |
Check content against style guide |
suggest_improvements |
Get improvement suggestions |
User: Run the editorial pipeline with 14 day lookback
User: Show me the editorial report
User: Cull D1, D5, G3, X2, and the ENS Labs quarterly update for the newsletter
User: Generate newsletter #105
User: Generate a twitter thread for the governance proposal
# Clone and install
git clone <repository-url>
cd editor
pip install -e .
# Configure
cp .env.example .env
# Edit .env with your API credentials# Run pipeline
editor run --lookback 14d --max-signals 100
# View report
editor report
# Cull items (interactive)
editor cull
# Generate content
editor generate --newsletter --number 105
editor generate --social --item G1 --type thread
# Validate configuration
editor validate --config --env --sources
# Test sources
editor test-sources
# Inspect outputs
editor inspect# LLM Providers (both required)
OPENAI_API_KEY=sk-... # Scoring, social posts
ANTHROPIC_API_KEY=sk-... # Newsletter generation
# Optional: Model configuration
LLM_MODEL=gpt-4o-mini
LLM_TEMPERATURE=0.2
# Source Adapters
GITHUB_TOKEN=ghp_... # GitHub API access
X_BEARER_TOKEN=... # X/Twitter API (Basic tier)
# Output
OUTPUT_DIR=./outsources:
# ENS Forum (Discourse) - No auth required
- id: ens-forum-latest
type: discourse
url: https://discuss.ens.domains
enabled: true
# GitHub - ENS Repositories
- id: ens-github-repos
type: github
repositories:
- "ensdomains/ens-contracts"
- "ensdomains/ens-app-v3"
- "ensdomains/ensjs"
monitor: [releases, pull_requests, commits]
enabled: true
# X/Twitter - Curated Accounts
- id: x-curated-voices
type: x
monitored_users:
- "ensdomains"
- "ens_dao"
max_posts_per_run: 500
enabled: trueThe system categorizes signals into newsletter sections:
| Section | Description | Source Signals |
|---|---|---|
proposals |
Governance proposals, temp checks, votes | Discourse governance posts |
enslabs |
ENS Labs team updates | @ensdomains, Labs team posts |
headlines |
DAO-wide news, reports, announcements | @ENS_DAO, financial reports |
metagov |
Meta-governance working group | Meta-Gov category posts |
ecosystem |
Service providers, integrations | Ecosystem partners |
publicgoods |
Public goods funding | Public goods category |
opensource |
Open source contributions | GitHub PRs, releases |
out/YYYY-MM-DD/
├── run.json # Run metadata
├── signals_ranked.json # Scored signals
├── report.md # Editorial report table
├── culled_items.json # Selected items by section
├── newsletter.md # Generated newsletter
└── social/
└── *.md # Social post drafts
editor/
├── src/
│ ├── adapters/ # Source adapters (discourse, github, x)
│ ├── cli/ # CLI commands
│ ├── mcp/ # MCP server
│ ├── models/ # Pydantic schemas
│ └── pipeline/ # Pipeline stages
├── templates/ # Newsletter template, style guide
├── tests/ # Unit, integration, red team tests
├── docs/internal/ # EDD, PRD, Claude.md
├── config.yml # Source configurations
├── .env # API credentials (gitignored)
├── .mcp.json # MCP config (gitignored)
└── .mcp.json.example # MCP config template
# Run all unit tests
pytest tests/unit/
# Run categorization red team tests
python tests/test_categorization_redteam.py
# Test MCP server functions
python tests/test_newsletter_workflow.py- Editor Authority Preserved - System assists, never replaces judgment
- Transparency - Visible sources, visible rationales
- Deterministic Outputs - Same inputs → same outputs
- Review-Gated - No autonomous publishing
- Neutral Tone - Factual, no hype or emojis
- Local-First - Filesystem as system of record
| API | Limit | Notes |
|---|---|---|
| X/Twitter Basic | 15,000 posts/month | Supports pagination, OR operators |
| GitHub | 5,000 requests/hour | Authenticated |
| Discourse | No strict limits | Public JSON endpoints |
MIT
Version: 1.0.0 Last updated: 2026-01-12