🎨 Notion Hero Image MCP
Transform your Notion pages with AI-powered animated hero banners! This MCP tool seamlessly integrates DALL-E 3, Google Veo 3, Cloudinary CDN, and the Notion API to create stunning animated covers for your Notion pages.
✨ Features
- 🖼️ AI Image Generation: Create hero images using DALL-E 3 with custom prompts
- 🎬 Video Animation: Animate still images using Google Veo 3 with detailed animation scripts
- ☁️ CDN Hosting: Automatic upload to Cloudinary for fast, reliable hosting
- 📄 Notion Integration: Direct cover image updates for Notion pages
- 🔄 Complete Pipeline: End-to-end workflow from prompt to published banner
- 🎯 Smart Conversion: Automatic MP4 to GIF conversion with optimization
🚀 Quick Start
Prerequisites
- Node.js 20.x or 22.x (Note: v24.3.0 has compatibility issues)
- npm (comes with Node.js)
Installation
# Install globally (recommended)
npm install -g @snahrup/notion-hero-image-mcp
# Run the interactive setup wizard
notion-hero-mcp-setup
The setup wizard will guide you through:
- 🔑 Getting API keys for each service
- 🔧 Configuring your environment
- 🤖 Setting up Claude Desktop automatically
- ✅ Testing your installation
Alternative: Manual Installation
# Clone and install locally
git clone https://github.com/stevedsimkins/notion-hero-image-mcp.git
cd notion-hero-image-mcp
npm install
# Run setup wizard
npm run setup
# or on Windows: setup.bat
# or on Mac/Linux: ./setup.sh
🔧 Detailed Setup Guide
1. OpenAI API Key
- Visit OpenAI Platform
- Sign in or create an account
- Navigate to API Keys section
- Create a new API key
- Add to
.env
:OPENAI_API_KEY=sk-proj-YOUR_KEY_HERE
2. Google Cloud Setup (for Veo 3)
Create a Google Cloud Project:
gcloud projects create YOUR_PROJECT_ID --name="Notion Hero MCP"
Enable required APIs:
gcloud services enable aiplatform.googleapis.com
Create a service account:
gcloud iam service-accounts create notion-hero-mcp-sa \ --display-name="Notion Hero MCP Service Account"
Download the key file:
gcloud iam service-accounts keys create notion-hero-image-mcp-sa-key.json \ --iam-account=notion-hero-mcp-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com
Grant necessary permissions:
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member="serviceAccount:notion-hero-mcp-sa@YOUR_PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/aiplatform.user"
Update
.env
:GOOGLE_PROJECT=YOUR_PROJECT_ID GOOGLE_REGION=us-central1 GOOGLE_APPLICATION_CREDENTIALS=C:/path/to/notion-hero-image-mcp-sa-key.json
3. Cloudinary Setup
- Create a free account at Cloudinary
- Navigate to Dashboard
- Copy your cloud name and API credentials
- Update
.env
with your credentials
4. Notion Integration
- Visit Notion Integrations
- Click "New integration"
- Name it "Notion Hero Image MCP"
- Select capabilities:
- Read content
- Update content
- Read comments (optional)
- Copy the Internal Integration Token
- Add to
.env
:NOTION_API_TOKEN=ntn_YOUR_TOKEN_HERE
- Share your Notion pages with the integration
📋 Available Tools
1. generate_image
Generate a hero still image using DALL-E 3.
Parameters:
prompt
(required): Visual description for the hero imagestyle
(optional): Art style - "cinematic", "illustration", "photorealistic" (default: "cinematic")
2. generate_video
Animate a still image using Google Veo 3.
Parameters:
image_url
(required): URL of the still image to animatetitle
(required): Title for the animationscene_description
(required): Detailed scene descriptionstyle_tags
(optional): Style descriptors for the animationanimation_beats
(optional): Timestamped animation sequencesduration
(optional): Duration in seconds, max 8 (default: 8)
3. mp4_to_gif
Convert MP4 to optimized GIF under 10MB.
Parameters:
mp4_path
(required): Local path to MP4 filewidth
(optional): Output width (default: 640)fps
(optional): Frames per second (default: 15)
4. upload_to_cloudinary
Upload GIF to Cloudinary and return permanent URL.
Parameters:
gif_path
(required): Local path to GIF filefolder
(optional): Cloudinary folder (default: "notion-banners")public_id
(optional): Public ID for the asset5.
Set a Notion page cover image from URL.set_notion_cover
Parameters:
page_id
(required): Notion page ID (32 chars with hyphens)cover_url
(required): HTTPS URL of the cover image
6. create_notion_banner
Complete pipeline: Find Notion page by name, generate animated banner, and set as cover.
Parameters:
page_name
(required): Name of the Notion pageprompt
(required): Creative prompt for the hero imagestyle
(optional): Visual style (default: "cinematic")references
(optional): URLs or descriptions of reference imagescustom_animation
(optional): Custom animation configuration
7. preview_banner_creation
Preview the banner creation plan before executing.
Parameters:
page_name
(required): Name of the Notion pageuser_request
(required): Natural language request for the bannerstyle_preference
(optional): Preferred visual style
🎯 Usage Examples
Basic Usage
// Generate a simple animated banner
await create_notion_banner({
page_name: "My Project",
prompt: "A futuristic cityscape with flying cars at sunset"
});
Advanced Usage with Custom Animation
await create_notion_banner({
page_name: "AI Research",
prompt: "Neural networks visualized as glowing interconnected nodes",
style: "cyberpunk",
custom_animation: {
title: "Neural Network Awakening",
scene_description: "A dark void where neural pathways begin to illuminate",
style_tags: "cinematic, sci-fi, dramatic lighting",
animation_beats: [
{
timeRange: "0s-2s",
description: "Darkness, then a single node sparks to life"
},
{
timeRange: "2s-5s",
description: "Energy cascades through connections exponentially"
},
{
timeRange: "5s-8s",
description: "Full network pulses with synchronized data flow"
}
]
}
});
Manual Pipeline
// Step 1: Generate image
const image = await generate_image({
prompt: "Serene mountain landscape at golden hour"
});
// Step 2: Animate it
const video = await generate_video({
image_url: image.url,
title: "Mountain Majesty",
scene_description: "Clouds drift across peaks as light shifts"
});
// Step 3: Convert to GIF
const gif = await mp4_to_gif({
mp4_path: video.local_path
});
// Step 4: Upload to CDN
const hosted = await upload_to_cloudinary({
gif_path: gif.path
});
// Step 5: Set as Notion cover
await set_notion_cover({
page_id: "your-page-id-here",
cover_url: hosted.url
});
🏗️ Architecture
User Request
│
▼
┌─────────────┐
│ DALL-E 3 │ ─── Generate hero still image
└─────────────┘
│
▼
┌─────────────┐
│ Google Veo 3│ ─── Animate with custom script
└─────────────┘
│
▼
┌─────────────┐
│ FFmpeg │ ─── Convert MP4 to optimized GIF
└─────────────┘
│
▼
┌─────────────┐
│ Cloudinary │ ─── Host on global CDN
└─────────────┘
│
▼
┌─────────────┐
│ Notion API │ ─── Update page cover
└─────────────┘
🐛 Troubleshooting
Common Issues
"Failed to find ffmpeg"
- Install FFmpeg: Download from ffmpeg.org
- Add to PATH or set FFMPEG_PATH environment variable
"Google Cloud authentication failed"
- Ensure service account key file exists at specified path
- Verify the service account has necessary permissions
- Check GOOGLE_APPLICATION_CREDENTIALS path uses forward slashes or escaped backslashes
"Notion page not found"
- Share the page with your integration
- Ensure page name matches exactly (case-sensitive)
- Try using page ID instead of name
"GIF exceeds 10MB limit"
- Reduce width parameter (try 480 or 320)
- Lower fps (try 10 or 12)
- Shorten animation duration
Debug Mode
Enable verbose logging by setting:
export DEBUG=notion-hero-mcp:*
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- OpenAI for DALL-E 3 API
- Google Cloud for Veo 3 video generation
- Cloudinary for reliable CDN hosting
- Notion for their excellent API
- The MCP ecosystem for enabling seamless tool integration
📧 Support
For issues, questions, or suggestions:
- Open an issue on GitHub
- Contact: your-email@example.com
Made with ❤️ for the Notion community