idoll/sfmc-single-tenant-mcp
If you are the rightful owner of sfmc-single-tenant-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.
A Model Context Protocol (MCP) server for Salesforce Marketing Cloud (SFMC) integration, built with FastMCP and OAuth 2.1, designed for deployment on Heroku as a public service.
SFMC MCP Server
A Model Context Protocol (MCP) server for Salesforce Marketing Cloud (SFMC) integration, built with FastMCP and OAuth 2.1, designed for deployment on Heroku as a public service.
Overview
This MCP server provides secure, authenticated access to Salesforce Marketing Cloud APIs through the Model Context Protocol, enabling you to:
- List and query Data Extensions
- Retrieve subscriber information
- Send emails via SFMC
- Manage multi-business unit (BU) accounts
- Integrate SFMC operations into AI workflows with Claude.ai
- Access SFMC functionality through OAuth-secured HTTP/SSE from anywhere
Features
Available MCP Tools
Note: All tools now require JWT authentication. Each user's OAuth tokens are used for API calls. All tools support multi-business unit (BU) accounts.
- list_data_extensions - Retrieve all data extensions using authenticated user's permissions (supports multi-BU)
- query_data_extension - Query specific data extension data with user's OAuth token (supports multi-BU)
- get_subscribers - Retrieve subscriber lists with user's permissions (supports multi-BU)
- send_email - Send emails using authenticated user's SFMC account (supports multi-BU)
- list_business_units - Discover which business units the authenticated user has access to (returns BU IDs for use in other tools)
Multi-Business Unit Support
For enterprise SFMC accounts with multiple business units:
- BU ID automatically detected from OAuth token
- Optional
business_unit_idparameter on all tools - Separate token storage per BU
- See for detailed documentation
Prerequisites
- Python 3.11+
- Salesforce Marketing Cloud account with API access
- SFMC API credentials (Client ID, Client Secret, Subdomain, Account ID)
- Heroku account (for cloud deployment)
Architecture
This server uses FastMCP (a high-level Python framework for MCP servers) with OAuth 2.1 delegated authentication, making it accessible as a secure, public HTTP service. Unlike stdio-based MCP servers that require local execution, this server can be deployed to the cloud and accessed from anywhere via HTTP/SSE.
Key Features
- OAuth 2.1 Delegated Flow: Users authenticate with their own SFMC accounts
- FastMCP Framework: High-level MCP server framework with built-in SSE/HTTP transport
- Direct API Integration: No FuelSDK dependency - uses native REST/SOAP APIs
- Multi-Business Unit Support: Seamlessly work across multiple SFMC business units
- Encrypted Token Storage: User tokens encrypted at rest with Fernet encryption
- PostgreSQL Database: Secure, scalable token and user management
Project Structure
SFMC MCP/
├── src/ # Source code
│ ├── server.py # Main FastMCP application
│ ├── core/ # Core SFMC functionality
│ │ ├── config.py # Basic server config
│ │ └── sfmc_client.py # Direct REST/SOAP API client
│ ├── auth/ # OAuth 2.1 authentication
│ │ ├── config.py # OAuth settings
│ │ ├── crypto.py # Token encryption (Fernet)
│ │ ├── fastmcp_oauth.py # FastMCP OAuth handler
│ │ ├── jwt.py # JWT token management
│ │ ├── models.py # Database models (User)
│ │ └── state.py # OAuth state management
│ └── utils/ # Utility scripts
│ └── generate_keys.py # Key generation helper
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── TESTING_GUIDE.md # Testing documentation
├── docs/ # Documentation
│ └── AI Generated Docs/ # AI-generated docs (gitignored)
├── pyproject.toml # Project config & dependencies
├── Makefile # Development commands
├── .pre-commit-config.yaml # Code quality hooks
└── requirements.txt # Production dependencies
Local Setup
Quick Start with Make
# Install dependencies
make install-dev
# Run tests
make test
# Format code
make format
# Run linters
make lint
# Start development server
make run
Manual Setup
1. Clone the Repository
git clone git@github.com:idoll_sfemu/SFMC_MCP.git
cd SFMC_MCP
2. Create Virtual Environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
3. Install Dependencies
pip install -r requirements.txt
4. Configure Environment Variables
Copy the example environment file and fill in your SFMC OAuth credentials:
cp env_oauth.example .env
Edit .env with your SFMC OAuth credentials and generate secure keys:
# Generate secure keys
python src/utils/generate_keys.py
# Then edit .env with:
# - SFMC OAuth credentials (Client ID, Client Secret, Subdomain)
# - Generated JWT_SECRET_KEY
# - Generated ENCRYPTION_KEY
# - Generated STATE_SECRET_KEY
# - SERVER_BASE_URL (e.g., http://localhost:5000 for local dev)
# - DATABASE_URL (defaults to SQLite for local dev)
Note: For local OAuth testing, you'll need to use a tunneling service like ngrok since SFMC requires HTTPS for OAuth callbacks and doesn't support localhost.
5. Initialize Database
# Database tables will be created automatically on first run
python -m src.server
6. Run the Server Locally
Start the FastMCP server:
make run
# or
python -m src.server
The server will be available at:
- Main API:
http://localhost:5000/ - Health check:
http://localhost:5000/health - MCP endpoint:
http://localhost:5000/mcp - OAuth authorization:
http://localhost:5000/auth/authorize
Heroku Deployment
Method 1: Heroku CLI
-
Install Heroku CLI (if not already installed)
brew install heroku/brew/heroku # macOS -
Login to Heroku
heroku login -
Create Heroku App
heroku create your-sfmc-mcp-server -
Add PostgreSQL Database
heroku addons:create heroku-postgresql:essential-0 -
Generate and Set Environment Variables
# Generate secure keys locally python src/utils/generate_keys.py # Set OAuth config heroku config:set SALESFORCE_CLIENT_ID=your_client_id heroku config:set SALESFORCE_CLIENT_SECRET=your_client_secret heroku config:set SALESFORCE_SUBDOMAIN=your_subdomain heroku config:set SERVER_BASE_URL=https://your-app-name.herokuapp.com # Set security keys (from generate_keys.py output) heroku config:set JWT_SECRET_KEY=generated_jwt_key heroku config:set ENCRYPTION_KEY=generated_encryption_key heroku config:set STATE_SECRET_KEY=generated_state_key # Set CORS (optional, defaults to Claude.ai) heroku config:set ALLOWED_ORIGINS=https://claude.ai,https://api.anthropic.com -
Deploy
git push heroku main -
Scale the Dyno
heroku ps:scale web=1 -
Verify Deployment
heroku open heroku logs --tail
Method 2: Deploy Button
Click the button below to deploy directly to Heroku:
You'll be prompted to enter your SFMC credentials during setup.
Getting SFMC API Credentials
- Log in to Salesforce Marketing Cloud
- Navigate to Setup > Apps > Installed Packages
- Click New to create a new package
- Add API Integration component with required permissions:
- Email: Read, Write, Send
- Web: Read, Write
- Contacts: Read, Write
- Data Extensions: Read, Write
- Save and note down:
- Client ID
- Client Secret
- Subdomain (from your SFMC URL, e.g.,
mc123456789) - Account ID (MID)
Usage
Authentication Flow
- User initiates OAuth: User navigates to
/auth/authorize?client_id=<your_client_id> - SFMC login: User authenticates with their SFMC account
- Token exchange: Server receives OAuth tokens and stores them encrypted
- JWT issued: Server issues a JWT to the user/client
- MCP tools: User includes JWT in tool calls for authenticated SFMC API access
API Endpoints
GET /- Server information and available toolsGET /health- Health check endpointGET /mcp- MCP endpoint for SSE communicationGET /auth/authorize- Start OAuth flow with SFMCGET /auth/callback- OAuth callback endpoint (internal)GET /.well-known/oauth-authorization-server- OAuth metadata (RFC 8414)
Accessing the Server
Once deployed to Heroku, your server will be publicly accessible via HTTPS:
https://your-app-name.herokuapp.com/
With MCP Clients
Configure your MCP client (e.g., Claude Desktop) to connect via SSE transport:
Example configuration for Claude Desktop:
{
"mcpServers": {
"sfmc": {
"url": "https://your-app-name.herokuapp.com/mcp",
"transport": "sse",
"authentication": {
"type": "oauth2",
"authorizationUrl": "https://your-app-name.herokuapp.com/auth/authorize"
}
}
}
}
For local development (with ngrok for OAuth):
{
"mcpServers": {
"sfmc": {
"url": "https://your-ngrok-url.ngrok.io/mcp",
"transport": "sse",
"authentication": {
"type": "oauth2",
"authorizationUrl": "https://your-ngrok-url.ngrok.io/auth/authorize"
}
}
}
}
Note: All tool calls require JWT authentication. The OAuth flow will automatically provide this token to authorized clients.
Testing with cURL
You can test the server endpoints directly:
# Check server status
curl https://your-app-name.herokuapp.com/
# Health check
curl https://your-app-name.herokuapp.com/health
# View API documentation
open https://your-app-name.herokuapp.com/docs
Example Tool Calls via MCP
Once connected through an MCP client:
List Data Extensions:
{
"tool": "list_data_extensions",
"arguments": {}
}
Query Data Extension:
{
"tool": "query_data_extension",
"arguments": {
"customer_key": "MyDataExtension",
"filter_clause": "EmailAddress = 'test@example.com'"
}
}
Get Subscribers:
{
"tool": "get_subscribers",
"arguments": {
"limit": 50
}
}
Send Email:
{
"tool": "send_email",
"arguments": {
"subscriber_key": "12345",
"email_address": "recipient@example.com",
"email_name": "Welcome Email"
}
}
Monitoring
Health Check Endpoints
The server provides multiple endpoints for monitoring:
GET /- Server information, version, and available toolsGET /health- Simple health check (returns{"status": "healthy"})GET /docs- Interactive API documentation
Access your deployed server:
# Health check
curl https://your-sfmc-mcp-server.herokuapp.com/health
# Server info
curl https://your-sfmc-mcp-server.herokuapp.com/
# Open interactive docs in browser
open https://your-sfmc-mcp-server.herokuapp.com/docs
Logs
View Heroku logs:
heroku logs --tail
Performance
FastMCP with SSE transport provides:
- Low latency HTTP communication
- Automatic reconnection handling
- Scalable architecture for multiple concurrent clients
- Built-in OAuth 2.1 authentication
- Encrypted token storage for security
Troubleshooting
Common Issues
-
Authentication Errors
- Verify your SFMC credentials are correct
- Ensure API package has necessary permissions
- Check that subdomain matches your SFMC instance
-
Connection Timeouts
- Verify SFMC API endpoint URLs
- Check network connectivity
- Review Heroku logs for detailed errors
-
Module Import Errors
- Ensure all dependencies are in
requirements.txt - Rebuild Heroku app if needed:
heroku restart
- Ensure all dependencies are in
Security Considerations
- Never commit
.envfile or credentials to Git - Use Heroku Config Vars for sensitive data
- Regularly rotate API credentials
- Implement rate limiting for production use
- Review SFMC API permissions regularly
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License.
Support
For issues and questions:
- Open an issue on GitHub
- Check SFMC API documentation: https://developer.salesforce.com/docs/marketing/marketing-cloud/guide/apis.html
- Review MCP specification: https://modelcontextprotocol.io/
Technology Stack
- FastMCP - High-level Python framework for MCP servers
- OAuth 2.1 - Delegated authentication flow
- SSE (Server-Sent Events) - Real-time HTTP communication (built into FastMCP)
- Uvicorn - Lightning-fast ASGI server
- SQLAlchemy 2.0 - Async ORM for database operations
- PostgreSQL - Production database (Heroku)
- Direct SFMC APIs - Native REST and SOAP integration (no FuelSDK)
- Cryptography (Fernet) - Symmetric encryption for tokens
- PyJWT - JWT token generation and validation
Acknowledgments
- Built with Model Context Protocol
- Powered by FastMCP
- Direct integration with SFMC REST & SOAP APIs
- Designed for deployment on Heroku