WhatsApp MCP: How to Use WhatsApp MCP Servers
In the rapidly evolving landscape of AI-assisted communication, the integration of messaging platforms with large language models represents a significant advancement in how we interact with digital assistants. WhatsApp MCP (Model Context Protocol) servers establish a secure bridge between conversational AI models and the world's most popular messaging platform, enabling AI assistants to interact with WhatsApp conversations, manage contacts, and respond to messages programmatically. This technical implementation transforms AI assistants from static, isolated systems into dynamic communication agents capable of real-time messaging interaction.
Introduction
The Model Context Protocol (MCP) provides a standardized framework for connecting AI models to external data sources and tools. WhatsApp MCP servers implement this protocol to create a secure, bidirectional interface between AI assistants and the WhatsApp messaging ecosystem. By leveraging WhatsApp's Business API or unofficial client libraries, MCP servers enable language models to programmatically access message history, send responses, manage media, and interact with contacts—all while maintaining proper authentication and respecting WhatsApp's usage policies.
https://github.com/whatsapp-mcp/whatsapp-mcp-server (opens in a new tab)
Technical Architecture of WhatsApp MCP
MCP Foundation
WhatsApp MCP operates within the standardized MCP architecture, which defines several key components:
-
Transport Layer:
- STDIO (Standard Input/Output): Direct process communication
- SSE (Server-Sent Events): HTTP-based asynchronous communication
- WebSocket: For real-time bidirectional communication
-
Resource Types:
- Prompts: Templated interaction patterns
- Tools: Executable WhatsApp operations
- Resources: Message history and contact data
-
Serialization Protocol: JSON for structured data exchange
WhatsApp MCP Server Architecture
The WhatsApp MCP server implements a multi-layered architecture optimized for messaging operations:
whatsapp-mcp/
├── src/
│ ├── auth/
│ │ ├── session.ts # Session management
│ │ ├── qr-handler.ts # QR authentication
│ │ └── token-manager.ts # API token management
│ ├── handlers/
│ │ ├── message-handler.ts # Message processing
│ │ ├── media-handler.ts # Media file operations
│ │ ├── contact-handler.ts # Contact management
│ │ └── group-handler.ts # Group operations
│ ├── tools/
│ │ ├── send-message.ts # Message sending tool
│ │ ├── read-messages.ts # Message retrieval tool
│ │ ├── media-tools.ts # Media handling tools
│ │ └── contact-tools.ts # Contact management tools
│ ├── resources/
│ │ ├── chat-history.ts # Chat history resource
│ │ └── contact-list.ts # Contact list resource
│ └── server.ts # MCP server implementation
├── config/
│ └── whatsapp-config.ts # Configuration options
└── package.json # Dependencies and scripts
The core technical implementation consists of:
- Client Wrapper: Abstraction over WhatsApp client libraries
- Authentication Manager: Handles WhatsApp session authentication
- Message Router: Directs messages between WhatsApp and MCP clients
- Media Handler: Processes media attachments
- Tool Implementations: Translates MCP commands to WhatsApp API calls
Authentication and Setup
Prerequisites
To implement WhatsApp MCP, ensure you have:
- Node.js 14+ runtime environment
- WhatsApp account (personal or business)
- An MCP-compatible client (Claude Desktop, VS Code, Cursor)
Authentication Methods
WhatsApp MCP supports multiple authentication flows:
1. QR Code Authentication Flow
For standard WhatsApp Web-based authentication:
const whatsappAuth = new QRAuthentication();
await whatsappAuth.initialize();
// Generates QR code for scanning with WhatsApp mobile app
const qrCode = await whatsappAuth.generateQR();
console.log(qrCode.ascii); // Display in terminal
console.log(qrCode.dataURL); // For web display
// Listens for successful authentication
whatsappAuth.on('authenticated', (session) => {
console.log('Authentication successful');
whatsappClient.initialize(session);
});
2. Persistent Authentication
For maintaining sessions across server restarts:
const sessionManager = new SessionManager('./sessions');
// Load existing session if available
const session = await sessionManager.loadSession(phoneNumber);
if (session) {
whatsappClient.initialize(session);
} else {
// Initiate new session
const qrAuth = new QRAuthentication();
const newSession = await qrAuth.authenticate();
await sessionManager.saveSession(phoneNumber, newSession);
whatsappClient.initialize(newSession);
}
Installation Methods
Option 1: Using npm
npm install -g whatsapp-mcp
Option 2: Using Smithery
npx -y @smithery/cli install whatsapp-mcp --client claude
Option 3: Manual Installation from Source
git clone https://github.com/whatsapp-mcp/whatsapp-mcp-server
cd whatsapp-mcp-server
npm install
npm run build
Configuration Settings
The WhatsApp MCP server accepts various configuration parameters:
-
Authentication Configuration:
WHATSAPP_SESSION_PATH
: Directory path for session storageWHATSAPP_PHONE_NUMBER
: Optional default phone numberWHATSAPP_BUSINESS_ID
: For business API authentication
-
Operation Controls:
WHATSAPP_MESSAGE_HISTORY_LIMIT
: Maximum messages to retrieveWHATSAPP_MEDIA_DOWNLOAD_PATH
: Directory for media downloadsWHATSAPP_TYPING_INDICATOR
: Enable/disable typing indicators
-
Security Settings:
WHATSAPP_ALLOWED_CONTACTS
: Restrict interactions to specific contactsWHATSAPP_GROUP_WHITELIST
: Allow interactions only in specified groupsWHATSAPP_ENCRYPTION_KEY
: Additional encryption for stored sessions
Example configuration in config.json
:
{
"authentication": {
"sessionPath": "./whatsapp-sessions",
"businessId": "optional-business-id",
"persistentSession": true
},
"messaging": {
"historyLimit": 50,
"typingIndicator": true,
"readReceipts": false
},
"security": {
"allowedContacts": ["1234567890", "0987654321"],
"groupWhitelist": ["Group A", "Group B"],
"encryptSessions": true
},
"media": {
"downloadPath": "./media-downloads",
"autoDownload": true,
"maxSize": 10485760
}
}
Integration with MCP Clients
Claude Desktop Integration
To integrate with Claude Desktop, edit the configuration file:
- macOS:
~/Library/Application\ Support/Claude/claude_desktop_config.json
- Windows:
%APPDATA%/Claude/claude_desktop_config.json
Add the following configuration:
{
"mcpServers": {
"whatsapp": {
"command": "npx",
"args": ["-y", "whatsapp-mcp"],
"env": {
"WHATSAPP_SESSION_PATH": "/path/to/sessions",
"WHATSAPP_ALLOWED_CONTACTS": "1234567890,0987654321"
}
}
}
}
VS Code Integration
For VS Code with GitHub Copilot, add to settings.json:
{
"github.copilot.chat.mcpServers": [
{
"name": "whatsapp",
"command": "npx",
"args": ["-y", "whatsapp-mcp"],
"env": {
"WHATSAPP_SESSION_PATH": "/path/to/sessions"
}
}
]
}
Core Functionality and Technical Implementation
Available Tools
The WhatsApp MCP server implements several key tools:
1. Message Operations
-
whatsapp_send_message: Sends text messages
interface SendMessageOptions { recipient: string; // Phone number or contact ID message: string; // Text content quotedMessageId?: string; // For replies mentionedContacts?: string[]; // For mentions markdownFormatting?: boolean; // Enable markdown parsing }
-
whatsapp_read_messages: Retrieves message history
interface ReadMessagesOptions { chatId: string; // Chat/contact identifier limit?: number; // Maximum messages to retrieve beforeMessage?: string; // Pagination token includeMedia?: boolean; // Include media messages markAsRead?: boolean; // Mark retrieved messages as read }
2. Media Operations
-
whatsapp_send_media: Sends media attachments
interface SendMediaOptions { recipient: string; mediaType: 'image' | 'document' | 'audio' | 'video' | 'sticker'; mediaUrl?: string; // External URL mediaBuffer?: string; // Base64 encoded buffer mediaPath?: string; // File system path caption?: string; // Media caption }
-
whatsapp_download_media: Downloads media from messages
interface DownloadMediaOptions { messageId: string; downloadPath?: string; returnAs?: 'path' | 'buffer' | 'url'; }
3. Contact Management
-
whatsapp_get_contacts: Retrieves contact list
interface GetContactsOptions { query?: string; // Search filter includeGroups?: boolean; limit?: number; offset?: number; }
-
whatsapp_contact_info: Retrieves detailed contact information
interface ContactInfoOptions { contactId: string; includeProfilePicture?: boolean; includeAbout?: boolean; }
4. Group Operations
-
whatsapp_group_participants: Gets group members
interface GroupParticipantsOptions { groupId: string; includeAdmins?: boolean; }
-
whatsapp_group_info: Retrieves group metadata
interface GroupInfoOptions { groupId: string; includeParticipants?: boolean; includeDescription?: boolean; }
Technical Usage Patterns
Multi-step Conversation Flow
// Connect to WhatsApp client
await tools.whatsapp_connect({
restoreSession: true,
sessionPath: './sessions'
});
// Read recent messages from a contact
const messages = await tools.whatsapp_read_messages({
chatId: '1234567890',
limit: 5,
includeMedia: false
});
// Process messages using LLM
const lastMessage = messages[0];
const responseText = await llmClient.generate({
prompt: `Respond to this message: ${lastMessage.body}`,
maxTokens: 100
});
// Send response back to WhatsApp
await tools.whatsapp_send_message({
recipient: '1234567890',
message: responseText,
quotedMessageId: lastMessage.id
});
Media Handling Workflow
// Process an incoming image message
const imageMessage = await tools.whatsapp_read_messages({
chatId: '1234567890',
limit: 1,
includeMedia: true
});
if (imageMessage[0].hasMedia) {
// Download the media
const mediaContent = await tools.whatsapp_download_media({
messageId: imageMessage[0].id,
returnAs: 'buffer'
});
// Process the image (e.g., with a vision model)
const imageDescription = await visionModel.describe(mediaContent);
// Respond with the description
await tools.whatsapp_send_message({
recipient: '1234567890',
message: `Image description: ${imageDescription}`,
quotedMessageId: imageMessage[0].id
});
}
Advanced Implementation Considerations
Rate Limiting and Throttling
To prevent API abuse and respect WhatsApp's limits:
class MessageThrottler {
private messageQueue: Queue<MessageTask>;
private rateLimitPerMinute: number;
private processingInterval: NodeJS.Timer;
constructor(rateLimitPerMinute = 20) {
this.messageQueue = new Queue();
this.rateLimitPerMinute = rateLimitPerMinute;
// Process queue at calculated interval
const intervalMs = (60 * 1000) / this.rateLimitPerMinute;
this.processingInterval = setInterval(
() => this.processNextMessage(),
intervalMs
);
}
async enqueueMessage(messageTask: MessageTask): Promise<string> {
return new Promise((resolve, reject) => {
this.messageQueue.enqueue({
...messageTask,
resolve,
reject
});
});
}
private async processNextMessage() {
if (this.messageQueue.isEmpty()) return;
const task = this.messageQueue.dequeue();
try {
const result = await this.whatsappClient.sendMessage(
task.recipient,
task.message,
task.options
);
task.resolve(result);
} catch (error) {
task.reject(error);
}
}
}
Security and Privacy Implementation
-
Message Encryption:
class MessageEncryption { private encryptionKey: Buffer; constructor(key: string) { this.encryptionKey = crypto.scryptSync(key, 'salt', 32); } encrypt(message: string): string { const iv = crypto.randomBytes(16); const cipher = crypto.createCipheriv('aes-256-gcm', this.encryptionKey, iv); let encrypted = cipher.update(message, 'utf8', 'hex'); encrypted += cipher.final('hex'); const authTag = cipher.getAuthTag(); return iv.toString('hex') + ':' + authTag.toString('hex') + ':' + encrypted; } decrypt(encryptedMessage: string): string { const [ivHex, authTagHex, encryptedHex] = encryptedMessage.split(':'); const iv = Buffer.from(ivHex, 'hex'); const authTag = Buffer.from(authTagHex, 'hex'); const decipher = crypto.createDecipheriv('aes-256-gcm', this.encryptionKey, iv); decipher.setAuthTag(authTag); let decrypted = decipher.update(encryptedHex, 'hex', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } }
-
Contact Permissioning:
function isContactAllowed(contactId: string): boolean { const allowedContacts = process.env.WHATSAPP_ALLOWED_CONTACTS?.split(',') || []; if (allowedContacts.length === 0) return true; return allowedContacts.includes(contactId); }
Error Handling Strategy
The server implements robust error handling:
async function withErrorHandling<T>(operation: () => Promise<T>): Promise<T> {
try {
return await operation();
} catch (error) {
if (error.name === 'AuthenticationError') {
throw new MCP.ToolError("WhatsApp authentication failed", "AUTHENTICATION_FAILED");
} else if (error.name === 'ConnectionError') {
throw new MCP.ToolError("Connection to WhatsApp failed", "CONNECTION_FAILED");
} else if (error.name === 'RateLimitError') {
throw new MCP.ToolError("Rate limit exceeded", "RATE_LIMIT_EXCEEDED");
} else {
throw new MCP.ToolError(`Unexpected error: ${error.message}`, "UNKNOWN");
}
}
}
Troubleshooting Common Technical Issues
Authentication Problems
If WhatsApp authentication fails:
- Verify QR code scanning process with mobile device
- Check for expired sessions:
rm -rf ./whatsapp-sessions/*
- Ensure WhatsApp mobile app is up to date
Connection Stability
For maintaining reliable connections:
class ConnectionManager {
private reconnectAttempts: number = 0;
private maxReconnectAttempts: number = 5;
private reconnectDelay: number = 5000;
async establishConnection(sessionData: any): Promise<void> {
try {
await this.whatsappClient.connect(sessionData);
this.reconnectAttempts = 0;
// Setup reconnection on disconnect
this.whatsappClient.on('disconnect', () => this.handleDisconnect());
} catch (error) {
this.handleConnectionError(error);
}
}
private async handleDisconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
console.log(`Connection lost. Reconnecting (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
setTimeout(() => this.establishConnection(this.lastSessionData),
this.reconnectDelay * this.reconnectAttempts);
} else {
console.error('Maximum reconnection attempts reached');
}
}
}
Conclusion
WhatsApp MCP servers represent a sophisticated technical bridge between conversational AI and the world's most widely used messaging platform. By leveraging the Model Context Protocol framework with WhatsApp's API capabilities, these servers enable AI assistants to engage in genuine messaging interactions, opening new possibilities for automated communication, customer service, and personal assistance.
The technical implementation described provides a robust foundation for building secure, scalable WhatsApp integration with AI systems. As both MCP and WhatsApp's API evolve, we can expect further enhancements in capabilities, security features, and ease of integration.
For developers looking to extend their AI systems with messaging capabilities, WhatsApp MCP offers a standardized, secure approach that respects the platform's constraints while unlocking powerful new interaction modalities for AI assistants.