Skip to main content
Glama

WhatsApp MCP Server

by gfb-47
index.js7.88 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod"; import { exec } from "child_process"; import { promisify } from "util"; import * as fs from "fs"; // Setup error logging to help with debugging const logError = (message, error) => { console.error(`ERROR: ${message}`, error ? error : ''); // Optionally log to a file for persistent debugging try { const logDir = process.env.HOME + '/Library/Logs/whatsapp-mcp'; if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } fs.appendFileSync(`${logDir}/error.log`, `${new Date().toISOString()} - ${message} ${error ? JSON.stringify(error) : ''}\n`); } catch (e) { console.error("Failed to write to log file:", e); } }; const execPromise = promisify(exec); // Create the MCP server console.error("Setting up MCP server..."); const server = new McpServer({ name: "WhatsApp-Helper", version: "1.0.0" }); console.error("MCP server created successfully"); // Helper function to execute AppleScript async function runAppleScript(script) { try { const { stdout } = await execPromise(`osascript -e '${script.replace(/'/g, "'\\''")}'`); return stdout.trim(); } catch (error) { console.error("AppleScript execution error:", error); throw new Error(`Failed to execute AppleScript: ${error}`); } } // Helper function to properly format messages for WhatsApp function formatWhatsAppMessage(message) { // Replace normal line breaks with AppleScript line breaks // This ensures proper line breaking in WhatsApp return message .replace(/\n/g, '" & return & "') .replace(/"/g, '\\"'); } // Improved function to send WhatsApp messages with specified contact selection method server.tool("send-whatsapp-message", "Send a message to a contact on WhatsApp", { contactName: z.string().describe("Full name of the contact as it appears in WhatsApp"), message: z.string().describe("Message content to send"), }, async ({ contactName, message }) => { try { // Format the message for proper line breaks const formattedMessage = formatWhatsAppMessage(message); // Updated AppleScript with specific contact selection method (down arrow twice, then enter) const appleScript = ` tell application "WhatsApp" to activate delay 4 -- Give WhatsApp time to fully activate tell application "System Events" tell process "WhatsApp" -- Access the search field try -- Keyboard shortcut for search keystroke "f" using {command down} delay 2 -- Clear any existing text keystroke "a" using {command down} keystroke (ASCII character 8) -- Backspace delay 1.5 -- Type the contact name keystroke "${contactName.replace(/"/g, '\\"')}" -- Give time for search results to populate delay 6 -- SPECIFIC CONTACT SELECTION METHOD: -- Tap down arrow twice and press enter keystroke (ASCII character 31) -- first down arrow delay 1 keystroke (ASCII character 31) -- second down arrow delay 1 keystroke return -- press enter delay 3 -- By now, chat should be open. Type and send the message keystroke "${formattedMessage}" delay 2 -- Send the message keystroke return delay 1 return "Message sent using down arrow twice then enter method" on error errMsg return "Failed to send message: " & errMsg end try end tell end tell `; const result = await runAppleScript(appleScript); return { content: [ { type: "text", text: `Message sent to ${contactName}: "${message}"`, } ] }; } catch (error) { return { content: [ { type: "text", text: `Error sending message: ${error}`, } ], isError: true }; } }); // Tool to check if WhatsApp is currently running server.tool("check-whatsapp-status", "Check if WhatsApp is currently running", {}, async () => { try { const appleScript = ` tell application "System Events" return (exists process "WhatsApp") end tell `; const result = await runAppleScript(appleScript); const isRunning = result.toLowerCase() === 'true'; return { content: [ { type: "text", text: isRunning ? "WhatsApp is currently running." : "WhatsApp is not currently running. Please start WhatsApp before trying to send messages.", } ] }; } catch (error) { return { content: [ { type: "text", text: `Error checking WhatsApp status: ${error}`, } ], isError: true }; } }); // Tool to list recent WhatsApp contacts (this is a simplified version as full access may be limited) server.tool("list-recent-contacts", "List recently contacted people on WhatsApp (simplified)", {}, async () => { try { // This is a simulated result since direct access to WhatsApp's contact list // through AppleScript is limited return { content: [ { type: "text", text: "Due to WhatsApp's privacy protections, listing contacts programmatically is limited. " + "Please specify the exact contact name when sending messages.", } ] }; } catch (error) { return { content: [ { type: "text", text: `Error listing contacts: ${error}`, } ], isError: true }; } }); // Connect to stdio transport async function main() { try { console.error("Starting WhatsApp MCP Server..."); // Create a more robust transport with error handling const transport = new StdioServerTransport(); transport.onerror = (error) => { logError("Transport error occurred", error); }; transport.onclose = () => { console.error("Transport closed"); }; // Connect with additional error handling await server.connect(transport); console.error("WhatsApp MCP Server is running"); // Keep the process alive process.on('uncaughtException', (err) => { logError('Uncaught exception', err); }); process.on('unhandledRejection', (reason) => { logError('Unhandled rejection', reason); }); } catch (error) { logError("Error starting server", error); // Give time for the error to be logged setTimeout(() => { process.exit(1); }, 1000); } } // Add startup logging console.error("Initializing WhatsApp MCP Server"); main().catch(err => { logError("Fatal error in main", err); // Give time for the error to be logged setTimeout(() => { process.exit(1); }, 1000); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gfb-47/whatsapp-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server