Medium Blog MCP Server
# š Medium Blog MCP Server
AI-powered blog generation system built with FastMCP. Automates research, content generation, quality checks, and Medium export for technical blog posts.
## ⨠Features
- š **Multi-Source Research**: Automatically gathers content from Wikipedia, arXiv, web search, and images
- š¤ **AI Content Generation**: Uses Claude API to generate high-quality blog posts
- š **Image Processing**: Downloads and describes images with AI-generated descriptions
- š **Quality Analysis**: Comprehensive readability, citation, and SEO checks
- ā
**Plagiarism Tracking**: Hybrid manual/automated plagiarism checking workflow
- š¤ **Medium Export**: One-click export to Medium-ready markdown format
- š¾ **SQLite Storage**: Persistent storage of all drafts and research
## šļø Architecture
```
Medium Blog MCP Server
āāā Research Engine (Wikipedia, arXiv, Web, Images)
āāā AI Content Generator (Claude API)
āāā Image Handler (Download + AI Description)
āāā Quality Analyzer (Readability, Citations, SEO)
āāā Medium Exporter (Markdown + Assets)
āāā SQLite Database (Sessions, Drafts, Research)
```
## š Prerequisites
- Python 3.10+
- Anthropic API Key ([Get one here](https://console.anthropic.com/))
- pip or conda
## š Quick Start
### 1. Clone and Install
```bash
# Clone repository
git clone <your-repo-url>
cd medium-blog-mcp
# Activate virtual environment
uv init
uv sync
# Install dependencies
uv add -r requirements.txt
# use these uv commands to test , run mcp servers
Test the server - uv run fastmcp dev main.py
Run the server - uv run fastmcp run main.py
Add the server to claude desktop - uv run fastmcp install
claude-desktop main.py
```
### 2. Configure Environment
```bash
# Copy environment template
cp .env.example .env
# Edit .env and add your DB URL
# DATABASE_URL=YOUR_SQLITE_DB_URL
```
### 3. Run the Server
```bash
python main.py
```
The MCP server will start and be available for Claude Desktop or other MCP clients.
## š§ Configuration for Claude Desktop
Add to your Claude Desktop `claude_desktop_config.json`:
```json
{
"mcpServers": {
"medium-blog-generator": {
"command": "[Your/Path/to/uv]",
"args": [
"--directory",
"C:\\medium_mcp",
"run",
"fastmcp",
"run",
"main.py"
],
"env": {},
"transport": "stdio",
"type": null,
"cwd": null,
"timeout": null,
"description": null,
"icon": null,
"authentication": null
}
}
}
```
**Config locations:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
## š Complete Workflow
### Step 1: Create Session
```
create_blog_session(topic="Latest AI Model Advancements", target_length="medium")
```
### Step 2: Research Phase ā USER CHECKPOINT
```
research_topic(session_id="abc123", depth="comprehensive")
get_research_summary(session_id="abc123") # Review research
approve_research(session_id="abc123") # Approve to continue
```
### Step 3: Outline Generation ā USER CHECKPOINT
```
generate_outline(session_id="abc123", style="technical", num_sections=5)
# Review outline, optionally modify
approve_outline(session_id="abc123")
```
### Step 4: Content Generation
```
generate_full_content(session_id="abc123")
get_full_draft(session_id="abc123") # Review full draft
```
### Step 5: Plagiarism Checking ā USER CHECKPOINT (Manual)
```
prepare_plagiarism_chunks(session_id="abc123")
# Copy chunks to Grammarly/QuillBot/GPTZero manually
record_plagiarism_result(session_id="abc123", chunk_id=1,
plagiarism_score=2.3, ai_detection_score=8.5,
tool_used="Grammarly")
```
### Step 6: Quality Analysis ā USER CHECKPOINT
```
run_quality_analysis(session_id="abc123") # Get detailed QA report
approve_final_draft(session_id="abc123") # Final approval
```
### Step 7: Export to Medium
```
export_to_medium(session_id="abc123")
```
## š ļø Available MCP Tools
### Session Management
- `create_blog_session` - Start new blog project
- `get_session_status` - Check progress
- `list_sessions` - List all sessions
### Research
- `research_topic` - Multi-source research
- `get_research_summary` - Review findings
- `add_custom_source` - Add manual sources
- `approve_research` - ā Proceed to outline
### Outline
- `generate_outline` - AI-generated structure
- `modify_outline` - Make changes
- `approve_outline` - ā Proceed to writing
### Content Generation
- `generate_full_content` - Generate blog
- `get_full_draft` - Review content
- `regenerate_section` - Improve specific section
### Plagiarism Checking
- `prepare_plagiarism_chunks` - Split for checking
- `record_plagiarism_result` - ā Record manual checks
- `get_plagiarism_summary` - View all results
### Quality & Export
- `run_quality_analysis` - Comprehensive QA
- `approve_final_draft` - ā Final approval
- `export_to_medium` - Generate export files
## š Project Structure
```
medium-blog-mcp/
āāā main.py # FastMCP server (all tools)
āāā database.py # SQLAlchemy models & DB operations
āāā research.py # Multi-source research engine
āāā content_generator.py # Claude API content generation
āāā image_handler.py # Image download & AI descriptions
āāā quality.py # Quality analysis & readability
āāā exporter.py # Medium markdown export
āāā config.py # Configuration management
āāā requirements.txt # Python dependencies
āāā .env.example # Environment variables template
āāā README.md # This file
āāā data/ # Generated data (auto-created)
āāā blog_database.db # SQLite database
āāā sessions/ # Session-specific data
ā āāā {session_id}/
ā āāā images/ # Downloaded images
āāā exports/ # Final exports
ā āāā {session_id}/
ā āāā blog_post.md
ā āāā images/
ā āāā citations.txt
ā āāā metadata.json
ā āāā qa_report.txt
āāā images/ # Image storage
```
## šÆ Usage Example
Here's a complete example of generating a blog about AI models:
```python
# 1. Create session
create_blog_session(topic="GPT-4 vs Claude 3: Technical Comparison", target_length="medium")
# Returns: {"session_id": "abc123", ...}
# 2. Research
research_topic(session_id="abc123", depth="comprehensive")
get_research_summary(session_id="abc123")
# Review the 15-20 sources gathered
approve_research(session_id="abc123")
# 3. Generate outline
generate_outline(session_id="abc123", style="technical", num_sections=5)
# Review outline structure
approve_outline(session_id="abc123")
# 4. Generate content
generate_full_content(session_id="abc123")
get_full_draft(session_id="abc123")
# Review the ~2500 word blog with images
# 5. Check plagiarism manually
prepare_plagiarism_chunks(session_id="abc123")
# Copy chunks to Grammarly, check, then:
record_plagiarism_result(session_id="abc123", chunk_id=1,
plagiarism_score=1.8, ai_detection_score=7.2,
tool_used="Grammarly")
# 6. Quality analysis
run_quality_analysis(session_id="abc123")
# Review QA report
approve_final_draft(session_id="abc123")
# 7. Export
export_to_medium(session_id="abc123")
# Get Medium-ready markdown + all assets!
```
**Total time:** 30-45 minutes for a complete 2500-word blog!
## š Quality Checks
The system automatically checks:
### Readability
- Flesch Reading Ease score
- Flesch-Kincaid Grade Level
- Average sentence length
- Passive voice percentage
### Citations
- All sources properly cited
- Citation format validation
- Unused sources identified
### Images
- All images have descriptions
- Alt text present
- Proper placement
### SEO
- Title length (50-70 chars optimal)
- Header hierarchy (H1, H2, H3)
- Keyword presence
- Meta information
### Structure
- Word count vs target
- Section balance
- Overall organization
## š Database Schema
### Tables
- **sessions** - Blog sessions
- **research_sources** - Research data
- **outlines** - Generated outlines
- **blog_drafts** - Blog content versions
- **images** - Downloaded images
- **plagiarism_checks** - Manual check results
- **quality_checks** - QA reports
All data persists across sessions and can be resumed.
## š Troubleshooting
### Database Issues
```bash
# Reset database (WARNING: deletes all data)
rm data/blog_database.db
python main.py # Will recreate database
```
### Image Download Failures
- Check internet connection
- Some images may be behind authentication
- System will create fallback descriptions
## š Development Roadmap
### Current Version (v1.0)
- ā
Multi-source research
- ā
AI content generation
- ā
Image processing
- ā
Quality analysis
- ā
Medium export
### Future Enhancements (v2.0+)
- š² Automated plagiarism APIs
- š² Multiple format exports (HTML, PDF)
- š² Note-taking app integrations (Obsidian, Notion)
- š² Multi-blog management
- š² SEO optimization suggestions
- š² Social media snippet generation
## š License
MIT License - feel free to use and modify for your needs.
## š¤ Contributing
Contributions welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request
## š¬ Support
For issues or questions:
- Open an issue on GitHub
- Check the documentation
- Review example workflows
## š Credits
Built with:
- [FastMCP](https://github.com/jlowin/fastmcp) - MCP server framework
- [Anthropic Claude](https://www.anthropic.com) - AI content generation
- [SQLAlchemy](https://www.sqlalchemy.org/) - Database ORM
- Various open-source research APIs
---
**Happy blogging! š**
TDQS
Scored across 23 tools
Most tools map to distinct workflow stages (research, outline, draft, plagiarism, QA, export), but a few could be confused: generate_outline/generate_full_content are agent instructions that overlap conceptually with save_outline/save_draft, and the multiple get_*_summary tools require reading descriptions to distinguish.
Every tool follows a consistent verb_noun snake_case pattern (create_*, get_*, list_*, approve_*, save_*, export_*). The verbs are predictable and the workflow stage is clear from the name.
At 23 tools, the surface feels heavy and falls in the borderline 16-25 range, though the multi-stage workflow gives most tools a purpose. Several session and file getters could potentially be consolidated.
The end-to-end pipeline is covered (research ā outline ā draft ā plagiarism ā QA ā export), but there are notable gaps: sessions can be created/listed but not updated/deleted, saved outlines cannot be retrieved directly, and the server exports markdown rather than publishing to Medium.