BlogPublisher
by perlahm0404
README.md
# BlogPublisher
Multi-platform blog publishing system that integrates with ResearchAgent for automated content distribution.
## Overview
BlogPublisher receives SEO-optimized articles from ResearchAgent and publishes them to multiple platforms:
- Personal website blog
- LinkedIn
- Twitter/X (as threads)
- Substack (email newsletter)
- Facebook (planned)
- Instagram (planned)
## Architecture
```
ResearchAgent (SEO writing) → BlogPublisher (distribution) → Multiple Platforms
```
### Features
✅ **Article Management**
- Save articles with SEO metadata
- Draft/scheduled/published status tracking
- PostgreSQL storage
✅ **Multi-Platform Publishing**
- Publish to 4+ platforms simultaneously
- Platform-specific content formatting
- Publication tracking and analytics
✅ **Scheduling**
- Schedule posts for future publication
- Automated cron-based publishing
- Retry logic for failures
✅ **MCP Integration**
- 7 MCP tools for Claude Desktop
- Seamless integration with ResearchAgent
- Single conversation workflow
## Quick Start
### 1. Prerequisites
- Python 3.10+
- PostgreSQL 14+
- Platform API credentials (see API Setup below)
### 2. Installation
```bash
cd ~/1_REPOS/BlogPublisher
# Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Setup environment
cp .env.example .env
# Edit .env with your credentials
```
### 3. Database Setup
```bash
# Create PostgreSQL database
createdb blogpublisher
# Update DATABASE_URL in .env
DATABASE_URL=postgresql://user:password@localhost:5432/blogpublisher
# Initialize database (tables auto-created on first run)
python backend/app.py # Runs migrations
```
### 4. Claude Desktop Configuration
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"research-agent": {
"command": "python",
"args": ["/Users/tmac/1_REPOS/ResearchAgent/backend/mcp_server.py"]
},
"blogpublisher": {
"command": "python",
"args": ["/Users/tmac/1_REPOS/BlogPublisher/backend/mcp_server.py"],
"env": {
"DATABASE_URL": "postgresql://localhost:5432/blogpublisher"
}
}
}
}
```
Restart Claude Desktop.
## Usage
### Daily Blogging Workflow
In Claude Desktop:
```
1. "Write SEO article about [topic]"
→ ResearchAgent creates optimized article
2. "Save this article to BlogPublisher"
→ Returns article_id
3. "Publish to website and LinkedIn immediately"
→ Publishes to both platforms
4. "Schedule Twitter thread for tomorrow at 10 AM"
→ Queues Twitter publication
```
### MCP Tools
**save_article**
```json
{
"title": "Article Title",
"content": "Markdown content...",
"summary": "Brief summary",
"keywords": ["seo", "keywords"],
"seo_score": {"score": 85}
}
```
Returns: `article_id`
**publish_article**
```json
{
"article_id": "uuid",
"platforms": ["website", "linkedin", "twitter", "substack"]
}
```
Returns: Publication results per platform
**schedule_article**
```json
{
"article_id": "uuid",
"platforms": ["linkedin", "twitter"],
"publish_time": "tomorrow at 6 AM"
}
```
Returns: Schedule confirmation
**get_article**
```json
{
"article_id": "uuid"
}
```
Returns: Full article with publication status
**list_articles**
```json
{
"status": "published",
"limit": 10
}
```
Returns: List of articles
**format_for_platform**
```json
{
"article_id": "uuid",
"platform": "twitter"
}
```
Returns: Platform-optimized content
**generate_social_posts**
```json
{
"article_id": "uuid"
}
```
Returns: Social media variants for all platforms
## API Setup
### Required Credentials
#### Website Blog
- `WEBSITE_API_URL`: Your blog API endpoint
- `WEBSITE_API_KEY`: API authentication key
#### LinkedIn
1. Create LinkedIn App: https://www.linkedin.com/developers/apps
2. Get OAuth 2.0 access token
3. Set `LINKEDIN_ACCESS_TOKEN`
#### Twitter/X
1. Create Twitter Developer account: https://developer.twitter.com
2. Create App and get API keys
3. Set:
- `TWITTER_API_KEY`
- `TWITTER_API_SECRET`
- `TWITTER_ACCESS_TOKEN`
- `TWITTER_ACCESS_SECRET`
#### Substack
1. Get Substack API credentials from your publication settings
2. Set:
- `SUBSTACK_API_KEY`
- `SUBSTACK_PUBLICATION_ID`
### Optional: Facebook & Instagram
- `FACEBOOK_ACCESS_TOKEN`
- `FACEBOOK_PAGE_ID`
- `INSTAGRAM_USERNAME`
- `INSTAGRAM_PASSWORD`
## Platform-Specific Formatting
### LinkedIn
- First 3 sentences as hook
- Professional tone
- 1-3 hashtags
- Link at end
### Twitter/X
- Converts to thread (280 chars/tweet)
- Numbered tweets (1/N)
- Link in last tweet
- Key points extracted
### Substack
- Full article as HTML email
- Subject line from title
- Preview text from summary
- Created as draft (manual publish)
### Website
- Markdown to HTML conversion
- SEO frontmatter
- Categories/tags
- Featured image support
## Automation
### Scheduler (Cron Jobs)
Start the scheduler:
```bash
python backend/scheduler/cron.py
```
Or run as background service:
```bash
# Using systemd (Linux)
sudo systemctl enable blogpublisher-scheduler
sudo systemctl start blogpublisher-scheduler
# Using launchd (macOS)
# See docs/deployment/macos-launchd.md
```
The scheduler runs every minute and publishes any pending scheduled posts.
## REST API
Optional REST API for programmatic access:
```bash
# Start API server
python backend/app.py
# Runs on http://localhost:8001
# API docs
open http://localhost:8001/docs
```
### Endpoints
- `POST /articles` - Create article
- `GET /articles` - List articles
- `GET /articles/{id}` - Get article
- `GET /health` - Health check
## Development
### Project Structure
```
BlogPublisher/
├── backend/
│ ├── database/
│ │ ├── models.py # SQLAlchemy models
│ │ └── db.py # Database connection
│ ├── publishers/
│ │ ├── base.py # Abstract publisher
│ │ ├── website.py # Website publisher
│ │ ├── linkedin.py # LinkedIn publisher
│ │ ├── twitter.py # Twitter publisher
│ │ └── substack.py # Substack publisher
│ ├── scheduler/
│ │ └── cron.py # Automated publishing
│ ├── mcp_server.py # MCP integration
│ └── app.py # FastAPI server
├── data/
│ ├── articles/ # Article storage
│ └── media/ # Images
├── requirements.txt
├── .env.example
└── README.md
```
### Adding New Platforms
1. Create publisher class in `backend/publishers/yourplatform.py`
2. Inherit from `BasePublisher`
3. Implement required methods:
- `validate_config()`
- `format_content()`
- `publish()`
4. Add to `Platform` enum in `models.py`
5. Update `get_publisher()` in `mcp_server.py` and `cron.py`
Example:
```python
from .base import BasePublisher
class NewPlatformPublisher(BasePublisher):
def validate_config(self):
if "api_key" not in self.config:
raise ValueError("Missing api_key")
def format_content(self, content, metadata=None):
# Platform-specific formatting
return formatted_content
def publish(self, title, content, metadata=None):
# API call to publish
return {
"success": True,
"post_id": "...",
"url": "..."
}
```
## Troubleshooting
### Database Connection Issues
```bash
# Check PostgreSQL is running
pg_isready
# Test connection
psql -U user -d blogpublisher
```
### MCP Tools Not Showing
1. Check Claude Desktop config file location
2. Verify Python path in config
3. Restart Claude Desktop
4. Check logs: `~/Library/Logs/Claude/mcp.log`
### Publishing Failures
Check platform API credentials:
```bash
# Test LinkedIn token
curl -H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
https://api.linkedin.com/v2/me
# Test Twitter credentials
# Use backend/publishers/test_publisher.py
```
## Testing
```bash
# Test database
python backend/database/db.py
# Test publishers
python backend/publishers/test_publisher.py
# Test MCP tools (requires running server)
python backend/mcp_server.py
```
## Roadmap
- [x] Core article storage
- [x] Website/LinkedIn/Twitter/Substack publishers
- [x] MCP integration
- [x] Scheduling system
- [ ] Facebook & Instagram publishers
- [ ] Analytics dashboard
- [ ] Content calendar UI
- [ ] Image optimization
- [ ] Link shortening
- [ ] A/B testing
- [ ] Performance metrics
## License
MIT
## Support
For issues or questions:
- Create GitHub issue
- Check documentation in `/docs`
- See ResearchAgent integration guide
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues